Exemple #1
0
void lvzwr_fini(zshow_out *out, int t)
{
	int4		size;
	mval 		local;
	mname_entry	temp_key;
	ht_ent_mname	*tabent;
	mident_fixed	m;

	zwr_output = out;
	assert(lvzwrite_block);
	if (zwr_patrn_mident == lvzwrite_block->zwr_intype)
	{	/* Mident specified for "pattern" (fixed name, no pattern) */
		size = (lvzwrite_block->pat->str.len <= MAX_MIDENT_LEN) ? lvzwrite_block->pat->str.len : MAX_MIDENT_LEN;
		temp_key.var_name = lvzwrite_block->pat->str;
		COMPUTE_HASH_MNAME(&temp_key);
		tabent = lookup_hashtab_mname(&curr_symval->h_symtab, &temp_key);
		if (!tabent || !LV_IS_VAL_DEFINED(tabent->value) && !LV_HAS_CHILD(tabent->value))
		{
			lvzwrite_block->subsc_count = 0;
			rts_error(VARLSTCNT(4) ERR_UNDEF, 2, size, lvzwrite_block->pat->str.addr);
		} else
		{
			lvzwrite_block->curr_name = &tabent->key.var_name;
			lvzwr_var(((lv_val *)tabent->value), 0);
		}
	} else
	{	/* mval specified for character "pattern" (pattern matching) */
		assert(zwr_patrn_mval == lvzwrite_block->zwr_intype);
		memset(m.c, 0, SIZEOF(m.c));
		local.mvtype = MV_STR;
		local.str.addr = &m.c[0];
		local.str.len = 1;
		m.c[0] = '%';	/* Starting variable name for search (first possible varname) */

		lvzwrite_block->fixed = FALSE;
		while (local.str.len)
		{
			if (do_pattern(&local, lvzwrite_block->pat))
			{
				memset(&m.c[local.str.len], 0, SIZEOF(m.c) - local.str.len);
				temp_key.var_name = local.str;
				COMPUTE_HASH_MNAME(&temp_key);
				if (NULL != (tabent = lookup_hashtab_mname(&curr_symval->h_symtab, &temp_key)))
				{
					lvzwrite_block->curr_name = &tabent->key.var_name;
					lvzwr_var(((lv_val *)tabent->value), 0);
				}
			}
			op_fnlvname(&local, TRUE, &local);
			assert(local.str.len <= MAX_MIDENT_LEN);
			memcpy(&m.c[0], local.str.addr, local.str.len);
			local.str.addr = &m.c[0];
		}
	}
	lvzwrite_block->curr_subsc = lvzwrite_block->subsc_count = 0;
	return;
}
Exemple #2
0
void bx_boollit_tail(triple *t, boolean_t jmp_type_one, boolean_t jmp_to_next, boolean_t sense, oprtype *addr)
/* search the Boolean in t (recursively) for literal leaves; the logic is similar to bx_tail
 * the rest of the arguments parallel those in bx_boolop and used primarily handling basic Boolean operations (ON, NOR, AND, NAND)
 * to get the jump target and sense right for the left-hand operand of the operation
 * jmp_type_one gives the sense of the jump associated with the first operand
 * jmp_to_next gives whether we need a second jump to complete the operation
 * sense gives the sense of the requested operation
 * *addr points the operand for the jump and is eventually used by logic back in the invocation stack to fill in a target location
 */
{
	boolean_t	sin[ARRAYSIZE(t->operand)], tv[ARRAYSIZE(t->operand)];
	int		com, comval, dummy, j, neg, num, tvr;
	mval		*mv, *v[ARRAYSIZE(t->operand)];
	opctype		c;
	oprtype		*i, *p;
	triple		*cob[ARRAYSIZE(t->operand)], *ref0, *tl[ARRAYSIZE(t->operand)];

	assert(OCT_BOOL & oc_tab[t->opcode].octype);
	assert(TRIP_REF == t->operand[0].oprclass);
	assert((OC_COBOOL != t->opcode) && (OC_COM != t->opcode) || (TRIP_REF == t->operand[1].oprclass));
	for (i = t->operand, j = 0; i < ARRAYTOP(t->operand); i++, j++)
	{	/* checkout an operand to see if we can simplify it */
		p = i;
		com = 0;
		for (tl[j] = i->oprval.tref; OCT_UNARY & oc_tab[(c = tl[j]->opcode)].octype; tl[j] = p->oprval.tref)
		{	/* find the real object of affection; WARNING assignment above */
			assert((TRIP_REF == tl[j]->operand[0].oprclass) && (NO_REF == tl[j]->operand[1].oprclass));
			com ^= (OC_COM == c);	/* if we make a recursive call below, COM matters, but NEG and FORCENUM don't */
			p = &tl[j]->operand[0];
		}
		if (OCT_ARITH & oc_tab[c].octype)
			ex_tail(p);								/* chained arithmetic */
		else if (OCT_BOOL & oc_tab[c].octype)
		{	/* recursively check an operand */
			sin[j] = sense;
			p = addr;
			if (!j && !(OCT_REL & oc_tab[t->opcode].octype))
			{	/* left hand operand of parent */
				sin[j] = jmp_type_one;
				if (jmp_to_next)
				{	/* left operands need extra attention to decide between jump next or to the end */
					p = (oprtype *)mcalloc(SIZEOF(oprtype));
					*p = put_tjmp(t);
				}
			}
			bx_boollit(tl[j], sin[j] ^ com, p);
		}
		if ((OC_JMPTRUE != tl[j]->opcode) && (OC_JMPFALSE != tl[j]->opcode) && (OC_LIT != tl[j]->opcode))
			return;									/* this operation doesn't qualify */
		com = comval = neg = num = 0;
		cob[j] = NULL;
		for (ref0 = i->oprval.tref; OCT_UNARY & oc_tab[(c = ref0->opcode)].octype; ref0 = ref0->operand[0].oprval.tref)
		{       /* we may be able to clean up this operand; WARNING assignment above */
			assert((TRIP_REF == ref0->operand[0].oprclass) && (NO_REF == ref0->operand[1].oprclass));
			num += (OC_FORCENUM == c);
			com += (OC_COM == c);
			if (!com)								/* "outside" com renders neg mute */
				neg ^= (OC_NEG == c);
			if (!comval && (NULL == cob[j]))
			{
				if (comval = (OC_COMVAL == c))					/* WARNING assignment */
				{
					if (ref0 != t->operand[j].oprval.tref)
						dqdel(t->operand[j].oprval.tref, exorder);
					t->operand[j].oprval.tref = tl[j];			/* need mval: no COBOOL needed */
				}
				else if (OC_COBOOL == c)
				{	/* the operand needs a COBOOL in case its operator remains unresolved */
					cob[j] = t->operand[j].oprval.tref;
					if (ref0 == cob[j])
						continue;					/* already where it belongs */
					cob[j]->opcode = OC_COBOOL;
					cob[j]->operand[0].oprval.tref = tl[j];
				} else if (ref0 == t->operand[j].oprval.tref)
					continue;
			}
			dqdel(ref0, exorder);
		}
		assert(ref0 == tl[j]);
		if (!comval && (NULL == cob[j]) && (tl[j] != t->operand[j].oprval.tref))
		{	/* left room for a COBOOL, but there's no need */
			dqdel(t->operand[j].oprval.tref, exorder);
			t->operand[j].oprval.tref = tl[j];
		}
		if ((OC_JMPTRUE == ref0->opcode) || (OC_JMPFALSE == ref0->opcode))
		{	/* switch to a literal representation of TRUE / FALSE */
			assert(INDR_REF == ref0->operand[0].oprclass);
			ref0->operand[1] = ref0->operand[0];					/* track info as we switch opcode */
			PUT_LITERAL_TRUTH((sin[j] ? OC_JMPFALSE : OC_JMPTRUE) == ref0->opcode, ref0);
			ref0->opcode = OC_LIT;
			com = 0;								/* already accounted for by sin */
		}
		assert((OC_LIT == ref0->opcode) && (MLIT_REF == ref0->operand[0].oprclass));
		v[j] = &ref0->operand[0].oprval.mlit->v;
		if (com)
		{       /* any complement reduces the literal value to [unsigned] 1 or 0 */
			unuse_literal(v[j]);
			tv[j] = (0 == v[j]->m[1]);
			assert(ref0 == tl[j]);
			PUT_LITERAL_TRUTH(tv[j], ref0);
			v[j] = &ref0->operand[0].oprval.mlit->v;
			num = 0;								/* any complement trumps num */
		}
		if (neg || num)
		{	/* get literal into uniform state */
			unuse_literal(v[j]);
			mv = (mval *)mcalloc(SIZEOF(mval));
			*mv = *v[j];
			if (neg)
			{
				if (MV_INT & mv->mvtype)
				{
					if (0 != mv->m[1])
						mv->m[1] = -mv->m[1];
					else
						mv->sgn = 0;
				} else if (MV_NM & mv->mvtype)
					mv->sgn = !mv->sgn;
			} else
				s2n(mv);
			n2s(mv);
			v[j] = mv;
			assert(ref0 == tl[j]);
			put_lit_s(v[j], ref0);
		}
	}
	assert(tl[0] != tl[1]);									/* start processing a live one */
	for (tvr = j, j = 0;  j < tvr; j++)
	{	/* both arguments are literals, so do the operation at compile time */
		if (NULL != cob[j])
			dqdel(cob[j], exorder);
		v[j] = &tl[j]->operand[0].oprval.mlit->v;
		tv[j] = (0 != v[j]->m[1]);
		unuse_literal(v[j]);
		tl[j]->opcode = OC_NOOP;
		tl[j]->operand[0].oprclass = NO_REF;
	}
	t->operand[1].oprclass = NO_REF;
	switch (c = t->opcode)									/* WARNING assignment */
	{	/* optimize the Boolean operations here */
		case OC_NAND:
		case OC_AND:
			tvr = (tv[0] && tv[1]);
			break;
		case OC_NOR:
		case OC_OR:
			tvr = (tv[0] || tv[1]);
			break;
		case OC_NCONTAIN:
		case OC_CONTAIN:
			tvr = 1;
			(void)matchc(v[1]->str.len, (unsigned char *)v[1]->str.addr, v[0]->str.len,
				(unsigned char *)v[0]->str.addr, &dummy, &tvr);
			tvr ^= 1;
			break;
		case OC_NEQU:
		case OC_EQU:
			tvr = is_equ(v[0], v[1]);
			break;
		case OC_NFOLLOW:
		case OC_FOLLOW:
			tvr = 0 < memvcmp(v[0]->str.addr, v[0]->str.len, v[1]->str.addr, v[1]->str.len);
			break;
		case OC_NGT:
		case OC_GT:
			tvr = 0 < numcmp(v[0], v[1]);
			break;
		case OC_NLT:
		case OC_LT:
			tvr = 0 > numcmp(v[0], v[1]);
			break;
		case OC_NPATTERN:
		case OC_PATTERN:
			tvr = !(*(uint4 *)v[1]->str.addr) ? do_pattern(v[0], v[1]) : do_patfixed(v[0], v[1]);
			break;
		case OC_NSORTS_AFTER:
		case OC_SORTS_AFTER:
			tvr = 0 < sorts_after(v[0], v[1]);
			break;
		default:
			assertpro(FALSE);
	}
	tvr ^= !sense;
	t->operand[0] = put_indr(addr);
	t->opcode = tvr ? OC_JMPFALSE : OC_JMPTRUE;
	return;
}
Exemple #3
0
void dir_srch (parse_blk *pfil)
{
	struct stat	statbuf;
	int		stat_res;
	lv_val		*dir1, *dir2, *tmp;
	mstr		tn;
	short		p2_len;
	char		filb[MAX_FBUFF + 1], patb[sizeof(ptstr)], *c, *lastd, *top, *p2, *c1, ch;
	mval		pat_mval, sub, compare;
	bool		wildname, seen_wd;
	struct dirent 	*dent;
	DIR		*dp;
	plength		*plen;
	int		closedir_res;

	op_kill(zsrch_dir1);
	op_kill(zsrch_dir2);

	if (!pfil->b_name)
		return;		/* nothing to search for */

	ESTABLISH(dir_ch);
	pat_mval.mvtype = MV_STR;
	pat_mval.str.addr = patb;	/* patb should be sizeof(ptstr.buff) but instead is sizeof(ptstr) since the C compiler
					 * complains about the former and the latter is just 4 bytes more */
	pat_mval.str.len = 0;
	sub.mvtype = MV_STR;
	sub.str.len = 0;
	compare.mvtype = MV_STR;
	compare.str.len = 0;
	wildname = (pfil->fnb & F_WILD_NAME) != 0;
	dir1 = zsrch_dir1;
	dir2 = zsrch_dir2;

	if (pfil->fnb & F_WILD_DIR)
	{
		seen_wd = FALSE;
		for (c = pfil->l_dir, lastd = c, top = c + pfil->b_dir; c < top;)
		{
			ch = *c++;
			if (ch == '/')	/* note the start of each directory segment */
			{
				if (seen_wd)
					break;
				lastd = c;
			}
			if (ch == '?' || ch == '*')
				seen_wd = TRUE;
		}
		assert(c <= top);
		sub.str.addr = pfil->l_dir;
		sub.str.len = lastd - sub.str.addr;
		tmp = op_putindx(VARLSTCNT(2) dir1, &sub);
		tmp->v.mvtype = MV_STR; tmp->v.str.len = 0;
		for(;;)
		{
			tn.addr = lastd;	/* wildcard segment */
			tn.len = c - lastd - 1;
			lastd = c;
			genpat(&tn, &pat_mval);
			seen_wd = FALSE;
			p2 = c - 1;
			for (; c < top;)
			{
				ch = *c++;
				if (ch == '/')	/* note the start of each directory segment */
				{
					if (seen_wd)
						break;
					lastd = c;
				}
				if (ch == '?' || ch == '*')
					seen_wd = TRUE;
			}
			p2_len = lastd - p2;	/* length of non-wild segment after wild section */
			for (;;)
			{
				pop_top(dir1, &sub);	/* get next item off the top */
				if (!sub.str.len)
					break;

				memcpy(filb, sub.str.addr, sub.str.len);
				filb[sub.str.len] = 0;
				sub.str.addr = filb;
				dp = OPENDIR(filb);
				if (!dp)
					continue;
				while(READDIR(dp, dent))
				{
					compare.str.addr = &dent->d_name[0];
					compare.str.len = strlen(&dent->d_name[0]);
					assert(compare.str.len);
					if (   dent->d_name[0] == '.'
					    && (compare.str.len == 1  ||  (compare.str.len == 2  &&  dent->d_name[1] == '.'))   )
					{
						continue;	/* don't want to read . and .. */
					}

					if (compare.str.len + sub.str.len + p2_len > MAX_FBUFF)
						continue;

					if (do_pattern(&compare, &pat_mval))
					{	/* got a hit */
						if (stringpool.free + compare.str.len + sub.str.len + p2_len + 1 > stringpool.top)
							stp_gcol(compare.str.len + sub.str.len + p2_len + 1);

						/* concatenate directory and name */
						c1 = (char *)stringpool.free;
						tn = sub.str;
						s2pool(&tn);
						tn = compare.str;
						s2pool(&tn);
						tn.addr = p2;
						tn.len = p2_len;
						s2pool(&tn);
						*stringpool.free++ = 0;
						compare.str.addr = c1;
						compare.str.len += sub.str.len + p2_len;
						STAT_FILE(compare.str.addr, &statbuf, stat_res);
						if (-1 == stat_res)
							continue;
						if (!(statbuf.st_mode & S_IFDIR))
							continue;
						/* put in results tree */
						tmp = op_putindx(VARLSTCNT(2) dir2, &compare);
						tmp->v.mvtype = MV_STR;
						tmp->v.str.len = 0;
					}
				}
				CLOSEDIR(dp, closedir_res);
			}
			tmp = dir1; dir1 = dir2; dir2 = tmp;
			if (c >= top)
				break;
		}
	} else
	{
		sub.str.addr = pfil->l_dir;
		sub.str.len = pfil->b_dir;
		tmp = op_putindx(VARLSTCNT(2) dir1, &sub);
		tmp->v.mvtype = MV_STR; tmp->v.str.len = 0;
	}

	if (wildname)
	{
		tn.addr = pfil->l_name;
		tn.len = pfil->b_name + pfil->b_ext;
		genpat(&tn, &pat_mval);
	}

	for (;;)
	{
		pop_top(dir1, &sub);	/* get next item off the top */
		if (!sub.str.len)
			break;

		if (wildname)
		{
			memcpy(filb, sub.str.addr, sub.str.len);
			filb[sub.str.len] = 0;
			sub.str.addr = filb;
			dp = OPENDIR(filb);
			if (!dp)
				continue;
			while(READDIR(dp, dent))
			{
				compare.str.addr = &dent->d_name[0];
				compare.str.len = strlen(&dent->d_name[0]);
				if (   dent->d_name[0] == '.'
				    && (compare.str.len == 1  ||  (compare.str.len == 2  &&  dent->d_name[1] == '.')))
				{
					continue;	/* don't want to read . and .. */
				}
				if (compare.str.len + sub.str.len > MAX_FBUFF)
					continue;

				if (do_pattern(&compare, &pat_mval))
				{	/* got a hit */
					if (stringpool.free + compare.str.len + sub.str.len > stringpool.top)
						stp_gcol(compare.str.len + sub.str.len);

					/* concatenate directory and name */
					c = (char *)stringpool.free;
					tn = sub.str;
					s2pool(&tn);
					tn = compare.str;
					s2pool(&tn);
					compare.str.addr = c;
					compare.str.len += sub.str.len;

					/* put in results tree */
					tmp = op_putindx(VARLSTCNT(2) ind_var, &compare);
					tmp->v.mvtype = MV_STR;
					tmp->v.str.len = 0;
					plen = (plength *)&tmp->v.m[1];
					plen->p.pblk.b_esl = compare.str.len;
					plen->p.pblk.b_dir = sub.str.len;
					for (c = &compare.str.addr[sub.str.len], c1 = top = &compare.str.addr[compare.str.len];
					     c < top;
					    )
					{
						if (*c++ != '.')
							break;
					}
					for (; c < top;)
					{
						if (*c++ == '.')
							c1 = c - 1;
					}
					plen->p.pblk.b_ext = top - c1;
					plen->p.pblk.b_name = plen->p.pblk.b_esl - plen->p.pblk.b_dir - plen->p.pblk.b_ext;
				}
			}
			CLOSEDIR(dp, closedir_res);
		} else
		{
			assert(pfil->fnb & F_WILD_DIR);
			compare.str.addr = pfil->l_name;
			compare.str.len = pfil->b_name + pfil->b_ext;

			if (compare.str.len + sub.str.len > MAX_FBUFF)
				continue;

			memcpy(filb, sub.str.addr, sub.str.len);
			filb[sub.str.len] = 0;
			sub.str.addr = filb;

			if (stringpool.free + compare.str.len + sub.str.len > stringpool.top)
				stp_gcol(compare.str.len + sub.str.len);

			/* concatenate directory and name */
			c1 = (char *)stringpool.free;
			tn = sub.str;
			s2pool(&tn);
			tn = compare.str;
			s2pool(&tn);
			compare.str.addr = c1;
			compare.str.len += sub.str.len;

			/* put in results tree */
			tmp = op_putindx(VARLSTCNT(2) ind_var, &compare);
			tmp->v.mvtype = MV_STR; tmp->v.str.len = 0;
			plen = (plength *)&tmp->v.m[1];
			plen->p.pblk.b_esl = compare.str.len;
			plen->p.pblk.b_dir = sub.str.len;
			plen->p.pblk.b_name = pfil->b_name;
			plen->p.pblk.b_ext = pfil->b_ext;
		}
	}
	op_kill(zsrch_dir1);
	op_kill(zsrch_dir2);
	REVERT;
}
void gvzwr_fini(zshow_out *out, int pat)
{
	char 		m[SIZEOF(mident_fixed)];
	mval 		local, data;
	gv_key		*old;
	gvnh_reg_t	*gvnh_reg;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	if (!gv_currkey)
		gvinit();
	ESTABLISH(gvzwrite_ch);
	zwr_output = out;
	assert(INVALID_GV_TARGET == reset_gv_target);
	reset_gv_target = gv_target;
	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
	gvzwrite_block->gd_reg = gv_cur_region;
	gvzwrite_block->old_targ = (unsigned char *)gv_target;
	old = (gv_key *)malloc(SIZEOF(gv_key) + gv_currkey->end);
	gvzwrite_block->old_key = (unsigned char *)old;
	memcpy(gvzwrite_block->old_key, gv_currkey, SIZEOF(gv_key) + gv_currkey->end);
	gvzwrite_block->gv_last_subsc_null = TREF(gv_last_subsc_null);
	gvzwrite_block->gv_some_subsc_null = TREF(gv_some_subsc_null);
	if (!pat)
	{
		local = *gvzwrite_block->pat;
		if (local.str.len)  /* New reference. Will get new gv_target.. */
		{
			gv_target = NULL;
			gv_currkey->base[0] = '\0';
			op_gvname(VARLSTCNT(1) &local);
 			op_gvdata(&data);
			if (!(MV_FORCE_INTD(&data)))
			{
				if (!undef_inhibit)
					sgnl_gvundef();
			} else
			{
				gvzwrite_block->fixed = (gvzwrite_block->fixed ? TRUE : FALSE);
				gvzwr_var(MV_FORCE_INTD(&data), 0);
			}
		} else	/* Old (naked) reference. Keep previous gv_target reference */
		{
			if (gv_currkey->prev == 0)
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_GVNAKED);
			gv_currkey->end = gv_currkey->prev;
			gv_currkey->base[gv_currkey->end] = 0;
			gv_currkey->prev = 0;
			/* If gvnh_reg corresponds to a spanning global, then determine
			 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
			 */
			gvnh_reg = TREF(gd_targ_gvnh_reg);	/* set by op_gvname in previous call */
			GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, gd_header, gv_currkey);
			op_gvdata(&data);
			if (!(MV_FORCE_INTD(&data)))
			{
				if (!undef_inhibit)
					sgnl_gvundef();
			} else
			{
				gvzwrite_block->fixed = (gvzwrite_block->fixed ? TRUE : FALSE);
				gvzwr_var((int4)MV_FORCE_INTD(&data), 0);
			}
		}
	} else
	{
		gv_target = NULL;
		gv_currkey->base[0] = '\0';
		local.mvtype = MV_STR;
		local.str.addr = &m[0];
		local.str.len = 1;
		m[0] = '%';

		gvzwrite_block->fixed = FALSE;
		for (; ;)
		{
			op_gvname(VARLSTCNT(1) &local);
			if (do_pattern(&local, gvzwrite_block->pat))
			{
				op_gvdata(&data);
				if ((MV_FORCE_INTD(&data)))
				{
					gvzwr_var((int4)MV_FORCE_INTD(&data), 0);
				}
			}
			op_gvorder(&local);
			if (local.str.len)
			{
				assert(local.str.len <= MAX_MIDENT_LEN + 1);
				local.str.addr++;
				local.str.len--;
				memcpy(&m[0], local.str.addr, local.str.len);
				local.str.addr = &m[0];
			} else
				break;
		}
	}
	gvzwrite_clnup();	/* this routine is called by gvzwrite_ch() too */
	REVERT;
	return;
}
Exemple #5
0
void gvzwr_fini(zshow_out *out, int pat)
{
	char 		m[sizeof(mident_fixed)];
	mval 		local, data;
	gv_key		*old;

	error_def(ERR_GVNAKED);

	if (!gv_currkey)
		gvinit();

	ESTABLISH(gvzwrite_ch);

	zwr_output = out;
	assert(INVALID_GV_TARGET == reset_gv_target);
	reset_gv_target = gv_target;
	DBG_CHECK_GVTARGET_CSADDRS_IN_SYNC;
	gvzwrite_block.gd_reg = gv_cur_region;
	gvzwrite_block.old_targ = (unsigned char *)gv_target;
	old = (gv_key *)malloc(sizeof(gv_key) + gv_currkey->end);
	gvzwrite_block.old_key = (unsigned char *)old;
	memcpy(gvzwrite_block.old_key, gv_currkey, sizeof(gv_key) + gv_currkey->end);
	gvzwrite_block.old_map = gd_map;
	gvzwrite_block.old_map_top = gd_map_top;
	if (!pat)
	{
		local = *gvzwrite_block.pat;
		if (local.str.len)  /* New reference. Will get new gv_target.. */
		{
			gv_target = NULL;
			gv_currkey->base[0] = '\0';
			op_gvname(VARLSTCNT(1) &local);
 			op_gvdata(&data);
			if (!(MV_FORCE_INTD(&data)))
				sgnl_gvundef();
			else
			{
				gvzwrite_block.fixed = (gvzwrite_block.fixed ? TRUE : FALSE);
				gvzwr_var(MV_FORCE_INTD(&data), 0);
			}
		} else               /* Old (naked) reference. Keep previous gv_target reference */
		{
			if (gv_currkey->prev == 0)
				rts_error(VARLSTCNT(1) ERR_GVNAKED);

			gv_currkey->end = gv_currkey->prev;
			gv_currkey->base[ gv_currkey->end ] = 0;
			gv_currkey->prev = 0;
			op_gvdata(&data);
			if (!(MV_FORCE_INTD(&data)))
				sgnl_gvundef();
			else
			{
				gvzwrite_block.fixed = (gvzwrite_block.fixed ? TRUE : FALSE);
				gvzwr_var((int4)MV_FORCE_INTD(&data), 0);
			}
		}
	} else
	{
		gv_target = NULL;
		gv_currkey->base[0] = '\0';
		local.mvtype = MV_STR;
		local.str.addr = &m[0];
		local.str.len = 1;
		m[0] = '%';

		gvzwrite_block.fixed = FALSE;
		for (; ;)
		{
			op_gvname(VARLSTCNT(1) &local);
			if (do_pattern(&local, gvzwrite_block.pat))
			{
				op_gvdata(&data);
				if ((MV_FORCE_INTD(&data)))
				{
					gvzwr_var((int4)MV_FORCE_INTD(&data), 0);
				}
			}
			op_gvorder(&local);
			if (local.str.len)
			{
				assert(local.str.len <= MAX_MIDENT_LEN + 1);
				local.str.addr++;
				local.str.len--;
				memcpy(&m[0], local.str.addr, local.str.len);
				local.str.addr = &m[0];
			} else
				break;
		}
	}
	gvzwrite_clnup();	/* this routine is called by gvzwrite_ch() too */
	REVERT;
	return;
}
Exemple #6
0
void dir_srch(parse_blk *pfil)
{
	struct stat	statbuf;
	int		stat_res;
	lv_val		*dir1, *dir2, *tmp;
	mstr		tn;
	short		p2_len;
	char		filb[MAX_FBUFF + 1], patb[SIZEOF(ptstr)], *c, *lastd, *top, *p2, *c1, ch;
	mval		pat_mval, sub, compare;
	boolean_t	wildname, seen_wd;
	struct dirent 	*dent;
	DIR		*dp;
	plength		*plen;
	int		closedir_res;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	op_kill(TREF(zsearch_dir1));
	op_kill(TREF(zsearch_dir2));
	if (!pfil->b_name)
		return;		/* nothing to search for */
	ESTABLISH(dir_ch);
	pat_mval.mvtype = MV_STR;
	pat_mval.str.addr = patb;	/* patb should be SIZEOF(ptstr.buff) but instead is SIZEOF(ptstr) since the C compiler
					 * complains about the former and the latter is just 4 bytes more */
	pat_mval.str.len = 0;
	sub.mvtype = MV_STR;
	sub.str.len = 0;
	compare.mvtype = MV_STR;
	compare.str.len = 0;
	wildname = (pfil->fnb & F_WILD_NAME) != 0;
	dir1 = TREF(zsearch_dir1);
	dir2 = TREF(zsearch_dir2);
	if (pfil->fnb & F_WILD_DIR)
	{
		seen_wd = FALSE;
		for (c = pfil->l_dir, lastd = c, top = c + pfil->b_dir; c < top;)
		{
			ch = *c++;
			if (ch == '/')	/* note the start of each directory segment */
			{
				if (seen_wd)
					break;
				lastd = c;
			}
			if (ch == '?' || ch == '*')
				seen_wd = TRUE;
		}
		assert(c <= top);
		sub.str.addr = pfil->l_dir;
		sub.str.len = INTCAST(lastd - sub.str.addr);
		tmp = op_putindx(VARLSTCNT(2) dir1, &sub);
		tmp->v.mvtype = MV_STR; tmp->v.str.len = 0;
		for (;;)
		{
			tn.addr = lastd;	/* wildcard segment */
			tn.len = INTCAST(c - lastd - 1);
			lastd = c;
			genpat(&tn, &pat_mval);
			seen_wd = FALSE;
			p2 = c - 1;
			for (; c < top;)
			{
				ch = *c++;
				if (ch == '/')	/* note the start of each directory segment */
				{
					if (seen_wd)
						break;
					lastd = c;
				}
				if (ch == '?' || ch == '*')
					seen_wd = TRUE;
			}
			p2_len = lastd - p2;	/* length of non-wild segment after wild section */
			for (;;)
			{
				pop_top(dir1, &sub);	/* get next item off the top */
				if (!sub.str.len)
					break;
				memcpy(filb, sub.str.addr, sub.str.len);
				filb[sub.str.len] = 0;
				sub.str.addr = filb;
				dp = OPENDIR(filb);
				if (!dp)
					continue;
				while (READDIR(dp, dent))
				{
					compare.str.addr = &dent->d_name[0];
					compare.str.len = STRLEN(&dent->d_name[0]);
					UNICODE_ONLY(
						if (gtm_utf8_mode)
							compare.mvtype &= ~MV_UTF_LEN;	/* to force "char_len" to be recomputed
											 * in do_pattern */
					)
					assert(compare.str.len);
					if (('.' == dent->d_name[0])
					    && ((1 == compare.str.len) || ((2 == compare.str.len) && ('.' == dent->d_name[1]))))
						continue;	/* don't want to read . and .. */
					if (compare.str.len + sub.str.len + p2_len > MAX_FBUFF)
						continue;
					if (do_pattern(&compare, &pat_mval))
					{	/* got a hit */
						ENSURE_STP_FREE_SPACE(compare.str.len + sub.str.len + p2_len + 1);
						/* concatenate directory and name */
						c1 = (char *)stringpool.free;
						tn = sub.str;
						s2pool(&tn);
						tn = compare.str;
						s2pool(&tn);
						tn.addr = p2;
						tn.len = p2_len;
						s2pool(&tn);
						*stringpool.free++ = 0;
						compare.str.addr = c1;
						compare.str.len += sub.str.len + p2_len;
						STAT_FILE(compare.str.addr, &statbuf, stat_res);
						if (-1 == stat_res)
							continue;
						if (!(statbuf.st_mode & S_IFDIR))
							continue;
						/* put in results tree */
						tmp = op_putindx(VARLSTCNT(2) dir2, &compare);
						tmp->v.mvtype = MV_STR;
						tmp->v.str.len = 0;
					}
				}
				CLOSEDIR(dp, closedir_res);
			}
			tmp = dir1; dir1 = dir2; dir2 = tmp;
			if (c >= top)
				break;
		}