static void read_directive(CppContext *ctx) { Token *tok; if (read_if(ctx, "define")) read_define(ctx); else if (read_if(ctx, "undef")) read_undef(ctx); else if (read_if(ctx, "if")) handle_cond_incl(ctx, COND_IF); else if (read_if(ctx, "elif")) handle_cond_incl(ctx, COND_ELIF); else if (read_if(ctx, "else")) handle_cond_incl(ctx, COND_ELSE); else if (read_if(ctx, "ifdef")) handle_cond_incl(ctx, COND_IFDEF); else if (read_if(ctx, "ifndef")) handle_cond_incl(ctx, COND_IFNDEF); else if (read_if(ctx, "endif")) handle_cond_incl(ctx, COND_ENDIF); else if (read_if(ctx, "include")) handle_include(ctx); else if (read_if(ctx, "line")) handle_line_directive(ctx); else if (read_if(ctx, "pragma")) handle_pragma(ctx); else if ( (tok = read_if(ctx, "error")) ) { read_error_directive(ctx, tok); } else { tok = read_cpp_token(ctx); if (tok && tok->toktype == TOKTYPE_NEWLINE) // 6.10.7 NULL directive. Do nothing. return; error_token(tok, "unsupported preprocessor directive: '%s'", token_to_string(tok)); } }
int main(int argc, char *argv[]) { int i = 1, mode, hlen; size_t n; FILE *fp; int tflag = 0, dflag = 0, bflag = 0, zflag = 0; int tbase = 0, dbase = 0, bbase = 0, zbase = 0; char *outfile = "a.o65"; int extract = 0; if (argc <= 1) { usage(stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, author, copyright); exit(0); } while(i<argc) { if(argv[i][0]=='-') { /* process options */ switch(argv[i][1]) { case 'o': if(argv[i][2]) outfile=argv[i]+2; else outfile=argv[++i]; break; case 'X': extract=3; break; case 'b': switch(argv[i][2]) { case 't': tflag= 1; if(argv[i][3]) tbase = atoi(argv[i]+3); else tbase = atoi(argv[++i]); break; case 'd': dflag= 1; if(argv[i][3]) dbase = atoi(argv[i]+3); else dbase = atoi(argv[++i]); break; case 'b': bflag= 1; if(argv[i][3]) bbase = atoi(argv[i]+3); else bbase = atoi(argv[++i]); break; case 'z': zflag= 1; if(argv[i][3]) zbase = atoi(argv[i]+3); else zbase = atoi(argv[++i]); break; default: printf("Unknown segment type '%c' - ignored!\n", argv[i][2]); break; } break; case 'x': /* extract segment */ switch(argv[i][2]) { case 't': extract = 1; break; case 'd': extract = 2; break; case 'z': case 'b': printf("Cannot extract segment type '%c' - ignored!\n", argv[i][2]); break; default: printf("Unknown segment type '%c' - ignored!\n", argv[i][2]); break; } break; default: fprintf(stderr,"reloc65: %s unknown option, use '-?' for help\n",argv[i]); break; } } else { struct stat fs; file.fname=argv[i]; stat(argv[i], &fs); file.fsize=fs.st_size; file.buf=malloc(file.fsize); if(!file.buf) { fprintf(stderr,"Oops, no more memory!\n"); exit(1); } printf("reloc65: read file %s -> %s\n",argv[i],outfile); fp = fopen(argv[i],"rb"); if(fp) { n = fread(file.buf, 1, file.fsize, fp); fclose(fp); if((n>=file.fsize) && (!memcmp(file.buf, cmp, 5))) { mode=file.buf[7]*256+file.buf[6]; if(mode & 0x2000) { fprintf(stderr,"reloc65: %s: 32 bit size not supported\n", argv[i]); } else if(mode & 0x4000) { fprintf(stderr,"reloc65: %s: pagewise relocation not supported\n", argv[i]); } else { hlen = BUF+read_options(file.buf+BUF); file.tbase = file.buf[ 9]*256+file.buf[ 8]; file.tlen = file.buf[11]*256+file.buf[10]; file.tdiff = tflag? tbase - file.tbase : 0; file.dbase = file.buf[13]*256+file.buf[12]; file.dlen = file.buf[15]*256+file.buf[14]; if (extract == 3) { if (dflag) { fprintf(stderr,"reloc65: %s: Warning: data segment address ignored for -X option\n", argv[i]); } dbase = file.tbase + file.tdiff + file.tlen; file.ddiff = dbase - file.dbase; } else { file.ddiff = dflag? dbase - file.dbase : 0; } file.bbase = file.buf[17]*256+file.buf[16]; file.blen = file.buf[19]*256+file.buf[18]; file.bdiff = bflag? bbase - file.bbase : 0; file.zbase = file.buf[21]*256+file.buf[20]; file.zlen = file.buf[23]*256+file.buf[21]; file.zdiff = zflag? zbase - file.zbase : 0; file.segt = file.buf + hlen; file.segd = file.segt + file.tlen; file.utab = file.segd + file.dlen; file.rttab = file.utab + read_undef(file.utab); file.rdtab = reloc_seg(file.segt, file.tlen, file.rttab, &file, extract); file.extab = reloc_seg(file.segd, file.dlen, file.rdtab, &file, extract); reloc_globals(file.extab, &file); if(tflag) { file.buf[ 9]= (tbase>>8)&255; file.buf[ 8]= tbase & 255; } if(dflag) { file.buf[13]= (dbase>>8)&255; file.buf[12]= dbase & 255; } if(bflag) { file.buf[17]= (bbase>>8)&255; file.buf[16]= bbase & 255; } if(zflag) { file.buf[21]= (zbase>>8)&255; file.buf[20]= zbase & 255; } fp = fopen(outfile, "wb"); if(fp) { switch(extract) { case 0: /* whole file */ fwrite(file.buf, 1, file.fsize, fp); break; case 1: /* text segment */ fwrite(file.segt, 1, file.tlen, fp); break; case 2: /* data segment */ fwrite(file.segd, 1, file.dlen, fp); break; case 3: /* text+data */ fwrite(file.segt, 1, file.tlen, fp); fwrite(file.segd, 1, file.dlen, fp); break; } fclose(fp); } else { fprintf(stderr,"reloc65: write '%s': %s\n", outfile, strerror(errno)); } } } else { fprintf(stderr,"reloc65: %s: not an o65 file!\n", argv[i]); if(file.buf[0]==1 && file.buf[1]==8 && file.buf[3]==8) { printf("%s: C64 BASIC executable (start address $0801)?\n", argv[i]); } else if(file.buf[0]==1 && file.buf[1]==4 && file.buf[3]==4) { printf("%s: CBM PET BASIC executable (start address $0401)?\n", argv[i]); } } } else {