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

📄 constantcode.c

📁 早期freebsd实现
💻 C
字号:
#ifndef lintstatic char RCSid[] = "$Header: constantcode.c,v 2.0 85/11/21 07:21:32 jqj Exp $";#endif/* $Log:	constantcode.c,v $ * Revision 2.0  85/11/21  07:21:32  jqj * 4.3BSD standard release *  * Revision 1.4  85/05/23  06:19:32  jqj * *** empty log message *** *  * Revision 1.4  85/05/23  06:19:32  jqj * Public Beta-test version, released 24 May 1985 *  * Revision 1.3  85/03/26  06:09:41  jqj * Revised public alpha-test version, released 26 March 1985 *  * Revision 1.2  85/03/11  16:38:56  jqj * Public alpha-test version, released 11 March 1985 *  * Revision 1.1  85/02/15  13:55:18  jqj * Initial revision *  *//* * Generate code for constant declarations. */#include "compiler.h"/* * Generate code for constant declarations */define_constant(name, typtr, value)	struct object *name;	struct type *typtr;	struct constant *value;{	char *fullname;	name->o_class = O_CONSTANT;	name->o_constant = value;	fullname = make_full_name( name->o_module,				name->o_modversion, name_of(name));	/*	 * Check for simple case of Foo: TypeBaz = Mumble;	 * where Mumble is another constant.  In this case,	 * just use the existing declaration	 */	if (value->cn_name != NULL) {		if (!recursive_flag) {			fprintf(header,"#define %s %s\n",				fullname, value->cn_name);			/* open scope */			fprintf(header1,"#define %s %s\n",				name_of(name), value->cn_name);		}		return;	}	/*	 * We have to generate some code for this one.  We'll generate	 * the declaration in the header file of a static variable	 * initialized to the appropriate values.	 */	value->cn_name = fullname;	if (recursive_flag)		return;		/* it's already been expanded elsewhere */	/* open scope */	fprintf(header1,"#define %s %s\n", name_of(name), fullname);	/* make sure the type is defined */	if (typename(typtr) == NULL) {		/* create an anonymous (not in symboltable) type and subtypes */		char * typenam;		typenam = gensym("T_cn");		code_type(typenam, typtr);		typename(typtr) = typenam;		}	/* depending on the type, generate appropriate initializer */	switch (typtr->type_constr) {	case C_PROCEDURE:		define_procedure_constant(name, typtr, value);		break;	case C_ERROR:		define_error_constant(name, typtr, value);		break;	case C_NUMERIC:	case C_BOOLEAN:	case C_STRING:	case C_ENUMERATION:		/* these are simple, since they can't include sequences */		fprintf(header, "\nstatic %s %s = {%s};\n",			typename(typtr), value->cn_name, value->cn_value);		break;	default:		/* the general case */		scan_for_sequences(typtr, value);	/* kludge */		fprintf(header, "\nstatic %s %s = ",				typename(typtr), value->cn_name);		code_constant(typtr, value);		fprintf(header,";\n");		break;	}	return;}/* * Generate client and server code for error constants */define_error_constant(symbol,typtr,value)	struct object *symbol;	struct type *typtr;	struct constant *value;{	char *errvalue;	if (recursive_flag)		return;		/* can't happen */	if (typtr->type_constr != C_ERROR)		error(FATAL, "internal error (define_error_constant): not an error");	if (value->cn_constr != C_NUMERIC) {		error(ERROR,"Values of ERRORs must be numeric");		errvalue = "-1";	}	else		errvalue = value->cn_value;	fprintf(header,"\n#define %s (ERROR_OFFSET+%s)\n\#define %sArgs %s\n",			value->cn_name, errvalue,			value->cn_name, typename(typtr));	fprintf(header1,"#define %sArgs %sArgs\n",			symbol->o_name, value->cn_name);	value->cn_constr = C_ERROR;	/* put this error in the constant's data structure */	/* also store this error on the global list */	if (typtr->type_list == NIL) {		value->cn_list = cons((list) errvalue, NIL);		Errors = cons( cons((list) value, NIL), Errors);	}	else {		value->cn_list = cons((list) errvalue, (list) typtr);		Errors = cons( cons((list) value, (list) typtr), Errors);	}}/* * recursively generate the code for a constant */code_constant(typtr, value)	struct type *typtr;	struct constant *value;{	switch (typtr->type_constr) {	case C_NUMERIC:	case C_BOOLEAN:	case C_STRING:	case C_ENUMERATION:		if (value == (struct constant*) 0)		  fprintf(header, "0");		else		  fprintf(header, "%s", value->cn_value);		break;	case C_ARRAY:		code_array_constant(typtr,value);		break;	case C_SEQUENCE:		code_sequence_constant(typtr,value);		break;	case C_RECORD:		code_record_constant(typtr,value);		break;	case C_CHOICE:		code_choice_constant(typtr,value);		break;	case C_ERROR:		error(ERROR,"Error constants may not be part of a structure");		break;	case C_PROCEDURE:		error(ERROR,"Procedures may not be part of a structure");	}}/* * Given the name of a record field and a record constant, return * the corresponding component of the record constant. */static struct constant *findcomponent(name,recvalue)	char *name;	struct constant *recvalue;{	list p;	if (recvalue->cn_constr != C_RECORD)		error(FATAL,"internal error (findcomponent): constant is of type %d",			recvalue->cn_constr);	for (p = recvalue->cn_list; p != NIL; p = cdr(p))		if (streq((char *) caar(p), name))			return((struct constant *) cdar(p));	return((struct constant *) 0);}/* * kludge since PCC doesn't like initializations of the form *   struct {int length; Seqtype *sequence} seq = {3,{1,2,3}}; * instead, use: *   Seqtype anonymous[3] = {1,2,3}; *   struct {int length; Seqtype *sequence} seq = {3,anonymous}; * We have to generate the sequence value before we walk the constant. */scan_for_sequences(typtr, value)	struct type *typtr;	struct constant *value;{	list p;	switch (typtr->type_constr) {	case C_ARRAY:		for (p = value->cn_list; p != NIL; p = cdr(p))			scan_for_sequences(typtr->type_basetype, 					   (struct constant *) car(p));		break;	case C_RECORD:		scan_record_for_sequences(typtr, value);		break;	case C_CHOICE:		scan_choice_for_sequences(typtr, value);		break;	case C_SEQUENCE:		for (p = value->cn_list; p != NIL; p = cdr(p))			scan_for_sequences(typtr->type_basetype, 					   (struct constant *) car(p));		value->cn_seqvalname = gensym("S_v");		fprintf(header,"\nstatic %s %s[%d] = {\n\t",			typename(typtr->type_basetype), value->cn_seqvalname,			length(value->cn_list));		for (p = value->cn_list ; p != NIL ; p = cdr(p)) {			code_constant(typtr->type_basetype,				      (struct constant *) car(p));			if (cdr(p) != NIL)				fprintf(header,",\n\t");		}		fprintf(header,"\n};\n");		break;	default:	/* other types don't have embedded sequences */		break;	}}scan_record_for_sequences(typtr, value)	struct type *typtr;	struct constant *value;{	list p, q;	struct constant *component;	for (p = typtr->type_list; p != NIL; p = cdr(p)) {		q = car(p);		component = findcomponent((char *) caar(q),value);		if (component != (struct constant *) 0)			scan_for_sequences((struct type *) cdr(q), component);	}}/*ARGSUSED*/scan_choice_for_sequences(typtr, value)	struct type *typtr;	struct constant *value;{	/* constants of type CHOICE are not implemented */}code_array_constant(typtr, value)	struct type *typtr;	struct constant *value;{	list p;	int i;	if (value == (struct constant *) 0) {		fprintf(header,"{0");		for (i = 1; i < typtr->type_size; i++)		  fprintf(header,",0");		fprintf(header,"}");		return;	}	if (typtr->type_size != length(value->cn_list))		error(WARNING,"wrong number of constant elements specified for array");	fprintf(header,"\n\t{");	for (p = value->cn_list; p != NIL; p = cdr(p)) {		code_constant(typtr->type_basetype,(struct constant *) car(p));		if (cdr(p) != NIL)			fprintf(header,",");	}	fprintf(header,"}");}code_choice_constant(typtr, value)	struct type *typtr;	struct constant *value;{	list p,q;	struct type *bt;	char *desigval;	struct object *name;	if (value == (struct constant *)0)	  desigval = "?";	/* caar(typtr->type_designator->type_list); */	else	  desigval = (char *) car(value->cn_list);	fprintf(header,"\n\t{ %s", desigval);	/* find the corresponding arm of the choice */	bt = TNIL;	for (p = typtr->type_candidates; bt==TNIL && p!=NIL; p = cdr(p)) {		for (q = caar(p); bt==TNIL && q!=NIL; q = cdr(q)) {			name = (struct object *) caar(q);			if (streq(name->o_enum->en_name,desigval))				bt = (struct type *) cdar(p);		}	}	if (bt == TNIL)		error(WARNING,"CHOICE designator %s is invalid here",desigval);	else if (bt != NilRecord_type)		error(WARNING,"Constants of type CHOICE are not supported");	fprintf(header,"\n\t}");}code_sequence_constant(typtr, value)	struct type *typtr;	struct constant *value;{	list p;	int l;	if (value == (struct constant *)0 ||	    (p = value->cn_list) == NIL) {		fprintf(header,"{0, 0}");		return;	}	l = length(p);	if (typtr->type_size < l)		error(WARNING,"too many constant elements specified for sequence");	fprintf(header,"{%d, %s}",l,value->cn_seqvalname);}code_record_constant(typtr, value)	struct type *typtr;	struct constant *value;{	list p, q;	struct constant *component;	fprintf(header,"{");	for (p = typtr->type_list; p != NIL; p = cdr(p)) {		q = car(p);		if (value == (struct constant *) 0)		  component = value;		else		  component = findcomponent((char *) caar(q), value);		code_constant((struct type *) cdr(q), component);		if (cdr(p) != NIL)			fprintf(header,",");	}	fprintf(header,"\n\t}");}

⌨️ 快捷键说明

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