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