// Include source file ("!source" or "!src"). Has to be re-entrant. static enum eos_t PO_source(void) {// Now GotByte = illegal char FILE* fd; char local_gotbyte; input_t new_input, *outer_input; // Enter new nesting level. // Quit program if recursion too deep. if(--source_recursions_left < 0) Throw_serious_error("Too deeply nested. Recursive \"!source\"?"); // Read file name. Quit function on error. if(Input_read_filename(TRUE)) return(SKIP_REMAINDER); // If file could be opened, parse it. Otherwise, complain. if((fd = fopen(GLOBALDYNABUF_CURRENT, FILE_READBINARY))) { char *filename = (char *) safe_malloc(GlobalDynaBuf->size); // MPi: Arrays must be a constant expression strcpy(filename, GLOBALDYNABUF_CURRENT); outer_input = Input_now;// remember old input local_gotbyte = GotByte;// CAUTION - ugly kluge Input_now = &new_input;// activate new input Parse_and_close_file(fd, filename); Input_now = outer_input;// restore previous input GotByte = local_gotbyte;// CAUTION - ugly kluge free(filename); } else Throw_error(exception_cannot_open_input_file); // Leave nesting level source_recursions_left++; return(ENSURE_EOS); }
// Select dump file static enum eos_t PO_sl(void) { // bugfix: first read filename, *then* check for first pass. // if skipping right away, quoted colons might be misinterpreted as EOS // FIXME - why not just fix the skipping code to handle quotes? :) // "!to" has been fixed as well // read filename to global dynamic buffer // if no file name given, exit (complaining will have been done) if (Input_read_filename(FALSE)) return SKIP_REMAINDER; // only process this pseudo opcode in first pass if (pass_count) return SKIP_REMAINDER; // if label dump file already chosen, complain and exit if (labeldump_filename) { Throw_warning("Label dump file already chosen."); return SKIP_REMAINDER; } // get malloc'd copy of filename labeldump_filename = DynaBuf_get_copy(GlobalDynaBuf); // ensure there's no garbage at end of line return ENSURE_EOS; }
// Include binary file static enum eos_t PO_binary(void) { FILE* fd; int byte; intval_t size = -1, // means "not given" => "until EOF" skip = 0, interleave = 1; int skipByte; // if file name is missing, don't bother continuing if(Input_read_filename(TRUE)) return(SKIP_REMAINDER); // try to open file fd = fopen(GLOBALDYNABUF_CURRENT, FILE_READBINARY); if(fd == NULL) { Throw_error(exception_cannot_open_input_file); return(SKIP_REMAINDER); } // read optional arguments if(Input_accept_comma()) { if(ALU_optional_defined_int(&size) && (size <0)) Throw_serious_error("Negative size argument."); if(Input_accept_comma()) { ALU_optional_defined_int(&skip);// read skip if(Input_accept_comma()) { ALU_optional_defined_int(&interleave);// read interleave if (interleave <= 1) { Throw_serious_error("Negative size argument."); } } } } skipByte = interleave; // check whether including is a waste of time if((size >= 0) && (pass_undefined_count || pass_real_errors)) Output_fake(size); // really including is useless anyway else { // really insert file fseek(fd, skip, SEEK_SET); // set read pointer // if "size" non-negative, read "size" bytes. // otherwise, read until EOF. while(size != 0) { byte = getc(fd); if(byte == EOF) break; skipByte++; if (skipByte >= interleave) { Output_byte(byte); size--; skipByte = 0; } } // if more should have been read, warn and add padding if(size > 0) { Throw_warning("Padding with zeroes."); do Output_byte(0); while(--size); } } fclose(fd); // if verbose, produce some output if((pass_count == 0) && (Process_verbosity > 1)) printf("Loaded %d ($%x) bytes from file offset %ld ($%lx).\n", CPU_2add, CPU_2add, skip, skip); return(ENSURE_EOS); }