1: #ifndef lint 2: static char RCSid[] = "$Header: constantcode.c,v 2.0 85/11/21 07:21:32 jqj Exp $"; 3: #endif 4: 5: /* $Log: constantcode.c,v $ 6: * Revision 2.0 85/11/21 07:21:32 jqj 7: * 4.3BSD standard release 8: * 9: * Revision 1.4 85/05/23 06:19:32 jqj 10: * *** empty log message *** 11: * 12: * Revision 1.4 85/05/23 06:19:32 jqj 13: * Public Beta-test version, released 24 May 1985 14: * 15: * Revision 1.3 85/03/26 06:09:41 jqj 16: * Revised public alpha-test version, released 26 March 1985 17: * 18: * Revision 1.2 85/03/11 16:38:56 jqj 19: * Public alpha-test version, released 11 March 1985 20: * 21: * Revision 1.1 85/02/15 13:55:18 jqj 22: * Initial revision 23: * 24: */ 25: 26: /* 27: * Generate code for constant declarations. 28: */ 29: 30: #include "compiler.h" 31: 32: /* 33: * Generate code for constant declarations 34: */ 35: define_constant(name, typtr, value) 36: struct object *name; 37: struct type *typtr; 38: struct constant *value; 39: { 40: char *fullname; 41: 42: name->o_class = O_CONSTANT; 43: name->o_constant = value; 44: fullname = make_full_name( name->o_module, 45: name->o_modversion, name_of(name)); 46: /* 47: * Check for simple case of Foo: TypeBaz = Mumble; 48: * where Mumble is another constant. In this case, 49: * just use the existing declaration 50: */ 51: if (value->cn_name != NULL) { 52: if (!recursive_flag) { 53: fprintf(header,"#define %s %s\n", 54: fullname, value->cn_name); 55: /* open scope */ 56: fprintf(header1,"#define %s %s\n", 57: name_of(name), value->cn_name); 58: } 59: return; 60: } 61: /* 62: * We have to generate some code for this one. We'll generate 63: * the declaration in the header file of a static variable 64: * initialized to the appropriate values. 65: */ 66: value->cn_name = fullname; 67: if (recursive_flag) 68: return; /* it's already been expanded elsewhere */ 69: /* open scope */ 70: fprintf(header1,"#define %s %s\n", name_of(name), fullname); 71: /* make sure the type is defined */ 72: if (typename(typtr) == NULL) { 73: /* create an anonymous (not in symboltable) type and subtypes */ 74: char * typenam; 75: typenam = gensym("T_cn"); 76: code_type(typenam, typtr); 77: typename(typtr) = typenam; 78: } 79: /* depending on the type, generate appropriate initializer */ 80: switch (typtr->type_constr) { 81: case C_PROCEDURE: 82: define_procedure_constant(name, typtr, value); 83: break; 84: case C_ERROR: 85: define_error_constant(name, typtr, value); 86: break; 87: case C_NUMERIC: 88: case C_BOOLEAN: 89: case C_STRING: 90: case C_ENUMERATION: 91: /* these are simple, since they can't include sequences */ 92: fprintf(header, "\nstatic %s %s = {%s};\n", 93: typename(typtr), value->cn_name, value->cn_value); 94: break; 95: default: 96: /* the general case */ 97: scan_for_sequences(typtr, value); /* kludge */ 98: fprintf(header, "\nstatic %s %s = ", 99: typename(typtr), value->cn_name); 100: code_constant(typtr, value); 101: fprintf(header,";\n"); 102: break; 103: } 104: return; 105: } 106: 107: 108: /* 109: * Generate client and server code for error constants 110: */ 111: define_error_constant(symbol,typtr,value) 112: struct object *symbol; 113: struct type *typtr; 114: struct constant *value; 115: { 116: char *errvalue; 117: 118: if (recursive_flag) 119: return; /* can't happen */ 120: if (typtr->type_constr != C_ERROR) 121: error(FATAL, "internal error (define_error_constant): not an error"); 122: if (value->cn_constr != C_NUMERIC) { 123: error(ERROR,"Values of ERRORs must be numeric"); 124: errvalue = "-1"; 125: } 126: else 127: errvalue = value->cn_value; 128: fprintf(header,"\n#define %s (ERROR_OFFSET+%s)\n\ 129: #define %sArgs %s\n", 130: value->cn_name, errvalue, 131: value->cn_name, typename(typtr)); 132: fprintf(header1,"#define %sArgs %sArgs\n", 133: symbol->o_name, value->cn_name); 134: value->cn_constr = C_ERROR; 135: /* put this error in the constant's data structure */ 136: /* also store this error on the global list */ 137: if (typtr->type_list == NIL) { 138: value->cn_list = cons((list) errvalue, NIL); 139: Errors = cons( cons((list) value, NIL), Errors); 140: } 141: else { 142: value->cn_list = cons((list) errvalue, (list) typtr); 143: Errors = cons( cons((list) value, (list) typtr), Errors); 144: } 145: } 146: 147: /* 148: * recursively generate the code for a constant 149: */ 150: code_constant(typtr, value) 151: struct type *typtr; 152: struct constant *value; 153: { 154: switch (typtr->type_constr) { 155: case C_NUMERIC: 156: case C_BOOLEAN: 157: case C_STRING: 158: case C_ENUMERATION: 159: if (value == (struct constant*) 0) 160: fprintf(header, "0"); 161: else 162: fprintf(header, "%s", value->cn_value); 163: break; 164: case C_ARRAY: 165: code_array_constant(typtr,value); 166: break; 167: case C_SEQUENCE: 168: code_sequence_constant(typtr,value); 169: break; 170: case C_RECORD: 171: code_record_constant(typtr,value); 172: break; 173: case C_CHOICE: 174: code_choice_constant(typtr,value); 175: break; 176: case C_ERROR: 177: error(ERROR,"Error constants may not be part of a structure"); 178: break; 179: case C_PROCEDURE: 180: error(ERROR,"Procedures may not be part of a structure"); 181: } 182: } 183: 184: /* 185: * Given the name of a record field and a record constant, return 186: * the corresponding component of the record constant. 187: */ 188: static struct constant * 189: findcomponent(name,recvalue) 190: char *name; 191: struct constant *recvalue; 192: { 193: list p; 194: 195: if (recvalue->cn_constr != C_RECORD) 196: error(FATAL,"internal error (findcomponent): constant is of type %d", 197: recvalue->cn_constr); 198: for (p = recvalue->cn_list; p != NIL; p = cdr(p)) 199: if (streq((char *) caar(p), name)) 200: return((struct constant *) cdar(p)); 201: return((struct constant *) 0); 202: } 203: 204: 205: /* 206: * kludge since PCC doesn't like initializations of the form 207: * struct {int length; Seqtype *sequence} seq = {3,{1,2,3}}; 208: * instead, use: 209: * Seqtype anonymous[3] = {1,2,3}; 210: * struct {int length; Seqtype *sequence} seq = {3,anonymous}; 211: * We have to generate the sequence value before we walk the constant. 212: */ 213: scan_for_sequences(typtr, value) 214: struct type *typtr; 215: struct constant *value; 216: { 217: list p; 218: 219: switch (typtr->type_constr) { 220: case C_ARRAY: 221: for (p = value->cn_list; p != NIL; p = cdr(p)) 222: scan_for_sequences(typtr->type_basetype, 223: (struct constant *) car(p)); 224: break; 225: case C_RECORD: 226: scan_record_for_sequences(typtr, value); 227: break; 228: case C_CHOICE: 229: scan_choice_for_sequences(typtr, value); 230: break; 231: case C_SEQUENCE: 232: for (p = value->cn_list; p != NIL; p = cdr(p)) 233: scan_for_sequences(typtr->type_basetype, 234: (struct constant *) car(p)); 235: value->cn_seqvalname = gensym("S_v"); 236: fprintf(header,"\nstatic %s %s[%d] = {\n\t", 237: typename(typtr->type_basetype), value->cn_seqvalname, 238: length(value->cn_list)); 239: for (p = value->cn_list ; p != NIL ; p = cdr(p)) { 240: code_constant(typtr->type_basetype, 241: (struct constant *) car(p)); 242: if (cdr(p) != NIL) 243: fprintf(header,",\n\t"); 244: } 245: fprintf(header,"\n};\n"); 246: break; 247: default: /* other types don't have embedded sequences */ 248: break; 249: } 250: } 251: 252: scan_record_for_sequences(typtr, value) 253: struct type *typtr; 254: struct constant *value; 255: { 256: list p, q; 257: struct constant *component; 258: 259: for (p = typtr->type_list; p != NIL; p = cdr(p)) { 260: q = car(p); 261: component = findcomponent((char *) caar(q),value); 262: if (component != (struct constant *) 0) 263: scan_for_sequences((struct type *) cdr(q), component); 264: } 265: } 266: 267: /*ARGSUSED*/ 268: scan_choice_for_sequences(typtr, value) 269: struct type *typtr; 270: struct constant *value; 271: { 272: /* constants of type CHOICE are not implemented */ 273: } 274: 275: 276: code_array_constant(typtr, value) 277: struct type *typtr; 278: struct constant *value; 279: { 280: list p; 281: int i; 282: 283: if (value == (struct constant *) 0) { 284: fprintf(header,"{0"); 285: for (i = 1; i < typtr->type_size; i++) 286: fprintf(header,",0"); 287: fprintf(header,"}"); 288: return; 289: } 290: if (typtr->type_size != length(value->cn_list)) 291: error(WARNING,"wrong number of constant elements specified for array"); 292: fprintf(header,"\n\t{"); 293: for (p = value->cn_list; p != NIL; p = cdr(p)) { 294: code_constant(typtr->type_basetype,(struct constant *) car(p)); 295: if (cdr(p) != NIL) 296: fprintf(header,","); 297: } 298: fprintf(header,"}"); 299: } 300: 301: code_choice_constant(typtr, value) 302: struct type *typtr; 303: struct constant *value; 304: { 305: list p,q; 306: struct type *bt; 307: char *desigval; 308: struct object *name; 309: 310: if (value == (struct constant *)0) 311: desigval = "?"; /* caar(typtr->type_designator->type_list); */ 312: else 313: desigval = (char *) car(value->cn_list); 314: fprintf(header,"\n\t{ %s", desigval); 315: /* find the corresponding arm of the choice */ 316: bt = TNIL; 317: for (p = typtr->type_candidates; bt==TNIL && p!=NIL; p = cdr(p)) { 318: for (q = caar(p); bt==TNIL && q!=NIL; q = cdr(q)) { 319: name = (struct object *) caar(q); 320: if (streq(name->o_enum->en_name,desigval)) 321: bt = (struct type *) cdar(p); 322: } 323: } 324: if (bt == TNIL) 325: error(WARNING,"CHOICE designator %s is invalid here",desigval); 326: else if (bt != NilRecord_type) 327: error(WARNING,"Constants of type CHOICE are not supported"); 328: 329: fprintf(header,"\n\t}"); 330: } 331: 332: code_sequence_constant(typtr, value) 333: struct type *typtr; 334: struct constant *value; 335: { 336: list p; 337: int l; 338: 339: if (value == (struct constant *)0 || 340: (p = value->cn_list) == NIL) { 341: fprintf(header,"{0, 0}"); 342: return; 343: } 344: l = length(p); 345: if (typtr->type_size < l) 346: error(WARNING,"too many constant elements specified for sequence"); 347: fprintf(header,"{%d, %s}",l,value->cn_seqvalname); 348: } 349: 350: code_record_constant(typtr, value) 351: struct type *typtr; 352: struct constant *value; 353: { 354: list p, q; 355: struct constant *component; 356: 357: fprintf(header,"{"); 358: for (p = typtr->type_list; p != NIL; p = cdr(p)) { 359: q = car(p); 360: if (value == (struct constant *) 0) 361: component = value; 362: else 363: component = findcomponent((char *) caar(q), value); 364: code_constant((struct type *) cdr(q), component); 365: if (cdr(p) != NIL) 366: fprintf(header,","); 367: } 368: fprintf(header,"\n\t}"); 369: }