static void maplit(int ctxt, Node *n, Node *var, NodeList **init) { Node *r, *a; NodeList *l; int nerr, b; Type *t, *tk, *tv, *t1; Node *vstat, *index, *value; Sym *syma, *symb; ctxt = 0; // make the map var nerr = nerrors; a = nod(OMAKE, N, N); a->list = list1(typenod(n->type)); litas(var, a, init); // count the initializers b = 0; for(l=n->list; l; l=l->next) { r = l->n; if(r->op != OKEY) fatal("slicelit: rhs not OKEY: %N", r); index = r->left; value = r->right; if(isliteral(index) && isliteral(value)) b++; } t = T; if(b != 0) { // build type [count]struct { a Tindex, b Tvalue } t = n->type; tk = t->down; tv = t->type; symb = lookup("b"); t = typ(TFIELD); t->type = tv; t->sym = symb; syma = lookup("a"); t1 = t; t = typ(TFIELD); t->type = tk; t->sym = syma; t->down = t1; t1 = t; t = typ(TSTRUCT); t->type = t1; t1 = t; t = typ(TARRAY); t->bound = b; t->type = t1; dowidth(t); // make and initialize static array vstat = staticname(t, ctxt); b = 0; for(l=n->list; l; l=l->next) { r = l->n; if(r->op != OKEY) fatal("slicelit: rhs not OKEY: %N", r); index = r->left; value = r->right; if(isliteral(index) && isliteral(value)) { // build vstat[b].a = key; a = nodintconst(b); a = nod(OINDEX, vstat, a); a = nod(ODOT, a, newname(syma)); a = nod(OAS, a, index); typecheck(&a, Etop); walkexpr(&a, init); a->dodata = 2; *init = list(*init, a); // build vstat[b].b = value; a = nodintconst(b); a = nod(OINDEX, vstat, a); a = nod(ODOT, a, newname(symb)); a = nod(OAS, a, value); typecheck(&a, Etop); walkexpr(&a, init); a->dodata = 2; *init = list(*init, a); b++; } } // loop adding structure elements to map // for i = 0; i < len(vstat); i++ { // map[vstat[i].a] = vstat[i].b // } index = nod(OXXX, N, N); tempname(index, types[TINT]); a = nod(OINDEX, vstat, index); a->etype = 1; // no bounds checking a = nod(ODOT, a, newname(symb)); r = nod(OINDEX, vstat, index); r->etype = 1; // no bounds checking r = nod(ODOT, r, newname(syma)); r = nod(OINDEX, var, r); r = nod(OAS, r, a); a = nod(OFOR, N, N); a->nbody = list1(r); a->ninit = list1(nod(OAS, index, nodintconst(0))); a->ntest = nod(OLT, index, nodintconst(t->bound)); a->nincr = nod(OASOP, index, nodintconst(1)); a->nincr->etype = OADD; typecheck(&a, Etop); walkstmt(&a); *init = list(*init, a); } // put in dynamic entries one-at-a-time for(l=n->list; l; l=l->next) { r = l->n; if(r->op != OKEY) fatal("slicelit: rhs not OKEY: %N", r); index = r->left; value = r->right; if(isliteral(index) && isliteral(value)) continue; // build list of var[c] = expr a = nod(OINDEX, var, r->left); a = nod(OAS, a, r->right); typecheck(&a, Etop); walkexpr(&a, init); if(nerr != nerrors) break; *init = list(*init, a); } }
void regopt(Prog *firstp) { Reg *r, *r1; Prog *p; int i, z, nr; uint32 vreg; Bits bit; if(first) { fmtinstall('Q', Qconv); exregoffset = D_R13; // R14,R15 are external first = 0; } fixjmp(firstp); // count instructions nr = 0; for(p=firstp; p!=P; p=p->link) nr++; // if too big dont bother if(nr >= 10000) { // print("********** %S is too big (%d)\n", curfn->nname->sym, nr); return; } r1 = R; firstr = R; lastr = R; /* * control flow is more complicated in generated go code * than in generated c code. define pseudo-variables for * registers, so we have complete register usage information. */ nvar = NREGVAR; memset(var, 0, NREGVAR*sizeof var[0]); for(i=0; i<NREGVAR; i++) var[i].node = newname(lookup(regname[i])); regbits = RtoB(D_SP); for(z=0; z<BITS; z++) { externs.b[z] = 0; params.b[z] = 0; consts.b[z] = 0; addrs.b[z] = 0; ovar.b[z] = 0; } // build list of return variables setoutvar(); /* * pass 1 * build aux data structure * allocate pcs * find use and set of variables */ nr = 0; for(p=firstp; p!=P; p=p->link) { switch(p->as) { case ADATA: case AGLOBL: case ANAME: case ASIGNAME: continue; } r = rega(); nr++; if(firstr == R) { firstr = r; lastr = r; } else { lastr->link = r; r->p1 = lastr; lastr->s1 = r; lastr = r; } r->prog = p; p->reg = r; r1 = r->p1; if(r1 != R) { switch(r1->prog->as) { case ARET: case AJMP: case AIRETL: case AIRETQ: r->p1 = R; r1->s1 = R; } } bit = mkvar(r, &p->from); if(bany(&bit)) switch(p->as) { /* * funny */ case ALEAL: case ALEAQ: setaddrs(bit); break; /* * left side read */ default: for(z=0; z<BITS; z++) r->use1.b[z] |= bit.b[z]; break; /* * left side read+write */ case AXCHGB: case AXCHGW: case AXCHGL: case AXCHGQ: for(z=0; z<BITS; z++) { r->use1.b[z] |= bit.b[z]; r->set.b[z] |= bit.b[z]; } break; } bit = mkvar(r, &p->to); if(bany(&bit)) switch(p->as) { default: yyerror("reg: unknown op: %A", p->as); break; /* * right side read */ case ACMPB: case ACMPL: case ACMPQ: case ACMPW: case ACOMISS: case ACOMISD: case AUCOMISS: case AUCOMISD: case ATESTB: case ATESTL: case ATESTQ: for(z=0; z<BITS; z++) r->use2.b[z] |= bit.b[z]; break; /* * right side write */ case ALEAQ: case ANOP: case AMOVL: case AMOVQ: case AMOVB: case AMOVW: case AMOVBLSX: case AMOVBLZX: case AMOVBWSX: case AMOVBWZX: case AMOVBQSX: case AMOVBQZX: case AMOVLQSX: case AMOVLQZX: case AMOVWLSX: case AMOVWLZX: case AMOVWQSX: case AMOVWQZX: case APOPQ: case AMOVSS: case AMOVSD: case ACVTSD2SL: case ACVTSD2SQ: case ACVTSD2SS: case ACVTSL2SD: case ACVTSL2SS: case ACVTSQ2SD: case ACVTSQ2SS: case ACVTSS2SD: case ACVTSS2SL: case ACVTSS2SQ: case ACVTTSD2SL: case ACVTTSD2SQ: case ACVTTSS2SL: case ACVTTSS2SQ: for(z=0; z<BITS; z++) r->set.b[z] |= bit.b[z]; break; /* * right side read+write */ case AINCB: case AINCL: case AINCQ: case AINCW: case ADECB: case ADECL: case ADECQ: case ADECW: case AADDB: case AADDL: case AADDQ: case AADDW: case AANDB: case AANDL: case AANDQ: case AANDW: case ASUBB: case ASUBL: case ASUBQ: case ASUBW: case AORB: case AORL: case AORQ: case AORW: case AXORB: case AXORL: case AXORQ: case AXORW: case ASALB: case ASALL: case ASALQ: case ASALW: case ASARB: case ASARL: case ASARQ: case ASARW: case ARCLB: case ARCLL: case ARCLQ: case ARCLW: case ARCRB: case ARCRL: case ARCRQ: case ARCRW: case AROLB: case AROLL: case AROLQ: case AROLW: case ARORB: case ARORL: case ARORQ: case ARORW: case ASHLB: case ASHLL: case ASHLQ: case ASHLW: case ASHRB: case ASHRL: case ASHRQ: case ASHRW: case AIMULL: case AIMULQ: case AIMULW: case ANEGB: case ANEGW: case ANEGL: case ANEGQ: case ANOTL: case ANOTQ: case AADCL: case AADCQ: case ASBBL: case ASBBQ: case ASETCC: case ASETCS: case ASETEQ: case ASETGE: case ASETGT: case ASETHI: case ASETLE: case ASETLS: case ASETLT: case ASETMI: case ASETNE: case ASETOC: case ASETOS: case ASETPC: case ASETPL: case ASETPS: case AXCHGB: case AXCHGW: case AXCHGL: case AXCHGQ: case AADDSD: case AADDSS: case ACMPSD: case ACMPSS: case ADIVSD: case ADIVSS: case AMAXSD: case AMAXSS: case AMINSD: case AMINSS: case AMULSD: case AMULSS: case ARCPSS: case ARSQRTSS: case ASQRTSD: case ASQRTSS: case ASUBSD: case ASUBSS: case AXORPD: for(z=0; z<BITS; z++) { r->set.b[z] |= bit.b[z]; r->use2.b[z] |= bit.b[z]; } break; /* * funny */ case ACALL: setaddrs(bit); break; } switch(p->as) { case AIMULL: case AIMULQ: case AIMULW: if(p->to.type != D_NONE) break; case AIDIVL: case AIDIVW: case AIDIVQ: case ADIVL: case ADIVW: case ADIVQ: case AMULL: case AMULW: case AMULQ: r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX); r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DX); break; case AIDIVB: case AIMULB: case ADIVB: case AMULB: r->set.b[0] |= RtoB(D_AX); r->use1.b[0] |= RtoB(D_AX); break; case ACWD: r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX); r->use1.b[0] |= RtoB(D_AX); break; case ACDQ: r->set.b[0] |= RtoB(D_DX); r->use1.b[0] |= RtoB(D_AX); break; case AREP: case AREPN: case ALOOP: case ALOOPEQ: case ALOOPNE: r->set.b[0] |= RtoB(D_CX); r->use1.b[0] |= RtoB(D_CX); break; case AMOVSB: case AMOVSL: case AMOVSQ: case AMOVSW: case ACMPSB: case ACMPSL: case ACMPSQ: case ACMPSW: r->set.b[0] |= RtoB(D_SI) | RtoB(D_DI); r->use1.b[0] |= RtoB(D_SI) | RtoB(D_DI); break; case ASTOSB: case ASTOSL: case ASTOSQ: case ASTOSW: case ASCASB: case ASCASL: case ASCASQ: case ASCASW: r->set.b[0] |= RtoB(D_DI); r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DI); break; case AINSB: case AINSL: case AINSW: r->set.b[0] |= RtoB(D_DX) | RtoB(D_DI); r->use1.b[0] |= RtoB(D_DI); break; case AOUTSB: case AOUTSL: case AOUTSW: r->set.b[0] |= RtoB(D_DI); r->use1.b[0] |= RtoB(D_DX) | RtoB(D_DI); break; } } if(firstr == R) return; for(i=0; i<nvar; i++) { Var *v = var+i; if(v->addr) { bit = blsh(i); for(z=0; z<BITS; z++) addrs.b[z] |= bit.b[z]; } // print("bit=%2d addr=%d et=%-6E w=%-2d s=%S + %lld\n", // i, v->addr, v->etype, v->width, v->sym, v->offset); } if(debug['R'] && debug['v']) dumpit("pass1", firstr); /* * pass 2 * turn branch references to pointers * build back pointers */ for(r=firstr; r!=R; r=r->link) { p = r->prog; if(p->to.type == D_BRANCH) { if(p->to.branch == P) fatal("pnil %P", p); r1 = p->to.branch->reg; if(r1 == R) fatal("rnil %P", p); if(r1 == r) { //fatal("ref to self %P", p); continue; } r->s2 = r1; r->p2link = r1->p2; r1->p2 = r; } } if(debug['R'] && debug['v']) dumpit("pass2", firstr); /* * pass 2.5 * find looping structure */ for(r = firstr; r != R; r = r->link) r->active = 0; change = 0; loopit(firstr, nr); if(debug['R'] && debug['v']) dumpit("pass2.5", firstr); /* * pass 3 * iterate propagating usage * back until flow graph is complete */ loop1: change = 0; for(r = firstr; r != R; r = r->link) r->active = 0; for(r = firstr; r != R; r = r->link) if(r->prog->as == ARET) prop(r, zbits, zbits); loop11: /* pick up unreachable code */ i = 0; for(r = firstr; r != R; r = r1) { r1 = r->link; if(r1 && r1->active && !r->active) { prop(r, zbits, zbits); i = 1; } } if(i) goto loop11; if(change) goto loop1; if(debug['R'] && debug['v']) dumpit("pass3", firstr); /* * pass 4 * iterate propagating register/variable synchrony * forward until graph is complete */ loop2: change = 0; for(r = firstr; r != R; r = r->link) r->active = 0; synch(firstr, zbits); if(change) goto loop2; if(debug['R'] && debug['v']) dumpit("pass4", firstr); /* * pass 4.5 * move register pseudo-variables into regu. */ for(r = firstr; r != R; r = r->link) { r->regu = (r->refbehind.b[0] | r->set.b[0]) & REGBITS; r->set.b[0] &= ~REGBITS; r->use1.b[0] &= ~REGBITS; r->use2.b[0] &= ~REGBITS; r->refbehind.b[0] &= ~REGBITS; r->refahead.b[0] &= ~REGBITS; r->calbehind.b[0] &= ~REGBITS; r->calahead.b[0] &= ~REGBITS; r->regdiff.b[0] &= ~REGBITS; r->act.b[0] &= ~REGBITS; } /* * pass 5 * isolate regions * calculate costs (paint1) */ r = firstr; if(r) { for(z=0; z<BITS; z++) bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) & ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]); if(bany(&bit) && !r->refset) { // should never happen - all variables are preset if(debug['w']) print("%L: used and not set: %Q\n", r->prog->lineno, bit); r->refset = 1; } } for(r = firstr; r != R; r = r->link) r->act = zbits; rgp = region; nregion = 0; for(r = firstr; r != R; r = r->link) { for(z=0; z<BITS; z++) bit.b[z] = r->set.b[z] & ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]); if(bany(&bit) && !r->refset) { if(debug['w']) print("%L: set and not used: %Q\n", r->prog->lineno, bit); r->refset = 1; excise(r); } for(z=0; z<BITS; z++) bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]); while(bany(&bit)) { i = bnum(bit); rgp->enter = r; rgp->varno = i; change = 0; paint1(r, i); bit.b[i/32] &= ~(1L<<(i%32)); if(change <= 0) continue; rgp->cost = change; nregion++; if(nregion >= NRGN) { if(debug['R'] && debug['v']) print("too many regions\n"); goto brk; } rgp++; } } brk: qsort(region, nregion, sizeof(region[0]), rcmp); /* * pass 6 * determine used registers (paint2) * replace code (paint3) */ rgp = region; for(i=0; i<nregion; i++) { bit = blsh(rgp->varno); vreg = paint2(rgp->enter, rgp->varno); vreg = allreg(vreg, rgp); if(rgp->regno != 0) paint3(rgp->enter, rgp->varno, vreg, rgp->regno); rgp++; } if(debug['R'] && debug['v']) dumpit("pass6", firstr); /* * pass 7 * peep-hole on basic block */ if(!debug['R'] || debug['P']) { peep(); } /* * eliminate nops * free aux structures */ for(p=firstp; p!=P; p=p->link) { while(p->link != P && p->link->as == ANOP) p->link = p->link->link; if(p->to.type == D_BRANCH) while(p->to.branch != P && p->to.branch->as == ANOP) p->to.branch = p->to.branch->link; } if(r1 != R) { r1->link = freer; freer = firstr; } if(debug['R']) { if(ostats.ncvtreg || ostats.nspill || ostats.nreload || ostats.ndelmov || ostats.nvar || ostats.naddr || 0) print("\nstats\n"); if(ostats.ncvtreg) print(" %4d cvtreg\n", ostats.ncvtreg); if(ostats.nspill) print(" %4d spill\n", ostats.nspill); if(ostats.nreload) print(" %4d reload\n", ostats.nreload); if(ostats.ndelmov) print(" %4d delmov\n", ostats.ndelmov); if(ostats.nvar) print(" %4d var\n", ostats.nvar); if(ostats.naddr) print(" %4d addr\n", ostats.naddr); memset(&ostats, 0, sizeof(ostats)); } }
void fninit(NodeList *n) { int i; Node *gatevar; Node *a, *b, *fn; NodeList *r; uint32 h; Sym *s, *initsym; if(debug['A']) { // sys.go or unsafe.go during compiler build return; } n = initfix(n); if(!anyinit(n)) return; r = nil; // (1) snprint(namebuf, sizeof(namebuf), "initdoneĀ·"); gatevar = newname(lookup(namebuf)); addvar(gatevar, types[TUINT8], PEXTERN); // (2) maxarg = 0; snprint(namebuf, sizeof(namebuf), "init"); fn = nod(ODCLFUNC, N, N); initsym = lookup(namebuf); fn->nname = newname(initsym); fn->nname->defn = fn; fn->nname->ntype = nod(OTFUNC, N, N); declare(fn->nname, PFUNC); funchdr(fn); // (3) a = nod(OIF, N, N); a->ntest = nod(ONE, gatevar, nodintconst(0)); r = list(r, a); // (4) b = nod(OIF, N, N); b->ntest = nod(OEQ, gatevar, nodintconst(2)); b->nbody = list1(nod(ORETURN, N, N)); a->nbody = list1(b); // (5) b = syslook("throwinit", 0); b = nod(OCALL, b, N); a->nbody = list(a->nbody, b); // (6) a = nod(OAS, gatevar, nodintconst(1)); r = list(r, a); // (7) for(h=0; h<NHASH; h++) for(s = hash[h]; s != S; s = s->link) { if(s->name[0] != 'i' || strcmp(s->name, "init") != 0) continue; if(s->def == N) continue; if(s == initsym) continue; // could check that it is fn of no args/returns a = nod(OCALL, s->def, N); r = list(r, a); } // (8) r = concat(r, n); // (9) // could check that it is fn of no args/returns for(i=1;; i++) { snprint(namebuf, sizeof(namebuf), "initĀ·%d", i); s = lookup(namebuf); if(s->def == N) break; a = nod(OCALL, s->def, N); r = list(r, a); } // (10) a = nod(OAS, gatevar, nodintconst(2)); r = list(r, a); // (11) a = nod(ORETURN, N, N); r = list(r, a); exportsym(fn->nname); fn->nbody = r; funcbody(fn); curfn = fn; typecheck(&fn, Etop); typechecklist(r, Etop); curfn = nil; funccompile(fn, 0); }
void dofile(const char *name) { int fd; struct stat st; char *s; if ((fd=open(name, O_RDWR))<0) swrite("?"); else if (fstat(fd, &st) || !S_ISREG(st.st_mode)) ex("open"); else swrite_free(md5sum(fd, st.st_size)); s = sread(); switch (*s) { case 'o': close(fd); free(s); return; case 'a': if (fd<0) ex("!fd"); if (lseek(fd, st.st_size, SEEK_SET)!=st.st_size) ex("lseek"); break; case 'w': if (fd<0) ex("!fd"); close(fd); fd = -1; free(s); s = newname(name); if (rename(name, s)) ex("name"); case 'c': if (fd>=0) ex("fd!"); mkparent(name); if ((fd=open(name, O_WRONLY|O_CREAT|O_EXCL, 0644))<0) ex("create"); break; default: ex("prot"); } free(s); swrite("OK"); if (docopy(sock, fd, 1)) ex("broken stream"); if (close(fd)) ex("close"); swrite("NEXT"); }
struct lmf_str * ncbl_openlib(char *name, int ldnaseq) { char hname[256]; char sname[256]; char tname[256]; long title_len; char *title_str; int rdtmp; int i; unsigned long line_len, c_len, clean_count; if (ldnaseq!=1) { newname(tname,name,AA_TABLE_EXT,(int)sizeof(tname)); if ((tfile = fopen(tname,RBSTR))==NULL) { fprintf(stderr," cannot open %s (%s.%s) table file\n", name,tname,NT_TABLE_EXT); return (-1); } seq_format = AAFORMAT; } else { newname(tname,name,NT_TABLE_EXT,(int)sizeof(tname)); if ((tfile = fopen(tname,RBSTR))==NULL) { fprintf(stderr," cannot open %s (%s.%s) table file\n", name,tname,NT_TABLE_EXT); return (-1); } seq_format = NTFORMAT; } src_ulong_read(tfile,&dbtype); src_ulong_read(tfile,&dbformat); if (seq_format == AAFORMAT && (dbformat != seq_format || dbtype != DB_TYPE_PRO)) { fprintf(stderr,"error - %s wrong type (%ld/%d) or format (%ld/%ld)\n", tname,dbtype,DB_TYPE_PRO,dbformat,seq_format); return (-1); } else if (seq_format == NTFORMAT && (dbformat != seq_format || dbtype != DB_TYPE_NUC)) { fprintf(stderr,"error - %s wrong type (%ld/%d) or format (%ld/%ld)\n", tname,dbtype,DB_TYPE_NUC,dbformat,seq_format); return (-1); } if (seq_format == AAFORMAT) { newname(hname,name,AA_HEADER_EXT,(int)sizeof(hname)); if ((hfile = fopen(hname,RBSTR))==NULL) { fprintf(stderr," cannot open %s header file\n",hname); return (-1); } newname(sname,name,AA_SEARCHSEQ_EXT,(int)sizeof(sname)); if ((sfile = fopen(sname,RBSTR))==NULL) { fprintf(stderr," cannot open %s sequence file\n",sname); return (-1); } } else { newname(hname,name,NT_HEADER_EXT,(int)sizeof(hname)); if ((hfile = fopen(hname,RBSTR))==NULL) { fprintf(stderr," cannot open %s header file\n",hname); return (-1); } newname(sname,name,NT_SEARCHSEQ_EXT,(int)sizeof(sname)); if ((sfile = fopen(sname,RBSTR))==NULL) { fprintf(stderr," cannot open %s sequence file\n",sname); return (-1); } } /* all files should be open */ src_ulong_read(tfile,&title_len); rdtmp = title_len + ((title_len%4 !=0 ) ? 4-(title_len%4) : 0); if ((title_str = calloc((size_t)rdtmp,sizeof(char)))==NULL) { fprintf(stderr," cannot allocate title string (%d)\n",rdtmp); return(-1); } fread(title_str,(size_t)1,(size_t)rdtmp,tfile); lib_cnt = 0; if (seq_format == AAFORMAT) { src_ulong_read(tfile,&max_cnt); src_ulong_read(tfile,&totlen); src_ulong_read(tfile,&mxlen); /* fprintf(stderr," max_cnt: %d, totlen: %d\n",max_cnt,totlen); */ if ((seq_beg=(unsigned long *)calloc((size_t)max_cnt+1,sizeof(long)))==NULL) { fprintf(stderr," cannot allocate sequence pointers\n"); return -1; } if ((hdr_beg=(unsigned long *)calloc((size_t)max_cnt+1,sizeof(long)))==NULL) { fprintf(stderr," cannot allocate header pointers\n"); return -1; } for (i=0; i<max_cnt+1; i++) src_ulong_read(tfile,&seq_beg[i]); for (i=0; i<max_cnt+1; i++) src_ulong_read(tfile,&hdr_beg[i]); for (i=0; i<sizeof(aa_btoa); i++) { if ((rdtmp=aascii[aa_btoa[i]])<NA) aa_btof[i]=rdtmp; else aa_btof[i]=aascii['X']; } } else if (seq_format == NTFORMAT) { src_ulong_read(tfile,&dbline_len); /* length of uncompress DB lines */ src_ulong_read(tfile,&max_cnt); /* number of entries */ src_ulong_read(tfile,&mxlen); /* maximum length sequence */ src_ulong_read(tfile,&totlen); /* total count */ src_ulong_read(tfile,&c_len); /* compressed db length */ src_ulong_read(tfile,&clean_count); /* count of nt's cleaned */ fseek(tfile,(size_t)((clean_count)*4),1); /* seek over clean_count */ if ((seq_beg=(unsigned long *)calloc((size_t)max_cnt+1,sizeof(long)))==NULL) { fprintf(stderr," cannot allocate sequence pointers\n"); return -1; } if ((hdr_beg=(unsigned long *)calloc((size_t)max_cnt+1,sizeof(long)))==NULL) { fprintf(stderr," cannot allocate header pointers\n"); return -1; } if ((ambiguity_ray= (unsigned char *)calloc((size_t)max_cnt/CHAR_BIT+1,sizeof(char)))==NULL) { fprintf(stderr," cannot allocate ambiguity_ray\n"); return -1; } for (i=0; i<max_cnt+1; i++) src_ulong_read(tfile,&seq_beg[i]); fseek(tfile,(size_t)((max_cnt+1)*4),1); /* seek over seq_beg */ for (i=0; i<max_cnt+1; i++) src_ulong_read(tfile,&hdr_beg[i]); for (i=0; i<max_cnt/CHAR_BIT+1; i++) src_char_read(tfile,&ambiguity_ray[i]); } return 1; }
static EORB_CPP_node *read_expr_10 (void) { char c; char *w; EORB_CPP_node *n; #ifdef DEBUG_EXPR if (debugging) { outputs("~E10:"); } #endif while (1) { c = getnhsexpand(); switch (c) { case '-': case '~': case '!': #ifdef DEBUG_EXPR if (debugging) { outputc(c); } #endif n = read_expr_10(); #ifdef DEBUG_EXPR if (debugging) { outputs("~"); } #endif return (newnode(0, c, n)); break; case 'd': Push(c); input_mark(); w = read_ident(); if (strcmp(w, "defined") == 0) { c = getnonspace(); if (c == '(') { char *id; id = read_ident(); if (id) { c = getnonspace(); if (c == ')') { input_unmark(); #ifdef DEBUG_EXPR if (debugging) { outputs("ifdef"); } #endif return (newname(id)); } } } else if (isbsymchar(c)) { char *id; Push(c); id = read_ident(); if (id) { input_unmark(); #ifdef DEBUG_EXPR if (debugging) { outputs("ifdef"); } #endif return (newname(id)); } } } input_recover(); n = read_expr_11(); #ifdef DEBUG_EXPR if (debugging) { outputs("~"); } #endif return (n); break; default: Push(c); n = read_expr_11(); #ifdef DEBUG_EXPR if (debugging) { outputs("~"); } #endif return (n); break; } } }
/* =========================================================================== * Process a name or wildcard expression to operate on (or exclude). * We will only arrive here if we do a Freshen or Delete. * Return an error code in the ZEN_ class. * ZEN_OK, ZEN_ABORT, ZEN_MISS03, ZEN_MISS04, ZEN_MISS05, ZEN_MEM22, ZEN_MEM23 *ArgName :: Name to process. */ int procname( char *ArgName, bool RecurseDir, struct Globals *pG ) { char *a; /* path and name for recursion */ zDIR *d; /* directory stream from opendir() */ char *e; /* pointer to name from readd() */ int m; /* matched flag */ char *p; /* path for recursion */ int pnError; /* ProcName error */ struct stat StatRes; /* result of stat() */ struct zlist *z; /* steps through zfiles list */ // sprintf( ewemsg, "in procname name=>%s<= recurse=%d", ArgName, RecurseDir ); // diag( ewemsg ); m = 1; /* set dflt for success indicator (0=success) */ if ( pG->global_abort_sw ) return ZEN_ABORT; /* RCV changed was ZEN_MISS? */ if ( *ArgName == '\0' ) return ZEN_MISS03; /* LSSTAT returns 0 if it's arg is any kind of file (even a dir). */ /* IsShExp returns true if a wildcard symbol is found, or * NULL if none were found -- IsShExp is in util.c */ if ( LSSTAT( GetFullPath( pG, ArgName ), &StatRes ) || (IsShExp( ArgName ) != NULL) ) { // diag( "not a file or dir - 'ArgName' must be a wildcard fspec" ); // Upon finding a wildcard fspec, we need to mark entries in // the "zfiles" list that are included by the wildcard. /* convert the "external" (native) filename to an internal * ZIP-archive-compatible filename. */ p = ex2in( ArgName, (int *)NULL, pG ); /* shouldn't affect matching chars */ /* does any file already in the archive match this spec? */ /* Note that we need the pathname and filename together for this */ for ( z = pG->zfiles; z; z = z->nxt ) { if ( dosmatch( p, z->zname, pG ) ) { /* name is in archive - mark it for updating */ z->mark = pG->pcount ? filter( z->zname, pG ) : 1; FREE( z->name ); // RCV added + next 8 lines needed for FRESHEN mode. if ( (z->name = MALLOC( lstrlen( z->zname ) + 4 )) == NULL ) return ZEN_MEM34; z->name[0] = '\0'; //v1.55 if ( isalpha( ArgName[0] ) && ArgName[1] == ':' && ArgName[2] == '\\') { z->name[0] = ArgName[0]; z->name[1] = ArgName[1]; z->name[2] = ArgName[2]; z->name[3] = '\0'; } lstrcat( z->name, z->zname ); if ( pG->verbose ) printf( "%scluding %s\n", z->mark ? "in" : "ex", z->name ); m = 0; /* we had at least one file in the archive that we marked */ } } FREE( p ); /* returns 1 if no "zfiles" entries were marked, * 0 if at least one entry was marked */ if ( m ) { // diag( "returning ZEN_MISS04 from procname" ); return ZEN_MISS04; } // diag( "returning ZEN_OK from procname" ); return ZEN_OK; } /* end of "if (LSSTAT..." */ /* Existing and good filename or directory-- add the name if it's a file, recurse if directory */ // diag( "good entry to add, or a dir to go into" ); /* check the status returned by LSSTAT earlier to see if 'ArgName' is a dir */ pnError = ZEN_OK; if ( !(StatRes.st_mode & S_IFDIR) ) { /* it's not a directory - add file to found list */ sprintf( pG->ewemsg, "spot 1: Add file %s to found list", ArgName ); diag( pG->ewemsg, pG ); /* newname (fileio.c) adds to found list. If error m!=0 on return */ if ( (m = newname( ArgName, StatRes.st_size, pG )) != ZEN_OK ) { sprintf( pG->ewemsg, "returning %d from procname after newname call", m ); diag( pG->ewemsg, pG ); return m; } } else { /* It is a directory - Add trailing / to the directory name */ // diag( "Spot 2, directory found" ); if ( (p = MALLOC( lstrlen( ArgName )+ 2) ) == NULL ) return ZEN_MEM22; if ( !strcmp( ArgName, "." ) || !strcmp( ArgName, "\\." ) ) { // SLASH *p = '\0'; /* avoid "./" prefix and do not create zip entry */ } else { // diag( "spot 3" ); lstrcpy( p, ArgName ); a = p + lstrlen( p ); if ( a[-1] != '\\' ) lstrcpy( a, "\\" ); // SLASH /* newname (fileio.c) adds to found list. If error m != 0 on return */ if ( pG->dirnames && (m = newname( p, 0, pG )) != ZEN_OK ) { FREE( p ); sprintf( pG->ewemsg, "returning %d from procname after 2nd newname call", m ); diag( pG->ewemsg, pG ); return m; } } /* recurse into directory */ // diag( "spot 4: optional recurse into dir" ); if ( RecurseDir && ((d = Opendir( ArgName, pG )) != NULL) ) { /* Open new dir (like chdir) */ // diag( "good open of dir" ); while ( (e = readd( d, pG )) != NULL ) { if ( pG->global_abort_sw ) { // RCV changed error handling pnError = ZEN_ABORT; break; } /* e is pointing to the new filename we just read from dir */ /* ignore dir entries of . and .. */ if ( strcmp( e, "." ) && strcmp( e, ".." ) ) { /* get a new tmp buffer for the path and fname */ if ( (a = MALLOC( lstrlen( p ) + lstrlen( e ) + 1 )) == NULL ) { pnError = ZEN_MEM23; /* RCV error handling changed */ break; } /* form the new dir's pathname followed by the fname just read */ /* (we need to send in the dir and fname, or it won't be * detected as a valid file by LSSTAT) */ lstrcat( lstrcpy( a, p ), e ); // diag( "DOING RECURSIVE CALL TO PROCNAME FROM PROCNAME" ); if ( (m = procname( a, RecurseDir, pG )) != ZEN_OK ) { /* recursive call failed; return code not ZEN_OK */ if ( m != ZEN_OK && m != ZEN_MISS05 ) { /* unknown error; RCV error handling changed */ pnError = m; FREE( a ); break; } else if ( (int)(char)(m & 0xFF) == ZEN_MISS ) zipwarn( "name not matched: ", a ); } FREE( a ); } } /* end while */ Closedir( d ); } /* end if (spot 4) */ FREE( p ); } /* (StatRes.st_mode & S_IFDIR) == 0) */ // diag( "returning ZEN_ class from procname" ); return pnError; }
/* =========================================================================== * If not in exclude mode, expand the pattern based on the contents * of the file system. * This function is used while gathering filenames to be added or updated *w :: Path/pattern to match. Possible return values: ZEN_MISS, ZEN_OK, ZEN_ABORT, ZEN_MEM or ZEN_PARMS. */ int Wild( char *w, struct Globals *pG ) { zDIR *d; /* Stream for reading directory */ char *e; /* File or directory name found. */ char *n; /* Constructed name from directory */ int WError; /* Result of Wild() */ char *p, *a; /* path originale and fixed. */ char *q; /* Filename / pattern. */ int r; /* Result / temp var. */ char v[5]; /* space for device current directory.*/ bool StopRecurs = false; /* No recursion if filespec is file. */ // sprintf( pG->ewemsg, "in Wild of win32zip.c, pattern=%s recurse=%d", w, pG->recurse ); // diag( pG->ewemsg, pG ); // "zip -$ foo a:" can be used to force a drive name once. // v1.6017 if ( pG->volume_label == 1 ) { pG->volume_label = 2; pG->label = getVolumeLabel( pG, (w != NULL && w[ 1 ] == ':') ? to_up( w[ 0 ] ) : '\0', &pG->label_time, &pG->label_mode, &pG->label_utim ); if ( pG->label != NULL ) (void)newname( pG->label, 0, pG ); if ( w == NULL || (w[1] == ':' && w[2] == '\0') ) return ZEN_OK; } /* Allocate and copy pattern */ if ( (p = a = MALLOC( lstrlen( w ) + 1) ) == NULL ) return ZEN_MEM19; lstrcpy( p, w ); /* Separate path and name into p and q */ // We have '\' or '\name' or 'path1\path2\name2' or 'C:\path\name' but NOT 'C:\name' if ( (q = strrchr( p, '\\' )) != NULL && (q == p || q[-1] != ':') ) { // SLASH *q++ = '\0'; if ( *p == '\0' ) p = lstrcpy( v, "\\." ); /* if path is just '\' SLASH */ } else if ( (q = strrchr( p, ':' )) != NULL ) { /* We have 'C:' or 'C:\' or 'C:\name' */ *q++ = '\0'; p = lstrcat( lstrcpy( v, p ), ":" ); /* copy device as path eg. 'C:' */ if ( *q == '\\' ) { /* -> device:/., name eg. 'C:\.' SLASH */ lstrcat( p, "\\" ); // SLASH q++; /* name or nothing. */ } lstrcat( p, "." ); /* eg. 'C:.' or 'C:\.' */ } else if ( pG->recurse && (!strcmp( p, "." ) || !strcmp( p, ".." )) ) { /* current or parent directory */ /* Get "zip -r foo ." to work. Allow the dubious "zip -r foo .." but * reject "zip -r -m foo ..". "dispose" means wipe out source path. */ if ( pG->dispose && !strcmp( p, ".." ) ) ziperr( ZEN_PARMS15, pG ); q = (char *)pG->wild_match_all; } else { /* no path or device */ q = p; p = lstrcpy( v, "." ); } if ( pG->recurse && *q == '\0' ) q = (char *)pG->wild_match_all; /* take out a possibly redundant dir name of "." */ if ( (r = lstrlen( p )) > 1 && (strcmp( p + r - 2, ":." ) == 0 || strcmp( p + r - 2, "\\." ) == 0) ) // SLASH *(p + r - 1) = '\0'; /* Only filename (not the path) can have special matching characters */ if ( IsShExp( p ) ) { diag( "path has illegal chars", pG ); FREE( a ); return ZEN_PARMS16; } // sprintf( ewemsg, "at break up place in Wild: path=%s name=%s", p, q ); // diag( ewemsg ); if ( !IsShExp( q ) ) { // Speed up checking if file exits in case there are no wildcards struct stat s; // and no recursion and no archiving v1.6016 if ( !pG->recurse && !pG->ArchiveFiles ) { if ( !LSSTAT( GetFullPath( pG, w ), &s ) ) /* file exists ? */ return procname( w, false, pG ); return ZEN_MISS02; /* woops, no wildcards where is the file! */ } if ( pG->norecursefiles ) StopRecurs = true; } /* Now that we have a dir spec, along with an fspec, we'll step * in the dir specified to see if there's any matches against the fspec. */ WError = ZEN_MISS02; if ( (d = Opendir( p, pG )) != NULL ) { while ( (e = readd( d, pG )) != NULL ) { if ( pG->global_abort_sw ) { WError = ZEN_ABORT; break; } // sprintf( ewemsg, "Found %s: %s", d->d_attr & FILE_ATTRIBUTE_DIRECTORY ? "directory" : "file", e ); // diag( ewemsg ); /* if e is NOT '.' or '..', and is a dir or match fspec. */ if ( strcmp( e, "." ) && strcmp( e, ".." ) && (d->d_attr & FILE_ATTRIBUTE_DIRECTORY || dosmatch( q, e, pG )) ) { // diag( "Matched" ); /* we matched fspec or it's a dir and entry is not '.' or '..' */ if ( d->d_attr & FILE_ATTRIBUTE_DIRECTORY ) { // We do not save dirs or go into dirs if norecursefiles==1 and we a file without * or ? specs. if ( !StopRecurs && (pG->dirnames || pG->recurse) ) { if ( (n = MALLOC( lstrlen( p ) + lstrlen( e ) + lstrlen( q ) + 3 )) == NULL ) { WError = ZEN_MEM20; break; } *n = '\0'; if ( *p != '.' ) AddSlash( lstrcpy( n, p ) ); // No ./ as first dir. lstrcat( n, e ); if ( pG->dirnames ) { // Save directory names also. r = procname( n, false, pG ); if ( (int)(char)(r & 0xFF) > ZEN_OK || !pG->recurse ) FREE( n ); if ( (int)(char)(r & 0xFF) > (int)(char)(WError & 0xFF) ) WError = r; if ( (int)(char)(r & 0xFF) > ZEN_OK ) break; } if ( pG->recurse ) { // Recursively go into dir and check for other pattern matches. r = Wild( lstrcat( AddSlash( n ), q ), pG ); // Add the original pattern. FREE( n ); // We keep a ZEN_OK even when ZEN_MISS occurs. if ( (int)(char)(r & 0xFF) > (int)(char)(WError & 0xFF) ) WError = r; if ( (int)(char)(r & 0xFF) > ZEN_OK ) break; // An error, stop processing. } } } else { if ( (n = MALLOC( lstrlen( p ) + lstrlen( e ) + 2 )) == NULL ) { WError = ZEN_MEM21; break; } if ( !strcmp( p, "." ) ) r = procname( e, false, pG ); else r = procname( lstrcat( AddSlash( lstrcpy( n, p ) ), e ), false, pG ); FREE( n ); if ( (int)(char)(r & 0xFF) > (int)(char)(WError & 0xFF) ) WError = r; if ( (int)(char)(r & 0xFF) > ZEN_OK ) break; } } /* end "if (strcmp..." */ } /* end while */ Closedir( d ); } else diag( "can't open dir", pG ); FREE( a ); // sprintf( ewemsg, "Wild returned: %d", WError ); // diag( ewemsg ); return WError; }
/* =========================================================================== select files to be processed */ int ZipSelect(struct Globals *pG, const ZCL2 *C) { int i; // arg counter, root directory flag int k; // next argument type, marked counter, const char *p; // steps through option arguments int r; // temporary variable long g_before; // 1.74 global 'before' int argno, arg1; if ((p = getenv("TZ")) == NULL || *p == '\0') pG->extra_fields = 0; // disable storing "Unix" time stamps SetExclFilters(pG); // Process arguments diag("ready to read zip file", pG); // the read will be done in file: zipfile.c if ((r = readzipfile(pG)) != ZEN_OK) { diag("err returned from \"readzipfile\"", pG); return (ziperr(r, pG)); } if (pG->action == UPDATE || pG->action == FRESHEN) pG->doall = 1; r = 0; arg1 = - 1; g_before = pG->before; for (argno = 0; !r && argno < C->fTotFileSpecs; argno++) { char *fspec; FileData *fileArg = &C->fFDS[argno]; if (!fileArg) continue; fspec = fileArg->fFileSpec; if (!fspec || *fspec == '>') continue; pG->FileArg = fileArg; pG->key = 0; //pG->user_key; // set globals pG->recurse = fileArg->fRecurse; r = C->fLevel; r = r < 0 ? 0 : (r > 9 ? 9 : r); if (r != pG->level) { pG->level = r; pG->method = r ? DEFLATE : STORE; if (pG->verbose) Inform(pG, 0, IDIAG, "setting compression level to %d", r); } // Set the new RootDir if needed; DLL v1.608, Component v1.60L if (fileArg->fRootDir) { // We can't use SetCurrentDirectory() because there is only one cd // in each process // when a user uses threads it went wrong. FREE(pG->OrigCurrentDir); // DLL v1.6017 pG->OCDlength = lstrlen(fileArg->fRootDir); if ((pG->OrigCurrentDir = (char*)MALLOC(pG->OCDlength + 2)) == NULL) { // RP allow space for '\' Inform(pG, ZEN_MEM36, 0, "CurrentDir allocation error"); return ziperr(ZEN_MEM36, pG); } lstrcpy(pG->OrigCurrentDir, fileArg->fRootDir); if (pG->verbose) Inform(pG, 0, IERROR, "Root dir now %s", pG->OrigCurrentDir); } if (C->fVersion > 178) { if (fileArg->fLevel) { r = fileArg->fLevel; r = r < 0 ? 0 : (r > 9 ? 9 : r); if (r != pG->level) { pG->level = r; pG->method = r ? DEFLATE : STORE; if (pG->verbose) Inform(pG, 0, IDIAG, "setting compression level to %d", r); } } if (fileArg->fFromDate) pG->before = fileArg->fFromDate == (unsigned) - 1 ? 0 : fileArg ->fFromDate; else pG->before = g_before; } #ifdef USE_STRM_INPUT if (arg1 < 0) { arg1 = argno; if (pG->UseInStream) { // Here we fill in the FoundList from the input stream data // newname (fileio.c) adds to found list. If error m!=0 on return if ((r = newname(fspec, pG->InStreamSize, pG)) != ZEN_OK) { if (pG->verbose) Inform(pG, 0, IDIAG, "Stream filename could not be added in newname call"); if (pG->zcount) FREE(pG->zsort); return r; } break; } } #endif #ifdef CRYPT if (fileArg->fEncrypt) { pG->key = fileArg->fPassword; if (!pG->key || !*(pG->key)) { // use global if ((r = GetUserPW(pG)) != ZEN_OK) break; pG->key = pG->user_key; } // pG->doesEncrypt = 1; // 1.73 } #endif pG->doall = 0; // do selected if ((pG->action == ADD) || (pG->action == UPDATE)) { if (pG->verbose) Inform(pG, 0, IDIAG, "collecting %s %s", fspec, pG->recurse ? "recurse" : " "); r = Wild(fspec, pG); } else // Freshen or Delete - must be internal file { if (pG->verbose) Inform(pG, 0, IDIAG, "collecting %s %s", fspec, pG->recurse ? "recurse" : " "); r = procname(fspec, pG->recurse, pG); } if (r != ZEN_OK) { if ((int)(char)(r &0xFF) == ZEN_MISS) { /* this occurs if new file wasn't found */ Inform(pG, r, IERROR, "File specification \"%s\" skipped", fspec); r = 0; } } if (r) return ziperr(r, pG); } return 0; }