1/* 2 * Parser routines called from yacc code (gram.y) 3 * 4 * This is very similar to the meaning of parse_be.c; the two may be 5 * merged at some point. 6 */ 7 8#include "ctwm.h" 9 10#include <stdio.h> 11#include <string.h> 12#include <strings.h> 13 14#include "functions_defs.h" 15#include "util.h" 16#include "screen.h" 17#include "parse.h" 18#include "parse_be.h" 19#include "parse_yacc.h" 20#include "win_decorations_init.h" 21 22#include "gram.tab.h" 23 24char *Action = ""; 25char *Name = ""; 26MenuRoot *root, *pull = NULL; 27 28int cont = 0; 29int mods = 0; 30unsigned int mods_used = (ShiftMask | ControlMask | Mod1Mask); 31 32 33void yyerror(char *s) 34{ 35 twmrc_error_prefix(); 36 fprintf(stderr, "error in input file: %s\n", s ? s : ""); 37 ParseError = true; 38} 39 40void InitGramVariables(void) 41{ 42 mods = 0; 43} 44 45void RemoveDQuote(char *str) 46{ 47 char *i, *o; 48 int n; 49 int count; 50 51 for(i = str + 1, o = str; *i && *i != '\"'; o++) { 52 if(*i == '\\') { 53 switch(*++i) { 54 case 'n': 55 *o = '\n'; 56 i++; 57 break; 58 case 'b': 59 *o = '\b'; 60 i++; 61 break; 62 case 'r': 63 *o = '\r'; 64 i++; 65 break; 66 case 't': 67 *o = '\t'; 68 i++; 69 break; 70 case 'f': 71 *o = '\f'; 72 i++; 73 break; 74 case '0': 75 if(*++i == 'x') { 76 goto hex; 77 } 78 else { 79 --i; 80 } 81 case '1': 82 case '2': 83 case '3': 84 case '4': 85 case '5': 86 case '6': 87 case '7': 88 n = 0; 89 count = 0; 90 while(*i >= '0' && *i <= '7' && count < 3) { 91 n = (n << 3) + (*i++ - '0'); 92 count++; 93 } 94 *o = n; 95 break; 96hex: 97 case 'x': 98 n = 0; 99 count = 0; 100 while(i++, count++ < 2) { 101 if(*i >= '0' && *i <= '9') { 102 n = (n << 4) + (*i - '0'); 103 } 104 else if(*i >= 'a' && *i <= 'f') { 105 n = (n << 4) + (*i - 'a') + 10; 106 } 107 else if(*i >= 'A' && *i <= 'F') { 108 n = (n << 4) + (*i - 'A') + 10; 109 } 110 else { 111 break; 112 } 113 } 114 *o = n; 115 break; 116 case '\n': 117 i++; /* punt */ 118 o--; /* to account for o++ at end of loop */ 119 break; 120 case '\"': 121 case '\'': 122 case '\\': 123 default: 124 *o = *i++; 125 break; 126 } 127 } 128 else { 129 *o = *i++; 130 } 131 } 132 *o = '\0'; 133} 134 135MenuRoot *GetRoot(char *name, char *fore, char *back) 136{ 137 MenuRoot *tmp; 138 139 tmp = FindMenuRoot(name); 140 if(tmp == NULL) { 141 tmp = NewMenuRoot(name); 142 } 143 144 if(fore) { 145 bool save; 146 147 save = Scr->FirstTime; 148 Scr->FirstTime = true; 149 GetColor(COLOR, &tmp->highlight.fore, fore); 150 GetColor(COLOR, &tmp->highlight.back, back); 151 Scr->FirstTime = save; 152 } 153 154 return tmp; 155} 156 157void GotButton(int butt, int func) 158{ 159 int i; 160 MenuItem *item; 161 162 for(i = 0; i < NUM_CONTEXTS; i++) { 163 if((cont & (1 << i)) == 0) { 164 continue; 165 } 166 167 if(func == F_MENU) { 168 pull->prev = NULL; 169 AddFuncButton(butt, i, mods, func, pull, NULL); 170 } 171 else { 172 root = GetRoot(TWM_ROOT, NULL, NULL); 173 item = AddToMenu(root, "x", Action, NULL, func, NULL, NULL); 174 AddFuncButton(butt, i, mods, func, NULL, item); 175 } 176 } 177 178 Action = ""; 179 pull = NULL; 180 cont = 0; 181 mods_used |= mods; 182 mods = 0; 183} 184 185void GotKey(char *key, int func) 186{ 187 int i; 188 189 for(i = 0; i < NUM_CONTEXTS; i++) { 190 if((cont & (1 << i)) == 0) { 191 continue; 192 } 193 194 if(func == F_MENU) { 195 pull->prev = NULL; 196 if(!AddFuncKey(key, i, mods, func, pull, Name, Action)) { 197 break; 198 } 199 } 200 else if(!AddFuncKey(key, i, mods, func, NULL, Name, Action)) { 201 break; 202 } 203 } 204 205 Action = ""; 206 pull = NULL; 207 cont = 0; 208 mods_used |= mods; 209 mods = 0; 210} 211 212 213void GotTitleButton(char *bitmapname, int func, bool rightside) 214{ 215 if(!CreateTitleButton(bitmapname, func, Action, pull, rightside, true)) { 216 twmrc_error_prefix(); 217 fprintf(stderr, 218 "unable to create %s titlebutton \"%s\"\n", 219 rightside ? "right" : "left", bitmapname); 220 } 221 Action = ""; 222 pull = NULL; 223} 224 225 226/* Check f.warptoscreen arg */ 227bool 228CheckWarpScreenArg(const char *s) 229{ 230 /* next/prev/back are valid */ 231 if(strcasecmp(s, WARPSCREEN_NEXT) == 0 || 232 strcasecmp(s, WARPSCREEN_PREV) == 0 || 233 strcasecmp(s, WARPSCREEN_BACK) == 0) { 234 return true; 235 } 236 237 /* Or if the whole thing is numeric, it's valid too */ 238 for(; *s && Isascii(*s) && Isdigit(*s); s++) { 239 /* nada */; 240 } 241 return (*s ? false : true); 242} 243 244 245/* f.warptoring arg */ 246bool 247CheckWarpRingArg(const char *s) 248{ 249 if(strcasecmp(s, WARPSCREEN_NEXT) == 0 || 250 strcasecmp(s, WARPSCREEN_PREV) == 0) { 251 return true; 252 } 253 254 return false; 255} 256 257 258/* f.colormap arg */ 259bool 260CheckColormapArg(const char *s) 261{ 262 if(strcasecmp(s, COLORMAP_NEXT) == 0 || 263 strcasecmp(s, COLORMAP_PREV) == 0 || 264 strcasecmp(s, COLORMAP_DEFAULT) == 0) { 265 return true; 266 } 267 268 return false; 269} 270