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

📄 field.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * field.c - routines for dealing with fields and record parsing *//*  * Copyright (C) 1986, 1988, 1989, 1991, 1992 the Free Software Foundation, Inc. *  * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *  * GAWK is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * GAWK is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with GAWK; see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "awk.h"static int (*parse_field) P((int, char **, int, NODE *,			     Regexp *, void (*)(), NODE *));static void rebuild_record P((void));static int re_parse_field P((int, char **, int, NODE *,			     Regexp *, void (*)(), NODE *));static int def_parse_field P((int, char **, int, NODE *,			      Regexp *, void (*)(), NODE *));static int sc_parse_field P((int, char **, int, NODE *,			     Regexp *, void (*)(), NODE *));static int fw_parse_field P((int, char **, int, NODE *,			     Regexp *, void (*)(), NODE *));static void set_element P((int, char *, int, NODE *));static void grow_fields_arr P((int num));static void set_field P((int num, char *str, int len, NODE *dummy));static Regexp *FS_regexp = NULL;static char *parse_extent;	/* marks where to restart parse of record */static int parse_high_water=0;	/* field number that we have parsed so far */static int nf_high_water = 0;	/* size of fields_arr */static int resave_fs;static NODE *save_FS;		/* save current value of FS when line is read,				 * to be used in deferred parsing				 */NODE **fields_arr;		/* array of pointers to the field nodes */int field0_valid;		/* $(>0) has not been changed yet */int default_FS;static NODE **nodes;		/* permanent repository of field nodes */static int *FIELDWIDTHS = NULL;voidinit_fields(){	NODE *n;	emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields");	emalloc(nodes, NODE **, sizeof(NODE *), "init_fields");	getnode(n);	*n = *Nnull_string;	fields_arr[0] = nodes[0] = n;	parse_extent = fields_arr[0]->stptr;	save_FS = dupnode(FS_node->var_value);	field0_valid = 1;}static voidgrow_fields_arr(num)int num;{	register int t;	register NODE *n;	erealloc(fields_arr, NODE **, (num + 1) * sizeof(NODE *), "set_field");	erealloc(nodes, NODE **, (num+1) * sizeof(NODE *), "set_field");	for (t = nf_high_water+1; t <= num; t++) {		getnode(n);		*n = *Nnull_string;		fields_arr[t] = nodes[t] = n;	}	nf_high_water = num;}/*ARGSUSED*/static voidset_field(num, str, len, dummy)int num;char *str;int len;NODE *dummy;	/* not used -- just to make interface same as set_element */{	register NODE *n;	if (num > nf_high_water)		grow_fields_arr(num);	n = nodes[num];	n->stptr = str;	n->stlen = len;	n->flags = (PERM|STR|STRING|MAYBE_NUM);	fields_arr[num] = n;}/* Someone assigned a value to $(something).  Fix up $0 to be right */static voidrebuild_record(){	register int tlen;	register NODE *tmp;	NODE *ofs;	char *ops;	register char *cops;	register NODE **ptr;	register int ofslen;	tlen = 0;	ofs = force_string(OFS_node->var_value);	ofslen = ofs->stlen;	ptr = &fields_arr[NF];	while (ptr > &fields_arr[0]) {		tmp = force_string(*ptr);		tlen += tmp->stlen;		ptr--;	}	tlen += (NF - 1) * ofslen;	if (tlen < 0)	    tlen = 0;	emalloc(ops, char *, tlen + 2, "fix_fields");	cops = ops;	ops[0] = '\0';	for (ptr = &fields_arr[1]; ptr <= &fields_arr[NF]; ptr++) {		tmp = *ptr;		if (tmp->stlen == 1)			*cops++ = tmp->stptr[0];		else if (tmp->stlen != 0) {			memcpy(cops, tmp->stptr, tmp->stlen);			cops += tmp->stlen;		}		if (ptr != &fields_arr[NF]) {			if (ofslen == 1)				*cops++ = ofs->stptr[0];			else if (ofslen != 0) {				memcpy(cops, ofs->stptr, ofslen);				cops += ofslen;			}		}	}	tmp = make_str_node(ops, tlen, ALREADY_MALLOCED);	unref(fields_arr[0]);	fields_arr[0] = tmp;	field0_valid = 1;}/* * setup $0, but defer parsing rest of line until reference is made to $(>0) * or to NF.  At that point, parse only as much as necessary. */voidset_record(buf, cnt, freeold)char *buf;int cnt;int freeold;{	register int i;	NF = -1;	for (i = 1; i <= parse_high_water; i++) {		unref(fields_arr[i]);	}	parse_high_water = 0;	if (freeold) {		unref(fields_arr[0]);		if (resave_fs) {			resave_fs = 0;			unref(save_FS);			save_FS = dupnode(FS_node->var_value);		}		nodes[0]->stptr = buf;		nodes[0]->stlen = cnt;		nodes[0]->stref = 1;		nodes[0]->flags = (STRING|STR|PERM|MAYBE_NUM);		fields_arr[0] = nodes[0];	}	fields_arr[0]->flags |= MAYBE_NUM;	field0_valid = 1;}voidreset_record(){	(void) force_string(fields_arr[0]);	set_record(fields_arr[0]->stptr, fields_arr[0]->stlen, 0);}voidset_NF(){	register int i;	NF = (int) force_number(NF_node->var_value);	if (NF > nf_high_water)		grow_fields_arr(NF);	for (i = parse_high_water + 1; i <= NF; i++) {		unref(fields_arr[i]);		fields_arr[i] = Nnull_string;	}	field0_valid = 0;}/* * this is called both from get_field() and from do_split() * via (*parse_field)().  This variation is for when FS is a regular * expression -- either user-defined or because RS=="" and FS==" " */static intre_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 *field;	register char *end = scan + len;	if (up_to == HUGE)		nf = 0;	if (len == 0)		return nf;	if (*RS == 0 && default_FS)		while (scan < end && isspace(*scan))			scan++;	field = scan;	while (scan < end	       && research(rp, scan, 0, (int)(end - scan), 1) != -1	       && nf < up_to) {		if (REEND(rp, scan) == RESTART(rp, scan)) {	/* null match */			scan++;			if (scan == end) {				(*set)(++nf, field, scan - field, n);				up_to = nf;				break;			}			continue;		}		(*set)(++nf, field, scan + RESTART(rp, scan) - field, n);		scan += REEND(rp, scan);		field = scan;		if (scan == end)	/* FS at end of record */			(*set)(++nf, field, 0, n);	}	if (nf != up_to && scan < end) {		(*set)(++nf, scan, (int)(end - scan), n);		scan = end;	}	*buf = scan;	return (nf);}/* * this is called both from get_field() and from do_split() * via (*parse_field)().  This variation is for when FS is a single space * character. */static intdef_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 *field;	register char *end = scan + len;	char sav;	if (up_to == HUGE)		nf = 0;	if (len == 0)		return nf;	/* before doing anything save the char at *end */	sav = *end;	/* because it will be destroyed now: */	*end = ' ';	/* sentinel character */	for (; nf < up_to; scan++) {		/*		 * special case:  fs is single space, strip leading whitespace 		 */		while (scan < end && (*scan == ' ' || *scan == '\t'))			scan++;		if (scan >= end)			break;		field = scan;		while (*scan != ' ' && *scan != '\t')			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;

⌨️ 快捷键说明

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