/* $CASE/95s522/95solc/msrdanov/olc7/JPsim/include/olc3common.h */ /* This adds 94 lines according to diff with respect to */ /* $CASE/93su523/olc/base/src//olcarch/olc3common.h - RJL 031104 */ /* WARNING in olccommon.h: DO NOT USE GETCHILD, GETFIRST and GETNEXT h to access children of a class which declare TWO fkeys to that class, because the parent also has two pointers to this child; e.g. PI in f93olc.sch has two fkeys to CX: CXid1 and CXid2; Therefore CX will have two child pointers, PIid1_fcp and PIid2_fcp, instead of the default PIid_fcp,which does not exist. (The same problem MAY exist with the sets HN==>HL and ST==>TR (both HL and TR have 2 fkeys) and with other OLC macros which paste together a table abbrev, 'id' and a pointer tag (e.g. _pp or _fcp) instead of requiring the full fkey name in addition to table_abbrev as an argument. - RJL 94/12/6. */ #if !defined(OLC3COMMON_H) #define OLC3COMMON_H #include /* ** Only Standard compilers have const date types */ #if !defined __STDC__ #define const #endif /* ** Boolean definitions */ #define OFF 1 #define ON 2 #define CLOSED 1 #define OPEN 2 #define UNASSIGNED 1 #define ASSIGNED 2 #define IDLE 1 #define INUSE 2 #define STORAGE 1 #define COOKING 2 #define CANNING 3 #define INPATH 1 #define IN2PATHS 2 #define NOTTRANSFERRING 1 #define TRANSFERRING 2 #define COMPLETE 3 /* added by arun mulpur 12/18/93 */ char * BATCH_NAME; int BATCH_AIID; /* ** Macros for pasting things together and for making strings of things */ #define P(a,b) XP(a,b) #define S(x) XS(x) #if defined __DECC /* DEC C has a bug with paste */ #define P3(a,b,c) XP3(a,b,c) /* and this is the work around */ #define XP3(a,b,c) a##b##c #else #define P3(a,b,c) P(P(a,b),c) #endif #if defined __STDC__ #define XP(a,b) a##b #define XS(x) #x #else #define XP(a,b) a/**/b #define XS(x) "x" #endif /* ** Key buffers for chgen keys are of the following type */ #define KEYBUFFER(x) char x[HCG_KEY_SIZE+1] /* ** Since we have to work on both old obsolete compilers and ANSI compilers ** define some macros for prototypes and function definitions ** ** PROTOTYPE - declare a function prototype ** 1st macro argument is the return type and name ** 2nd macro argument is the parentizied argument list ** ** PROTOTYPE(int xyz, (char x, float y)) produces either ** ** int xyz(); - non standard C compiler ** int xyz(char x, float y) - standard C compiler ** ** FUNCTION - define a function which takes no arguments ** 1st and only macro argument is the return type and name ** ** FUNCTION(int xyz) produces either ** ** int xyz() - non standard C compiler ** int xyz(void) - standard C compiler ** ** FUNCTION1 - define a function which takes one argument ** FUNCTION - define a function which takes arguments ** 1st macro argument is the return type and name ** 2nd macro argument is type of 1st function argument ** 3rd macro argument is name of 1st function argument ** 4th macro argument is type of 2nd function argument ** 5th macro argument is name of 2rd function argument ** ... ** ** FUNCTION2(int xyz, char, x, float, y) produces either ** ** int xyz(x, y) - non standard C compiler ** char x; ** float y; ** int xyz(char x, float y) - standard C compiler ** */ #if __STDC__ || __DECC #define PROTOTYPE(return_type_and_name, args) return_type_and_name args; #else #define PROTOTYPE(return_type_and_name, args) return_type_and_name (); #endif #if __STDC__ || __DECC #define FUNCTION(return_type_and_name) \ return_type_and_name (void) #define FUNCTION1(return_type_and_name, p1t, p1) \ return_type_and_name (p1t p1) #define FUNCTION2(return_type_and_name, p1t, p1, p2t, p2) \ return_type_and_name (p1t p1, p2t p2) #define FUNCTION3(return_type_and_name, p1t, p1, p2t, p2, p3t, p3) \ return_type_and_name (p1t p1, p2t p2, p3t p3) #define FUNCTION4(return_type_and_name, p1t, p1, p2t, p2, p3t, p3, p4t, p4) \ return_type_and_name (p1t p1, p2t p2, p3t p3, p4t p4) #define FUNCTION5(return_type_and_name, p1t, p1, p2t, p2, p3t, p3, p4t, p4, \ p5t, p5)\ return_type_and_name (p1t p1, p2t p2, p3t p3, p4t p4, p5t p5) #define FUNCTION6(return_type_and_name, p1t, p1, p2t, p2, p3t, p3, p4t, p4, \ p5t, p5, p6t, p6) \ return_type_and_name (p1t p1, p2t p2, p3t p3, p4t p4, \ p5t p5, p6t p6) #define FUNCTION8(return_type_and_name, p1t, p1, p2t, p2, p3t, p3, p4t, p4, \ p5t, p5, p6t, p6, p7t, p7, p8t, p8) \ return_type_and_name (p1t p1, p2t p2, p3t p3, p4t p4, \ p5t p5, p6t p6, p7t p7, p8t p8) #else #define FUNCTION(return_type_and_name) \ return_type_and_name () #define FUNCTION1(return_type_and_name, p1t, p1) \ return_type_and_name (p1) \ p1t p1; #define FUNCTION2(return_type_and_name, p1t, p1, p2t, p2) \ return_type_and_name (p1, p2) \ p1t p1;\ p2t p2; #define FUNCTION3(return_type_and_name, p1t, p1, p2t, p2, p3t, p3) \ return_type_and_name (p1, p2, p3) \ p1t p1; \ p2t p2; \ p3t p3; #define FUNCTION4(return_type_and_name, p1t, p1, p2t, p2, p3t, p3, p4t, p4) \ return_type_and_name (p1, p2, p3, p4) \ p1t p1; \ p2t p2; \ p3t p3; \ p4t p4; #define FUNCTION5(return_type_and_name, p1t, p1, p2t, p2, p3t, p3, p4t, p4, \ p5t, p5) \ return_type_and_name (p1, p2, p3, p4, p5) \ p1t p1; \ p2t p2; \ p3t p3; \ p4t p4; \ p5t p5; #define FUNCTION6(return_type_and_name, p1t, p1, p2t, p2, p3t, p3, p4t, p4, \ p5t, p5, p6t, p6) \ return_type_and_name (p1, p2, p3, p4, p5, p6) \ p1t p1; \ p2t p2; \ p3t p3; \ p4t p4; \ p5t p5; \ p6t p6; #define FUNCTION8(return_type_and_name, p1t, p1, p2t, p2, p3t, p3, p4t, p4, \ p5t, p5, p6t, p6, p7t, p7, p8t, p8) \ return_type_and_name (p1, p2, p3, p4, p5, p6, p7, p8) \ p1t p1; \ p2t p2; \ p3t p3; \ p4t p4; \ p5t p5; \ p6t p6; \ p7t p7; \ p8t p8; #endif /* ** The examples below refer to the following schema ** ** ActiveInstance AI ** { ** AIid ActiveInstanceId c8 1 ** ACid ActiveInstanceInThisClass c8 1 ** State ActiveInstancesCurrentState t80 0 ** Name ActiveInstanceName t80 0 ** } ** ** EventInstance EI ** { ** EIid EventInstanceId c8 1 ** AIid1 EventInstanceGenerater c8 1 ** AIid2 EventInstanceReceiver c8 1 ** ETid EventInstancesType c8 1 ** Int1 EventInstanceDataInt1 i4 0 ** Int2 EventInstanceDataInt2 i4 0 ** Flt1 EventInstanceDataDbl1 f8 0 ** Flt2 EventInstanceDataDbl2 f8 0 ** Text EventInstanceDataText t80 0 ** } ** */ /* ** The SETROUTINE macro generates a routine to set a field in an object. ** The macro takes five arguments. ** ** field_type - the type of the field ** object_name - the name of the object containing the field ** object_abbrev - the object's abbreviation ** field - the field whose value you wish ** value_type - the type of the argument to the Set routine ** ** Usually, field_type and value_type will be the same. However, it ** may be that there is a need to do type casting. For example, ** chgen can't handle pointers and there is a need to store pointers in ** the chgen created structures. Thus, a need for a set routine that ** takes pointers and stores them in int fields ** ** When using this macro, there must be no spaces after the object_name ** or before the field argument. ** With old-style token pasting the space gets passed on resulting ** in Get/_*_*_/ State not Get/_*_*_/State. ** (Ignore the _, they are there to avoid nested comments.) ** ** SETROUTINE(int,EventInstance,EI,Int1,int) produces ** ** FUNCTION2( ** void EventInstanceSetInt1, ** hcg_key, EIid, ** int, value ** ) ** { ** pr_find(EI, EIid, EIid); ** EIcurr->Int1 = (int)value; ** } ** */ #define SETROUTINE(field_type, object_name, object_abbrev, field, value_type) \ FUNCTION2( \ void P3(object_name,Set,field), \ hcg_key, P(object_abbrev,id), \ value_type, value \ ) \ { \ pr_find(object_abbrev, P(object_abbrev,id), P(object_abbrev,id)); \ P(object_abbrev,curr)->field = (field_type)value; \ } /* ** The GETROUTINE macro generates a routine to get the value of a field ** in an object. The macro takes four arguments. ** ** return_type - the return type of the generated function ** object_name - the name of the object containing the field ** object_abbrev - the object's abbreviation ** field - the field whose value you wish ** ** When using this macro, there must be no spaces after the before the field ** argument. With old style token pasting the space gets pass on resulting ** in Get/_*_*_/ State not Get/_*_*_/State (ignore the _, they are there to ** avoid nested comments ** ** GETROUTINE(const char *,ActiveInstance,AI,State) produces ** ** FUNCTION1( ** const char * ActiveInstanceGetState, ** hcg_key, AIid ** ) ** { ** pr_find(AI, AIid, AIid); ** if (AIcurr == 0) { ** return (const char *)0; ** } else { ** return (const char *)(AIcurr->State); ** } ** } ** */ #define GETROUTINE(return_type, object_name, object_abbrev, field) \ FUNCTION1( \ return_type P3(object_name,Get,field), \ hcg_key, P(object_abbrev,id) \ ) \ { \ pr_find(object_abbrev, P(object_abbrev,id), P(object_abbrev,id)); \ if (P(object_abbrev,curr) == 0) { \ return (return_type)0; \ } else { \ return (return_type)(P(object_abbrev,curr)->field); \ } \ } /* ** The COPYROUTINE macro generates a routine to copy a char * field into ** a user supplied destination, much like strcpy. The caller is responsible ** for ensuring that there is enough space in the destination to receive all ** the characters in the object's field. The macro takes three arguments. ** ** object_name - the name of the object containing the field ** object_abbrev - the object's abbreviation ** field - the field you wish to copy ** ** When using this macro, there must be no spaces after the before the field ** argument. With old style token pasting the space gets pass on resulting ** in Get/_*_*_/ State not Get/_*_*_/State (ignore the _, they are there to ** avoid nested comments ** ** COPYROUTINE(ActiveInstance,AI,Name) ** ** FUNCTION2( ** void ActiveInstanceCopyName, ** hcg_key, AIid, ** char *, CopyDst ** ) ** { ** const char *CopySrc; ** CopySrc = ActiveInstanceGetName(AIid); ** if (CopySrc != 0) { ** (void)strcpy(CopyDst, CopySrc); ** } else { ** (void)strcpy(CopyDst, ""); ** } ** } ** */ #define COPYROUTINE(object_name, object_abbrev, field) \ FUNCTION2( \ void P3(object_name,Copy,field), \ hcg_key, P(object_abbrev,id), \ char *, CopyDst \ ) \ { \ const char *CopySrc; \ CopySrc = P3(object_name,Get,field)(P(object_abbrev,id)); \ if (CopySrc != 0) { \ (void)strcpy(CopyDst, CopySrc); \ } else { \ (void)strcpy(CopyDst, ""); \ } \ } /* ** All objects need a delete routine and most need the ObjectFirst ** and ObjectNext routines. Since these macros have the same signature ** the STANDARDROUTINES macro defines all three of these routines. */ #define STANDARDROUTINES(object_name, object_abbrev) \ DELETEROUTINE(object_name, object_abbrev) \ GETFIRST(object_name, object_abbrev) \ GETNEXT(object_name, object_abbrev) /* ** The DELETEROUTINE macro generates a routine which deletes an instance ** of an object. The macro has two arguments ** ** object_name - the name of the object containing ** object_abbrev - the object's abbreviation ** ** DELETEROUTINE(ActiveInstance, AI) produces ** ** FUNCTION1( ** void ActiveInstanceDelete, ** hcg_key, ActiveInstanceId ** ) ** { ** pr_find(AI, AIid, AIid); ** ** if (AIcurr == 0) { ** (void)printf("Could not find %s with key %x, nothing delete.\n", ** "ActiveInstance", ** AIid); ** } else { ** pr_delete(AI); ** } ** } */ #define DELETEROUTINE(object_name, object_abbrev) \ FUNCTION1( \ void P(object_name,Delete), \ hcg_key, P(object_abbrev,id) \ ) \ { \ pr_find(object_abbrev, P(object_abbrev,id), P(object_abbrev,id)); \ \ if (P(object_abbrev,curr) == 0) { \ (void)printf("Could not find %s with key %x, nothing deleted.\n",\ S(object_name), \ P(object_abbrev,id)); \ } else { \ pr_delete(object_abbrev); \ } \ } /* ** The GETFIRST macro generates a routine which returns the first ** the element in the object table. The macro has two arguments ** ** object_name - the name of the object containing ** object_abbrev - the object's abbreviation ** ** The GETNEXT macro generates a routine which returns the element in ** on object table immediately following a specified object. ** ** GETFIRST(ActiveInstance,AI) produces ** ** FUNCTION( ** hcg_key ActiveInstanceFirst ** ) ** { ** table_loop("JuicePlant", AI) { ** return AIcurr->AIid; ** } ** return (hcg_key)0; ** } ** ** GETNEXT(ActiveInstance,AI) produces ** ** FUNCTION1( ** hcg_key ActiveInstanceNext, ** hcg_key, AIid ** ) ** { ** pr_find(AI, AIid, AIid); ** if (AIcurr != 0) { ** AIcurr = AIcurr->next_ptr ** } ** ** if (AIcurr == 0) { ** return (hcg_key)0; ** } else { ** return AIcurr->AIid; ** } ** } */ #define GETFIRST(object_name, object_abbrev) \ FUNCTION( \ hcg_key P(object_name,First) \ ) \ { \ table_loop("JuicePlant", object_abbrev) { \ return P(object_abbrev,curr)->P(object_abbrev,id); \ } \ return (hcg_key)0; \ } \ #define GETCHILD(object_name, object_abbrev,child_name,child_abbrev) \ FUNCTION1( \ hcg_key P3(object_name,Child,child_name), \ hcg_key, P(object_abbrev,id) \ ) \ { \ pr_find(object_abbrev, P(object_abbrev,id), P(object_abbrev,id)); \ \ if (P(object_abbrev,curr) != 0) { \ P(child_abbrev,curr) = P(object_abbrev,curr)->P(child_abbrev,id_fcp);\ } \ \ if (P(child_abbrev,curr) == 0) { \ return (hcg_key)0; \ } else { \ return P(child_abbrev,curr)->P(child_abbrev,id); \ } \ } #define GETNEXT(object_name, object_abbrev) \ FUNCTION1( \ hcg_key P(object_name,Next), \ hcg_key, P(object_abbrev,id) \ ) \ { \ pr_find(object_abbrev, P(object_abbrev,id), P(object_abbrev,id)); \ \ if (P(object_abbrev,curr) != 0) { \ P(object_abbrev,curr) = P(object_abbrev,curr)->next_ptr; \ } \ \ if (P(object_abbrev,curr) == 0) { \ return (hcg_key)0; \ } else { \ return P(object_abbrev,curr)->P(object_abbrev,id); \ } \ } #endif