gram.y revision c2535118
1/*****************************************************************************/
2/*
3
4Copyright 1989, 1998  The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25
26*/
27/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
28/**                          Salt Lake City, Utah                           **/
29/**                        Cambridge, Massachusetts                         **/
30/**                                                                         **/
31/**                           All Rights Reserved                           **/
32/**                                                                         **/
33/**    Permission to use, copy, modify, and distribute this software and    **/
34/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
35/**    granted, provided that the above copyright notice appear  in  all    **/
36/**    copies and that both  that  copyright  notice  and  this  permis-    **/
37/**    sion  notice appear in supporting  documentation,  and  that  the    **/
38/**    name of Evans & Sutherland not be used in advertising    **/
39/**    in publicity pertaining to distribution of the  software  without    **/
40/**    specific, written prior permission.                                  **/
41/**                                                                         **/
42/**    EVANS & SUTHERLAND DISCLAIMs ALL WARRANTIES WITH REGARD    **/
43/**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
44/**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND    **/
45/**    BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
46/**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
47/**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
48/**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
49/**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
50/*****************************************************************************/
51
52
53/***********************************************************************
54 *
55 * $Xorg: gram.y,v 1.4 2001/02/09 02:05:36 xorgcvs Exp $
56 *
57 * .twmrc command grammer
58 *
59 * 07-Jan-86 Thomas E. LaStrange	File created
60 * 11-Nov-90 Dave Sternlicht            Adding SaveColors
61 * 10-Oct-90 David M. Sternlicht        Storing saved colors on root
62 *
63 * $XFree86: xc/programs/twm/gram.y,v 3.8 2002/10/16 21:33:03 tsi Exp $
64 *
65 ***********************************************************************/
66
67%{
68#include <stdio.h>
69#include <ctype.h>
70#include "twm.h"
71#include "menus.h"
72#include "list.h"
73#include "util.h"
74#include "screen.h"
75#include "parse.h"
76#include "add_window.h"
77#include "icons.h"
78#include <X11/Xos.h>
79#include <X11/Xmu/CharSet.h>
80
81static char *Action = "";
82static char *Name = "";
83static MenuRoot	*root, *pull = NULL;
84
85static MenuRoot *GetRoot ( const char *name, const char *fore, const char *back );
86static void GotButton ( int butt, int func );
87static void GotKey ( char *key, int func );
88static void GotTitleButton ( char *bitmapname, int func, Bool rightside );
89static Bool CheckWarpScreenArg ( char *s );
90static Bool CheckWarpRingArg ( char *s );
91static Bool CheckColormapArg ( char *s );
92static void RemoveDQuote ( char *str );
93
94static char *ptr;
95static name_list **list;
96static int cont = 0;
97static int color;
98int mods = 0;
99unsigned int mods_used = (ShiftMask | ControlMask | Mod1Mask);
100
101extern int yylineno;
102static void yyerror ( const char *s );
103
104%}
105
106%union
107{
108    int num;
109    char *ptr;
110};
111
112%token <num> LB RB LP RP MENUS MENU BUTTON DEFAULT_FUNCTION PLUS MINUS
113%token <num> ALL OR CURSORS PIXMAPS ICONS COLOR SAVECOLOR MONOCHROME FUNCTION
114%token <num> ICONMGR_SHOW ICONMGR WINDOW_FUNCTION ZOOM ICONMGRS
115%token <num> ICONMGR_GEOMETRY ICONMGR_NOSHOW MAKE_TITLE GRAYSCALE
116%token <num> ICONIFY_BY_UNMAPPING DONT_ICONIFY_BY_UNMAPPING
117%token <num> NO_TITLE AUTO_RAISE NO_HILITE ICON_REGION
118%token <num> META SHIFT LOCK CONTROL WINDOW TITLE ICON ROOT FRAME
119%token <num> COLON EQUALS SQUEEZE_TITLE DONT_SQUEEZE_TITLE
120%token <num> START_ICONIFIED NO_TITLE_HILITE TITLE_HILITE
121%token <num> MOVE RESIZE WAIT SELECT KILL LEFT_TITLEBUTTON RIGHT_TITLEBUTTON
122%token <num> NUMBER KEYWORD NKEYWORD CKEYWORD CLKEYWORD FKEYWORD FSKEYWORD
123%token <num> SKEYWORD DKEYWORD JKEYWORD WINDOW_RING WARP_CURSOR ERRORTOKEN
124%token <num> NO_STACKMODE
125%token <ptr> STRING
126
127%type <ptr> string
128%type <num> pixmap_list cursor_list color_list save_color_list stmt
129%type <num> win_color_list iconm_list win_list icon_list function menu
130%type <num> noarg sarg error narg squeeze color_entry
131%type <num> action button number signed_number full fullkey
132
133%start twmrc
134
135%%
136twmrc		: stmts
137		;
138
139stmts		: /* Empty */
140		| stmts stmt
141		;
142
143stmt		: error
144		| noarg
145		| sarg
146		| narg
147		| squeeze
148		| ICON_REGION string DKEYWORD DKEYWORD number number
149					{ AddIconRegion($2, $3, $4, $5, $6); }
150		| ICONMGR_GEOMETRY string number	{ if (Scr->FirstTime)
151						  {
152						    Scr->iconmgr.geometry=$2;
153						    Scr->iconmgr.columns=$3;
154						  }
155						}
156		| ICONMGR_GEOMETRY string	{ if (Scr->FirstTime)
157						    Scr->iconmgr.geometry = $2;
158						}
159		| ZOOM number		{ if (Scr->FirstTime)
160					  {
161						Scr->DoZoom = TRUE;
162						Scr->ZoomCount = $2;
163					  }
164					}
165		| ZOOM			{ if (Scr->FirstTime)
166						Scr->DoZoom = TRUE; }
167		| PIXMAPS pixmap_list	{}
168		| CURSORS cursor_list	{}
169		| ICONIFY_BY_UNMAPPING	{ list = &Scr->IconifyByUn; }
170		  win_list
171		| ICONIFY_BY_UNMAPPING	{ if (Scr->FirstTime)
172		    Scr->IconifyByUnmapping = TRUE; }
173		| LEFT_TITLEBUTTON string EQUALS action {
174					  GotTitleButton ($2, $4, False);
175					}
176		| RIGHT_TITLEBUTTON string EQUALS action {
177					  GotTitleButton ($2, $4, True);
178					}
179		| button string		{ root = GetRoot($2, NULLSTR, NULLSTR);
180					  Scr->Mouse[$1][C_ROOT][0].func = F_MENU;
181					  Scr->Mouse[$1][C_ROOT][0].menu = root;
182					}
183		| button action		{ Scr->Mouse[$1][C_ROOT][0].func = $2;
184					  if ($2 == F_MENU)
185					  {
186					    pull->prev = NULL;
187					    Scr->Mouse[$1][C_ROOT][0].menu = pull;
188					  }
189					  else
190					  {
191					    root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
192					    Scr->Mouse[$1][C_ROOT][0].item =
193						AddToMenu(root,"x",Action,
194							  NULL,$2,NULLSTR,NULLSTR);
195					  }
196					  Action = "";
197					  pull = NULL;
198					}
199		| string fullkey	{ GotKey($1, $2); }
200		| button full		{ GotButton($1, $2); }
201		| DONT_ICONIFY_BY_UNMAPPING { list = &Scr->DontIconify; }
202		  win_list
203		| ICONMGR_NOSHOW	{ list = &Scr->IconMgrNoShow; }
204		  win_list
205		| ICONMGR_NOSHOW	{ Scr->IconManagerDontShow = TRUE; }
206		| ICONMGRS		{ list = &Scr->IconMgrs; }
207		  iconm_list
208		| ICONMGR_SHOW		{ list = &Scr->IconMgrShow; }
209		  win_list
210		| NO_TITLE_HILITE	{ list = &Scr->NoTitleHighlight; }
211		  win_list
212		| NO_TITLE_HILITE	{ if (Scr->FirstTime)
213						Scr->TitleHighlight = FALSE; }
214		| NO_HILITE		{ list = &Scr->NoHighlight; }
215		  win_list
216		| NO_HILITE		{ if (Scr->FirstTime)
217						Scr->Highlight = FALSE; }
218		| NO_STACKMODE		{ list = &Scr->NoStackModeL; }
219		  win_list
220		| NO_STACKMODE		{ if (Scr->FirstTime)
221						Scr->StackMode = FALSE; }
222		| NO_TITLE		{ list = &Scr->NoTitle; }
223		  win_list
224		| NO_TITLE		{ if (Scr->FirstTime)
225						Scr->NoTitlebar = TRUE; }
226		| MAKE_TITLE		{ list = &Scr->MakeTitle; }
227		  win_list
228		| START_ICONIFIED	{ list = &Scr->StartIconified; }
229		  win_list
230		| AUTO_RAISE		{ list = &Scr->AutoRaise; }
231		  win_list
232		| MENU string LP string COLON string RP	{
233					root = GetRoot($2, $4, $6); }
234		  menu			{ root->real_menu = TRUE;}
235		| MENU string 		{ root = GetRoot($2, NULLSTR, NULLSTR); }
236		  menu			{ root->real_menu = TRUE; }
237		| FUNCTION string	{ root = GetRoot($2, NULLSTR, NULLSTR); }
238		  function
239		| ICONS 		{ list = &Scr->IconNames; }
240		  icon_list
241		| COLOR 		{ color = COLOR; }
242		  color_list
243		| GRAYSCALE 		{ color = GRAYSCALE; }
244  		  color_list
245		| SAVECOLOR
246                  save_color_list
247		| MONOCHROME 		{ color = MONOCHROME; }
248	          color_list
249		| DEFAULT_FUNCTION action { Scr->DefaultFunction.func = $2;
250					  if ($2 == F_MENU)
251					  {
252					    pull->prev = NULL;
253					    Scr->DefaultFunction.menu = pull;
254					  }
255					  else
256					  {
257					    root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
258					    Scr->DefaultFunction.item =
259						AddToMenu(root,"x",Action,
260							  NULL,$2, NULLSTR, NULLSTR);
261					  }
262					  Action = "";
263					  pull = NULL;
264					}
265		| WINDOW_FUNCTION action { Scr->WindowFunction.func = $2;
266					   root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
267					   Scr->WindowFunction.item =
268						AddToMenu(root,"x",Action,
269							  NULL,$2, NULLSTR, NULLSTR);
270					   Action = "";
271					   pull = NULL;
272					}
273		| WARP_CURSOR		{ list = &Scr->WarpCursorL; }
274		  win_list
275		| WARP_CURSOR		{ if (Scr->FirstTime)
276					    Scr->WarpCursor = TRUE; }
277		| WINDOW_RING		{ list = &Scr->WindowRingL; }
278		  win_list
279		;
280
281
282noarg		: KEYWORD		{ if (!do_single_keyword ($1)) {
283					    twmrc_error_prefix();
284					    fprintf (stderr,
285					"unknown singleton keyword %d\n",
286						     $1);
287					    ParseError = 1;
288					  }
289					}
290		;
291
292sarg		: SKEYWORD string	{ if (!do_string_keyword ($1, $2)) {
293					    twmrc_error_prefix();
294					    fprintf (stderr,
295				"unknown string keyword %d (value \"%s\")\n",
296						     $1, $2);
297					    ParseError = 1;
298					  }
299					}
300		;
301
302narg		: NKEYWORD number	{ if (!do_number_keyword ($1, $2)) {
303					    twmrc_error_prefix();
304					    fprintf (stderr,
305				"unknown numeric keyword %d (value %d)\n",
306						     $1, $2);
307					    ParseError = 1;
308					  }
309					}
310		;
311
312
313
314full		: EQUALS keys COLON contexts COLON action  { $$ = $6; }
315		;
316
317fullkey		: EQUALS keys COLON contextkeys COLON action  { $$ = $6; }
318		;
319
320keys		: /* Empty */
321		| keys key
322		;
323
324key		: META			{ mods |= Mod1Mask; }
325		| SHIFT			{ mods |= ShiftMask; }
326		| LOCK			{ mods |= LockMask; }
327		| CONTROL		{ mods |= ControlMask; }
328		| META number		{ if ($2 < 1 || $2 > 5) {
329					     twmrc_error_prefix();
330					     fprintf (stderr,
331				"bad modifier number (%d), must be 1-5\n",
332						      $2);
333					     ParseError = 1;
334					  } else {
335					     mods |= (Mod1Mask << ($2 - 1));
336					  }
337					}
338		| OR			{ }
339		;
340
341contexts	: /* Empty */
342		| contexts context
343		;
344
345context		: WINDOW		{ cont |= C_WINDOW_BIT; }
346		| TITLE			{ cont |= C_TITLE_BIT; }
347		| ICON			{ cont |= C_ICON_BIT; }
348		| ROOT			{ cont |= C_ROOT_BIT; }
349		| FRAME			{ cont |= C_FRAME_BIT; }
350		| ICONMGR		{ cont |= C_ICONMGR_BIT; }
351		| META			{ cont |= C_ICONMGR_BIT; }
352		| ALL			{ cont |= C_ALL_BITS; }
353		| OR			{  }
354		;
355
356contextkeys	: /* Empty */
357		| contextkeys contextkey
358		;
359
360contextkey	: WINDOW		{ cont |= C_WINDOW_BIT; }
361		| TITLE			{ cont |= C_TITLE_BIT; }
362		| ICON			{ cont |= C_ICON_BIT; }
363		| ROOT			{ cont |= C_ROOT_BIT; }
364		| FRAME			{ cont |= C_FRAME_BIT; }
365		| ICONMGR		{ cont |= C_ICONMGR_BIT; }
366		| META			{ cont |= C_ICONMGR_BIT; }
367		| ALL			{ cont |= C_ALL_BITS; }
368		| OR			{ }
369		| string		{ Name = $1; cont |= C_NAME_BIT; }
370		;
371
372
373pixmap_list	: LB pixmap_entries RB
374		;
375
376pixmap_entries	: /* Empty */
377		| pixmap_entries pixmap_entry
378		;
379
380pixmap_entry	: TITLE_HILITE string { SetHighlightPixmap ($2); }
381		;
382
383
384cursor_list	: LB cursor_entries RB
385		;
386
387cursor_entries	: /* Empty */
388		| cursor_entries cursor_entry
389		;
390
391cursor_entry	: FRAME string string {
392			NewBitmapCursor(&Scr->FrameCursor, $2, $3); }
393		| FRAME string	{
394			NewFontCursor(&Scr->FrameCursor, $2); }
395		| TITLE string string {
396			NewBitmapCursor(&Scr->TitleCursor, $2, $3); }
397		| TITLE string {
398			NewFontCursor(&Scr->TitleCursor, $2); }
399		| ICON string string {
400			NewBitmapCursor(&Scr->IconCursor, $2, $3); }
401		| ICON string {
402			NewFontCursor(&Scr->IconCursor, $2); }
403		| ICONMGR string string {
404			NewBitmapCursor(&Scr->IconMgrCursor, $2, $3); }
405		| ICONMGR string {
406			NewFontCursor(&Scr->IconMgrCursor, $2); }
407		| BUTTON string string {
408			NewBitmapCursor(&Scr->ButtonCursor, $2, $3); }
409		| BUTTON string {
410			NewFontCursor(&Scr->ButtonCursor, $2); }
411		| MOVE string string {
412			NewBitmapCursor(&Scr->MoveCursor, $2, $3); }
413		| MOVE string {
414			NewFontCursor(&Scr->MoveCursor, $2); }
415		| RESIZE string string {
416			NewBitmapCursor(&Scr->ResizeCursor, $2, $3); }
417		| RESIZE string {
418			NewFontCursor(&Scr->ResizeCursor, $2); }
419		| WAIT string string {
420			NewBitmapCursor(&Scr->WaitCursor, $2, $3); }
421		| WAIT string {
422			NewFontCursor(&Scr->WaitCursor, $2); }
423		| MENU string string {
424			NewBitmapCursor(&Scr->MenuCursor, $2, $3); }
425		| MENU string {
426			NewFontCursor(&Scr->MenuCursor, $2); }
427		| SELECT string string {
428			NewBitmapCursor(&Scr->SelectCursor, $2, $3); }
429		| SELECT string {
430			NewFontCursor(&Scr->SelectCursor, $2); }
431		| KILL string string {
432			NewBitmapCursor(&Scr->DestroyCursor, $2, $3); }
433		| KILL string {
434			NewFontCursor(&Scr->DestroyCursor, $2); }
435		;
436
437color_list	: LB color_entries RB
438		;
439
440
441color_entries	: /* Empty */
442		| color_entries color_entry
443		;
444
445color_entry	: CLKEYWORD string	{ if (!do_colorlist_keyword ($1, color,
446								     $2)) {
447					    twmrc_error_prefix();
448					    fprintf (stderr,
449			"unhandled list color keyword %d (string \"%s\")\n",
450						     $1, $2);
451					    ParseError = 1;
452					  }
453					}
454		| CLKEYWORD string	{ list = do_colorlist_keyword($1,color,
455								      $2);
456					  if (!list) {
457					    twmrc_error_prefix();
458					    fprintf (stderr,
459			"unhandled color list keyword %d (string \"%s\")\n",
460						     $1, $2);
461					    ParseError = 1;
462					  }
463					}
464		  win_color_list	{ /* No action */; }
465		| CKEYWORD string	{ if (!do_color_keyword ($1, color,
466								 $2)) {
467					    twmrc_error_prefix();
468					    fprintf (stderr,
469			"unhandled color keyword %d (string \"%s\")\n",
470						     $1, $2);
471					    ParseError = 1;
472					  }
473					}
474		;
475
476save_color_list : LB s_color_entries RB
477                ;
478
479s_color_entries : /* Empty */
480                | s_color_entries s_color_entry
481                ;
482
483s_color_entry   : string            { do_string_savecolor(color, $1); }
484                | CLKEYWORD         { do_var_savecolor($1); }
485                ;
486
487win_color_list	: LB win_color_entries RB
488		;
489
490win_color_entries	: /* Empty */
491		| win_color_entries win_color_entry
492		;
493
494win_color_entry	: string string		{ if (Scr->FirstTime &&
495					      color == Scr->Monochrome)
496					    AddToList(list, $1, $2); }
497		;
498
499squeeze		: SQUEEZE_TITLE {
500				    if (HasShape) Scr->SqueezeTitle = TRUE;
501				}
502		| SQUEEZE_TITLE { list = &Scr->SqueezeTitleL;
503				  if (HasShape && Scr->SqueezeTitle == -1)
504				    Scr->SqueezeTitle = TRUE;
505				}
506		  LB win_sqz_entries RB
507		| DONT_SQUEEZE_TITLE { Scr->SqueezeTitle = FALSE; }
508		| DONT_SQUEEZE_TITLE { list = &Scr->DontSqueezeTitleL; }
509		  win_list
510		;
511
512win_sqz_entries	: /* Empty */
513		| win_sqz_entries string JKEYWORD signed_number number	{
514				if (Scr->FirstTime) {
515				   do_squeeze_entry (list, $2, $3, $4, $5);
516				}
517			}
518		;
519
520
521iconm_list	: LB iconm_entries RB
522		;
523
524iconm_entries	: /* Empty */
525		| iconm_entries iconm_entry
526		;
527
528iconm_entry	: string string number	{ if (Scr->FirstTime)
529					    AddToList(list, $1, (char *)
530						AllocateIconManager($1, NULLSTR,
531							$2,$3));
532					}
533		| string string string number
534					{ if (Scr->FirstTime)
535					    AddToList(list, $1, (char *)
536						AllocateIconManager($1,$2,
537						$3, $4));
538					}
539		;
540
541win_list	: LB win_entries RB
542		;
543
544win_entries	: /* Empty */
545		| win_entries win_entry
546		;
547
548win_entry	: string		{ if (Scr->FirstTime)
549					    AddToList(list, $1, 0);
550					}
551		;
552
553icon_list	: LB icon_entries RB
554		;
555
556icon_entries	: /* Empty */
557		| icon_entries icon_entry
558		;
559
560icon_entry	: string string		{ if (Scr->FirstTime) AddToList(list, $1, $2); }
561		;
562
563function	: LB function_entries RB
564		;
565
566function_entries: /* Empty */
567		| function_entries function_entry
568		;
569
570function_entry	: action		{ AddToMenu(root, "", Action, NULL, $1,
571						NULLSTR, NULLSTR);
572					  Action = "";
573					}
574		;
575
576menu		: LB menu_entries RB
577		;
578
579menu_entries	: /* Empty */
580		| menu_entries menu_entry
581		;
582
583menu_entry	: string action		{ AddToMenu(root, $1, Action, pull, $2,
584						NULLSTR, NULLSTR);
585					  Action = "";
586					  pull = NULL;
587					}
588		| string LP string COLON string RP action {
589					  AddToMenu(root, $1, Action, pull, $7,
590						$3, $5);
591					  Action = "";
592					  pull = NULL;
593					}
594		;
595
596action		: FKEYWORD	{ $$ = $1; }
597		| FSKEYWORD string {
598				$$ = $1;
599				Action = $2;
600				switch ($1) {
601				  case F_MENU:
602				    pull = GetRoot ($2, NULLSTR,NULLSTR);
603				    pull->prev = root;
604				    break;
605				  case F_WARPRING:
606				    if (!CheckWarpRingArg (Action)) {
607					twmrc_error_prefix();
608					fprintf (stderr,
609			"ignoring invalid f.warptoring argument \"%s\"\n",
610						 Action);
611					$$ = F_NOP;
612				    }
613				  case F_WARPTOSCREEN:
614				    if (!CheckWarpScreenArg (Action)) {
615					twmrc_error_prefix();
616					fprintf (stderr,
617			"ignoring invalid f.warptoscreen argument \"%s\"\n",
618					         Action);
619					$$ = F_NOP;
620				    }
621				    break;
622				  case F_COLORMAP:
623				    if (CheckColormapArg (Action)) {
624					$$ = F_COLORMAP;
625				    } else {
626					twmrc_error_prefix();
627					fprintf (stderr,
628			"ignoring invalid f.colormap argument \"%s\"\n",
629						 Action);
630					$$ = F_NOP;
631				    }
632				    break;
633				} /* end switch */
634				   }
635		;
636
637
638signed_number	: number		{ $$ = $1; }
639		| PLUS number		{ $$ = $2; }
640		| MINUS number		{ $$ = -($2); }
641		;
642
643button		: BUTTON number		{ $$ = $2;
644					  if ($2 == 0)
645						yyerror("bad button 0");
646
647					  if ($2 > MAX_BUTTONS)
648					  {
649						$$ = 0;
650						yyerror("button number too large");
651					  }
652					}
653		;
654
655string		: STRING		{ ptr = strdup($1);
656					  RemoveDQuote(ptr);
657					  $$ = ptr;
658					}
659		;
660number		: NUMBER		{ $$ = $1; }
661		;
662
663%%
664static void
665yyerror(const char *s)
666{
667    twmrc_error_prefix();
668    fprintf (stderr, "error in input file:  %s\n", s ? s : "");
669    ParseError = 1;
670}
671
672static void
673RemoveDQuote(char *str)
674{
675    register char *i, *o;
676    register int n;
677    register int count;
678
679    for (i=str+1, o=str; *i && *i != '\"'; o++)
680    {
681	if (*i == '\\')
682	{
683	    switch (*++i)
684	    {
685	    case 'n':
686		*o = '\n';
687		i++;
688		break;
689	    case 'b':
690		*o = '\b';
691		i++;
692		break;
693	    case 'r':
694		*o = '\r';
695		i++;
696		break;
697	    case 't':
698		*o = '\t';
699		i++;
700		break;
701	    case 'f':
702		*o = '\f';
703		i++;
704		break;
705	    case '0':
706		if (*++i == 'x')
707		    goto hex;
708		else
709		    --i;
710	    case '1': case '2': case '3':
711	    case '4': case '5': case '6': case '7':
712		n = 0;
713		count = 0;
714		while (*i >= '0' && *i <= '7' && count < 3)
715		{
716		    n = (n<<3) + (*i++ - '0');
717		    count++;
718		}
719		*o = n;
720		break;
721	    hex:
722	    case 'x':
723		n = 0;
724		count = 0;
725		while (i++, count++ < 2)
726		{
727		    if (*i >= '0' && *i <= '9')
728			n = (n<<4) + (*i - '0');
729		    else if (*i >= 'a' && *i <= 'f')
730			n = (n<<4) + (*i - 'a') + 10;
731		    else if (*i >= 'A' && *i <= 'F')
732			n = (n<<4) + (*i - 'A') + 10;
733		    else
734			break;
735		}
736		*o = n;
737		break;
738	    case '\n':
739		i++;	/* punt */
740		o--;	/* to account for o++ at end of loop */
741		break;
742	    case '\"':
743	    case '\'':
744	    case '\\':
745	    default:
746		*o = *i++;
747		break;
748	    }
749	}
750	else
751	    *o = *i++;
752    }
753    *o = '\0';
754}
755
756static MenuRoot *GetRoot(const char *name, const char* fore, const char *back)
757{
758    MenuRoot *tmp;
759
760    tmp = FindMenuRoot(name);
761    if (tmp == NULL)
762	tmp = NewMenuRoot(name);
763
764    if (fore)
765    {
766	int save;
767
768	save = Scr->FirstTime;
769	Scr->FirstTime = TRUE;
770	GetColor(COLOR, &tmp->hi_fore, fore);
771	GetColor(COLOR, &tmp->hi_back, back);
772	Scr->FirstTime = save;
773    }
774
775    return tmp;
776}
777
778static void GotButton(int butt, int func)
779{
780    int i;
781
782    for (i = 0; i < NUM_CONTEXTS; i++)
783    {
784	if ((cont & (1 << i)) == 0)
785	    continue;
786
787	Scr->Mouse[butt][i][mods].func = func;
788	if (func == F_MENU)
789	{
790	    pull->prev = NULL;
791	    Scr->Mouse[butt][i][mods].menu = pull;
792	}
793	else
794	{
795	    root = GetRoot(TWM_ROOT, NULLSTR, NULLSTR);
796	    Scr->Mouse[butt][i][mods].item = AddToMenu(root,"x",Action,
797		    NULL, func, NULLSTR, NULLSTR);
798	}
799    }
800    Action = "";
801    pull = NULL;
802    cont = 0;
803    mods_used |= mods;
804    mods = 0;
805}
806
807static void GotKey(char *key, int func)
808{
809    int i;
810
811    for (i = 0; i < NUM_CONTEXTS; i++)
812    {
813	if ((cont & (1 << i)) == 0)
814	  continue;
815	if (!AddFuncKey(key, i, mods, func, Name, Action))
816	  break;
817    }
818
819    Action = "";
820    pull = NULL;
821    cont = 0;
822    mods_used |= mods;
823    mods = 0;
824}
825
826
827static void GotTitleButton (char *bitmapname, int func, Bool rightside)
828{
829    if (!CreateTitleButton (bitmapname, func, Action, pull, rightside, True)) {
830	twmrc_error_prefix();
831	fprintf (stderr,
832		 "unable to create %s titlebutton \"%s\"\n",
833		 rightside ? "right" : "left", bitmapname);
834    }
835    Action = "";
836    pull = NULL;
837}
838
839static Bool CheckWarpScreenArg (char *s)
840{
841    XmuCopyISOLatin1Lowered (s, s);
842
843    if (strcmp (s,  WARPSCREEN_NEXT) == 0 ||
844	strcmp (s,  WARPSCREEN_PREV) == 0 ||
845	strcmp (s,  WARPSCREEN_BACK) == 0)
846      return True;
847
848    for (; *s && isascii(*s) && isdigit(*s); s++) ; /* SUPPRESS 530 */
849    return (*s ? False : True);
850}
851
852
853static Bool CheckWarpRingArg (char *s)
854{
855    XmuCopyISOLatin1Lowered (s, s);
856
857    if (strcmp (s,  WARPSCREEN_NEXT) == 0 ||
858	strcmp (s,  WARPSCREEN_PREV) == 0)
859      return True;
860
861    return False;
862}
863
864
865static Bool CheckColormapArg (char *s)
866{
867    XmuCopyISOLatin1Lowered (s, s);
868
869    if (strcmp (s, COLORMAP_NEXT) == 0 ||
870	strcmp (s, COLORMAP_PREV) == 0 ||
871	strcmp (s, COLORMAP_DEFAULT) == 0)
872      return True;
873
874    return False;
875}
876
877
878void
879twmrc_error_prefix (void)
880{
881    fprintf (stderr, "%s:  line %d:  ", ProgramName, yylineno);
882}
883