main() { glbptr=startglb; /* clear global symbols */ locptr=startloc; /* clear local symbols */ wqptr=wq; /* clear while queue */ macptr= /* clear the macro pool */ litptr= /* clear literal pool */ sp = /* stack ptr (relative) */ errcnt= /* no errors */ eof= /* not eof yet */ input= /* no input file */ input2= /* or include file */ output= /* no open units */ ncmp= /* no open compound states */ lastst= /* no last statement yet */ quote[1]= 0; /* ...all set to zero.... */ quote[0]='"'; /* fake a quote literal */ cmode=1; /* enable preprocessing */ /* */ /* compiler body */ /* */ ask(); /* get user options */ openout(); /* get an output file */ openin(); /* and initial input file */ header(); /* intro code */ parse(); /* process ALL input */ dumplits(); /* then dump literal pool */ dumpglbs(); /* and all static memory */ errorsummary(); /* summarize errors */ trailer(); /* follow-up code */ closeout(); /* close the output (if any) */ return; /* then exit to system */ }
static void start_writing(FILE **f,int version) { const char *format[] = {"(format zero)", "PBM-ascii", "PGM-ascii", "PPM-ascii", "PBM", "PGM", "PPM" }; if( verboseFlag ) fprintf(stderr,f == &outfile ? _("Writing converted image as %s\n") : _("Writing transparency map as %s\n"), format[version]); *f = openout( f == &outfile ? flatspec.output_filename : flatspec.transmap_filename ); fprintf(*f,"P%d",version); if( suppress_byline ) ; else if( f == &outfile ) fprintf(*f,_(" # Converted by xcf2pnm %s"),PACKAGE_VERSION); else fprintf(*f,_(" # Transparency map by xcf2pnm %s"),PACKAGE_VERSION); fprintf(*f,"\n%d %d\n%s", flatspec.dim.width, flatspec.dim.height, version == 4 ? "" : "255\n"); }
/** * compile one file if filename is NULL redirect do to stdin/stdout * @param file filename * @return */ void compile(char *file) { if (file == NULL || filename_typeof(file) == 'c') { global_table_index = 0; local_table_index = NUMBER_OF_GLOBALS; while_table_index = 0; tag_table_index = 0; inclsp = iflevel = skiplevel = swstp = litptr = stkp = errcnt = ncmp = lastst = //quote[1] = 0; input2 = -1; //quote[0] = '"'; cmode = 1; glbflag = 1; nxtlab = 0; litlab = getlabel(); defmac("end\tmemory"); //add_global("memory", ARRAY, CCHAR, 0, EXTERN); //add_global("stack", ARRAY, CCHAR, 0, EXTERN); rglobal_table_index = global_table_index; //rglbptr = glbptr; //add_global("etext", ARRAY, CCHAR, 0, EXTERN); //add_global("edata", ARRAY, CCHAR, 0, EXTERN); defmac("short\tint"); initmac(); // compiler body if (file == NULL) { input = 0; } else if (!openin(file)) return; if (file == NULL) { output = 1; } else if (!openout()) return; header(); code_segment_gtext(); parse(); close(input); data_segment_gdata(); dumplits(); dumpglbs(); errorsummary(); trailer(); oflush(); close(output); pl(""); errs = errs || errfile; } else { writee("Don't understand file "); writee(file); errs = 1; } }
int main(int argc, char * const *argv) { int opt; memset(&LOG, 0, sizeof LOG); VUT_Init(progname); while ((opt = getopt(argc, argv, vopt_optstring)) != -1) { switch (opt) { case 'a': /* Append to file */ LOG.a_opt = 1; break; case 'B': /* Binary output */ LOG.B_opt = 1; break; case 'h': /* Usage help */ usage(0); break; case 'w': /* Write to file */ REPLACE(LOG.w_arg, optarg); break; default: if (!VUT_Arg(opt, optarg)) usage(1); } } if (optind != argc) usage(1); /* Setup output */ if (LOG.B_opt) VUT.dispatch_f = VSL_WriteTransactions; else VUT.dispatch_f = VSL_PrintTransactions; if (LOG.w_arg) { openout(LOG.a_opt); AN(LOG.fo); VUT.sighup_f = rotateout; } else LOG.fo = stdout; VUT.idle_f = flushout; VUT_Setup(); VUT_Main(); VUT_Fini(); (void)flushout(); exit(0); }
rotateout(void) { AN(LOG.w_arg); AN(LOG.fo); fclose(LOG.fo); openout(1); AN(LOG.fo); return (0); }
static void init_output(void) { int bit_depth ; int color_type ; int invert_mono = 0 ; png_colorp pngpalette = NULL ; png_bytep ptrans = NULL ; outfile = openout(flatspec.output_filename); libpng = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, my_error_callback, png_error_ptr_NULL); if( !libpng ) FatalUnexpected(_("Couldn't initialize libpng library")); libpng2 = png_create_info_struct(libpng); if( !libpng2 ) FatalUnexpected("Couldn't create PNG info structure"); png_init_io(libpng,outfile); bit_depth = 8; switch( flatspec.out_color_mode ) { case COLOR_GRAY: if( flatspec.default_pixel == PERHAPS_ALPHA_CHANNEL || flatspec.default_pixel == FORCE_ALPHA_CHANNEL ) color_type = PNG_COLOR_TYPE_GRAY_ALPHA ; else color_type = PNG_COLOR_TYPE_GRAY ; break ; case COLOR_RGB: if( flatspec.default_pixel == PERHAPS_ALPHA_CHANNEL || flatspec.default_pixel == FORCE_ALPHA_CHANNEL ) color_type = PNG_COLOR_TYPE_RGB_ALPHA ; else color_type = PNG_COLOR_TYPE_RGB ; break ; case COLOR_INDEXED: if( paletteSize == 2 && palette[0] == NEWALPHA(0,255) && palette[1] == NEWALPHA(-1,255) ) { color_type = PNG_COLOR_TYPE_GRAY ; bit_depth = 1 ; } else if( paletteSize == 2 && palette[0] == NEWALPHA(-1,255) && palette[1] == NEWALPHA(0,255) ) { color_type = PNG_COLOR_TYPE_GRAY ; bit_depth = 1 ; invert_mono = 1 ; } else { unsigned i ; int need_trans = flatspec.default_pixel == FORCE_ALPHA_CHANNEL ; color_type = PNG_COLOR_TYPE_PALETTE ; pngpalette = xcfmalloc(paletteSize*sizeof(png_color)) ; ptrans = xcfmalloc(paletteSize); for(i = 0; i<paletteSize; i++ ) { pngpalette[i].red = 255 & (palette[i] >> RED_SHIFT); pngpalette[i].green = 255 & (palette[i] >> GREEN_SHIFT); pngpalette[i].blue = 255 & (palette[i] >> BLUE_SHIFT); if( (ptrans[i] = ALPHA(palette[i])) != 255 ) need_trans = 1 ; } if( !need_trans ) { xcffree(ptrans); ptrans = NULL ; } if( paletteSize <= 2 ) bit_depth = 1 ; else if( paletteSize <= 4 ) bit_depth = 2 ; else if( paletteSize <= 16 ) bit_depth = 4 ; else bit_depth = 8; } break ; default: FatalUnexpected("This can't happen (unknown out_color_mode)"); } if( verboseFlag ) { fprintf(stderr,"Writing PNG: %s%s%s%s, %d bits", color_type & PNG_COLOR_MASK_COLOR ? _("color") : _("grayscale"), color_type & PNG_COLOR_MASK_PALETTE ? _("+palette") : "", color_type & PNG_COLOR_MASK_ALPHA ? _("+alpha") : "", ptrans || NULLALPHA(flatspec.default_pixel) ? _("+transparency") : "", bit_depth); if( pngpalette ) fprintf(stderr,_(" (%d colors)"),paletteSize); fprintf(stderr,"\n"); } png_set_IHDR(libpng,libpng2,flatspec.dim.width,flatspec.dim.height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); if( invert_mono ) png_set_invert_mono(libpng); if( pngpalette ) png_set_PLTE(libpng,libpng2,pngpalette,paletteSize); if( ptrans ) png_set_tRNS(libpng,libpng2,ptrans,paletteSize,NULL); else if ( !pngpalette && NULLALPHA(flatspec.default_pixel) ) { static png_color_16 trans ; trans.gray = trans.red = 255 & (flatspec.default_pixel >> RED_SHIFT) ; trans.green = 255 & (flatspec.default_pixel >> GREEN_SHIFT) ; trans.blue = 255 & (flatspec.default_pixel >> BLUE_SHIFT) ; png_set_tRNS(libpng,libpng2,NULL,0,&trans); } /* png_set_text here */ png_write_info(libpng,libpng2); if( bit_depth < 8 ) png_set_packing(libpng); switch( color_type ) { case PNG_COLOR_TYPE_RGB: case PNG_COLOR_TYPE_RGBA: #if (BLUE_SHIFT < RED_SHIFT) == !defined(WORDS_BIGENDIAN) png_set_bgr(libpng); #endif if( color_type == PNG_COLOR_TYPE_RGB ) #if (ALPHA_SHIFT < RED_SHIFT) == !defined(WORDS_BIGENDIAN) png_set_filler(libpng,0,PNG_FILLER_BEFORE); else png_set_swap_alpha(libpng); #else png_set_filler(libpng,0,PNG_FILLER_AFTER); #endif break ; case PNG_COLOR_TYPE_GRAY: png_set_filler(libpng,0,PNG_FILLER_AFTER); break ; case PNG_COLOR_TYPE_GRAY_ALPHA: case PNG_COLOR_TYPE_PALETTE: break ; default: FatalUnexpected("This can't happen (unexpected png color_type)"); } }
int main (int argc, char *argv[]) { char *p, *pp, *bp; char **oldargv = argv; char **link_lib; long smacptr; int first = 1; char *asmdefs_global_end; macptr = 0; ctext = 0; argc--; argv++; errs = 0; sflag = 0; cdflag = 0; verboseflag = 0; startup_incl = 0; optimize = 2; /* -O2 by default */ overlayflag = 0; asmdefs[0] = '\0'; while ((p = *argv++)) { if (*p == '-') { while (*++p) switch (*p) { case 't': case 'T': ctext = 1; break; case 'c': if ((*(p + 1) == 'd')) { cdflag = 1; /* pass '-cd' to assembler */ p++; break; } else { usage(oldargv[0]); break; } case 's': if (strncmp(p, "scd", 3) == 0) { cdflag = 2; /* pass '-scd' to assembler */ p += 2; break; } else if (strncmp(p, "sgx", 3) == 0) { strcat(asmdefs, "_SGX = 1\n"); defmac("_SGX"); p += 2; break; } /* fallthrough */ case 'S': sflag = 1; break; /* defines to pass to assembler */ case 'a': if (strncmp(p, "acd", 3) == 0) { cdflag = 2; /* pass '-scd' to assembler */ strcat(asmdefs, "_AC = 1\n"); defmac("_AC"); p += 2; break; } /* fallthrough */ case 'A': bp = ++p; if (!*p) usage(oldargv[0]); while (*p && *p != '=') p++; strncat(asmdefs, bp, (p - bp)); /* if (*p == '=') *p = '\t'; */ bp = ++p; strcat(asmdefs, "\t= "); if (*bp == '\0') strcat(asmdefs, "1\n"); else { strcat(asmdefs, bp); strcat(asmdefs, "\n"); } break; case 'v': verboseflag++; if (verboseflag > 1) ctext = 1; /* "C" code in asm output */ break; case 'd': case 'D': bp = ++p; if (!*p) usage(oldargv[0]); while (*p && *p != '=') p++; if (*p == '=') *p = '\t'; while (*p) p++; p--; defmac(bp); break; case 'o': if (strncmp(p, "over", 4) == 0) { overlayflag = 1; if (strncmp(p, "overlay", 7) == 0) p += 6; else p += 3; } else { bp = ++p; while (*p && *p != ' ' && *p != '\t') p++; memcpy(user_outfile, bp, p - bp); user_outfile[p - bp] = 0; p--; } break; case 'O': /* David, made -O equal to -O2 * I'm too lazy to tape -O2 each time :) */ if (!p[1]) optimize = 2; else optimize = atoi(++p); break; case 'f': p++; if (!strcmp(p, "no-recursive")) { user_norecurse = 1; p += 11; } else if (!strcmp(p, "recursive")) { user_norecurse = 0; p += 8; } else if (!strcmp(p, "no-short-enums")) { user_short_enums = 0; p += 13; } else if (!strcmp(p, "short-enums")) { user_short_enums = 1; p += 10; } else goto unknown_option; break; case 'l': bp = ++p; while (*p && *p != ' ' && *p != '\t') p++; link_libs = realloc(link_libs, (link_lib_ptr + 2) * sizeof(*link_libs)); link_libs[link_lib_ptr] = malloc(p - bp + 1); memcpy(link_libs[link_lib_ptr], bp, p - bp); link_libs[link_lib_ptr][p - bp] = 0; strcat(asmdefs, "LINK_"); strcat(asmdefs, link_libs[link_lib_ptr]); strcat(asmdefs, "\t= 1\n"); link_libs[++link_lib_ptr] = 0; p--; break; case 'm': if (!strcmp(p + 1, "small")) { strcat(asmdefs, "SMALL\t= 1\n"); p += 5; } else { unknown_option: fprintf(stderr, "unknown option %s\n", p); exit(1); } break; default: usage(oldargv[0]); } } else { infiles = realloc(infiles, (infile_ptr + 2) * sizeof(*infiles)); infiles[infile_ptr++] = p; infiles[infile_ptr] = 0; } } smacptr = macptr; if (!infiles) usage(oldargv[0]); printf(HUC_VERSION); printf("\n"); init_path(); /* Remember the first file, it will be used as the base for the output file name unless there is a user-specified outfile. */ p = pp = infiles[0]; /* Labels count is not reset for each file because labels are global and conflicts would arise. */ nxtlab = 0; link_lib = link_libs; infile_ptr = 1; /* Remember where the global assembler defines end so we can reset to that point for each file. */ /* XXX: Even if we don't repeat the local asm defines, they are still defined because we compile everything into one assembly file. */ asmdefs_global_end = asmdefs + strlen(asmdefs); while (p) { errfile = 0; /* Truncate asm defines to the point where global defines end. */ asmdefs_global_end[0] = 0; if (extension(p) == 'c' || extension(p) == 'C') { glbptr = STARTGLB; locptr = STARTLOC; wsptr = ws; inclsp = iflevel = skiplevel = swstp = litptr = stkp = errcnt = ncmp = lastst = quote[1] = const_nb = line_number = 0; macptr = smacptr; input2 = NULL; quote[0] = '"'; cmode = 1; glbflag = 1; litlab = getlabel(); member_table_index = 0; memset(member_table, 0, sizeof(member_table)); tag_table_index = 0; norecurse = user_norecurse; typedef_ptr = 0; enum_ptr = 0; enum_type_ptr = 0; memset(fastcall_tbl, 0, sizeof(fastcall_tbl)); defpragma(); /* Macros and globals have to be reset for each file, so we have to define the defaults all over each time. */ defmac("__end\t__memory"); addglb("__memory", ARRAY, CCHAR, 0, EXTERN, 0); addglb("stack", ARRAY, CCHAR, 0, EXTERN, 0); rglbptr = glbptr; addglb("etext", ARRAY, CCHAR, 0, EXTERN, 0); addglb("edata", ARRAY, CCHAR, 0, EXTERN, 0); /* PCE specific externs */ addglb("font_base", VARIABLE, CINT, 0, EXTERN, 0); addglb_far("vdc", CINT); addglb_far("vram", CCHAR); /* end specific externs */ defmac("huc6280\t1"); defmac("huc\t1"); if (cdflag == 1) defmac("_CD\t1"); else if (cdflag == 2) defmac("_SCD\t1"); else defmac("_ROM\t1"); if (overlayflag == 1) defmac("_OVERLAY\t1"); // initmac(); /* * compiler body */ if (!openin(p)) exit(1); if (first && !openout()) exit(1); if (first) header(); asmdefines(); // gtext (); parse(); fclose(input); // gdata (); dumplits(); dumpglbs(); errorsummary(); // trailer (); pl(""); errs = errs || errfile; } else { fputs("Don't understand file ", stderr); fputs(p, stderr); fputc('\n', stderr); exit(1); } p = infiles[infile_ptr]; if (!p && link_lib && *link_lib) { /* No more command-line files, continue with libraries. */ p = lib_to_file(*link_lib); if (!p) { fprintf(stderr, "cannot find library %s\n", *link_lib); exit(1); } link_lib++; } else infile_ptr++; first = 0; } dumpfinal(); fclose(output); if (!errs && !sflag) { if (user_outfile[0]) errs = errs || assemble(user_outfile); else errs = errs || assemble(pp); } exit(errs != 0); }
/* * Compiler begins execution here */ int main(int argc, char **argv) { int n; /* Loop counter */ int i; gargc = argc ; gargv = argv ; /* * Empty our mem ptrs */ litq=dubq=tempq=glbq=0; symtab=loctab=0; wqueue=0;membptr=0;tagptr=0;swnext=0;stage=0; gotoq=0; /* allocate space for arrays */ litq = mymalloc(FNLITQ) ; /* literals, these 2 dumped end */ dubq = mymalloc(FNLITQ) ; /* Doubles */ tempq = mymalloc(LITABSZ) ; /* Temp strings... */ glbq = mymalloc(LITABSZ) ; /* Used for glb lits, dumped now */ symtab = SYM_CAST mymalloc(NUMGLBS*sizeof(SYMBOL)) ; loctab = SYM_CAST mymalloc(NUMLOC*sizeof(SYMBOL)) ; wqueue = WQ_CAST mymalloc(NUMWHILE*sizeof(WHILE_TAB)) ; gotoq= (GOTO_TAB *)calloc(NUMGOTO,sizeof(GOTO_TAB)); if (gotoq==NULL) OutOfMem(); tagptr = tagtab = TAG_CAST mymalloc(NUMTAG*sizeof(TAG_SYMBOL)) ; membptr = membtab = SYM_CAST mymalloc(NUMMEMB*sizeof(SYMBOL)) ; swnext = SW_CAST mymalloc(NUMCASE*sizeof(SW_TAB)) ; swend = swnext + (NUMCASE-1) ; stage = mymalloc(STAGESIZE) ; stagelast = stage+STAGELIMIT ; /* empty symbol table */ glbptr = STARTGLB; while ( glbptr < ENDGLB ) { glbptr->name[0] = 0 ; ++glbptr ; } glbcnt = 0 ; /* clear global symbols */ locptr = STARTLOC ; /* clear local symbols */ wqptr = wqueue ; /* clear while queue */ gltptr=dubptr=0 ; /* clear literal pools */ *litq=0; /* First entry in literal queue is zero */ litptr=1; /* So miniprintf search works */ Zsp = /* stack ptr (relative) */ errcnt = /* no errors */ errstop = /* keep going after an error */ eof = /* not eof yet */ swactive = /* not in switch */ skiplevel = /* #if not encountered */ iflevel = /* #if nesting level = 0 */ ncmp = /* no open compound states */ lastst = /* not first file to asm */ fnstart = /* current "function" started at line 0 */ lineno = /* no lines read from file */ infunc = /* not in function now */ 0 ; /* ...all set to zero.... */ stagenext = NULL_CHAR ; /* direct output mode */ input = /* no input file */ inpt2 = /* or include file */ saveout = /* no diverted output */ output = NULL_FD ; /* no open units */ currfn = NULL_SYM ; /* no function yet */ macptr = cmode = 1 ; /* clear macro pool and enable preprocessing */ ncomp=doinline=mathz88 = incfloat= compactcode =0; intuition=zorg=lpointer=cppcom=appz88=0; dosigned=NO; makelib=useshare=makeshare=sharedfile=NO; smartprintf=expanded=YES; startup=0; /* Which startup do we want? */ nxtlab = /* start numbers at lowest possible */ ctext = /* don't include the C text as comments */ errstop = /* don't stop after errors */ verbose = 0; gotocnt=0; defdenums=0; doublestrings = 0; noaltreg = NO; safedata=reqpag = -1; shareoffset=SHAREOFFSET; /* Offset for shared libs */ debuglevel=NO; farheapsz=-1; /* Size of far heap */ assemtype = ASM_Z80ASM; printflevel=0; #ifdef USEFRAME indexix=YES; useframe=NO; #endif /* * compiler body */ setup_sym() ; /* define some symbols */ /* Parse the command line options */ atexit(MemCleanup); /* To free everything */ clear(); filenum=0; for (n=1;n<argc;n++) { if (argv[n][0]=='-') ParseArgs(1+argv[n]); else {filenum=n; break;} } clear(); if (filenum == 0) { info(); exit(1); } litlab=getlabel(); /* Get labels for function lits*/ dublab=getlabel(); /* and fn doubles*/ openout(); /* get the output file */ openin(); /* and initial input file */ header(); /* intro code */ parse(); /* process ALL input */ /* dump literal queues, with label */ /* litq starts from 1, so literp has to be -1 */ dumplits(0, YES,litptr-1,litlab,litq+1) ; dumplits(1, YES,dubptr,dublab,dubq) ; dumpvars(); dumpfns(); trailer(); /* follow-up code */ closeout(); errsummary(); /* summarize errors */ if (errcnt) exit(1); exit(0); }
int copyinout(Ftw_t* ftw) { register File_t* f = &state.out->file; register char* s; register off_t c; register ssize_t n; register int rfd; register int wfd; if (getfile(state.out, f, ftw) && selectfile(state.out, f)) { s = f->name; f->name = stash(&state.out->path.copy, NiL, state.pwdlen + f->namesize); strcpy(stpcpy(f->name, state.pwd), s + (*s == '/')); if ((wfd = openout(state.out, f)) >= 0) { if ((rfd = openin(state.out, f)) >= 0) { #if defined(SEEK_DATA) && defined(SEEK_HOLE) off_t data; off_t hole; int more; data = 0; more = 1; while (more) { if ((hole = lseek(rfd, data, SEEK_HOLE)) < data) { hole = lseek(rfd, 0, SEEK_END); more = 0; } while ((c = hole - data) > 0) { if (c > state.buffersize) c = state.buffersize; if (lseek(rfd, data, SEEK_SET) != data || (n = read(rfd, state.tmp.buffer, (size_t)c)) <= 0) { error(ERROR_SYSTEM|2, "%s: read error", f->name); more = 0; break; } if (lseek(wfd, data, SEEK_SET) != data || write(wfd, state.tmp.buffer, n) != n) { error(ERROR_SYSTEM|2, "%s: write error", f->name); more = 0; break; } state.out->io->count += n; data += n; } if (!more) break; if ((data = lseek(rfd, hole, SEEK_DATA)) < hole) { if ((data = lseek(rfd, -1, SEEK_END)) < 0 || (data + 1) > hole && (lseek(wfd, data, SEEK_SET) != data || write(wfd, "", 1) != 1)) error(ERROR_SYSTEM|2, "%s: write error", f->name); state.out->io->count += 1; break; } } #else holeinit(wfd); for (c = f->st->st_size; c > 0; c -= n) { if ((n = read(rfd, state.tmp.buffer, (size_t)((c > state.buffersize) ? state.buffersize : c))) <= 0) { error(ERROR_SYSTEM|2, "%s: read error", f->name); break; } if (holewrite(wfd, state.tmp.buffer, n) != n) { error(ERROR_SYSTEM|2, "%s: write error", f->name); break; } state.out->io->count += n; } holedone(wfd); #endif closeout(state.out, f, wfd); closein(state.out, f, rfd); setfile(state.out, f); listentry(f); } else closeout(state.out, f, wfd); } else if (wfd != -1) listentry(f); } return 0; }
void filein(register Archive_t* ap, register File_t* f) { register off_t c; register int n; register char* s; int dfd; int wfd; long checksum; Filter_t* fp; Proc_t* pp; Tv_t t1; Tv_t t2; struct stat st; if (f->skip) goto skip; else if (state.list) { if (fp = filter(ap, f)) { for (n = 0; s = fp->argv[n]; n++) { while (*s) if (*s++ == '%' && *s == '(') break; if (*s) { s = fp->argv[n]; listprintf(state.tmp.str, ap, f, s); if (!(fp->argv[n] = sfstruse(state.tmp.str))) nospace(); break; } } pp = procopen(*fp->argv, fp->argv, NiL, NiL, PROC_WRITE); if (s) fp->argv[n] = s; if (!pp) { error(2, "%s: %s: cannot execute filter %s", ap->name, f->path, *fp->argv); goto skip; } if (!ap->format->getdata || !(*ap->format->getdata)(&state, ap, f, pp->wfd)) { checksum = 0; for (c = f->st->st_size; c > 0; c -= n) { n = (c > state.buffersize) ? state.buffersize : c; if (!(s = bget(ap, n, NiL))) { error(ERROR_SYSTEM|2, "%s: read error", f->name); break; } if (write(pp->wfd, s, n) != n) { error(ERROR_SYSTEM|2, "%s: write error", f->name); break; } if (ap->format->checksum) checksum = (*ap->format->checksum)(&state, ap, f, s, n, checksum); } } if (ap->format->checksum && checksum != f->checksum) error(1, "%s: %s checksum error (0x%08x != 0x%08x)", f->name, ap->format->name, checksum, f->checksum); /* * explicitly ignore exit status */ procclose(pp); return; } listentry(f); goto skip; } else switch (f->delta.op) { case DELTA_create: if (f->delta.base) error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__); if (ap->delta->format->flags & PSEUDO) goto regular; if ((wfd = openout(ap, f)) < 0) goto skip; else paxdelta(NiL, ap, f, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, f->st->st_size, 0); break; case DELTA_update: if (!f->delta.base || (unsigned long)f->delta.base->mtime.tv_sec >= (unsigned long)f->st->st_mtime) error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__); c = f->st->st_size; if ((wfd = openout(ap, f)) < 0) goto skip; if (state.ordered) { if (!f->delta.base->uncompressed) paxdelta(NiL, ap, f, DELTA_SRC|DELTA_BIO|DELTA_SIZE, ap->delta->base, f->delta.base->size, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0); else if (!paxdelta(NiL, ap, f, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap->delta->base, f->delta.base->size, DELTA_TAR|DELTA_TEMP|DELTA_OUTPUT, &dfd, 0)) paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_SIZE|DELTA_FREE, dfd, f->delta.base->uncompressed, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0); } else if (!f->delta.base->uncompressed) paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_OFFSET|DELTA_SIZE, ap->delta->base->io->fd, f->delta.base->offset, f->delta.base->size, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0); else if (!paxdelta(NiL, ap, f, DELTA_DEL|DELTA_FD|DELTA_OFFSET|DELTA_SIZE, ap->delta->base->io->fd, f->delta.base->offset, f->delta.base->size, DELTA_TAR|DELTA_TEMP|DELTA_OUTPUT, &dfd, 0)) paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_SIZE|DELTA_FREE, dfd, f->delta.base->uncompressed, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0); break; case DELTA_verify: if (!f->delta.base || f->delta.base->mtime.tv_sec != f->st->st_mtime) error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__); if ((*state.statf)(f->name, &st)) error(2, "%s: not copied from base archive", f->name); else if (st.st_size != f->delta.base->size || state.modtime && tvcmp(tvmtime(&t1, &st), tvmtime(&t2, f->st))) error(1, "%s: changed from base archive", f->name); break; case DELTA_delete: if (!f->delta.base) error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__); /*FALLTHROUGH*/ default: regular: wfd = openout(ap, f); if (wfd >= 0) { holeinit(wfd); if (!ap->format->getdata || !(*ap->format->getdata)(&state, ap, f, wfd)) { checksum = 0; for (c = f->st->st_size; c > 0; c -= n) { n = (c > state.buffersize) ? state.buffersize : c; if (!(s = bget(ap, n, NiL))) { error(ERROR_SYSTEM|2, "%s: read error", f->name); break; } if (holewrite(wfd, s, n) != n) { error(ERROR_SYSTEM|2, "%s: write error", f->name); break; } if (ap->format->checksum) checksum = (*ap->format->checksum)(&state, ap, f, s, n, checksum); } } holedone(wfd); closeout(ap, f, wfd); setfile(ap, f); if (ap->format->checksum && checksum != f->checksum) error(1, "%s: %s checksum error (0x%08x != 0x%08x)", f->name, ap->format->name, checksum, f->checksum); } else if (ap->format->getdata) (*ap->format->getdata)(&state, ap, f, wfd); else { if (wfd < -1) listentry(f); goto skip; } break; } listentry(f); return; skip: fileskip(ap, f); }
int main(int argc, char ** argv) { char * fn; int ix; if (3 > argc) return fprintf(stderr, "Specify library file name and copy file name(s).\n"), 1; if (openout(argv[1])) return 16; if (getdir(cards * 80)) return 20; for (ix = 2; argv[ix]; ix++) { char * dot; char * slash; char * name; int namelen; int ismacro = 1; /* Assume file is macro */ char * s; fn = argv[ix]; f = fopen(fn, "r"); if (!f) return fprintf(stderr, "Cannot open %s: %s\n", fn, strerror(errno)), 16; slash = strrchr(fn, '/'); name = slash ? slash + 1 : fn; namelen = strlen(name); dot = strrchr(name, '.'); if (dot) { namelen = dot - name; if (!strcmp(dot + 1, "copy")) ismacro = 0; } s = gline(); if (!s) continue; if (!ismacro && memcmp(s, "*COPY ", 6)) ismacro = 1; /* Not stacked copy */ if (ismacro) { loadname(name, namelen); if (doline(line)) return 20; } else if (newmember(s)) return 20; for (;;) { s = gline(); if (!s) break; if (!ismacro && !memcmp(s, "*COPY ", 6)) { if (eom()) return 20; if (newmember(s)) return 20; continue; } if (doline(line)) return 20; } if (eom()) return 20; } if (wrapup(dirs, dir)) return 16; printf("%s %d files %d members.\n", fno, ix - 2, members); return 0; }