// Switch to new zone ("!zone" or "!zn"). Has to be re-entrant. static enum eos_t PO_zone(void) { section_t entry_values;// buffer for outer zone char* new_title; bool allocated; // remember everything about current structure entry_values = *Section_now; // set default values in case there is no valid title new_title = untitled; allocated = FALSE; // Check whether a zone title is given. If yes and it can be read, // get copy, remember pointer and remember to free it later on. if(BYTEFLAGS(GotByte) & CONTS_KEYWORD) { // Because we know of one character for sure, // there's no need to check the return value. Input_read_keyword(); new_title = DynaBuf_get_copy(GlobalDynaBuf); allocated = TRUE; } // setup new section // section type is "subzone", just in case a block follows Section_new_zone(Section_now, "Subzone", new_title, allocated); if(Parse_optional_block()) { // Block has been parsed, so it was a SUBzone. Section_finalize(Section_now);// end inner zone *Section_now = entry_values;// restore entry values } else { // no block found, so it's a normal zone change Section_finalize(&entry_values);// end outer zone Section_now->type = type_zone;// change type to "zone" } return(ENSURE_EOS); }
// Append to GlobalDynaBuf while characters are legal for keywords. // Throws "missing string" error if none. // Returns number of characters added. int Input_append_keyword_to_global_dynabuf(void) { int length = 0; // add characters to buffer until an illegal one comes along while(BYTEFLAGS(GotByte) & CONTS_KEYWORD) { DYNABUF_APPEND(GlobalDynaBuf, GotByte); length++; GetByte(); } if(length == 0) Throw_error(exception_missing_string); return(length); }
// Deliver source code from current file (!) in shortened high-level format static char get_processed_from_file(void) { int from_file; do { switch(Input_now->state) { case INPUTSTATE_NORMAL: // fetch a fresh byte from the current source file //from_file = getc(Input_now->src.fd); from_file = hacked_getc(Input_now); // now process it /*FALLTHROUGH*/ case INPUTSTATE_AGAIN: // Process the latest byte again. Of course, this only // makes sense if the loop has executed at least once, // otherwise the contents of from_file are undefined. // If the source is changed so there is a possibility // to enter INPUTSTATE_AGAIN mode without first having // defined "from_file", trouble may arise... Input_now->state = INPUTSTATE_NORMAL; // EOF must be checked first because it cannot be used // as an index into Byte_flags[] if(from_file == EOF) { // remember to send an end-of-file Input_now->state = INPUTSTATE_EOF; return(CHAR_EOS);// end of statement } // check whether character is special one // if not, everything's cool and froody, so return it if((BYTEFLAGS(from_file) & BYTEIS_SYNTAX) == 0) return((char) from_file); // check special characters ("0x00 TAB LF CR SPC :;}") switch(from_file) { case CHAR_TAB:// TAB character case ' ': // remember to skip all following blanks Input_now->state = INPUTSTATE_SKIPBLANKS; return(' '); case CHAR_LF:// LF character // remember to send a start-of-line Input_now->state = INPUTSTATE_LF; return(CHAR_EOS);// end of statement case CHAR_CR:// CR character // remember to check CRLF + send start-of-line Input_now->state = INPUTSTATE_CR; return(CHAR_EOS);// end of statement case CHAR_EOB: // remember to send an end-of-block Input_now->state = INPUTSTATE_EOB; return(CHAR_EOS);// end of statement case CHAR_STATEMENT_DELIMITER: // just deliver an EOS instead return(CHAR_EOS);// end of statement case CHAR_COMMENT_SEPARATOR: // remember to skip remainder of line Input_now->state = INPUTSTATE_COMMENT; return(CHAR_EOS);// end of statement default: // complain if byte is 0 Throw_error("Source file contains illegal character."); return((char) from_file); } case INPUTSTATE_SKIPBLANKS: // read until non-blank, then deliver that do { // from_file = getc(Input_now->src.fd); from_file = hacked_getc(Input_now); } while((from_file == CHAR_TAB) || (from_file == ' ')); // re-process last byte Input_now->state = INPUTSTATE_AGAIN; break; case INPUTSTATE_LF: // return start-of-line, then continue in normal mode Input_now->state = INPUTSTATE_NORMAL; return(CHAR_SOL);// new line case INPUTSTATE_CR: // return start-of-line, remember to check for LF Input_now->state = INPUTSTATE_SKIPLF; return(CHAR_SOL);// new line case INPUTSTATE_SKIPLF: from_file = hacked_getc(Input_now); // if LF, ignore it and fetch another byte // otherwise, process current byte if(from_file == CHAR_LF) Input_now->state = INPUTSTATE_NORMAL; else Input_now->state = INPUTSTATE_AGAIN; break; case INPUTSTATE_COMMENT: // read until end-of-line or end-of-file do from_file = hacked_getc(Input_now); while((from_file != EOF) && (from_file != CHAR_CR) && (from_file != CHAR_LF)); // re-process last byte Input_now->state = INPUTSTATE_AGAIN; break; case INPUTSTATE_EOB: // deliver EOB Input_now->state = INPUTSTATE_NORMAL; return(CHAR_EOB);// end of block case INPUTSTATE_EOF: // deliver EOF Input_now->state = INPUTSTATE_NORMAL; return(CHAR_EOF);// end of file default: Bug_found("StrangeInputMode", Input_now->state); } } while(TRUE); }