Ejemplo n.º 1
0
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);
	}
}
Ejemplo n.º 2
0
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));
    }
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
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");
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
      }
   }
}
Ejemplo n.º 7
0
/* ===========================================================================
 * 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;
}
Ejemplo n.º 8
0
/* ===========================================================================
 * 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;
}
Ejemplo n.º 9
0
/* =========================================================================== 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;
}