coan 4.2.4
|
00001 /*************************************************************************** 00002 * Copyright (C) 2004, 2006 Symbian Software Ltd. * 00003 * All rights reserved. * 00004 * Copyright (C) 2002, 2003 Tony Finch <dot@dotat.at>. * 00005 * All rights reserved. * 00006 * Copyright (C) 1985, 1993 The Regents of the University of California. * 00007 * All rights reserved. * 00008 * * 00009 * Contributed by Mike Kinghan, imk@strudl.org, derived from the code * 00010 * of Tony Finch * 00011 * * 00012 * Redistribution and use in source and binary forms, with or without * 00013 * modification, are permitted provided that the following conditions * 00014 * are met: * 00015 * * 00016 * Redistributions of source code must retain the above copyright * 00017 * notice, this list of conditions and the following disclaimer. * 00018 * * 00019 * Redistributions in binary form must reproduce the above copyright * 00020 * notice, this list of conditions and the following disclaimer in the * 00021 * documentation and/or other materials provided with the distribution. * 00022 * * 00023 * Neither the name of Symbian Software Ltd. nor the names of its * 00024 * contributors may be used to endorse or promote products derived from * 00025 * this software without specific prior written permission. * 00026 * * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 00028 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 00029 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 00030 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 00031 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 00032 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 00033 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * 00034 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * 00035 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* 00036 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * 00037 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * 00038 * DAMAGE. * 00039 * * 00040 **************************************************************************/ 00041 00042 #include "if_control.h" 00043 #include "report.h" 00044 #include "line_edit.h" 00045 #include "line_despatch.h" 00046 #include "chew.h" 00047 #include "io.h" 00048 00049 00058 00062 #define MAXDEPTH 64 00063 00064 /* Helpers ****************************************************************/ 00065 00067 typedef void transition_t(void); 00068 00073 static void 00074 done_file(void); 00075 00077 static void 00078 nest(void); 00079 00082 static void 00083 set_state(if_state_t is); 00084 00086 static void Strue (void) 00087 { 00088 drop(); 00089 set_state(IF_STATE_TRUE_PREFIX); 00090 } 00092 static void Sfalse(void) 00093 { 00094 drop(); 00095 set_state(IF_STATE_FALSE_PREFIX); 00096 } 00098 static void Selse (void) 00099 { 00100 drop(); 00101 set_state(IF_STATE_TRUE_ELSE); 00102 } 00104 static void Pelif (void) 00105 { 00106 print(); 00107 set_state(IF_STATE_PASS_MIDDLE); 00108 } 00110 static void Pelse (void) 00111 { 00112 print(); 00113 set_state(IF_STATE_PASS_ELSE); 00114 } 00116 static void Pendif(void); 00118 static void Dfalse(void) 00119 { 00120 drop(); 00121 set_state(IF_STATE_FALSE_TRAILER); 00122 } 00124 static void Delif (void) 00125 { 00126 drop(); 00127 set_state(IF_STATE_FALSE_MIDDLE); 00128 } 00130 static void Delse (void) 00131 { 00132 drop(); 00133 set_state(IF_STATE_FALSE_ELSE); 00134 } 00136 static void Dendif(void); 00138 static void Fdrop (void) 00139 { 00140 nest(); 00141 Dfalse(); 00142 } 00144 static void Fpass (void) 00145 { 00146 nest(); 00147 Pelif(); 00148 } 00150 static void Ftrue (void) 00151 { 00152 nest(); 00153 Strue(); 00154 } 00156 static void Ffalse(void) 00157 { 00158 nest(); 00159 Sfalse(); 00160 } 00162 static void Mpass (void) 00163 { 00164 strncpy(GET_PUBLIC(line_edit,keyword), "if ", 4); 00165 Pelif(); 00166 } 00168 static void Mtrue (void) 00169 { 00170 keywordedit("else\n"); 00171 set_state(IF_STATE_TRUE_MIDDLE); 00172 } 00174 static void Melif (void) 00175 { 00176 keywordedit("endif\n"); 00177 set_state(IF_STATE_FALSE_TRAILER); 00178 } 00180 static void Melse (void) 00181 { 00182 keywordedit("endif\n"); 00183 set_state(IF_STATE_FALSE_ELSE); 00184 } 00185 00190 static transition_t * const 00191 transition_table[IF_STATE_COUNT][LT_SENTINEL] = { 00192 /* IF_STATE_OUTSIDE*/ 00193 { 00194 Fpass, 00195 Ftrue, 00196 Ffalse, 00197 orphan_elif, 00198 orphan_elif, 00199 orphan_elif, 00200 orphan_else, 00201 orphan_endif, 00202 print, 00203 done_file 00204 }, 00205 /* IF_STATE_FALSE_PREFIX*/ 00206 { 00207 Fdrop, 00208 Fdrop, 00209 Fdrop, 00210 Mpass, 00211 Strue, 00212 Sfalse, 00213 Selse, 00214 Dendif, 00215 drop, 00216 early_eof 00217 }, 00218 /* IF_STATE_TRUE_PREFIX*/ 00219 { 00220 Fpass, 00221 Ftrue, 00222 Ffalse, 00223 Dfalse, 00224 Dfalse, 00225 Dfalse, 00226 Delse, 00227 Dendif, 00228 print, 00229 early_eof 00230 }, 00231 /* IF_STATE_PASS_MIDDLE*/ 00232 { 00233 Fpass, 00234 Ftrue, 00235 Ffalse, 00236 Pelif, 00237 Mtrue, 00238 Delif, 00239 Pelse, 00240 Pendif, 00241 print, 00242 early_eof 00243 }, 00244 /* IF_STATE_FALSE_MIDDLE*/ 00245 { 00246 Fdrop, 00247 Fdrop, 00248 Fdrop, 00249 Pelif, 00250 Mtrue, 00251 Delif, 00252 Pelse, 00253 Pendif, 00254 drop, 00255 early_eof 00256 }, 00257 /* IF_STATE_TRUE_MIDDLE*/ 00258 { 00259 Fpass, 00260 Ftrue, 00261 Ffalse, 00262 Melif, 00263 Melif, 00264 Melif, 00265 Melse, 00266 Pendif, 00267 print, 00268 early_eof 00269 }, 00270 /* IF_STATE_PASS_ELSE*/ 00271 { 00272 Fpass, 00273 Ftrue, 00274 Ffalse, 00275 orphan_elif, 00276 orphan_elif, 00277 orphan_elif, 00278 orphan_else, 00279 Pendif, 00280 print, 00281 early_eof 00282 }, 00283 /* IF_STATE_FALSE_ELSE*/ 00284 { 00285 Fdrop, 00286 Fdrop, 00287 Fdrop, 00288 orphan_elif, 00289 orphan_elif, 00290 orphan_elif, 00291 orphan_else, 00292 Dendif, 00293 drop, 00294 early_eof 00295 }, 00296 /* IF_STATE_TRUE_ELSE*/ 00297 { 00298 Fpass, 00299 Ftrue, 00300 Ffalse, 00301 orphan_elif, 00302 orphan_elif, 00303 orphan_elif, 00304 orphan_else, 00305 Dendif, 00306 print, 00307 early_eof 00308 }, 00309 /* IF_STATE_FALSE_TRAILER*/ 00310 { 00311 Fdrop, 00312 Fdrop, 00313 Fdrop, 00314 Dfalse, 00315 Dfalse, 00316 Dfalse, 00317 Delse, 00318 Dendif, 00319 drop, 00320 early_eof 00321 } 00322 /*IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF PLAIN EOF*/ 00323 }; 00324 00330 00332 STATE_DEF(if_control) 00333 { 00335 if_state_t ifstate[MAXDEPTH]; 00337 size_t depth; 00339 size_t if_start_lines[MAXDEPTH]; 00340 } 00341 STATE_T(if_control); 00342 00347 00348 NO_PUBLIC_STATE(if_control); 00349 00350 IMPLEMENT(if_control,ZERO_INITABLE); 00351 00354 static void 00355 done_file(void) 00356 { 00357 if (GET_PUBLIC(chew,comment_state) != NO_COMMENT) { 00358 parse_error(GRIPE_EOF_IN_COMMENT, 00359 "EOF in comment, #error ... or #define ... commencing line %d", 00360 GET_PUBLIC(chew,last_comment_start_line)); 00361 } 00362 if (GET_PUBLIC(chew,in_double_quote)) { 00363 parse_error(GRIPE_EOF_IN_QUOTE, 00364 "EOF in quotation commencing line %d", 00365 GET_PUBLIC(chew,last_quote_start_line)); 00366 } 00367 } 00368 00369 static void 00370 nest(void) 00371 { 00372 size_t deep = ++SET_STATE(if_control,depth); 00373 if (deep >= MAXDEPTH) { 00374 bail(GRIPE_TOO_DEEP,"Too many levels of nesting"); 00375 } 00376 GET_STATE(if_control,if_start_lines)[deep] = GET_PUBLIC(io,line_num); 00377 } 00378 00379 static void 00380 set_state(if_state_t is) 00381 { 00382 size_t deep = if_depth(); 00383 GET_STATE(if_control,ifstate)[deep] = is; 00384 } 00385 00386 static void Pendif(void) 00387 { 00388 print(); 00389 --SET_STATE(if_control,depth); 00390 } 00391 00392 static void Dendif(void) 00393 { 00394 drop(); 00395 --SET_STATE(if_control,depth); 00396 } 00397 00398 /* API ********************************************************************/ 00399 00400 void 00401 transition(line_type_t linetype) 00402 { 00403 if_state_t state = GET_STATE(if_control,ifstate)[if_depth()]; 00404 transition_table[state][linetype](); 00405 } 00406 00407 bool 00408 dead_line(void) 00409 { 00410 if_state_t state = 00411 GET_STATE(if_control,ifstate)[if_depth()]; 00412 return state == IF_STATE_FALSE_PREFIX || 00413 state == IF_STATE_FALSE_MIDDLE || 00414 state == IF_STATE_FALSE_ELSE || 00415 state == IF_STATE_FALSE_TRAILER; 00416 } 00417 00418 bool 00419 was_unconditional_line(void) 00420 { 00421 return 00422 GET_STATE(if_control,ifstate)[if_depth()] == 00423 IF_STATE_OUTSIDE; 00424 } 00425 00426 bool 00427 is_unconditional_line(void) 00428 { 00429 if_state_t state = 00430 GET_STATE(if_control,ifstate)[if_depth()]; 00431 return state == IF_STATE_OUTSIDE || 00432 state == IF_STATE_TRUE_PREFIX || 00433 state == IF_STATE_TRUE_MIDDLE || 00434 state == IF_STATE_TRUE_ELSE ; 00435 } 00436 00437 if_state_t 00438 if_state(void) 00439 { 00440 return GET_STATE(if_control,ifstate)[if_depth()]; 00441 } 00442 00443 size_t 00444 if_depth(void) 00445 { 00446 return GET_STATE(if_control,depth); 00447 } 00448 00449 size_t 00450 if_start_line(void) 00451 { 00452 return GET_STATE(if_control,if_start_lines)[if_depth()]; 00453 } 00454 00455 void 00456 if_control_toplevel(void) 00457 { 00458 SET_STATE(if_control,depth) = 0; 00459 } 00460 00461 00462 /* EOF*/