⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 field.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* * this is called both from get_field() and from do_split() * via (*parse_field)().  This variation is for when FS is a single character * other than space. */static intsc_parse_field(up_to, buf, len, fs, rp, set, n)int up_to;	/* parse only up to this field number */char **buf;	/* on input: string to parse; on output: point to start next */int len;NODE *fs;Regexp *rp;void (*set) ();	/* routine to set the value of the parsed field */NODE *n;{	register char *scan = *buf;	register char fschar;	register int nf = parse_high_water;	register char *field;	register char *end = scan + len;	char sav;	if (up_to == HUGE)		nf = 0;	if (len == 0)		return nf;	if (*RS == 0 && fs->stlen == 0)		fschar = '\n';	else		fschar = fs->stptr[0];	/* before doing anything save the char at *end */	sav = *end;	/* because it will be destroyed now: */	*end = fschar;	/* sentinel character */	for (; nf < up_to; scan++) {		field = scan;		while (*scan++ != fschar)			;		scan--;		(*set)(++nf, field, (int)(scan - field), n);		if (scan == end)			break;	}	/* everything done, restore original char at *end */	*end = sav;	*buf = scan;	return nf;}/* * this is called both from get_field() and from do_split() * via (*parse_field)().  This variation is for fields are fixed widths. */static intfw_parse_field(up_to, buf, len, fs, rp, set, n)int up_to;	/* parse only up to this field number */char **buf;	/* on input: string to parse; on output: point to start next */int len;NODE *fs;Regexp *rp;void (*set) ();	/* routine to set the value of the parsed field */NODE *n;{	register char *scan = *buf;	register int nf = parse_high_water;	register char *end = scan + len;	if (up_to == HUGE)		nf = 0;	if (len == 0)		return nf;	for (; nf < up_to && (len = FIELDWIDTHS[nf+1]) != -1; ) {		if (len > end - scan)			len = end - scan;		(*set)(++nf, scan, len, n);		scan += len;	}	if (len == -1)		*buf = end;	else		*buf = scan;	return nf;}NODE **get_field(requested, assign)register int requested;Func_ptr *assign;	/* this field is on the LHS of an assign */{	/*	 * if requesting whole line but some other field has been altered,	 * then the whole line must be rebuilt	 */	if (requested == 0) {		if (!field0_valid) {			/* first, parse remainder of input record */			if (NF == -1) {				NF = (*parse_field)(HUGE-1, &parse_extent,		    			fields_arr[0]->stlen -					(parse_extent - fields_arr[0]->stptr),		    			save_FS, FS_regexp, set_field,					(NODE *)NULL);				parse_high_water = NF;			}			rebuild_record();		}		if (assign)			*assign = reset_record;		return &fields_arr[0];	}	/* assert(requested > 0); */	if (assign)		field0_valid = 0;		/* $0 needs reconstruction */	if (requested <= parse_high_water)	/* already parsed this field */		return &fields_arr[requested];	if (NF == -1) {	/* have not yet parsed to end of record */		/*		 * parse up to requested fields, calling set_field() for each,		 * saving in parse_extent the point where the parse left off		 */		if (parse_high_water == 0)	/* starting at the beginning */			parse_extent = fields_arr[0]->stptr;		parse_high_water = (*parse_field)(requested, &parse_extent,		     fields_arr[0]->stlen - (parse_extent-fields_arr[0]->stptr),		     save_FS, FS_regexp, set_field, (NODE *)NULL);		/*		 * if we reached the end of the record, set NF to the number of 		 * fields so far.  Note that requested might actually refer to		 * a field that is beyond the end of the record, but we won't		 * set NF to that value at this point, since this is only a		 * reference to the field and NF only gets set if the field		 * is assigned to -- this case is handled below		 */		if (parse_extent == fields_arr[0]->stptr + fields_arr[0]->stlen)			NF = parse_high_water;		if (requested == HUGE-1)	/* HUGE-1 means set NF */			requested = parse_high_water;	}	if (parse_high_water < requested) { /* requested beyond end of record */		if (assign) {	/* expand record */			register int i;			if (requested > nf_high_water)				grow_fields_arr(requested);			/* fill in fields that don't exist */			for (i = parse_high_water + 1; i <= requested; i++)				fields_arr[i] = Nnull_string;			NF = requested;			parse_high_water = requested;		} else			return &Nnull_string;	}	return &fields_arr[requested];}static voidset_element(num, s, len, n)int num;char *s;int len;NODE *n;{	register NODE *it;	it = make_string(s, len);	it->flags |= MAYBE_NUM;	*assoc_lookup(n, tmp_number((AWKNUM) (num))) = it;}NODE *do_split(tree)NODE *tree;{	NODE *t1, *t2, *t3, *tmp;	NODE *fs;	char *s;	int (*parseit)P((int, char **, int, NODE *,			 Regexp *, void (*)(), NODE *));	Regexp *rp = NULL;	t1 = tree_eval(tree->lnode);	t2 = tree->rnode->lnode;	t3 = tree->rnode->rnode->lnode;	(void) force_string(t1);	if (t2->type == Node_param_list)		t2 = stack_ptr[t2->param_cnt];	if (t2->type != Node_var && t2->type != Node_var_array)		fatal("second argument of split is not a variable");	assoc_clear(t2);	if (t3->re_flags & FS_DFLT) {		parseit = parse_field;		fs = force_string(FS_node->var_value);		rp = FS_regexp;	} else {		tmp = force_string(tree_eval(t3->re_exp));		if (tmp->stlen == 1) {			if (tmp->stptr[0] == ' ')				parseit = def_parse_field;			else				parseit = sc_parse_field;		} else {			parseit = re_parse_field;			rp = re_update(t3);		}		fs = tmp;	}	s = t1->stptr;	tmp = tmp_number((AWKNUM) (*parseit)(HUGE, &s, (int)t1->stlen,					     fs, rp, set_element, t2));	free_temp(t1);	free_temp(t3);	return tmp;}voidset_FS(){	NODE *tmp = NULL;	char buf[10];	NODE *fs;	buf[0] = '\0';	default_FS = 0;	if (FS_regexp) {		refree(FS_regexp);		FS_regexp = NULL;	}	fs = force_string(FS_node->var_value);	if (fs->stlen > 1)		parse_field = re_parse_field;	else if (*RS == 0) {		parse_field = sc_parse_field;		if (fs->stlen == 1) {			if (fs->stptr[0] == ' ') {				default_FS = 1;				strcpy(buf, "[ \t\n]+");			} else if (fs->stptr[0] != '\n')				sprintf(buf, "[%c\n]", fs->stptr[0]);		}	} else {		parse_field = def_parse_field;		if (fs->stptr[0] == ' ' && fs->stlen == 1)			default_FS = 1;		else if (fs->stptr[0] != ' ' && fs->stlen == 1) {			if (IGNORECASE == 0)				parse_field = sc_parse_field;			else				sprintf(buf, "[%c]", fs->stptr[0]);		}	}	if (buf[0]) {		FS_regexp = make_regexp(buf, strlen(buf), IGNORECASE, 1);		parse_field = re_parse_field;	} else if (parse_field == re_parse_field) {		FS_regexp = make_regexp(fs->stptr, fs->stlen, IGNORECASE, 1);	} else		FS_regexp = NULL;	resave_fs = 1;}voidset_RS(){	(void) force_string(RS_node->var_value);	RS = RS_node->var_value->stptr;	set_FS();}voidset_FIELDWIDTHS(){	register char *scan;	char *end;	register int i;	static int fw_alloc = 1;	static int warned = 0;	extern double strtod();	if (do_lint && ! warned) {		warned = 1;		warning("use of FIELDWIDTHS is a gawk extension");	}	if (do_unix)	/* quick and dirty, does the trick */		return;	parse_field = fw_parse_field;	scan = force_string(FIELDWIDTHS_node->var_value)->stptr;	end = scan + 1;	if (FIELDWIDTHS == NULL)		emalloc(FIELDWIDTHS, int *, fw_alloc * sizeof(int), "set_FIELDWIDTHS");	FIELDWIDTHS[0] = 0;	for (i = 1; ; i++) {		if (i >= fw_alloc) {			fw_alloc *= 2;			erealloc(FIELDWIDTHS, int *, fw_alloc * sizeof(int), "set_FIELDWIDTHS");		}		FIELDWIDTHS[i] = (int) strtod(scan, &end);		if (end == scan)			break;		scan = end;	}	FIELDWIDTHS[i] = -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -