aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-06-11 15:56:02 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-06-11 15:56:02 -0300
commit33f4fef4101f4c834516ad3be9869d90182559c4 (patch)
tree7641515cb8309276bd494f2b1ccc3bddcb6c7c8b
parente77534c08f6470c01ee8be2b609422ef0834463b (diff)
downloadlua-33f4fef4101f4c834516ad3be9869d90182559c4.tar.gz
lua-33f4fef4101f4c834516ad3be9869d90182559c4.tar.bz2
lua-33f4fef4101f4c834516ad3be9869d90182559c4.zip
BUG: did not handle properly pragmas $endinput/$debug inside a $if.
-rw-r--r--lex.c80
1 files changed, 44 insertions, 36 deletions
diff --git a/lex.c b/lex.c
index 9e3a0857..4cfc7e13 100644
--- a/lex.c
+++ b/lex.c
@@ -1,4 +1,4 @@
1char *rcs_lex = "$Id: lex.c,v 3.2 1997/04/14 15:30:29 roberto Exp roberto $"; 1char *rcs_lex = "$Id: lex.c,v 3.4 1997/06/11 14:20:51 roberto Exp $";
2 2
3 3
4#include <ctype.h> 4#include <ctype.h>
@@ -23,17 +23,17 @@ char *rcs_lex = "$Id: lex.c,v 3.2 1997/04/14 15:30:29 roberto Exp roberto $";
23static int current; /* look ahead character */ 23static int current; /* look ahead character */
24static Input input; /* input function */ 24static Input input; /* input function */
25 25
26#define MAX_IFS 10
27 26
28/* "ifstate" keeps the state of each nested $if the lexical is 27#define MAX_IFS 5
29** dealing with. The first bit indicates whether the $if condition 28
30** is false or true. The second bit indicates whether the lexical is 29/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
31** inside the "then" part (0) or the "else" part (2) 30
32*/ 31static struct {
33static int ifstate[MAX_IFS]; /* 0 => then part - condition false */ 32 int elsepart; /* true if its in the $else part */
34 /* 1 => then part - condition true */ 33 int condition; /* true if $if condition is true */
35 /* 2 => else part - condition false */ 34 int skip; /* true if part must be skiped */
36 /* 3 => else part - condition true */ 35} ifstate[MAX_IFS];
36
37static int iflevel; /* level of nested $if's */ 37static int iflevel; /* level of nested $if's */
38 38
39 39
@@ -42,6 +42,8 @@ void lua_setinput (Input fn)
42 current = '\n'; 42 current = '\n';
43 lua_linenumber = 0; 43 lua_linenumber = 0;
44 iflevel = 0; 44 iflevel = 0;
45 ifstate[0].skip = 0;
46 ifstate[0].elsepart = 1; /* to avoid a free $else */
45 input = fn; 47 input = fn;
46} 48}
47 49
@@ -117,10 +119,9 @@ static void skipspace (void)
117 119
118static int checkcond (char *buff) 120static int checkcond (char *buff)
119{ 121{
120 if (strcmp(buff, "nil") == 0) 122 static char *opts[] = {"nil", "1"};
121 return 0; 123 int i = luaI_findstring(buff, opts);
122 else if (strcmp(buff, "1") == 0) 124 if (i >= 0) return i;
123 return 1;
124 else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') 125 else if (isalpha((unsigned char)buff[0]) || buff[0] == '_')
125 return luaI_globaldefined(buff); 126 return luaI_globaldefined(buff);
126 else { 127 else {
@@ -149,11 +150,9 @@ static void readname (char *buff)
149static void inclinenumber (void); 150static void inclinenumber (void);
150 151
151 152
152static void ifskip (int thisiflevel) 153static void ifskip (void)
153{ 154{
154 if (thisiflevel < 0) return; 155 while (ifstate[iflevel].skip) {
155 while (iflevel > thisiflevel &&
156 (ifstate[thisiflevel] == 0 || ifstate[thisiflevel] == 3)) {
157 if (current == '\n') 156 if (current == '\n')
158 inclinenumber(); 157 inclinenumber();
159 else if (current == 0) 158 else if (current == 0)
@@ -166,51 +165,60 @@ static void ifskip (int thisiflevel)
166static void inclinenumber (void) 165static void inclinenumber (void)
167{ 166{
168 static char *pragmas [] = 167 static char *pragmas [] =
169 {"debug", "nodebug", "end", "ifnot", "if", "else", "endinput", NULL}; 168 {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL};
170 next(); /* skip '\n' */ 169 next(); /* skip '\n' */
171 ++lua_linenumber; 170 ++lua_linenumber;
172 if (current == '$') { /* is a pragma? */ 171 if (current == '$') { /* is a pragma? */
173 char buff[PRAGMASIZE+1]; 172 char buff[PRAGMASIZE+1];
174 int ifnot = 0; 173 int ifnot = 0;
174 int skip = ifstate[iflevel].skip;
175 next(); /* skip $ */ 175 next(); /* skip $ */
176 readname(buff); 176 readname(buff);
177 switch (luaI_findstring(buff, pragmas)) { 177 switch (luaI_findstring(buff, pragmas)) {
178 case 0: /* debug */ 178 case 0: /* debug */
179 lua_debug = 1; 179 if (!skip) lua_debug = 1;
180 break; 180 break;
181 case 1: /* nodebug */ 181 case 1: /* nodebug */
182 lua_debug = 0; 182 if (!skip) lua_debug = 0;
183 break; 183 break;
184 case 2: /* end */ 184 case 2: /* endinput */
185 if (--iflevel < 0) 185 if (!skip) {
186 current = 0;
187 iflevel = 0; /* to allow $endinput inside a $if */
188 }
189 break;
190 case 3: /* end */
191 if (iflevel-- == 0)
186 luaI_auxsyntaxerror("unmatched $endif"); 192 luaI_auxsyntaxerror("unmatched $endif");
187 break; 193 break;
188 case 3: /* ifnot */ 194 case 4: /* ifnot */
189 ifnot = 1; 195 ifnot = 1;
190 /* go through */ 196 /* go through */
191 case 4: /* if */ 197 case 5: /* if */
192 if (iflevel == MAX_IFS) 198 if (iflevel == MAX_IFS-1)
193 luaI_auxsyntaxerror("too many nested `$ifs'"); 199 luaI_auxsyntaxerror("too many nested `$ifs'");
194 readname(buff); 200 readname(buff);
195 ifstate[iflevel++] = checkcond(buff) ? !ifnot : ifnot; 201 iflevel++;
202 ifstate[iflevel].elsepart = 0;
203 ifstate[iflevel].condition = checkcond(buff) ? !ifnot : ifnot;
204 ifstate[iflevel].skip = skip || !ifstate[iflevel].condition;
196 break; 205 break;
197 case 5: /* else */ 206 case 6: /* else */
198 if (iflevel <= 0 || (ifstate[iflevel-1] & 2)) 207 if (ifstate[iflevel].elsepart)
199 luaI_auxsyntaxerror("unmatched $else"); 208 luaI_auxsyntaxerror("unmatched $else");
200 ifstate[iflevel-1] = ifstate[iflevel-1] | 2; 209 ifstate[iflevel].elsepart = 1;
201 break; 210 ifstate[iflevel].skip =
202 case 6: /* endinput */ 211 ifstate[iflevel-1].skip || ifstate[iflevel].condition;
203 current = 0;
204 break; 212 break;
205 default: 213 default:
206 luaI_auxsynterrbf("invalid pragma", buff); 214 luaI_auxsynterrbf("invalid pragma", buff);
207 } 215 }
208 skipspace(); 216 skipspace();
209 if (current == '\n') /* pragma must end with a '\n' */ 217 if (current == '\n') /* pragma must end with a '\n' ... */
210 inclinenumber(); 218 inclinenumber();
211 else if (current != 0) /* or eof */ 219 else if (current != 0) /* or eof */
212 luaI_auxsyntaxerror("invalid pragma format"); 220 luaI_auxsyntaxerror("invalid pragma format");
213 ifskip(iflevel-1); 221 ifskip();
214 } 222 }
215} 223}
216 224