|
|
1.1 ! root 1: /* $Header: gram.y,v 1.6 87/05/24 22:11:00 jg Exp $ */ ! 2: ! 3: ! 4: /* ! 5: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. ! 6: * ! 7: * All Rights Reserved ! 8: * ! 9: * Permission to use, copy, modify, and distribute this software and its ! 10: * documentation for any purpose and without fee is hereby granted, ! 11: * provided that the above copyright notice appear in all copies and that ! 12: * both that copyright notice and this permission notice appear in ! 13: * supporting documentation, and that the name of Digital Equipment ! 14: * Corporation not be used in advertising or publicity pertaining to ! 15: * distribution of the software without specific, written prior permission. ! 16: * ! 17: * ! 18: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 19: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 20: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 21: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 22: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 23: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 24: * SOFTWARE. ! 25: */ ! 26: ! 27: ! 28: /* ! 29: * MODIFICATION HISTORY ! 30: * ! 31: * 000 -- M. Gancarz, DEC Ultrix Engineering Group ! 32: * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group ! 33: * Western Software Lab. Convert to X11. ! 34: */ ! 35: ! 36: %{ ! 37: #ifndef lint ! 38: static char *sccsid = "@(#)gram.y 3.8 1/24/86"; ! 39: #endif ! 40: ! 41: #include <X11/copyright.h> ! 42: #include "uwm.h" ! 43: ! 44: /* ! 45: * Values returned by complex expression parser. ! 46: */ ! 47: #define C_STRING 1 /* IsString. */ ! 48: #define C_MENU 2 /* IsMenu. */ ! 49: #define C_MAP 3 /* IsMap. */ ! 50: #define C_MENUMAP 4 /* IsMenuMap. */ ! 51: ! 52: static int ki; /* Keyword index. */ ! 53: static int bkmask; /* Button/key mask. */ ! 54: static int cmask; /* Context mask. */ ! 55: static char msg[BUFSIZ]; /* Error message buffer. */ ! 56: static char *menu_name; /* Menu name. */ ! 57: static MenuInfo *menu_info; /* Menu info. */ ! 58: static MenuLine *ml_ptr; /* Temporary menu line pointer. */ ! 59: static char *hcolors[4]; /* Color values used in menu hdrs. */ ! 60: static char *mcolors[2]; /* Color values used in menus. */ ! 61: MenuLink *menu_link; /* Temporary menu link pointer. */ ! 62: ! 63: char *calloc(); ! 64: ! 65: %} ! 66: ! 67: %union { ! 68: char *sval; ! 69: int ival; ! 70: short shval; ! 71: struct _menuline *mlval; ! 72: struct _menuinfo *mival; ! 73: char **cval; ! 74: } ! 75: ! 76: %token NL ! 77: %token <sval> STRING ! 78: %token <ival> COMMENT ! 79: %type <ival> keyword ! 80: %type <ival> compexpr ! 81: %type <ival> keyexpr ! 82: %type <ival> kmask ! 83: %type <ival> contexpr ! 84: %type <ival> contmask ! 85: %type <ival> buttmodexpr ! 86: %type <ival> buttmodifier ! 87: %type <ival> buttexpr ! 88: %type <sval> menuname ! 89: %type <sval> strings ! 90: %type <sval> color ! 91: %type <cval> color2 ! 92: %type <cval> color4 ! 93: %type <mlval> menuexpr ! 94: %type <mlval> menulist ! 95: %type <mlval> menuline ! 96: %type <mlval> menuaction ! 97: ! 98: %% /* beginning of rules section */ ! 99: ! 100: input: | input command ! 101: | input error command { yyerrok; } ! 102: ; ! 103: ! 104: command: boolvar term ! 105: | expr term ! 106: | COMMENT { Lineno++; } ! 107: | term ! 108: ; ! 109: ! 110: term: NL { Lineno++; } ! 111: | ';' ! 112: ; ! 113: ! 114: expr: keyword '=' compexpr ! 115: { ! 116: switch (KeywordTable[$1].type) { ! 117: case IsString: ! 118: if ($3 == C_STRING) { ! 119: strcpy(KeywordTable[$1].sptr, ! 120: yylval.sval); ! 121: } else { ! 122: yyerror("illegal construct"); ! 123: } ! 124: free(yylval.sval); ! 125: break; ! 126: case IsNumeric: ! 127: if ($3 == C_STRING) { ! 128: *(KeywordTable[$1].nptr) = ! 129: y_atoi(yylval.sval); ! 130: } else yyerror("illegal construct"); ! 131: free(yylval.sval); ! 132: break; ! 133: case IsBoolTrue: ! 134: case IsBoolFalse: ! 135: yyerror("illegal value assignment"); ! 136: break; ! 137: case IsQuitFunction: ! 138: case IsFunction: ! 139: if ($3 == C_MAP) { ! 140: bindtofunc($1, bkmask, cmask, NULL); ! 141: } else yyerror("illegal construct"); ! 142: break; ! 143: case IsDownFunction: ! 144: if (bkmask & ButtonUp) { ! 145: sprintf(msg, ! 146: "cannot bind %s to button up", ! 147: KeywordTable[$1].name); ! 148: yyerror(msg); ! 149: } ! 150: if ($3 == C_MAP) { ! 151: bindtofunc($1, bkmask, cmask, NULL); ! 152: } else yyerror("illegal construct"); ! 153: break; ! 154: case IsMenuMap: ! 155: if (bkmask & ButtonUp) { ! 156: sprintf(msg, ! 157: "cannot bind %s to button up", ! 158: KeywordTable[$1].name); ! 159: yyerror(msg); ! 160: } ! 161: if ($3 == C_MENUMAP) { ! 162: bindtofunc ! 163: ($1, bkmask, cmask, menu_name); ! 164: } else yyerror("illegal construct"); ! 165: break; ! 166: case IsMenu: ! 167: if ($3 == C_MENU) { ! 168: menu_info = stashmenuinfo(menu_name, ml_ptr, hcolors); ! 169: menu_link = stashmenulink(menu_info); ! 170: Menus = appendmenulink(Menus, menu_link); ! 171: } else yyerror("illegal menu construct"); ! 172: break; ! 173: default: ! 174: yyerror("internal binding error"); ! 175: break; ! 176: } ! 177: } ! 178: ; ! 179: ! 180: compexpr: keyexpr ':' contexpr ':' buttexpr ! 181: { ! 182: $$ = C_MAP; ! 183: bkmask = $1 | $5; ! 184: cmask = $3; ! 185: } ! 186: | keyexpr ':' contexpr ':' buttexpr ':' menuname ! 187: { ! 188: $$ = C_MENUMAP; ! 189: bkmask = $1 | $5; ! 190: cmask = $3; ! 191: menu_name = $7; ! 192: } ! 193: | STRING color4 menuexpr ! 194: { ! 195: $$ = C_MENU; ! 196: menu_name = $1; ! 197: ml_ptr = $3; ! 198: } ! 199: | STRING ! 200: { $$ = C_STRING; } ! 201: ; ! 202: ! 203: boolvar: STRING ! 204: { ! 205: ki = keywordlookup(yylval.sval); ! 206: switch (KeywordTable[ki].type) { ! 207: case IsBoolTrue: ! 208: *(KeywordTable[ki].bptr) = TRUE; ! 209: break; ! 210: case IsBoolFalse: ! 211: *(KeywordTable[ki].bptr) = FALSE; ! 212: break; ! 213: case IsParser: ! 214: (*KeywordTable[ki].fptr)(); ! 215: break; ! 216: default: ! 217: yyerror("keyword error"); ! 218: } ! 219: } ! 220: ; ! 221: ! 222: keyword: STRING { ! 223: $$ = keywordlookup(yylval.sval); ! 224: } ! 225: ; ! 226: ! 227: keyexpr: /* empty */ ! 228: { $$ = 0; } ! 229: | kmask ! 230: { $$ = $1; } ! 231: | kmask '|' kmask ! 232: { $$ = $1 | $3; } ! 233: ; ! 234: ! 235: contexpr: /* empty */ ! 236: { $$ = ROOT | WINDOW | ICON; } ! 237: | contmask ! 238: { $$ = $1; } ! 239: | contmask '|' contmask ! 240: { $$ = $1 | $3; } ! 241: | contmask '|' contmask '|' contmask ! 242: { $$ = $1 | $3 | $5; } ! 243: ; ! 244: ! 245: buttexpr: buttmodexpr ! 246: { $$ = CheckButtonState($1); } ! 247: ; ! 248: ! 249: kmask: STRING { $$ = keyexprlookup(yylval.sval); } ! 250: ! 251: contmask: STRING { $$ = contexprlookup(yylval.sval); } ! 252: ! 253: buttmodexpr: buttmodifier ! 254: { $$ = $1; } ! 255: | buttmodexpr buttmodifier ! 256: { $$ = $1 | $2; } ! 257: ; ! 258: ! 259: buttmodifier: STRING ! 260: { $$ = buttexprlookup(yylval.sval); } ! 261: ; ! 262: ! 263: menuname: STRING ! 264: { $$ = $1; } ! 265: ; ! 266: ! 267: menuexpr: '{' menulist '}' ! 268: { $$ = $2; } ! 269: ; ! 270: ! 271: menulist: menuline ! 272: { $$ = $1; } ! 273: | menulist menuline ! 274: { $$ = appendmenuline($1, $2); } ! 275: | menulist COMMENT ! 276: { ! 277: Lineno++; ! 278: $$ = $1; ! 279: } ! 280: | COMMENT ! 281: { ! 282: Lineno++; ! 283: $$ = NULL; ! 284: } ! 285: | term ! 286: { $$ = NULL; } ! 287: | menulist term ! 288: { $$ = $1; } ! 289: | error term ! 290: { ! 291: $$ = NULL; ! 292: yyerrok; ! 293: } ! 294: ; ! 295: ! 296: menuline: strings ':' color2 menuaction term ! 297: { ! 298: $4->name = $1; ! 299: $4->foreground = mcolors[0]; ! 300: $4->background = mcolors[1]; ! 301: $$ = $4; ! 302: } ! 303: ; ! 304: ! 305: menuaction: STRING ! 306: { ! 307: ki = keywordlookup(yylval.sval); ! 308: if ((ki != -1) && ! 309: (KeywordTable[ki].type != IsFunction) && ! 310: (KeywordTable[ki].type != IsQuitFunction) && ! 311: (KeywordTable[ki].type != IsDownFunction)) { ! 312: sprintf(msg, ! 313: "menu action \"%s\" not a function", ! 314: KeywordTable[ki].name); ! 315: yyerror(msg); ! 316: } ! 317: ml_ptr = AllocMenuLine(); ! 318: if (KeywordTable[ki].type == IsQuitFunction) ! 319: ml_ptr->type = IsImmFunction; ! 320: else ml_ptr->type = IsUwmFunction; ! 321: ml_ptr->func = KeywordTable[ki].fptr; ! 322: $$ = ml_ptr; ! 323: } ! 324: | STRING ':' menuname ! 325: { ! 326: ki = keywordlookup($1); ! 327: if (ki != -1 && ! 328: KeywordTable[ki].type != IsMenuMap) { ! 329: sprintf(msg, ! 330: "menu action \"%s\" not a menu function", ! 331: KeywordTable[ki].name); ! 332: yyerror(msg); ! 333: } ! 334: ml_ptr = AllocMenuLine(); ! 335: ml_ptr->type = IsMenuFunction; ! 336: ml_ptr->text = $3; ! 337: $$ = ml_ptr; ! 338: } ! 339: | '!' strings ! 340: { ! 341: $$ = StashMenuLine(IsShellCommand, $2); ! 342: } ! 343: | '^' strings ! 344: { ! 345: $$ = StashMenuLine(IsTextNL, $2); ! 346: } ! 347: | '|' strings ! 348: { ! 349: $$ = StashMenuLine(IsText, $2); ! 350: } ! 351: ; ! 352: ! 353: strings: STRING { $$ = yylval.sval; } ! 354: | strings STRING ! 355: { $$ = strconcat($1, $2); } ! 356: ; ! 357: ! 358: color4: '(' color ':' color ':' color ':' color ')' ! 359: { ! 360: hcolors[0] = $2; ! 361: hcolors[1] = $4; ! 362: hcolors[2] = $6; ! 363: hcolors[3] = $8; ! 364: $$ = hcolors; ! 365: } ! 366: | /* empty */ ! 367: { ! 368: hcolors[0] = NULL; ! 369: hcolors[1] = NULL; ! 370: hcolors[2] = NULL; ! 371: hcolors[3] = NULL; ! 372: $$ = hcolors; ! 373: } ! 374: ; ! 375: ! 376: color2: '(' color ':' color ')' ':' ! 377: { ! 378: mcolors[0] = $2; ! 379: mcolors[1] = $4; ! 380: $$ = mcolors; ! 381: } ! 382: | /* empty */ ! 383: { ! 384: mcolors[0] = NULL; ! 385: mcolors[1] = NULL; ! 386: $$ = mcolors; ! 387: } ! 388: ; ! 389: ! 390: color: STRING { $$ = yylval.sval; } ! 391: | /* empty */ { $$ = NULL; } ! 392: ; ! 393: %% ! 394: ! 395: /* ! 396: * Look up a string in the keyword table and return its index, else ! 397: * return -1. ! 398: */ ! 399: keywordlookup(string) ! 400: char *string; ! 401: { ! 402: int i; ! 403: ! 404: for (i = 0; KeywordTable[i].name; i++) { ! 405: if (!strcmp(KeywordTable[i].name, string)) { ! 406: free(string); ! 407: return(i); ! 408: } ! 409: } ! 410: sprintf(msg,"keyword error: \"%s\"", string); ! 411: yyerror(msg); ! 412: free(string); ! 413: return(-1); ! 414: } ! 415: ! 416: /* ! 417: * Look up a string in the key expression table and return its mask, else ! 418: * return -1. ! 419: */ ! 420: int keyexprlookup(string) ! 421: char *string; ! 422: { ! 423: int i; ! 424: ! 425: for (i = 0; KeyExprTbl[i].name; i++) { ! 426: if (!strcmp(KeyExprTbl[i].name, string)) { ! 427: free(string); ! 428: return(KeyExprTbl[i].mask); ! 429: } ! 430: } ! 431: sprintf(msg,"key expression error: \"%s\"", string); ! 432: yyerror(msg); ! 433: free(string); ! 434: return(-1); ! 435: } ! 436: ! 437: /* ! 438: * Look up a string in the context expression table and return its mask, else ! 439: * return -1. ! 440: */ ! 441: contexprlookup(string) ! 442: char *string; ! 443: { ! 444: int i; ! 445: ! 446: for (i = 0; ContExprTbl[i].name; i++) { ! 447: if (!strcmp(ContExprTbl[i].name, string)) { ! 448: free(string); ! 449: return(ContExprTbl[i].mask); ! 450: } ! 451: } ! 452: sprintf(msg,"context expression error: \"%s\"", string); ! 453: yyerror(msg); ! 454: free(string); ! 455: return(-1); ! 456: } ! 457: /* ! 458: * Look up a string in the button expression table and return its mask, else ! 459: * return -1. ! 460: */ ! 461: buttexprlookup(string) ! 462: char *string; ! 463: { ! 464: int i; ! 465: ! 466: for (i = 0; ButtModTbl[i].name; i++) { ! 467: if (!strcmp(ButtModTbl[i].name, string)) { ! 468: free(string); ! 469: return(ButtModTbl[i].mask); ! 470: } ! 471: } ! 472: sprintf(msg,"button modifier error: \"%s\"", string); ! 473: yyerror(msg); ! 474: free(string); ! 475: return(-1); ! 476: } ! 477: ! 478: /* ! 479: * Scan a string and return an integer. Report an error if any ! 480: * non-numeric characters are found. ! 481: */ ! 482: y_atoi(s) ! 483: char *s; ! 484: { ! 485: int n = 0; ! 486: ! 487: while (*s) { ! 488: if (*s >= '0' && *s <= '9') ! 489: n = 10 * n + *s - '0'; ! 490: else { ! 491: yyerror("non-numeric argument"); ! 492: return(-1); ! 493: } ! 494: s++; ! 495: } ! 496: return(n); ! 497: } ! 498: ! 499: /* ! 500: * Append s2 to s1, extending s1 as necessary. ! 501: */ ! 502: char * ! 503: strconcat(s1, s2) ! 504: char *s1, *s2; ! 505: { ! 506: char *malloc(); ! 507: char *p; ! 508: ! 509: p = malloc(strlen(s1) + strlen(s2) + 2); ! 510: sprintf(p, "%s %s", s1, s2); ! 511: free(s1); ! 512: free(s2); ! 513: s1 = p; ! 514: return(s1); ! 515: } ! 516: ! 517: /* ! 518: * Check a button expression for errors. ! 519: */ ! 520: int ! 521: CheckButtonState(expr) ! 522: int expr; ! 523: { ! 524: /* ! 525: * Check for one (and only one) button. ! 526: */ ! 527: switch (expr & (LeftMask | MiddleMask | RightMask)) { ! 528: case 0: ! 529: yyerror("no button specified"); ! 530: break; ! 531: case LeftMask: ! 532: break; ! 533: case MiddleMask: ! 534: break; ! 535: case RightMask: ! 536: break; ! 537: default: ! 538: yyerror("more than one button specified"); ! 539: } ! 540: ! 541: /* ! 542: * Check for one (and only one) up/down/motion modifier. ! 543: */ ! 544: switch (expr & (ButtonUp | ButtonDown | DeltaMotion)) { ! 545: case 0: ! 546: yyerror("no button action specified"); ! 547: break; ! 548: case ButtonUp: ! 549: break; ! 550: case ButtonDown: ! 551: break; ! 552: case DeltaMotion: ! 553: break; ! 554: default: ! 555: yyerror("only one of up/down/motion may be specified"); ! 556: } ! 557: return(expr); ! 558: } ! 559: ! 560: /* ! 561: * Bind button/key/context to a function. ! 562: */ ! 563: bindtofunc(index, mask, context, name) ! 564: int index; /* Index into keyword table. */ ! 565: int mask; /* Button/key/modifier mask. */ ! 566: int context; /* ROOT, WINDOW, or ICON. */ ! 567: char *name; /* Menu, if needed. */ ! 568: { ! 569: if (context & ROOT) ! 570: setbinding(ROOT, index, mask, name); ! 571: if (context & ICON) ! 572: setbinding(ICON, index, mask, name); ! 573: if (context & WINDOW) ! 574: setbinding(WINDOW, index, mask, name); ! 575: } ! 576: ! 577: /* ! 578: * Allocate a Binding type and return a pointer. ! 579: */ ! 580: Binding * ! 581: AllocBinding() ! 582: { ! 583: Binding *ptr; ! 584: ! 585: if (!(ptr = (Binding *)calloc(1, sizeof(Binding)))) { ! 586: fprintf(stderr, "Can't allocate binding--out of space\n"); ! 587: exit(1); ! 588: } ! 589: return(ptr); ! 590: } ! 591: ! 592: /* ! 593: * Stash the data in a Binding. ! 594: */ ! 595: setbinding(cont, i, m, mname) ! 596: int cont; /* Context: ROOT, WINDOW, or ICON. */ ! 597: int i; /* Keyword table index. */ ! 598: int m; /* Key/button/modifier mask. */ ! 599: char *mname; /* Pointer to menu name, if needed. */ ! 600: { ! 601: Binding *ptr; ! 602: ! 603: ptr = AllocBinding(); ! 604: ptr->context = cont; ! 605: ptr->mask = m; ! 606: ptr->func = KeywordTable[i].fptr; ! 607: ptr->menuname = mname; ! 608: ! 609: switch (m & (LeftMask | MiddleMask | RightMask)) { ! 610: case LeftMask: ! 611: ptr->button = LeftButton; ! 612: break; ! 613: case MiddleMask: ! 614: ptr->button = MiddleButton; ! 615: break; ! 616: case RightMask: ! 617: ptr->button = RightButton; ! 618: break; ! 619: } ! 620: appendbinding(ptr); ! 621: } ! 622: ! 623: /* ! 624: * Append a Binding to the Bindings list. ! 625: */ ! 626: appendbinding(binding) ! 627: Binding *binding; ! 628: { ! 629: Binding *ptr; ! 630: ! 631: if (Blist == NULL) ! 632: Blist = binding; ! 633: else { ! 634: for(ptr = Blist; ptr->next; ptr = ptr->next) /* NULL */; ! 635: ptr->next = binding; ! 636: ptr = ptr->next; ! 637: ptr->next = NULL; ! 638: } ! 639: } ! 640: ! 641: /* ! 642: * Allocate a menu line and return a pointer. ! 643: */ ! 644: MenuLine * ! 645: AllocMenuLine() ! 646: { ! 647: MenuLine *ptr; ! 648: ! 649: if (!(ptr = (MenuLine *)calloc(1, sizeof(MenuLine)))) { ! 650: fprintf(stderr, "Can't allocate menu line--out of space\n"); ! 651: exit(1); ! 652: } ! 653: return(ptr); ! 654: } ! 655: ! 656: /* ! 657: * Allocate a MenuInfo structure and return a pointer. ! 658: */ ! 659: MenuInfo * ! 660: AllocMenuInfo() ! 661: { ! 662: MenuInfo *ptr; ! 663: ! 664: if (!(ptr = (MenuInfo *)calloc(1, sizeof(MenuInfo)))) { ! 665: fprintf(stderr, "Can't allocate menu storage--out of space\n"); ! 666: exit(1); ! 667: } ! 668: return(ptr); ! 669: } ! 670: ! 671: /* ! 672: * Allocate a MenuLink structure and return a pointer. ! 673: */ ! 674: MenuLink * ! 675: AllocMenuLink() ! 676: { ! 677: MenuLink *ptr; ! 678: ! 679: if (!(ptr = (MenuLink *)calloc(1, sizeof(MenuLink)))) { ! 680: fprintf(stderr, "Can't allocate menu linked list storage--out of space\n"); ! 681: exit(1); ! 682: } ! 683: return(ptr); ! 684: } ! 685: ! 686: /* ! 687: * Stash the data in a menu line. ! 688: */ ! 689: MenuLine * ! 690: StashMenuLine(type, string) ! 691: int type; ! 692: char *string; ! 693: { ! 694: MenuLine *ptr; ! 695: ! 696: ptr = AllocMenuLine(); ! 697: ptr->type = type; ! 698: ptr->text = string; ! 699: return(ptr); ! 700: } ! 701: ! 702: /* ! 703: * Stash menu data in a MenuInfo structure; ! 704: */ ! 705: MenuInfo * ! 706: stashmenuinfo(name, line, colors) ! 707: char *name; ! 708: MenuLine *line; ! 709: char *colors[]; ! 710: { ! 711: MenuInfo *ptr; ! 712: ! 713: ptr = AllocMenuInfo(); ! 714: ptr->name = name; ! 715: ptr->line = line; ! 716: ptr->foreground = colors[1]; ! 717: ptr->background = colors[0]; ! 718: ptr->fghighlight = colors[2]; ! 719: ptr->bghighlight = colors[3]; ! 720: return(ptr); ! 721: } ! 722: ! 723: /* ! 724: * Stash menu info data in a MenuLink structure; ! 725: */ ! 726: MenuLink * ! 727: stashmenulink(menuinfo) ! 728: MenuInfo *menuinfo; ! 729: { ! 730: MenuLink *ptr; ! 731: ! 732: ptr = AllocMenuLink(); ! 733: ptr->next = NULL; ! 734: ptr->menu = menuinfo; ! 735: return(ptr); ! 736: } ! 737: ! 738: /* ! 739: * Append a menu line to a linked list of menu lines. ! 740: */ ! 741: MenuLine * ! 742: appendmenuline(list, line) ! 743: MenuLine *list; ! 744: MenuLine *line; ! 745: { ! 746: MenuLine *ptr; ! 747: ! 748: if (list == NULL) ! 749: list = line; ! 750: else { ! 751: for(ptr = list; ptr->next; ptr = ptr->next) /* NULL */; ! 752: ptr->next = line; ! 753: ptr = ptr->next; ! 754: ptr->next = NULL; ! 755: } ! 756: return(list); ! 757: } ! 758: ! 759: /* ! 760: * Append a menu to a linked list of menus. ! 761: */ ! 762: MenuLink * ! 763: appendmenulink(list, link) ! 764: MenuLink *list; ! 765: MenuLink *link; ! 766: { ! 767: MenuLink *ptr; ! 768: ! 769: if (list == NULL) ! 770: list = link; ! 771: else { ! 772: for(ptr = list; ptr->next; ptr = ptr->next) /* NULL */; ! 773: ptr->next = link; ! 774: ptr = ptr->next; ! 775: ptr->next = NULL; ! 776: } ! 777: return(list); ! 778: } ! 779: ! 780: /* ! 781: * Reset all previous bindings and free the space allocated to them. ! 782: */ ! 783: Bool ResetBindings() ! 784: { ! 785: Binding *ptr, *nextptr; ! 786: ! 787: for(ptr = Blist; ptr; ptr = nextptr) { ! 788: if(ptr->menuname) free(ptr->menuname); ! 789: nextptr = ptr->next; ! 790: free(ptr); ! 791: } ! 792: Blist = NULL; ! 793: } ! 794: ! 795: /* ! 796: * De-allocate all menus. ! 797: */ ! 798: Bool ResetMenus() ! 799: { ! 800: MenuLink *mptr, *next_mptr; ! 801: register MenuLine *lptr, *next_lptr; ! 802: ! 803: for(mptr = Menus; mptr; mptr = next_mptr) { ! 804: free(mptr->menu->name); ! 805: for(lptr = mptr->menu->line; lptr; lptr = next_lptr) { ! 806: free(lptr->name); ! 807: if (lptr->text) free(lptr->text); ! 808: next_lptr = lptr->next; ! 809: free(lptr); ! 810: } ! 811: next_mptr = mptr->next; ! 812: free(mptr); ! 813: } ! 814: Menus = NULL; ! 815: } ! 816: ! 817: /* ! 818: * Set all numeric variables to zero and all boolean variables to FALSE. ! 819: */ ! 820: Bool ResetVariables() ! 821: { ! 822: register int i; ! 823: ! 824: for (i = 0; KeywordTable[i].name; i++) { ! 825: switch (KeywordTable[i].type) { ! 826: case IsBoolTrue: ! 827: case IsBoolFalse: ! 828: *(KeywordTable[i].bptr) = FALSE; ! 829: break; ! 830: case IsNumeric: ! 831: *(KeywordTable[i].nptr) = 0; ! 832: break; ! 833: default: ! 834: break; ! 835: } ! 836: } ! 837: SetVarDefaults(); ! 838: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.