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

📄 array.c

📁 早期freebsd实现
💻 C
字号:
/* * array.c - routines for associative arrays. *//*  * 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 NODE *assoc_find P((NODE *symbol, NODE *subs, int hash1));NODE *concat_exp(tree)register NODE *tree;{	register NODE *r;	char *str;	char *s;	unsigned len;	int offset;	int subseplen;	char *subsep;	if (tree->type != Node_expression_list)		return force_string(tree_eval(tree));	r = force_string(tree_eval(tree->lnode));	if (tree->rnode == NULL)		return r;	subseplen = SUBSEP_node->lnode->stlen;	subsep = SUBSEP_node->lnode->stptr;	len = r->stlen + subseplen + 2;	emalloc(str, char *, len, "concat_exp");	memcpy(str, r->stptr, r->stlen+1);	s = str + r->stlen;	free_temp(r);	tree = tree->rnode;	while (tree) {		if (subseplen == 1)			*s++ = *subsep;		else {			memcpy(s, subsep, subseplen+1);			s += subseplen;		}		r = force_string(tree_eval(tree->lnode));		len += r->stlen + subseplen;		offset = s - str;		erealloc(str, char *, len, "concat_exp");		s = str + offset;		memcpy(s, r->stptr, r->stlen+1);		s += r->stlen;		free_temp(r);		tree = tree->rnode;	}	r = make_str_node(str, s - str, ALREADY_MALLOCED);	r->flags |= TEMP;	return r;}/* Flush all the values in symbol[] before doing a split() */voidassoc_clear(symbol)NODE *symbol;{	int i;	NODE *bucket, *next;	if (symbol->var_array == 0)		return;	for (i = 0; i < HASHSIZE; i++) {		for (bucket = symbol->var_array[i]; bucket; bucket = next) {			next = bucket->ahnext;			unref(bucket->ahname);			unref(bucket->ahvalue);			freenode(bucket);		}		symbol->var_array[i] = 0;	}}/* * calculate the hash function of the string in subs */unsigned inthash(s, len)register char *s;register int len;{	register unsigned long h = 0, g;	while (len--) {		h = (h << 4) + *s++;		g = (h & 0xf0000000);		if (g) {			h = h ^ (g >> 24);			h = h ^ g;		}	}	if (h < HASHSIZE)		return h;	else		return h%HASHSIZE;}/* * locate symbol[subs] */static NODE *				/* NULL if not found */assoc_find(symbol, subs, hash1)NODE *symbol;register NODE *subs;int hash1;{	register NODE *bucket, *prev = 0;	for (bucket = symbol->var_array[hash1]; bucket; bucket = bucket->ahnext) {		if (cmp_nodes(bucket->ahname, subs) == 0) {			if (prev) {	/* move found to front of chain */				prev->ahnext = bucket->ahnext;				bucket->ahnext = symbol->var_array[hash1];				symbol->var_array[hash1] = bucket;			}			return bucket;		} else			prev = bucket;	/* save previous list entry */	}	return NULL;}/* * test whether the array element symbol[subs] exists or not  */intin_array(symbol, subs)NODE *symbol, *subs;{	register int hash1;	if (symbol->type == Node_param_list)		symbol = stack_ptr[symbol->param_cnt];	if (symbol->var_array == 0)		return 0;	subs = concat_exp(subs);	/* concat_exp returns a string node */	hash1 = hash(subs->stptr, subs->stlen);	if (assoc_find(symbol, subs, hash1) == NULL) {		free_temp(subs);		return 0;	} else {		free_temp(subs);		return 1;	}}/* * SYMBOL is the address of the node (or other pointer) being dereferenced. * SUBS is a number or string used as the subscript.  * * Find SYMBOL[SUBS] in the assoc array.  Install it with value "" if it * isn't there. Returns a pointer ala get_lhs to where its value is stored  */NODE **assoc_lookup(symbol, subs)NODE *symbol, *subs;{	register int hash1;	register NODE *bucket;	(void) force_string(subs);	hash1 = hash(subs->stptr, subs->stlen);	if (symbol->var_array == 0) {	/* this table really should grow					 * dynamically */		unsigned size;		size = sizeof(NODE *) * HASHSIZE;		emalloc(symbol->var_array, NODE **, size, "assoc_lookup");		memset((char *)symbol->var_array, 0, size);		symbol->type = Node_var_array;	} else {		bucket = assoc_find(symbol, subs, hash1);		if (bucket != NULL) {			free_temp(subs);			return &(bucket->ahvalue);		}	}	/* It's not there, install it. */	if (do_lint && subs->stlen == 0)		warning("subscript of array `%s' is null string",			symbol->vname);	getnode(bucket);	bucket->type = Node_ahash;	if (subs->flags & TEMP)		bucket->ahname = dupnode(subs);	else {		unsigned int saveflags = subs->flags;		subs->flags &= ~MALLOC;		bucket->ahname = dupnode(subs);		subs->flags = saveflags;	}	free_temp(subs);	/* array subscripts are strings */	bucket->ahname->flags &= ~NUMBER;	bucket->ahname->flags |= STRING;	bucket->ahvalue = Nnull_string;	bucket->ahnext = symbol->var_array[hash1];	symbol->var_array[hash1] = bucket;	return &(bucket->ahvalue);}voiddo_delete(symbol, tree)NODE *symbol, *tree;{	register int hash1;	register NODE *bucket, *last;	NODE *subs;	if (symbol->type == Node_param_list)		symbol = stack_ptr[symbol->param_cnt];	if (symbol->var_array == 0)		return;	subs = concat_exp(tree);	/* concat_exp returns string node */	hash1 = hash(subs->stptr, subs->stlen);	last = NULL;	for (bucket = symbol->var_array[hash1]; bucket; last = bucket, bucket = bucket->ahnext)		if (cmp_nodes(bucket->ahname, subs) == 0)			break;	free_temp(subs);	if (bucket == NULL)		return;	if (last)		last->ahnext = bucket->ahnext;	else		symbol->var_array[hash1] = bucket->ahnext;	unref(bucket->ahname);	unref(bucket->ahvalue);	freenode(bucket);}voidassoc_scan(symbol, lookat)NODE *symbol;struct search *lookat;{	if (!symbol->var_array) {		lookat->retval = NULL;		return;	}	lookat->arr_ptr = symbol->var_array;	lookat->arr_end = lookat->arr_ptr + HASHSIZE;	/* added */	lookat->bucket = symbol->var_array[0];	assoc_next(lookat);}voidassoc_next(lookat)struct search *lookat;{	while (lookat->arr_ptr < lookat->arr_end) {		if (lookat->bucket != 0) {			lookat->retval = lookat->bucket->ahname;			lookat->bucket = lookat->bucket->ahnext;			return;		}		lookat->arr_ptr++;		if (lookat->arr_ptr < lookat->arr_end)			lookat->bucket = *(lookat->arr_ptr);		else			lookat->retval = NULL;	}	return;}

⌨️ 快捷键说明

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