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: }

Defined functions

_AllocBinding defined in line 584; used 1 times
_AllocMenuInfo defined in line 663; used 1 times
_AllocMenuLine defined in line 648; used 3 times
_AllocMenuLink defined in line 678; used 1 times
_CheckButtonState defined in line 524; used 1 times
_ResetBindings defined in line 787; used 1 times
_ResetMenus defined in line 802; used 1 times
_ResetVariables defined in line 824; used 1 times
_StashMenuLine defined in line 693; used 3 times
_appendbinding defined in line 630; used 1 times
_appendmenuline defined in line 745; used 1 times
_appendmenulink defined in line 766; used 1 times
_bind defined in line 567; used 3 times
_buttexprlookup defined in line 465; used 1 times
_contexprlookup defined in line 445; used 1 times
_keyexprlookup defined in line 424; used 1 times
_keywordlookup defined in line 397; used 4 times
_setbinding defined in line 599; used 3 times
_stashmenuinfo defined in line 709; used 1 times
_stashmenulink defined in line 730; used 1 times
_strconcat defined in line 506; used 1 times
_y_atoi defined in line 486; used 1 times

Defined macros

C_MAP defined in line 54; used 3 times
C_MENU defined in line 53; used 2 times
C_MENUMAP defined in line 55; used 2 times
C_STRING defined in line 52; used 3 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2237
Valid CSS Valid XHTML 1.0 Strict