1 /*****************************************************************************/
2 /** Copyright 1988 by Evans & Sutherland Computer Corporation, **/
3 /** Salt Lake City, Utah **/
4 /** Portions Copyright 1989 by the Massachusetts Institute of Technology **/
5 /** Cambridge, Massachusetts **/
6 /** **/
7 /** All Rights Reserved **/
8 /** **/
9 /** Permission to use, copy, modify, and distribute this software and **/
10 /** its documentation for any purpose and without fee is hereby **/
11 /** granted, provided that the above copyright notice appear in all **/
12 /** copies and that both that copyright notice and this permis- **/
13 /** sion notice appear in supporting documentation, and that the **/
14 /** names of Evans & Sutherland and M.I.T. not be used in advertising **/
15 /** in publicity pertaining to distribution of the software without **/
16 /** specific, written prior permission. **/
17 /** **/
18 /** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/
19 /** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/
20 /** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/
21 /** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/
22 /** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/
23 /** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/
24 /** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/
25 /** OR PERFORMANCE OF THIS SOFTWARE. **/
26 /*****************************************************************************/
27
28
29 /***********************************************************************
30 *
31 * $XConsortium: gram.y,v 1.91 91/02/08 18:21:56 dave Exp $
32 *
33 * .twmrc command grammer
34 *
35 * 07-Jan-86 Thomas E. LaStrange File created
36 * 11-Nov-90 Dave Sternlicht Adding SaveColors
37 * 10-Oct-90 David M. Sternlicht Storing saved colors on root
38 *
39 ***********************************************************************/
40
41 %{
42 #ifndef YYBISON /* bison includes stdio.h automatically */
43 #include <stdio.h>
44 #endif
45 #include <ctype.h>
46 #include "twm.h"
47 #include "menus.h"
48 #include "list.h"
49 #include "util.h"
50 #include "screen.h"
51 #include "parse.h"
52 #include <X11/Xos.h>
53 #include <X11/Xmu/CharSet.h>
54
55 static char *Action = "";
56 static char *Name = "";
57 static MenuRoot *root, *pull = NULL;
58 static int menu_default_index;
59
60 static MenuRoot *GetRoot();
61
62 static Bool CheckWarpScreenArg(), CheckWarpRingArg();
63 static Bool CheckColormapArg();
64 static void GotButton(), GotKey(), GotTitleButton();
65 #ifdef RJC
66 extern char *CacheAndNameIconImage();
67 #endif
68
69 static char *ptr;
70 static name_list **list;
71 static int cont = 0;
72 static int color;
73 int mods = 0;
74 char *menu_name = NULL; /* if we are reading a menu */
75 MenuRoot *input_menu;
76
77 unsigned int mods_used = (ShiftMask | ControlMask | Mod1Mask);
78
79 extern int do_single_keyword(), do_string_keyword(), do_number_keyword();
80 extern name_list **do_colorlist_keyword();
81 extern int do_color_keyword(), do_string_savecolor();
82 extern int yylineno;
83 %}
84
85 %union
86 {
87 int num;
88 char *ptr;
89 struct {
90 short ltype;
91 char *lval;
92 } match;
93 struct {
94 char *gstring;
95 short itterate;
96 } geom;
97 };
98
99 %token <num> LB RB LP RP MENUS MENU BUTTON DEFAULT_FUNCTION PLUS MINUS
100 %token <num> ASTERISK GREATER
101 %token <num> ALL OR CURSORS PIXMAPS ICONS COLOR SAVECOLOR MONOCHROME FUNCTION
102 %token <num> ICONMGR_SHOW ICONMGR WINDOW_FUNCTION ZOOM ICONMGRS
103 %token <num> ICONMGR_GEOMETRY ICONMGR_NOSHOW MAKE_TITLE
104 %token <num> ICONIFY_BY_UNMAPPING DONT_ICONIFY_BY_UNMAPPING STICKY
105 %token <num> NO_TITLE AUTO_RAISE NO_HILITE ICON_REGION
106 %token <num> META SHIFT LOCK CONTROL WINDOW TITLE ICON ROOT FRAME
107 %token <num> COLON EQUALS TILDE SQUEEZE_TITLE DONT_SQUEEZE_TITLE
108 %token <num> SQUEEZE_ICON DONT_SQUEEZE_ICON
109 %token <num> START_ICONIFIED NO_TITLE_HILITE TITLE_HILITE
110 %token <num> MOVE RESIZE WAIT_CURS SELECT KILL LEFT_TITLEBUTTON RIGHT_TITLEBUTTON
111 %token <num> NUMBER KEYWORD MKEYWORD NKEYWORD CKEYWORD CLKEYWORD FKEYWORD
112 %token <num> FSKEYWORD SKEYWORD DKEYWORD JKEYWORD PKEYWORD WINDOW_RING
113 %token <num> WARP_CURSOR ERRORTOKEN NO_STACKMODE ICON_TITLE NO_ICON_TITLE
114 %token <ptr> STRING REGEXP
115
116 %type <ptr> string regexp
117 %type <geom> geometry
118 %type <match> matcher
119 %type <num> action button number signed_number full fullkey def_indicator
120
121 %start file
122
123 /*
124 * Notice that this grammar reads tvtwmrc files *and* menu files. It would
125 * make more sense to have two separate parsers, but it is not possible
126 * to have two yacc grammars in one program without non portable hackery
127 * (so far as I know).
128 */
129
130 %%
131 file : twmrc { input_menu = NULL; }
132 | menufile { input_menu = root; }
133 | menutreefile {input_menu = GetRoot(menu_name, NULL, NULL); }
134 ;
135
136 menufile : { root = GetRoot(menu_name, NULL, NULL); }
137 menu_body
138 ;
139
140 menutreefile : menu_definition
141 | menutreefile menu_definition
142 ;
143
144 twmrc : /* Empty */
145 | stmts
146 ;
147
148 stmts : stmt
149 | stmts stmt
150 | stmts menu_definition
151 ;
152
153 stmt : error { printf("error in statements\n"); }
154 | noarg
155 | sarg
156 | narg
157 | squeeze
158 | ICON_REGION geometry DKEYWORD DKEYWORD number number
159 { AddIconRegion("", LTYPE_ANYTHING,
160 $2.gstring, $2.itterate,
161 $3, $4, $5, $6); }
162 | ICON_REGION matcher geometry DKEYWORD DKEYWORD number number
163 { AddIconRegion($2.lval, $2.ltype,
164 $3.gstring, $3.itterate,
165 $4, $5, $6, $7); }
166 | ICONMGR_GEOMETRY string number { if (Scr->FirstTime)
167 {
168 Scr->iconmgr.geometry=$2;
169 Scr->iconmgr.columns=$3;
170 }
171 }
172 | ICONMGR_GEOMETRY string { if (Scr->FirstTime)
173 Scr->iconmgr.geometry = $2;
174 }
175 | ZOOM number { if (Scr->FirstTime)
176 {
177 Scr->DoZoom = TRUE;
178 Scr->ZoomCount = $2;
179 }
180 }
181 | ZOOM { if (Scr->FirstTime)
182 Scr->DoZoom = TRUE; }
183 | PIXMAPS pixmap_list {}
184 | CURSORS cursor_list {}
185 | ICONIFY_BY_UNMAPPING { list = &Scr->IconifyByUn; }
186 win_list
187 | ICONIFY_BY_UNMAPPING { if (Scr->FirstTime)
188 Scr->IconifyByUnmapping = TRUE; }
189 | LEFT_TITLEBUTTON string EQUALS action {
190 GotTitleButton ($2, $4, False);
191 }
192 | RIGHT_TITLEBUTTON string EQUALS action {
193 GotTitleButton ($2, $4, True);
194 }
195 | button string { root = GetRoot($2, NULLSTR, NULLSTR);
196 Scr->Mouse[$1][C_ROOT][0].func = F_MENU;
197 Scr->Mouse[$1][C_ROOT][0].menu = root;
198 }
199 | button action { Scr->Mouse[$1][C_ROOT][0].func = $2;
200 if ($2 == F_MENU)
201 {
202 pull->prev = NULL;
203 Scr->Mouse[$1][C_ROOT][0].menu = pull;
204 }
205 else
206 {
207 root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
208 Scr->Mouse[$1][C_ROOT][0].item =
209 AddToMenu(root,"x",Action,
210 NULLSTR,$2,NULLSTR,NULLSTR);
211 }
212 Action = "";
213 pull = NULL;
214 }
215 | string fullkey { GotKey($1, $2); }
216 | button full { GotButton($1, $2); }
217 | DONT_ICONIFY_BY_UNMAPPING { list = &Scr->DontIconify; }
218 win_list
219 | ICONMGR_NOSHOW { list = &Scr->IconMgrNoShow; }
220 win_list
221 | ICONMGR_NOSHOW { Scr->IconManagerDontShow = TRUE; }
222 | ICONMGRS { list = &Scr->IconMgrs; }
223 iconm_list
224 | ICONMGR_SHOW { list = &Scr->IconMgrShow; }
225 win_list
226 | NO_TITLE_HILITE { list = &Scr->NoTitleHighlight; }
227 win_list
228 | NO_TITLE_HILITE { if (Scr->FirstTime)
229 Scr->TitleHighlight = FALSE; }
230 | NO_HILITE { list = &Scr->NoHighlight; }
231 win_list
232 | NO_HILITE { if (Scr->FirstTime)
233 Scr->Highlight = FALSE; }
234 | NO_STACKMODE { list = &Scr->NoStackModeL; }
235 win_list
236 | NO_STACKMODE { if (Scr->FirstTime)
237 Scr->StackMode = FALSE; }
238 | NO_TITLE { list = &Scr->NoTitle; }
239 win_list
240 | NO_TITLE { if (Scr->FirstTime)
241 Scr->NoTitlebar = TRUE; }
242 | NO_ICON_TITLE { list = &Scr->NoIconTitleL; }
243 win_list
244 | NO_ICON_TITLE { if (Scr->FirstTime)
245 Scr->NoIconTitle = TRUE; }
246 | ICON_TITLE { list = &Scr->IconTitleL; }
247 win_list
248 | MAKE_TITLE { list = &Scr->MakeTitle; }
249 win_list
250 | START_ICONIFIED { list = &Scr->StartIconified; }
251 win_list
252 | AUTO_RAISE { list = &Scr->AutoRaise; }
253 win_list
254 | STICKY { list = &Scr->StickyL; }
255 win_list
256 | FUNCTION string { root = GetRoot($2, NULLSTR, NULLSTR); }
257 function
258 | ICONS { list = &Scr->IconNames; }
259 icon_list
260 | COLOR { color = COLOR; }
261 color_list
262 | SAVECOLOR { }
263 save_color_list
264 | MONOCHROME { color = MONOCHROME; }
265 color_list
266 | DEFAULT_FUNCTION action { Scr->DefaultFunction.func = $2;
267 if ($2 == F_MENU)
268 {
269 pull->prev = NULL;
270 Scr->DefaultFunction.menu = pull;
271 }
272 else
273 {
274 root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
275 Scr->DefaultFunction.item =
276 AddToMenu(root,"x",Action,
277 NULLSTR,$2, NULLSTR, NULLSTR);
278 }
279 Action = "";
280 pull = NULL;
281 }
282 | WINDOW_FUNCTION action { Scr->WindowFunction.func = $2;
283 root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
284 Scr->WindowFunction.item =
285 AddToMenu(root,"x",Action,
286 NULLSTR,$2, NULLSTR, NULLSTR);
287 Action = "";
288 pull = NULL;
289 }
290 | WARP_CURSOR { list = &Scr->WarpCursorL; }
291 win_list
292 | WARP_CURSOR { if (Scr->FirstTime)
293 Scr->WarpCursor = TRUE; }
294 | WINDOW_RING { list = &Scr->WindowRingL; }
295 win_list
296 ;
297
298
299 noarg : KEYWORD { if (!do_single_keyword ($1)) {
300 twmrc_error_prefix();
301 fprintf (stderr,
302 "unknown singleton keyword %d\n",
303 $1);
304 ParseError = 1;
305 }
306 }
307 ;
308
309 sarg : SKEYWORD string { if (!do_string_keyword ($1, $2)) {
310 twmrc_error_prefix();
311 fprintf (stderr,
312 "unknown string keyword %d (value \"%s\")\n",
313 $1, $2);
314 ParseError = 1;
315 }
316 }
317 | SKEYWORD string COLON string {
318 #ifdef RJC
319 #define kws_UnknownIcon 7
320 if ($1 != kws_UnknownIcon)
321 yyerror("syntax error");
322 else if (Scr->FirstTime) {
323 char *full_name=CacheAndNameIconImage($2, $4);
324 if (full_name != NULL) {
325 if (!do_string_keyword ($1, full_name)) {
326 twmrc_error_prefix();
327 fprintf (stderr,
328 "unknown string keyword %d (value \"%s\")\n",
329 $1, full_name);
330 ParseError = 1;
331 }
332 } else {
333 twmrc_error_prefix();
334 fprintf(stderr, "can't access bitmap and mask %s, %s\n",
335 $2, $4);
336 }
337 }
338 #else
339 yyerror("\"pixmap\" : \"mask\" syntax no longer supported");
340 #endif
341 }
342 ;
343
344 narg : NKEYWORD number { if (!do_number_keyword ($1, $2)) {
345 twmrc_error_prefix();
346 fprintf (stderr,
347 "unknown numeric keyword %d (value %d)\n",
348 $1, $2);
349 ParseError = 1;
350 }
351 }
352 ;
353
354
355
356 full : EQUALS keys COLON contexts COLON action { $$ = $6; }
357 ;
358
359 fullkey : EQUALS keys COLON contextkeys COLON action { $$ = $6; }
360 ;
361
362 keys : /* Empty */
363 | keys key
364 ;
365
366 key : META { mods |= Mod1Mask; }
367 | SHIFT { mods |= ShiftMask; }
368 | LOCK { mods |= LockMask; }
369 | CONTROL { mods |= ControlMask; }
370 | META number { if ($2 < 1 || $2 > 5) {
371 twmrc_error_prefix();
372 fprintf (stderr,
373 "bad modifier number (%d), must be 1-5\n",
374 $2);
375 ParseError = 1;
376 } else {
377 mods |= (Mod1Mask << ($2 - 1));
378 }
379 }
380 | OR { }
381 ;
382
383 contexts : /* Empty */
384 | contexts context
385 ;
386
387 context : WINDOW { cont |= C_WINDOW_BIT; }
388 | TITLE { cont |= C_TITLE_BIT; }
389 | ICON { cont |= C_ICON_BIT; }
390 | ROOT { cont |= C_ROOT_BIT; }
391 | FRAME { cont |= C_FRAME_BIT; }
392 | ICONMGR { cont |= C_ICONMGR_BIT; }
393 | META { cont |= C_ICONMGR_BIT; }
394 | ALL { cont |= C_ALL_BITS; }
395 | OR { }
396 ;
397
398 contextkeys : /* Empty */
399 | contextkeys contextkey
400 ;
401
402 contextkey : WINDOW { cont |= C_WINDOW_BIT; }
403 | TITLE { cont |= C_TITLE_BIT; }
404 | ICON { cont |= C_ICON_BIT; }
405 | ROOT { cont |= C_ROOT_BIT; }
406 | FRAME { cont |= C_FRAME_BIT; }
407 | ICONMGR { cont |= C_ICONMGR_BIT; }
408 | META { cont |= C_ICONMGR_BIT; }
409 | ALL { cont |= C_ALL_BITS; }
410 | OR { }
411 | string { Name = $1; cont |= C_NAME_BIT; }
412 ;
413
414
415 pixmap_list : LB pixmap_entries RB
416 { }
417 ;
418
419 pixmap_entries : /* Empty */
420 | pixmap_entries pixmap_entry
421 ;
422
423 pixmap_entry : PKEYWORD string { do_pixmap_keyword($1,$2); }
424 ;
425
426
427 cursor_list : LB cursor_entries RB
428 { }
429 ;
430
431 cursor_entries : /* Empty */
432 | cursor_entries cursor_entry
433 ;
434
435 cursor_entry : FRAME string string {
436 NewBitmapCursor(&Scr->FrameCursor, $2, $3); }
437 | FRAME string {
438 NewFontCursor(&Scr->FrameCursor, $2); }
439 | TITLE string string {
440 NewBitmapCursor(&Scr->TitleCursor, $2, $3); }
441 | TITLE string {
442 NewFontCursor(&Scr->TitleCursor, $2); }
443 | ICON string string {
444 NewBitmapCursor(&Scr->IconCursor, $2, $3); }
445 | ICON string {
446 NewFontCursor(&Scr->IconCursor, $2); }
447 | ICONMGR string string {
448 NewBitmapCursor(&Scr->IconMgrCursor, $2, $3); }
449 | ICONMGR string {
450 NewFontCursor(&Scr->IconMgrCursor, $2); }
451 | BUTTON string string {
452 NewBitmapCursor(&Scr->ButtonCursor, $2, $3); }
453 | BUTTON string {
454 NewFontCursor(&Scr->ButtonCursor, $2); }
455 | MOVE string string {
456 NewBitmapCursor(&Scr->MoveCursor, $2, $3); }
457 | MOVE string {
458 NewFontCursor(&Scr->MoveCursor, $2); }
459 | RESIZE string string {
460 NewBitmapCursor(&Scr->ResizeCursor, $2, $3); }
461 | RESIZE string {
462 NewFontCursor(&Scr->ResizeCursor, $2); }
463 | WAIT_CURS string string {
464 NewBitmapCursor(&Scr->WaitCursor, $2, $3); }
465 | WAIT_CURS string {
466 NewFontCursor(&Scr->WaitCursor, $2); }
467 | MENU string string {
468 NewBitmapCursor(&Scr->MenuCursor, $2, $3); }
469 | MENU string {
470 NewFontCursor(&Scr->MenuCursor, $2); }
471 | SELECT string string {
472 NewBitmapCursor(&Scr->SelectCursor, $2, $3); }
473 | SELECT string {
474 NewFontCursor(&Scr->SelectCursor, $2); }
475 | KILL string string {
476 NewBitmapCursor(&Scr->DestroyCursor, $2, $3); }
477 | KILL string {
478 NewFontCursor(&Scr->DestroyCursor, $2); }
479 ;
480
481 color_list : LB color_entries RB
482 { }
483 ;
484
485
486 color_entries : /* Empty */
487 | color_entries color_entry
488 ;
489
490 color_entry : CLKEYWORD string { if (!do_colorlist_keyword ($1, color,
491 $2)) {
492 twmrc_error_prefix();
493 fprintf (stderr,
494 "unhandled list color keyword %d (string \"%s\")\n",
495 $1, $2);
496 ParseError = 1;
497 }
498 }
499 | CLKEYWORD string { list = do_colorlist_keyword($1,color,
500 $2);
501 if (!list) {
502 twmrc_error_prefix();
503 fprintf (stderr,
504 "unhandled color list keyword %d (string \"%s\")\n",
505 $1, $2);
506 ParseError = 1;
507 }
508 }
509 win_color_list
510 | CKEYWORD string { if (!do_color_keyword ($1, color,
511 $2)) {
512 twmrc_error_prefix();
513 fprintf (stderr,
514 "unhandled color keyword %d (string \"%s\")\n",
515 $1, $2);
516 ParseError = 1;
517 }
518 }
519 ;
520
521 save_color_list : LB s_color_entries RB
522 { }
523 ;
524
525 s_color_entries : /* Empty */
526 | s_color_entries s_color_entry
527 ;
528
529 s_color_entry : string { do_string_savecolor(color, $1); }
530 | CLKEYWORD { do_var_savecolor($1); }
531 ;
532
533 win_color_list : LB win_color_entries RB
534 { }
535 ;
536
537 win_color_entries : /* Empty */
538 | win_color_entries win_color_entry
539 ;
540
541 win_color_entry : matcher string { if (Scr->FirstTime &&
542 color == Scr->Monochrome)
543 AddToList(list, $1.lval, $1.ltype,
544 $2); }
545 ;
546
547 squeeze : SQUEEZE_TITLE {
548 if (HasShape) Scr->SqueezeTitle = TRUE;
549 }
550 | SQUEEZE_TITLE { list = &Scr->SqueezeTitleL; }
551 LB win_sqz_entries RB
552 | DONT_SQUEEZE_TITLE { Scr->SqueezeTitle = FALSE; }
553 | DONT_SQUEEZE_TITLE { list = &Scr->DontSqueezeTitleL; }
554 win_list
555 | SQUEEZE_ICON { if (HasShape) Scr->SqueezeIcon = TRUE; }
556 | DONT_SQUEEZE_ICON { if (HasShape) Scr->SqueezeIcon = FALSE; }
557 | SQUEEZE_ICON { list = &Scr->SqueezeIconL; }
558 win_list
559 | DONT_SQUEEZE_ICON { list = &Scr->DontSqueezeIconL; }
560 win_list
561 ;
562
563 win_sqz_entries : /* Empty */
564 | win_sqz_entries matcher JKEYWORD signed_number number {
565 if (Scr->FirstTime) {
566 do_squeeze_entry (list, $2.lval, $2.ltype,
567 $3, $4, $5);
568 }
569 }
570 ;
571
572
573 iconm_list : LB iconm_entries RB
574 { }
575 ;
576
577 iconm_entries : /* Empty */
578 | iconm_entries iconm_entry
579 ;
580
581 iconm_entry : matcher string number { if (Scr->FirstTime)
582 AddToList(list, $1.lval, $1.ltype, (char *)
583 AllocateIconManager($1.lval, NULLSTR,
584 $2, $3));
585 }
586 | matcher string string number
587 { if (Scr->FirstTime)
588 AddToList(list, $1.lval, $1.ltype, (char *)
589 AllocateIconManager($1.lval, $2,
590 $3, $4));
591 }
592 ;
593
594 win_list : LB win_entries RB
595 { }
596 ;
597
598 win_entries : /* Empty */
599 | win_entries win_entry
600 ;
601
602 win_entry : matcher { if (Scr->FirstTime)
603 AddToList(list, $1.lval, $1.ltype, 0);
604 }
605 ;
606
607 icon_list : LB icon_entries RB
608 { }
609 ;
610
611 icon_entries : /* Empty */
612 | icon_entries icon_entry
613 ;
614
615 icon_entry : matcher string { if (Scr->FirstTime)
616 AddToList(list, $1.lval, $1.ltype, $2); }
617 | matcher string COLON string {
618 if (Scr->FirstTime) {
619 #ifdef RJC
620 char *full_name=CacheAndNameIconImage($2, $4);
621 if (full_name != NULL)
622 AddToList(list, $1.lval, $1.ltype, full_name);
623 else {
624 twmrc_error_prefix();
625 fprintf(stderr, "can't access bitmap and mask %s, %s\n",
626 $2, $4);
627 }
628 #else
629 yyerror("\"pixmap\" : \"mask\" syntax no longer supported");
630 #endif /* RJC */
631 }
632 }
633 ;
634
635 function : LB function_entries RB
636 { }
637 ;
638
639 function_entries: /* Empty */
640 | function_entries function_entry
641 ;
642
643 function_entry : action { AddToMenu(root, "", Action, NULLSTR, $1,
644 NULLSTR, NULLSTR);
645 Action = "";
646 }
647 ;
648
649 menu_definition : MENU string LP string COLON string RP {
650 root = GetRoot($2, $4, $6); }
651 menu
652 | MENU string { root = GetRoot($2, NULLSTR, NULLSTR); }
653 menu
654 ;
655
656 menu : menu_body
657 | string {
658 root->file = ExpandFilename($1);
659 root->real_menu = TRUE;
660 }
661 ;
662
663 menu_body : {
664 if (Scr->SetupDone == TRUE) {
665 DestroyMenu(root);
666 root->first = NULL;
667 root->items = 0;
668 root->width = 0;
669 root->mapped = NEVER_MAPPED;
670 }
671 menu_default_index = 0;
672 }
673 LB menu_entries RB {
674 if (Scr->SetupDone == TRUE) {
675 MakeMenu(root);
676 }
677 root->real_menu = TRUE;
678 root->def = menu_default_index;
679 }
680 ;
681
682 menu_entries : /* Empty */
683 | menu_entries menu_entry
684 ;
685
686 menu_entry : def_indicator string action
687 { AddToMenu(root, $2, Action, pull, $3,
688 NULLSTR, NULLSTR);
689 Action = "";
690 pull = NULL;
691 if ($1) {
692 if (menu_default_index)
693 yyerror("two defaults in menu");
694 else if ($1 == 1)
695 menu_default_index = root->items;
696 else if ($1 == 2)
697 menu_default_index =
698 (-root->items);
699 }
700 }
701 | def_indicator string LP string COLON string RP action
702 { AddToMenu(root, $2, Action, pull, $8,
703 $4, $6);
704 Action = "";
705 pull = NULL;
706 if ($1) {
707 if (menu_default_index)
708 yyerror("two defaults in menu");
709 else if ($1 == 1)
710 menu_default_index = root->items;
711 else if ($1 == 2)
712 menu_default_index =
713 (-root->items);
714 }
715 }
716 ;
717
718 def_indicator : /* EMPTY */ { $$ = 0; }
719 | GREATER { $$ = 1; }
720 | GREATER GREATER { $$ = 2; }
721 ;
722
723 action : FKEYWORD { $$ = $1; }
724 | FSKEYWORD string {
725 $$ = $1;
726 Action = $2;
727 switch ($1) {
728 case F_MENU:
729 pull = GetRoot ($2, NULLSTR,NULLSTR);
730 pull->prev = NULL;
731 break;
732 case F_WARPRING:
733 if (!CheckWarpRingArg (Action)) {
734 twmrc_error_prefix();
735 fprintf (stderr,
736 "ignoring invalid f.warptoring argument \"%s\"\n",
737 Action);
738 $$ = F_NOP;
739 }
740 case F_WARPTOSCREEN:
741 if (!CheckWarpScreenArg (Action)) {
742 twmrc_error_prefix();
743 fprintf (stderr,
744 "ignoring invalid f.warptoscreen argument \"%s\"\n",
745 Action);
746 $$ = F_NOP;
747 }
748 break;
749 case F_COLORMAP:
750 if (CheckColormapArg (Action)) {
751 $$ = F_COLORMAP;
752 } else {
753 twmrc_error_prefix();
754 fprintf (stderr,
755 "ignoring invalid f.colormap argument \"%s\"\n",
756 Action);
757 $$ = F_NOP;
758 }
759 break;
760 } /* end switch */
761 }
762 | FSKEYWORD string COLON string {
763 $$ = $1;
764 Action = $4;
765 pull = GetRoot ($2, NULLSTR,NULLSTR);
766 pull->prev = NULL;
767 break;
768 }
769 ;
770
771
772 signed_number : number { $$ = $1; }
773 | PLUS number { $$ = $2; }
774 | MINUS number { $$ = -($2); }
775 ;
776
777 button : BUTTON number { $$ = $2;
778 if ($2 == 0)
779 yyerror("bad button 0");
780
781 if ($2 > MAX_BUTTONS)
782 {
783 $$ = 0;
784 yyerror("button number too large");
785 }
786 }
787 ;
788
789 matcher : string {
790 $$.ltype = LTYPE_ANY_STRING;
791 $$.lval = $1;
792 }
793 | regexp {
794 $$.ltype = LTYPE_ANY_REGEXP;
795 $$.lval = $1;
796 }
797 | MKEYWORD EQUALS string {
798 $$.lval = $3;
799 $$.ltype = $1 | LTYPE_STRING;
800 }
801 | MKEYWORD TILDE regexp {
802 $$.lval = $3;
803 $$.ltype = $1 | LTYPE_REGEXP;
804 }
805 ;
806
807 geometry : string { $$.gstring = $1;
808 $$.itterate = FALSE;
809 }
810 | string ASTERISK { $$.gstring = $1;
811 $$.itterate = TRUE;
812 }
813 ;
814
815 string : STRING { ptr = (char *)malloc(strlen($1)+1);
816 strcpy(ptr, $1);
817 RemoveDQuote(ptr);
818 $$ = ptr;
819 }
820
821 regexp : REGEXP { ptr = (char *)malloc(strlen($1));
822 /* chop off the '/'s */
823 strcpy(ptr, $1+1);
824 ptr[strlen(ptr)-1] = '\0';
825 $$ = ptr;
826 }
827
828 number : NUMBER { $$ = $1; }
829 ;
830
831 %%
yyerror(s)832 yyerror(s) char *s;
833 {
834 twmrc_error_prefix();
835 fprintf (stderr, "error in input file: %s\n", s ? s : "");
836 fprintf (stderr, ": %s", current_input_line());
837 ParseError = 1;
838 }
RemoveDQuote(str)839 RemoveDQuote(str)
840 char *str;
841 {
842 register char *i, *o;
843 register n;
844 register count;
845
846 for (i=str+1, o=str; *i && *i != '\"'; o++)
847 {
848 if (*i == '\\')
849 {
850 switch (*++i)
851 {
852 case 'n':
853 *o = '\n';
854 i++;
855 break;
856 case 'b':
857 *o = '\b';
858 i++;
859 break;
860 case 'r':
861 *o = '\r';
862 i++;
863 break;
864 case 't':
865 *o = '\t';
866 i++;
867 break;
868 case 'f':
869 *o = '\f';
870 i++;
871 break;
872 case '0':
873 if (*++i == 'x')
874 goto hex;
875 else
876 --i;
877 case '1': case '2': case '3':
878 case '4': case '5': case '6': case '7':
879 n = 0;
880 count = 0;
881 while (*i >= '0' && *i <= '7' && count < 3)
882 {
883 n = (n<<3) + (*i++ - '0');
884 count++;
885 }
886 *o = n;
887 break;
888 hex:
889 case 'x':
890 n = 0;
891 count = 0;
892 while (i++, count++ < 2)
893 {
894 if (*i >= '0' && *i <= '9')
895 n = (n<<4) + (*i - '0');
896 else if (*i >= 'a' && *i <= 'f')
897 n = (n<<4) + (*i - 'a') + 10;
898 else if (*i >= 'A' && *i <= 'F')
899 n = (n<<4) + (*i - 'A') + 10;
900 else
901 break;
902 }
903 *o = n;
904 break;
905 case '\n':
906 i++; /* punt */
907 o--; /* to account for o++ at end of loop */
908 break;
909 case '\"':
910 case '\'':
911 case '\\':
912 default:
913 *o = *i++;
914 break;
915 }
916 }
917 else
918 *o = *i++;
919 }
920 *o = '\0';
921 }
922
GetRoot(name,fore,back)923 static MenuRoot *GetRoot(name, fore, back)
924 char *name;
925 char *fore, *back;
926 {
927 MenuRoot *tmp;
928
929 tmp = FindMenuRoot(name);
930 if (tmp == NULL)
931 tmp = NewMenuRoot(name);
932
933 if (fore)
934 {
935 int save;
936
937 save = Scr->FirstTime;
938 Scr->FirstTime = TRUE;
939 GetColor(COLOR, &tmp->hi_fore, fore);
940 GetColor(COLOR, &tmp->hi_back, back);
941 Scr->FirstTime = save;
942 }
943
944 return tmp;
945 }
946
GotButton(butt,func)947 static void GotButton(butt, func)
948 int butt, func;
949 {
950 int i;
951
952 for (i = 0; i < NUM_CONTEXTS; i++)
953 {
954 if ((cont & (1 << i)) == 0)
955 continue;
956
957 Scr->Mouse[butt][i][mods].func = func;
958 if (func == F_MENU || func == F_MENUFUNC)
959 {
960 pull->prev = NULL;
961 Scr->Mouse[butt][i][mods].menu = pull;
962 }
963 else
964 {
965 root = GetRoot(TWM_ROOT, NULLSTR, NULLSTR);
966 Scr->Mouse[butt][i][mods].item = AddToMenu(root,"x",Action,
967 NULLSTR, func, NULLSTR, NULLSTR);
968 }
969 }
970 Action = "";
971 pull = NULL;
972 cont = 0;
973 mods_used |= mods;
974 mods = 0;
975 }
976
GotKey(key,func)977 static void GotKey(key, func)
978 char *key;
979 int func;
980 {
981 int i;
982
983 for (i = 0; i < NUM_CONTEXTS; i++)
984 {
985 if ((cont & (1 << i)) == 0)
986 continue;
987 if (!AddFuncKey(key, i, mods, func, Name, Action))
988 break;
989 }
990
991 Action = "";
992 pull = NULL;
993 cont = 0;
994 mods_used |= mods;
995 mods = 0;
996 }
997
998
GotTitleButton(bitmapname,func,rightside)999 static void GotTitleButton (bitmapname, func, rightside)
1000 char *bitmapname;
1001 int func;
1002 Bool rightside;
1003 {
1004 if (!CreateTitleButton (bitmapname, func, Action, pull, rightside, True)) {
1005 twmrc_error_prefix();
1006 fprintf (stderr,
1007 "unable to create %s titlebutton \"%s\"\n",
1008 rightside ? "right" : "left", bitmapname);
1009 }
1010 Action = "";
1011 pull = NULL;
1012 }
1013
CheckWarpScreenArg(s)1014 static Bool CheckWarpScreenArg (s)
1015 register char *s;
1016 {
1017 XmuCopyISOLatin1Lowered (s, s);
1018
1019 if (strcmp (s, WARPSCREEN_NEXT) == 0 ||
1020 strcmp (s, WARPSCREEN_PREV) == 0 ||
1021 strcmp (s, WARPSCREEN_BACK) == 0)
1022 return True;
1023
1024 for (; *s && isascii(*s) && isdigit(*s); s++) ; /* SUPPRESS 530 */
1025 return (*s ? False : True);
1026 }
1027
1028
CheckWarpRingArg(s)1029 static Bool CheckWarpRingArg (s)
1030 register char *s;
1031 {
1032 XmuCopyISOLatin1Lowered (s, s);
1033
1034 if (strcmp (s, WARPSCREEN_NEXT) == 0 ||
1035 strcmp (s, WARPSCREEN_PREV) == 0)
1036 return True;
1037
1038 return False;
1039 }
1040
1041
CheckColormapArg(s)1042 static Bool CheckColormapArg (s)
1043 register char *s;
1044 {
1045 XmuCopyISOLatin1Lowered (s, s);
1046
1047 if (strcmp (s, COLORMAP_NEXT) == 0 ||
1048 strcmp (s, COLORMAP_PREV) == 0 ||
1049 strcmp (s, COLORMAP_DEFAULT) == 0)
1050 return True;
1051
1052 return False;
1053 }
1054
1055
twmrc_error_prefix()1056 twmrc_error_prefix ()
1057 {
1058 fprintf (stderr, "%s: line %d: ", ProgramName, yylineno);
1059 }
1060