From 48d8ab66fa0b86dd41fa15388045e3413ee36c0e Mon Sep 17 00:00:00 2001 From: ripley Date: Thu, 24 Nov 2005 08:19:45 +0000 Subject: [PATCH] dynamically allocate additional menus. git-svn-id: https://svn.r-project.org/R/trunk@36438 00db46b3-68df-0310-9c12-caf00c1e9a41 --- src/gnuwin32/CHANGES | 3 +- src/gnuwin32/rui.c | 75 ++++++++++++++--------- src/library/utils/man/windows/winMenus.Rd | 7 +-- 3 files changed, 51 insertions(+), 34 deletions(-) diff --git a/src/gnuwin32/CHANGES b/src/gnuwin32/CHANGES index 99b919d8d63..42dd91d0cb3 100644 --- a/src/gnuwin32/CHANGES +++ b/src/gnuwin32/CHANGES @@ -41,7 +41,8 @@ CRAN have been updated.) Since the Goto BLAS is no longer available for Windows, support for it has been withdrawn. -winMenuAdd() now has a limit of 50 additional menus. +winMenuAdd() now has no limits on the number of menus or items, and names +are now limited to 500 (not 50) bytes. diff --git a/src/gnuwin32/rui.c b/src/gnuwin32/rui.c index 293d838e804..b0c7b129990 100644 --- a/src/gnuwin32/rui.c +++ b/src/gnuwin32/rui.c @@ -1208,12 +1208,12 @@ int DialogSelectFile(char *buf, int len) return (strlen(buf)); } -static menu usermenus[50]; -static char usermenunames[50][51]; +static menu *usermenus; +static char **usermenunames; -static Uitem umitems[500]; +static Uitem *umitems; -static int nmenus=0, nitems=0; +static int nmenus=0, nitems=0, alloc_menus=-1, alloc_items=-1; static void menuuser(control m) { @@ -1234,22 +1234,21 @@ char *getusermenuname(int pos) { menuItems *wingetmenuitems(char *mname, char *errmsg) { menuItems *items; - char mitem[102], *p, *q, *r; + char mitem[1002], *p, *q, *r; int i,j=0; - q = (char *)malloc(100 * sizeof(char)); - r = (char *)malloc(100 * sizeof(char)); + q = (char *)malloc(1000 * sizeof(char)); + r = (char *)malloc(1000 * sizeof(char)); - items = (menuItems *)malloc(sizeof(menuItems)); - items->mItems = (Uitem *)malloc(500 * sizeof(Uitem)); - - if (strlen(mname) > 100) { - strcpy(errmsg, G_("'mname' is limited to 100 chars")); - free(items->mItems); - free(items); + if (strlen(mname) > 1000) { + strcpy(errmsg, G_("'mname' is limited to 1000 bytes")); return NULL; } + items = (menuItems *)malloc(sizeof(menuItems)); + if(nitems > 0) + items->mItems = (Uitem *)malloc(alloc_items * sizeof(Uitem)); + strcpy(mitem, mname); strcat(mitem, "/"); for (i = 0; i < nitems; i++) { @@ -1319,18 +1318,26 @@ static menu getMenu(char * name) int winaddmenu(char * name, char *errmsg) { - char *p, *submenu = name, start[50]; + char *p, *submenu = name, start[501]; menu parent; if (getMenu(name)) return 0; /* Don't add repeats */ - if (nmenus >= 50) { - strcpy(errmsg, G_("Only 50 menus are allowed")); - return 2; + if (nmenus > alloc_menus) { + if(alloc_menus <= 0) { + alloc_menus = 10; + usermenus = (menu *) malloc(sizeof(menu) * alloc_menus); + usermenunames = (char **) malloc(sizeof(char *) * alloc_menus); + } else { + alloc_menus += 10; + usermenus = (menu *) realloc(usermenus, sizeof(menu) * alloc_menus); + usermenunames = (char **) realloc(usermenunames, + sizeof(char *) * alloc_menus); + } } - if (strlen(name) > 50) { - strcpy(errmsg, G_("'menu' is limited to 50 bytes")); + if (strlen(name) > 500) { + strcpy(errmsg, G_("'menu' is limited to 500 bytes")); return 5; } p = Rf_strrchr(name, '/'); @@ -1350,7 +1357,7 @@ int winaddmenu(char * name, char *errmsg) } if (m) { usermenus[nmenus] = m; - strcpy(usermenunames[nmenus], name); + usermenunames[nmenus]= strdup(name); nmenus++; show(RConsole); return 0; @@ -1364,14 +1371,14 @@ int winaddmenuitem(char * item, char * menu, char * action, char *errmsg) { int i, im; menuitem m; - char mitem[102], *p; + char mitem[1002], *p; - if (nitems > 499) { + /* if (nitems > 499) { strcpy(errmsg, G_("too many menu items have been created")); return 2; - } - if (strlen(item) + strlen(menu) > 100) { - strcpy(errmsg, G_("menu + item is limited to 100 bytes")); + } */ + if (strlen(item) + strlen(menu) > 1000) { + strcpy(errmsg, G_("menu + item is limited to 1000 bytes")); return 5; } @@ -1406,6 +1413,16 @@ int winaddmenuitem(char * item, char * menu, char * action, char *errmsg) addto(usermenus[im]); m = newmenuitem(item, 0, menuuser); if (m) { + if(alloc_items < nitems) { + if(alloc_items <= 0) { + alloc_items = 100; + umitems = (Uitem *) malloc(sizeof(Uitem) * alloc_items); + } else { + alloc_items += 100; + umitems = (Uitem *) realloc(umitems, + sizeof(Uitem) * alloc_items); + } + } umitems[nitems] = (Uitem) malloc(sizeof(uitem)); umitems[nitems]->m = m; umitems[nitems]->name = p = (char *) malloc(strlen(mitem) + 1); @@ -1479,10 +1496,10 @@ void windelmenus(char * prefix) int windelmenuitem(char * item, char * menu, char *errmsg) { int i; - char mitem[102]; + char mitem[1002]; - if (strlen(item) + strlen(menu) > 100) { - strcpy(errmsg, G_("menu + item is limited to 100 bytes")); + if (strlen(item) + strlen(menu) > 1000) { + strcpy(errmsg, G_("menu + item is limited to 1000 bytes")); return 5; } strcpy(mitem, menu); strcat(mitem, "/"); strcat(mitem, item); diff --git a/src/library/utils/man/windows/winMenus.Rd b/src/library/utils/man/windows/winMenus.Rd index d91ce16360f..e4b822835b2 100644 --- a/src/library/utils/man/windows/winMenus.Rd +++ b/src/library/utils/man/windows/winMenus.Rd @@ -18,15 +18,14 @@ winMenuNames() winMenuItems(menuname) } \arguments{ - \item{menuname}{a character string naming a menu, of up to 50 bytes.} + \item{menuname}{a character string naming a menu.} \item{itemname}{a character string naming a menu item on an existing menu.} \item{action}{a character string describing the action when that menu is selected, or \code{"enable"} or \code{"disable"}.} } \details{ User menus are added to the right of existing menus, and items are - added at the bottom of the menu. Up to 50 menus or sub-menus can be - added with up to 500 items. + added at the bottom of the menu. By default the action character string is treated as \R input, being echoed on the command line and parsed and executed as usual. @@ -67,7 +66,7 @@ winMenuItems(menuname) and submenus. \code{winMenuDelItem} just deletes one menu item. The total path to an item (menu string plus item string) cannot exceed - 100 bytes. + 1000 bytes, and the menu string cannot exceed 500 bytes. } \value{ \code{NULL}, invisibly. If an error occurs, an informative error