Skip to content

Commit

Permalink
dynamically allocate additional menus.
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.r-project.org/R/trunk@36438 00db46b3-68df-0310-9c12-caf00c1e9a41
  • Loading branch information
ripley committed Nov 24, 2005
1 parent 777436b commit 48d8ab6
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 34 deletions.
3 changes: 2 additions & 1 deletion src/gnuwin32/CHANGES
Expand Up @@ -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.



Expand Down
75 changes: 46 additions & 29 deletions src/gnuwin32/rui.c
Expand Up @@ -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)
{
Expand All @@ -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++) {
Expand Down Expand Up @@ -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, '/');
Expand All @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 3 additions & 4 deletions src/library/utils/man/windows/winMenus.Rd
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 48d8ab6

Please sign in to comment.