/* this used to always return TRUE (the return value was checked) */ static void is_undo(int *pptr, int *dir) { int redo = FALSE; switch (cmds[cip].s_code) { case SRCH_BEGIN: case SRCH_NOPR: *pptr = -1; break; case SRCH_MARK: break; case SRCH_FORW: *dir = SRCH_BACK; redo = TRUE; break; case SRCH_BACK: *dir = SRCH_FORW; redo = TRUE; break; case SRCH_ACCM: default: *pptr -= 1; if (*pptr < 0) *pptr = 0; pat[*pptr] = '\0'; break; } is_pop(); if (redo) is_undo(pptr, dir); }
/* ** skip_if ** ** skip text, until <$/IF> or <$ELSE> is found ** also handle recursive IFs ** ** params: inpf..input file ** result: IFST_CIF, if exited with </$IF>, ** IFST_ELSE, if exited with </$ELSE> ** errors: call err_eof(), if end-of-file, ** return IFST_ERR */ BYTE skip_if( INFILE *inpf ) { BOOL quit = FALSE; /* TRUE, if end-of-if found */ STRPTR nw = NULL; /* word read from input */ BYTE state = IFST_TEXT; /* current state */ LONG if_nest = 0; /* counter for $IF nesting */ do { if ( state != IFST_TAG ) nw = infgetw( inpf ); if ( nw ) { if ( state == IFST_TAG ) { /* ** skip inside tags */ BYTE tag_state = TGST_TAG; /* state var passe to */ /* eot_reached() */ do { if ( eot_reached( inpf, &tag_state ) ); state = IFST_TEXT; } while ( (tag_state!=TGST_END) && !fatal_error ); } else { /* ** NOTE: I know that this section could be ** shorter, but it would also make the ** source less readable */ /* ** evaluate next state depending on ** previous state */ switch ( state ) { case IFST_TEXT: if ( !strcmp( nw, "<" ) ) state = IFST_LT; break; case IFST_LT: if ( !strcmp( nw, "$" ) ) state = IFST_HSC; else if ( !strcmp( nw, "/" ) ) state = IFST_SLASH; else if ( !upstrcmp( nw, HSC_COMMENT_STR ) ) { skip_hsc_comment( inpf ); state = IFST_TEXT; } else state = IFST_TAG; break; case IFST_HSC: if ( !upstrcmp( nw, "ELSE" ) ) state = IFST_ELSE; else if ( !upstrcmp( nw, "IF" ) ) state = IFST_IF; else state = IFST_TAG; break; case IFST_SLASH: if ( !strcmp( nw, "$" ) ) state = IFST_SLHSC; else state = IFST_TAG; break; case IFST_SLHSC: if ( !upstrcmp( nw, "IF" ) ) state = IFST_CIF; else state = IFST_TAG; break; } /* ** handle special states */ switch ( state ) { case IFST_IF: state = IFST_TAG; if_nest++; DIF( fprintf( stderr, "** skip <$IF> (%d)\n", if_nest ) ); break; case IFST_ELSE: if ( if_nest ) { state = IFST_TAG; DIF( fprintf( stderr, "** skip <$ELSE> (%d)\n", if_nest ) ); } else { /* TODO: check for 2nd <$ELSE> */ quit = TRUE; } break; case IFST_CIF: if ( if_nest ) { state = IFST_TAG; if_nest--; DIF( fprintf( stderr, "** skip </$IF> (%d)\n", if_nest+1 ) ); } else quit = TRUE; break; } } } else { err_eof( inpf, "missing </" HSC_IF_STR ">" ); state = IFST_ERR; } } while ( !quit && nw ); /* check for legal end state */ if ( (state == IFST_CIF) || (state == IFST_ELSE) ) { #if 0 /* remove closing if-tag from stack */ if ( state == IFST_CIF ) { remove_cif_tag( inpf ); is_pop(); } #endif if ( !parse_wd( inpf, ">" ) ) skip_until_eot( inpf ); DIF( { if ( state==IFST_CIF ) fprintf( stderr, "** </$IF> reached\n" ); else fprintf( stderr, "** <$ELSE> reached\n" ); } ); }