diff --git a/calc/calc.h b/calc/calc.h index 27cd5eb..8a19d87 100644 --- a/calc/calc.h +++ b/calc/calc.h @@ -279,6 +279,7 @@ typedef struct packedvar_s { unsigned pv_cond; /* if VT_COND */ pSym *pv_sym; /* if VT_DSYM */ struct user_type *pv_usertype; /* if VT_USER */ + char *pv_prototype; /* if VT_PROCNAME: C prototype string */ dim_t pv_dimu; /* if VT_ARRAY|VECTOR|MATRIX */ struct packedvar_s *pv_next; /* next allocated packedvar */ } packedvar_t; diff --git a/calc/decl.c b/calc/decl.c index cb5f4ff..a366692 100644 --- a/calc/decl.c +++ b/calc/decl.c @@ -150,7 +150,7 @@ The following type declarations may be specified. VT_REAL is the default base VT_INTEGER, name VT_REAL, name VT_TYPENAME, typename, name -VT_PROCNAME, name, +VT_PROCNAME, name, prototype VT_INTEGER|VT_ARRAY, name {,dimension} ... , 0 int array, VT_BYREF implied VT_ARRAY, name {,dimension} ... , 0 real array, VT_BYREF implied These array types take array dimensions as strings rather than numbers: @@ -220,7 +220,7 @@ packvar(unsigned vtype, ...) pvar = (packedvar_t *)malloc(sizeof(packedvar_t)); pvar->pv_flags = vtype; - pvar->pv_name = pvar->pv_typename = NULL; + pvar->pv_name = pvar->pv_typename = pvar->pv_prototype = NULL; pvar->pv_cond = 0; pvar->pv_sym = NULL; pvar->pv_usertype = NULL; @@ -246,6 +246,9 @@ packvar(unsigned vtype, ...) pvar->pv_name = va_arg(argptr, char *); + if ((vtype & VT_BASETYPE) == VT_PROCNAME) + pvar->pv_prototype = va_arg(argptr, char *); + if (vtype & VT_ARRAY) { uintptr_t *dimp = pvar->pv_dimu.ut_dim; while (*dimp++ = va_arg(argptr, unsigned)); @@ -314,6 +317,15 @@ VARNAME(va_list *argptr, : va_arg(*argptr, char*); } +static char* +VARPROTOTYPE(va_list *argptr, + unsigned decl_flags, + packedvar_t *pvar) +{ + return decl_flags & DECL_PACKED ? pvar->pv_prototype + : va_arg(*argptr, char*); +} + static char* VARTYPENAME(va_list *argptr, unsigned decl_flags, @@ -546,7 +558,7 @@ DECL_NOPRINT with this flag, we define the user type but produce no VT_INTEGER, name VT_REAL, name -VT_PROCNAME, name +VT_PROCNAME, name, prototype VT_INTEGER|VT_ARRAY, name {,dimension} ... , 0 int array, VT_BYREF implied VT_ARRAY, name {,dimension} ... , 0 real array, VT_BYREF implied VT_INTEGER|VT_SARRAY, name {,dimension} ... , NULL int array, VT_BYREF implied @@ -590,6 +602,8 @@ declare_type(FILE *F, unsigned decl_flags, ...) continue; } user_type->name = va_arg(argptr, char *); + if ((user_type->type & VT_BASETYPE) == VT_PROCNAME) + (void) va_arg(argptr, char *); /* past prototype */ get_dims(user_type->type, &user_type->dimu, &argptr, PVNULL, 0); user_type->type |= VT_ISUSER; } @@ -652,7 +666,9 @@ do_declare_vars1(FILE *F, static unsigned last_vtype; static int skip, first_name; static char *vname; + static char *last_prototype; static dim_t dimu; + char *prototype; uintptr_t *dimp; char **sdimp; struct user_type *user_type; @@ -751,6 +767,14 @@ do_declare_vars1(FILE *F, } vname = VARNAME(&*argptr, decl_flags, pvar); + prototype = NULL; + if ((vtype & VT_BASETYPE) == VT_PROCNAME) { + prototype = VARPROTOTYPE(&*argptr, decl_flags, pvar); + last_prototype = prototype; + } else if ((vtype & VT_BASETYPE) == VT_DUP && + (last_vtype & VT_BASETYPE) == VT_PROCNAME) { + prototype = last_prototype; + } if ((decl_flags & DECL_NUMSUFFIX) && vname) { esprintf(tmpvname, "%@s%@d", vname, num_suffix); vname = tmpvname; @@ -814,7 +838,8 @@ do_declare_vars1(FILE *F, } else { if ((Lang->flags & LANG_C_FAMILY) && (vtype & VT_BASETYPE) == VT_PROCNAME) - efprintf(F, "(*%s)()", vname); + efprintf(F, "(*%s)(%s)", vname, + prototype ? prototype : ""); else efprintf(F, "%s%s", vtype & VT_BYREF ? Lang->deref : "", vname); @@ -948,6 +973,8 @@ do_declare_vars2(FILE *F, first_name = 1; } vname = VARNAME(&*argptr, decl_flags, pvar); + if ((next_vtype & VT_BASETYPE) == VT_PROCNAME) + (void) VARPROTOTYPE(&*argptr, decl_flags, pvar); if (decl_flags & DECL_NUMSUFFIX && vname) { esprintf(tmpvname, "%@s%@d", vname, num_suffix); vname = tmpvname; @@ -1130,6 +1157,9 @@ skip_decl(unsigned vtype, name = va_arg(*argptr, char *); + if ((vtype & VT_BASETYPE) == VT_PROCNAME) + (void) va_arg(*argptr, char *); /* past prototype */ + if (vtype & VT_ARRAY) while (va_arg(*argptr, unsigned)); /* past dimensions */ else if (vtype & VT_SARRAY) diff --git a/sdfast_main/main.c b/sdfast_main/main.c index 48047bf..f7bda5c 100644 --- a/sdfast_main/main.c +++ b/sdfast_main/main.c @@ -561,7 +561,7 @@ if you try to steal one.\n"); #if defined(_WIN32) && !defined(APPLIED_MOTION) int am_debug; -EX2UI_heartbeat(void) +void EX2UI_heartbeat(void) { } #endif diff --git a/sdfast_main/sdinteg.c b/sdfast_main/sdinteg.c index 82d7448..37a58b1 100644 --- a/sdfast_main/sdinteg.c +++ b/sdfast_main/sdinteg.c @@ -113,6 +113,8 @@ void PRINT_SDINTEG(FILE *F) { char str_flt0[10], lowlmt[10]; + char integ_func_proto[128]; + esprintf(integ_func_proto, "%t, %t[], %t[], %t[], int*"); esprintf(str_flt0, "%r", 0.); esprintf(lowlmt, "%@d", 0); @@ -141,7 +143,8 @@ void PRINT_SDINTEG(FILE *F) */ declare_proc(F, DECL_PACKED, "rk4m", - packvar(VT_PROCNAME, "func"), + packvar(VT_PROCNAME, "func", + integ_func_proto), packvar(VT_REAL, "time"), packvar(VT_SARRAY, "st", "neq", NULL), packvar(VT_DUP, "dst0"), @@ -238,7 +241,7 @@ void PRINT_SDINTEG(FILE *F) A fixed-step integrator. Work should be dimensioned 4*neq.%}\n"); declare_proc(F, 0, "finteg", - VT_PROCNAME, "func", + VT_PROCNAME, "func", integ_func_proto, VT_REAL|VT_BYREF, "time", VT_SARRAY, "st", "neq", NULL, VT_DUP, "dst", @@ -300,7 +303,8 @@ A fixed-step integrator. Work should be dimensioned 4*neq.%}\n"); A variable-step integrator. Work should be dimensioned 6*neq.%}"); declare_proc(F, DECL_PACKED, "vinteg", - packvar(VT_PROCNAME, "func"), + packvar(VT_PROCNAME, "func", + integ_func_proto), packvar(VT_REAL|VT_BYREF, "time"), packvar(VT_SARRAY, "st", "neqin", NULL), packvar(VT_DUP, "dst"), diff --git a/sdfast_main/sdroot.c b/sdfast_main/sdroot.c index 24fecb7..73abfc2 100644 --- a/sdfast_main/sdroot.c +++ b/sdfast_main/sdroot.c @@ -160,6 +160,8 @@ void PRINT_SDROOT(FILE *F) char lowlmt[10],str_flt0[10]; char uplmtntrys[15]; char numtrys[15],maxfixits[15]; + char root_func_proto[128]; + esprintf(root_func_proto, "%t[], %t[], %t[]"); esprintf(lowlmt, "%@d", 0); esprintf(str_flt0, "%r", 0.); @@ -242,7 +244,8 @@ void PRINT_SDROOT(FILE *F) * the direction of movement is preserved. */ declare_proc(F, DECL_PACKED, "adjvars", - packvar(VT_PROCNAME, "func"), + packvar(VT_PROCNAME, "func", + root_func_proto), packvar(VT_SARRAY, "vars", "nvar", NULL), packvar(VT_SARRAY, "param", Lang->unknown_len, NULL), packvar(VT_INTEGER, "nfunc"), @@ -374,7 +377,8 @@ void PRINT_SDROOT(FILE *F) * by the number of evaluations of f() performed here. */ declare_proc(F, DECL_PACKED, "calcjac", - packvar(VT_PROCNAME, "func"), + packvar(VT_PROCNAME, "func", + root_func_proto), packvar(VT_SARRAY, "vars", "nvar", NULL), packvar(VT_SARRAY, "param", Lang->unknown_len, NULL), packvar(VT_INTEGER, "nfunc"), @@ -509,7 +513,8 @@ Work arrays should be dimensioned as follows:\n\ ====================================================================\n%}"); declare_proc(F, DECL_PACKED, "root", - packvar(VT_PROCNAME, "func"), + packvar(VT_PROCNAME, "func", + root_func_proto), packvar(VT_SARRAY, "vars", "nvar", NULL), packvar(VT_SARRAY, "param", Lang->unknown_len, NULL), packvar(VT_INTEGER, "nfunc"),