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