win/X11 lint
[aNetHack.git] / util / lev_comp.l
blob35f4eb252d667c63f724fdab2b598ba9df20847d
1 %{
2 /* NetHack 3.6  lev_comp.l      $NHDT-Date: 1449385191 2015/12/06 06:59:51 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.22 $ */
3 /*      Copyright (c) 1989 by Jean-Christophe Collet */
4 /* NetHack may be freely redistributed.  See license for details. */
6 #define LEV_LEX_C
8 #include "hack.h"
9 #include "lev_comp.h"
10 #include "sp_lev.h"
12 /* Most of these don't exist in flex, yywrap is macro and
13  * yyunput is properly declared in flex.skel.
14  */
15 #if !defined(FLEX_SCANNER) && !defined(FLEXHACK_SCANNER)
16 int FDECL(yyback, (int *,int));
17 int NDECL(yylook);
18 int NDECL(yyinput);
19 int NDECL(yywrap);
20 int NDECL(yylex);
21         /* Traditional lexes let yyunput() and yyoutput() default to int;
22          * newer ones may declare them as void since they don't return
23          * values.  For even more fun, the lex supplied as part of the
24          * newer unbundled compiler for SunOS 4.x adds the void declarations
25          * (under __STDC__ or _cplusplus ifdefs -- otherwise they remain
26          * int) while the bundled lex and the one with the older unbundled
27          * compiler do not.  To detect this, we need help from outside --
28          * sys/unix/Makefile.utl.
29          *
30          * Digital UNIX is difficult and still has int in spite of all
31          * other signs.
32          */
33 # if defined(NeXT) || defined(SVR4) || defined(_AIX32)
34 #  define VOIDYYPUT
35 # endif
36 # if !defined(VOIDYYPUT) && defined(POSIX_TYPES)
37 #  if !defined(BOS) && !defined(HISX) && !defined(_M_UNIX) && !defined(VMS)
38 #   define VOIDYYPUT
39 #  endif
40 # endif
41 # if !defined(VOIDYYPUT) && defined(WEIRD_LEX)
42 #  if defined(SUNOS4) && defined(__STDC__) && (WEIRD_LEX > 1)
43 #   define VOIDYYPUT
44 #  endif
45 # endif
46 # if defined(VOIDYYPUT) && defined(__osf__)
47 #  undef VOIDYYPUT
48 # endif
49 # ifdef VOIDYYPUT
50 void FDECL(yyunput, (int));
51 void FDECL(yyoutput, (int));
52 # else
53 int FDECL(yyunput, (int));
54 int FDECL(yyoutput, (int));
55 # endif
57 #else   /* !FLEX_SCANNER && !FLEXHACK_SCANNER */
58 /* most recent flex allows suppressing yyunput() altogether when not needed */
59 #define YY_NO_UNPUT
60 #endif
62 #if defined(FLEX_SCANNER) || defined(FLEXHACK_SCANNER)
63 /* older flex wants this */
64 #define YY_MALLOC_DECL  genericptr_t FDECL(malloc, (size_t)); \
65                         genericptr_t FDECL(realloc, (genericptr_t, size_t));
66 /* newer flex assumes <stdlib.h> so needs this in case it's been suppressed */
67 YY_MALLOC_DECL
68 #endif
70 void FDECL(init_yyin, (FILE *));
71 void FDECL(init_yyout, (FILE *));
73 long NDECL(handle_varstring_check);
74 long FDECL(corefunc_str_check, (char *, long));
76 extern void VDECL(lc_error, (const char *, ...));
77 extern struct lc_vardefs *FDECL(vardef_defined,(struct lc_vardefs *,char *, int));
79 extern struct lc_vardefs *variable_definitions;
81 extern long FDECL(method_defined, (char *, long, long *));
83 void FDECL(savetoken, (char *));
84 void NDECL(newline);
85 void FDECL(advancepos, (char *));
88  * This doesn't always get put in lev_comp.h
89  * (esp. when using older versions of bison).
90  */
91 extern YYSTYPE yylval;
93 int nh_line_number = 1;
94 int token_start_pos = 0;
95 char curr_token[512];
96 static char map[4096];
97 static int map_cnt = 0;
99 FILE *orig_yyin = NULL;
101 #define ST_RET(x) do { savetoken(yytext); return x; } while (0);
102 #define ST_RETF(y, x) do { savetoken(yytext); y; return x; } while (0);
105 %e 2500
106 %p 10000
107 %n 1500
108 %s MAPC
110 <MAPC>ENDMAP    {
111                   savetoken(yytext);
112                   BEGIN(INITIAL);
113                   yylval.map = (char *) alloc(map_cnt + 1);
114                   (void) strncpy(yylval.map, map, map_cnt);
115                   yylval.map[map_cnt] = 0;
116                   map_cnt = 0;
117                   return MAP_ID;
118                 }
119 <MAPC>[-|}{+xABCISHKPLWTF\\#. 0123456789]*\r?\n {
120                   int len = yyleng;
121                   savetoken(yytext);
122                   /* convert \r\n to \n */
123                   if (len >= 2 && yytext[len - 2] == '\r')
124                       len -= 1;
125                   (void) strncpy(map + map_cnt, yytext, len);
126                   map_cnt += len;
127                   map[map_cnt - 1] = '\n';
128                   map[map_cnt] = '\0';
129                   newline();
130                 }
131 ^[ \t]*#.*\n    { savetoken(yytext); newline(); }
132 MESSAGE         ST_RET(MESSAGE_ID);
133 NOMAP           ST_RET(NOMAP_ID);
134 MAZE            ST_RET(MAZE_ID);
135 LEVEL           ST_RET(LEVEL_ID);
136 INIT_MAP        ST_RET(LEV_INIT_ID);
137 mazegrid        ST_RET(MAZE_GRID_ID);
138 solidfill       ST_RET(SOLID_FILL_ID);
139 mines           ST_RET(MINES_ID);
140 rogue           ST_RET(ROGUELEV_ID);
141 FLAGS           ST_RET(FLAGS_ID);
142 GEOMETRY        ST_RET(GEOMETRY_ID);
143 ^MAP\r?\n       { savetoken(yytext); BEGIN(MAPC); newline(); }
144 obj(ect)?       ST_RET(object_ID);
145 OBJECT          ST_RET(OBJECT_ID);
146 CONTAINER       ST_RET(COBJECT_ID);
147 MONSTER         ST_RET(MONSTER_ID);
148 monster         ST_RET(monster_ID);
149 TRAP            ST_RET(TRAP_ID);
150 DOOR            ST_RET(DOOR_ID);
151 ROOMDOOR        ST_RET(ROOMDOOR_ID);
152 DRAWBRIDGE      ST_RET(DRAWBRIDGE_ID);
153 MAZEWALK        ST_RET(MAZEWALK_ID);
154 WALLIFY         ST_RET(WALLIFY_ID);
155 REGION          ST_RET(REGION_ID);
156 ALTAR           ST_RET(ALTAR_ID);
157 LADDER          ST_RET(LADDER_ID);
158 STAIR           ST_RET(STAIR_ID);
159 PORTAL          ST_RET(PORTAL_ID);
160 TELEPORT_REGION ST_RET(TELEPRT_ID);
161 BRANCH          ST_RET(BRANCH_ID);
162 FOUNTAIN        ST_RET(FOUNTAIN_ID);
163 SINK            ST_RET(SINK_ID);
164 POOL            ST_RET(POOL_ID);
165 NON_DIGGABLE    ST_RET(NON_DIGGABLE_ID);
166 NON_PASSWALL    ST_RET(NON_PASSWALL_ID);
167 IF              ST_RET(IF_ID);
168 ELSE            ST_RET(ELSE_ID);
169 EXIT            ST_RET(EXIT_ID);
170 ROOM            ST_RET(ROOM_ID);
171 SUBROOM         ST_RET(SUBROOM_ID);
172 RANDOM_CORRIDORS        ST_RET(RAND_CORRIDOR_ID);
173 CORRIDOR        ST_RET(CORRIDOR_ID);
174 TERRAIN         ST_RET(TERRAIN_ID);
175 terrain         ST_RET(terrain_ID);
176 REPLACE_TERRAIN ST_RET(REPLACE_TERRAIN_ID);
177 GOLD            ST_RET(GOLD_ID);
178 GRAVE           ST_RET(GRAVE_ID);
179 ENGRAVING       ST_RET(ENGRAVING_ID);
180 MINERALIZE      ST_RET(MINERALIZE_ID);
181 (NAME|name)     ST_RET(NAME_ID);
182 FOR             ST_RET(FOR_ID);
183 TO              ST_RET(TO_ID);
184 LOOP            ST_RET(LOOP_ID);
185 SWITCH          ST_RET(SWITCH_ID);
186 CASE            ST_RET(CASE_ID);
187 BREAK           ST_RET(BREAK_ID);
188 DEFAULT         ST_RET(DEFAULT_ID);
189 FUNCTION        ST_RET(FUNCTION_ID);
190 SHUFFLE         ST_RET(SHUFFLE_ID);
191 montype         ST_RET(MONTYPE_ID);
192 selection       ST_RET(selection_ID);
193 rect            ST_RET(rect_ID);
194 fillrect        ST_RET(fillrect_ID);
195 line            ST_RET(line_ID);
196 randline        ST_RET(randline_ID);
197 grow            ST_RET(grow_ID);
198 floodfill       ST_RET(flood_ID);
199 rndcoord        ST_RET(rndcoord_ID);
200 circle          ST_RET(circle_ID);
201 ellipse         ST_RET(ellipse_ID);
202 filter          ST_RET(filter_ID);
203 gradient        ST_RET(gradient_ID);
204 complement      ST_RET(complement_ID);
205 radial          { savetoken(yytext); yylval.i=SEL_GRADIENT_RADIAL;  return GRADIENT_TYPE; }
206 square          { savetoken(yytext); yylval.i=SEL_GRADIENT_SQUARE;  return GRADIENT_TYPE; }
207 dry             { savetoken(yytext); yylval.i=DRY;  return HUMIDITY_TYPE; }
208 wet             { savetoken(yytext); yylval.i=WET;  return HUMIDITY_TYPE; }
209 hot             { savetoken(yytext); yylval.i=HOT;  return HUMIDITY_TYPE; }
210 solid           { savetoken(yytext); yylval.i=SOLID;  return HUMIDITY_TYPE; }
211 any             { savetoken(yytext); yylval.i=ANY_LOC;  return HUMIDITY_TYPE; }
212 levregion       ST_RET(LEV);
213 quantity        ST_RET(QUANTITY_ID);
214 buried          ST_RET(BURIED_ID);
215 eroded          ST_RET(ERODED_ID);
216 erodeproof      ST_RET(ERODEPROOF_ID);
217 trapped     { savetoken(yytext); yylval.i=1; return TRAPPED_STATE; }
218 not_trapped { savetoken(yytext); yylval.i=0; return TRAPPED_STATE; }
219 recharged       ST_RET(RECHARGED_ID);
220 invisible       ST_RET(INVIS_ID);
221 greased         ST_RET(GREASED_ID);
222 female          ST_RET(FEMALE_ID);
223 cancelled       ST_RET(CANCELLED_ID);
224 revived         ST_RET(REVIVED_ID);
225 avenge          ST_RET(AVENGE_ID);
226 fleeing         ST_RET(FLEEING_ID);
227 blinded         ST_RET(BLINDED_ID);
228 paralyzed       ST_RET(PARALYZED_ID);
229 stunned         ST_RET(STUNNED_ID);
230 confused        ST_RET(CONFUSED_ID);
231 seen_traps      ST_RET(SEENTRAPS_ID);
232 all             ST_RET(ALL_ID);
233 horizontal      ST_RETF((yylval.i=1), HORIZ_OR_VERT);
234 vertical        { savetoken(yytext); yylval.i=2; return HORIZ_OR_VERT; }
235 open            { savetoken(yytext); yylval.i=D_ISOPEN; return DOOR_STATE; }
236 closed          { savetoken(yytext); yylval.i=D_CLOSED; return DOOR_STATE; }
237 locked          { savetoken(yytext); yylval.i=D_LOCKED; return DOOR_STATE; }
238 nodoor          { savetoken(yytext); yylval.i=D_NODOOR; return DOOR_STATE; }
239 broken          { savetoken(yytext); yylval.i=D_BROKEN; return DOOR_STATE; }
240 secret          { savetoken(yytext); yylval.i=D_SECRET; return DOOR_STATE; }
241 north           { savetoken(yytext); yylval.i=W_NORTH; return DIRECTION; }
242 east            { savetoken(yytext); yylval.i=W_EAST; return DIRECTION; }
243 south           { savetoken(yytext); yylval.i=W_SOUTH; return DIRECTION; }
244 west            { savetoken(yytext); yylval.i=W_WEST; return DIRECTION; }
245 random          { savetoken(yytext); yylval.i = -1; return RANDOM_TYPE; }
246 random\[        { savetoken(yytext); yylval.i = -1; return RANDOM_TYPE_BRACKET; }
247 none            { savetoken(yytext); yylval.i = -2; return NONE; }
248 align           ST_RET(A_REGISTER);
249 left            { savetoken(yytext); yylval.i=1; return LEFT_OR_RIGHT; }
250 half-left       { savetoken(yytext); yylval.i=2; return LEFT_OR_RIGHT; }
251 center          { savetoken(yytext); yylval.i=3; return CENTER; }
252 half-right      { savetoken(yytext); yylval.i=4; return LEFT_OR_RIGHT; }
253 right           { savetoken(yytext); yylval.i=5; return LEFT_OR_RIGHT; }
254 top             { savetoken(yytext); yylval.i=1; return TOP_OR_BOT; }
255 bottom          { savetoken(yytext); yylval.i=5; return TOP_OR_BOT; }
256 lit             { savetoken(yytext); yylval.i=1; return LIGHT_STATE; }
257 unlit           { savetoken(yytext); yylval.i=0; return LIGHT_STATE; }
258 filled          { savetoken(yytext); yylval.i=1; return FILLING; }
259 unfilled        { savetoken(yytext); yylval.i=0; return FILLING; }
260 regular         { savetoken(yytext); yylval.i=0; return IRREGULAR; }
261 irregular       { savetoken(yytext); yylval.i=1; return IRREGULAR; }
262 unjoined        { savetoken(yytext); yylval.i=1; return JOINED; }
263 joined          { savetoken(yytext); yylval.i=0; return JOINED; }
264 limited         { savetoken(yytext); yylval.i=1; return LIMITED; }
265 unlimited       { savetoken(yytext); yylval.i=0; return LIMITED; }
266 noalign         { savetoken(yytext); yylval.i= AM_NONE; return ALIGNMENT; }
267 law             { savetoken(yytext); yylval.i= AM_LAWFUL; return ALIGNMENT; }
268 neutral         { savetoken(yytext); yylval.i= AM_NEUTRAL; return ALIGNMENT; }
269 chaos           { savetoken(yytext); yylval.i= AM_CHAOTIC; return ALIGNMENT; }
270 coaligned       { savetoken(yytext); yylval.i= AM_SPLEV_CO; return ALIGNMENT; }
271 noncoaligned    { savetoken(yytext); yylval.i= AM_SPLEV_NONCO; return ALIGNMENT; }
272 peaceful        { savetoken(yytext); yylval.i=1; return MON_ATTITUDE; }
273 hostile         { savetoken(yytext); yylval.i=0; return MON_ATTITUDE; }
274 asleep          { savetoken(yytext); yylval.i=1; return MON_ALERTNESS; }
275 awake           { savetoken(yytext); yylval.i=0; return MON_ALERTNESS; }
276 m_feature       { savetoken(yytext); yylval.i= M_AP_FURNITURE; return MON_APPEARANCE; }
277 m_monster       { savetoken(yytext); yylval.i= M_AP_MONSTER;   return MON_APPEARANCE; }
278 m_object        { savetoken(yytext); yylval.i= M_AP_OBJECT;    return MON_APPEARANCE; }
279 sanctum         { savetoken(yytext); yylval.i=2; return ALTAR_TYPE; }
280 shrine          { savetoken(yytext); yylval.i=1; return ALTAR_TYPE; }
281 altar           { savetoken(yytext); yylval.i=0; return ALTAR_TYPE; }
282 up              { savetoken(yytext); yylval.i=1; return UP_OR_DOWN; }
283 down            { savetoken(yytext); yylval.i=0; return UP_OR_DOWN; }
284 false           { savetoken(yytext); yylval.i=0; return BOOLEAN; }
285 true            { savetoken(yytext); yylval.i=1; return BOOLEAN; }
286 dust            { savetoken(yytext); yylval.i=DUST; return ENGRAVING_TYPE; }
287 engrave         { savetoken(yytext); yylval.i=ENGRAVE; return ENGRAVING_TYPE; }
288 burn            { savetoken(yytext); yylval.i=BURN; return ENGRAVING_TYPE; }
289 mark            { savetoken(yytext); yylval.i=MARK; return ENGRAVING_TYPE; }
290 blood           { savetoken(yytext); yylval.i=ENGR_BLOOD; return ENGRAVING_TYPE; }
291 blessed         { savetoken(yytext); yylval.i=1; return CURSE_TYPE; }
292 uncursed        { savetoken(yytext); yylval.i=2; return CURSE_TYPE; }
293 cursed          { savetoken(yytext); yylval.i=3; return CURSE_TYPE; }
294 noteleport      { savetoken(yytext); yylval.i=NOTELEPORT; return FLAG_TYPE; }
295 hardfloor       { savetoken(yytext); yylval.i=HARDFLOOR; return FLAG_TYPE; }
296 nommap          { savetoken(yytext); yylval.i=NOMMAP; return FLAG_TYPE; }
297 arboreal        { savetoken(yytext); yylval.i=ARBOREAL; return FLAG_TYPE; } /* KMH */
298 shortsighted    { savetoken(yytext); yylval.i=SHORTSIGHTED; return FLAG_TYPE; }
299 mazelevel       { savetoken(yytext); yylval.i=MAZELEVEL; return FLAG_TYPE; }
300 premapped       { savetoken(yytext); yylval.i=PREMAPPED; return FLAG_TYPE; }
301 shroud          { savetoken(yytext); yylval.i=SHROUD; return FLAG_TYPE; }
302 graveyard       { savetoken(yytext); yylval.i=GRAVEYARD; return FLAG_TYPE; }
303 icedpools       { savetoken(yytext); yylval.i=ICEDPOOLS; return FLAG_TYPE; }
304 solidify        { savetoken(yytext); yylval.i=SOLIDIFY; return FLAG_TYPE; }
305 corrmaze        { savetoken(yytext); yylval.i=CORRMAZE; return FLAG_TYPE; }
306 inaccessibles   { savetoken(yytext); yylval.i=CHECK_INACCESSIBLES; return FLAG_TYPE; }
307 [0-9]+d[0-9]+   { char *p = index(yytext, 'd');
308                   savetoken(yytext);
309                   if (p) {
310                         *p++ = '\0';
311                         yylval.dice.num = atoi(yytext);
312                         yylval.dice.die = atoi(p);
313                   } else {
314                         yylval.dice.num = yylval.dice.die = 1;
315                   }
316                   return DICE;
317                 }
318 \[\ *[0-9]+\%\ *\] { savetoken(yytext); yylval.i = atoi(yytext + 1);
319                      if (yylval.i < 0 || yylval.i > 100)
320                         lc_error("Unexpected percentile '%li%%'", yylval.i);
321                      return PERCENT; }
322 -[0-9]+         { savetoken(yytext); yylval.i=atoi(yytext); return MINUS_INTEGER; }
323 \+[0-9]+        { savetoken(yytext); yylval.i=atoi(yytext); return PLUS_INTEGER; }
324 [0-9]+\%        { savetoken(yytext); yylval.i = atoi(yytext);
325                   if (yylval.i < 0 || yylval.i > 100)
326                      lc_error("Unexpected percentile '%li%%'", yylval.i);
327                   return SPERCENT; }
328 [0-9]+          { savetoken(yytext); yylval.i=atoi(yytext); return INTEGER; }
329 \"[^"]*\"       { savetoken(yytext);
330                   yytext[yyleng - 1] = '\0'; /* discard the trailing \" */
331                   yylval.map = dupstr(yytext + 1); /* skip the first \" */
332                   return STRING; }
333 \$[a-zA-Z_]+    { savetoken(yytext); return handle_varstring_check(); }
334 "=="            { savetoken(yytext); yylval.i = SPO_JE; return COMPARE_TYPE; }
335 "!="            { savetoken(yytext); yylval.i = SPO_JNE; return COMPARE_TYPE; }
336 "<>"            { savetoken(yytext); yylval.i = SPO_JNE; return COMPARE_TYPE; }
337 "<="            { savetoken(yytext); yylval.i = SPO_JLE; return COMPARE_TYPE; }
338 ">="            { savetoken(yytext); yylval.i = SPO_JGE; return COMPARE_TYPE; }
339 "<"             { savetoken(yytext); yylval.i = SPO_JL; return COMPARE_TYPE; }
340 ">"             { savetoken(yytext); yylval.i = SPO_JG; return COMPARE_TYPE; }
341 \r?\n           { newline(); }
342 [ \t]+          { advancepos(yytext); }
343 '\\.'           { savetoken(yytext); yylval.i = yytext[2]; return CHAR; }
344 '.'             { savetoken(yytext); yylval.i = yytext[1]; return CHAR; }
345 [-_a-zA-Z0-9]+  ST_RET(UNKNOWN_TYPE);
346 .               { savetoken(yytext); return yytext[0]; }
348 #ifdef  AMIGA
349 long *
350 alloc(n)
351     unsigned n;
353     return (long *) malloc(n);
355 #endif
357 /* routine to switch to another input file; needed for flex */
358 void
359 init_yyin( input_f )
360 FILE *input_f;
362 #if defined(FLEX_SCANNER) || defined(FLEXHACK_SCANNER)
363     if (yyin)
364         yyrestart(input_f);
365     else
366 #endif
367         yyin = input_f;
369     if (!orig_yyin)
370         orig_yyin = yyin;
372 /* analogous routine (for completeness) */
373 void
374 init_yyout( output_f )
375 FILE *output_f;
377     yyout = output_f;
380 long
381 handle_varstring_check()
383     struct lc_vardefs *vd;
385     yylval.map = dupstr(yytext);
386     if ((vd = vardef_defined(variable_definitions, yytext, 1)) != 0) {
387         long l = vd->var_type;
388         int a = ((l & SPOVAR_ARRAY) == SPOVAR_ARRAY);
390         l &= ~SPOVAR_ARRAY;
391         if (l == SPOVAR_INT)
392             return (a ? VARSTRING_INT_ARRAY : VARSTRING_INT);
393         if (l == SPOVAR_STRING)
394             return (a ? VARSTRING_STRING_ARRAY : VARSTRING_STRING);
395         if (l == SPOVAR_VARIABLE)
396             return (a ? VARSTRING_VAR_ARRAY : VARSTRING_VAR);
397         if (l == SPOVAR_COORD)
398             return (a ? VARSTRING_COORD_ARRAY : VARSTRING_COORD);
399         if (l == SPOVAR_REGION)
400             return (a ? VARSTRING_REGION_ARRAY : VARSTRING_REGION);
401         if (l == SPOVAR_MAPCHAR)
402             return (a ? VARSTRING_MAPCHAR_ARRAY : VARSTRING_MAPCHAR);
403         if (l == SPOVAR_MONST)
404             return (a ? VARSTRING_MONST_ARRAY : VARSTRING_MONST);
405         if (l == SPOVAR_OBJ)
406             return (a ? VARSTRING_OBJ_ARRAY : VARSTRING_OBJ);
407         if (l == SPOVAR_SEL)
408             return (a ? VARSTRING_SEL_ARRAY : VARSTRING_SEL);
409     }
410     return VARSTRING;
413 void
414 newline()
416     nh_line_number++;
417     token_start_pos = 0;
418     (void) memset((genericptr_t) curr_token, 0, 512);
421 void
422 savetoken(s)
423 char *s;
425     Sprintf(curr_token, "%s", s);
426     advancepos(s);
429 void
430 advancepos(s)
431 char *s;
433     token_start_pos += strlen(s);
436 /*lev_comp.l*/