home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume21
/
p2c
/
part28
< prev
next >
Wrap
Text File
|
1990-04-05
|
53KB
|
1,890 lines
Subject: v21i073: Pascal to C translator, Part28/32
Newsgroups: comp.sources.unix
Approved: rsalz@uunet.UU.NET
X-Checksum-Snefru: 1cb00360 91d85a32 6e2d46c8 954f3167
Submitted-by: Dave Gillespie <daveg@csvax.caltech.edu>
Posting-number: Volume 21, Issue 73
Archive-name: p2c/part28
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 28 (of 32)."
# Contents: src/decl.c.1
# Wrapped by rsalz@litchi.bbn.com on Mon Mar 26 14:29:51 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/decl.c.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/decl.c.1'\"
else
echo shar: Extracting \"'src/decl.c.1'\" \(49193 characters\)
sed "s/^X//" >'src/decl.c.1' <<'END_OF_FILE'
X/* "p2c", a Pascal to C translator.
X Copyright (C) 1989 David Gillespie.
X Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
X
XThis program is free software; you can redistribute it and/or modify
Xit under the terms of the GNU General Public License as published by
Xthe Free Software Foundation (any version).
X
XThis program is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
XGNU General Public License for more details.
X
XYou should have received a copy of the GNU General Public License
Xalong with this program; see the file COPYING. If not, write to
Xthe Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
X
X
X
X#define PROTO_DECL_C
X#include "trans.h"
X
X
X
X#define MAXIMPORTS 100
X
X
X
XStatic struct ptrdesc {
X struct ptrdesc *next;
X Symbol *sym;
X Type *tp;
X} *ptrbase;
X
XStatic struct ctxstack {
X struct ctxstack *next;
X Meaning *ctx, *ctxlast;
X struct tempvarlist *tempvars;
X int tempvarcount, importmark;
X} *ctxtop;
X
XStatic struct tempvarlist {
X struct tempvarlist *next;
X Meaning *tvar;
X int active;
X} *tempvars, *stmttempvars;
X
XStatic int tempvarcount;
X
XStatic int stringtypecachesize;
XStatic Type **stringtypecache;
X
XStatic Meaning *importlist[MAXIMPORTS];
XStatic int firstimport;
X
XStatic Type *tp_special_anyptr;
X
XStatic int wasaliased;
XStatic int deferallptrs;
XStatic int anydeferredptrs;
XStatic int silentalreadydef;
XStatic int nonloclabelcount;
X
XStatic Strlist *varstructdecllist;
X
X
X
X
XStatic Meaning *findstandardmeaning(kind, name)
Xenum meaningkind kind;
Xchar *name;
X{
X Meaning *mp;
X Symbol *sym;
X
X sym = findsymbol(fixpascalname(name));
X for (mp = sym->mbase; mp && mp->ctx != curctx; mp = mp->snext) ;
X if (mp) {
X if (mp->kind == kind)
X mp->refcount = 1;
X else
X mp = NULL;
X }
X return mp;
X}
X
X
XStatic Meaning *makestandardmeaning(kind, name)
Xenum meaningkind kind;
Xchar *name;
X{
X Meaning *mp;
X Symbol *sym;
X
X sym = findsymbol(fixpascalname(name));
X for (mp = sym->mbase; mp && mp->ctx != curctx; mp = mp->snext) ;
X if (!mp) {
X mp = addmeaning(sym, kind);
X strchange(&mp->name, stralloc(name));
X if (debug < 4)
X mp->dumped = partialdump; /* prevent irrelevant dumping */
X } else {
X mp->kind = kind;
X }
X mp->refcount = 1;
X return mp;
X}
X
X
XStatic Type *makestandardtype(kind, mp)
Xenum typekind kind;
XMeaning *mp;
X{
X Type *tp;
X
X tp = maketype(kind);
X tp->meaning = mp;
X if (mp)
X mp->type = tp;
X return tp;
X}
X
X
X
X
XStatic Stmt *nullspecialproc(mp)
XMeaning *mp;
X{
X warning(format_s("Procedure %s not yet supported [118]", mp->name));
X if (curtok == TOK_LPAR)
X skipparens();
X return NULL;
X}
X
XMeaning *makespecialproc(name, handler)
Xchar *name;
XStmt *(*handler)();
X{
X Meaning *mp;
X
X if (!handler)
X handler = nullspecialproc;
X mp = makestandardmeaning(MK_SPECIAL, name);
X mp->handler = (Expr *(*)())handler;
X return mp;
X}
X
X
X
XStatic Stmt *nullstandardproc(ex)
XExpr *ex;
X{
X warning(format_s("Procedure %s not yet supported [118]", ((Meaning *)ex->val.i)->name));
X return makestmt_call(ex);
X}
X
XMeaning *makestandardproc(name, handler)
Xchar *name;
XStmt *(*handler)();
X{
X Meaning *mp;
X
X if (!handler)
X handler = nullstandardproc;
X mp = findstandardmeaning(MK_FUNCTION, name);
X if (mp) {
X mp->handler = (Expr *(*)())handler;
X if (mp->isfunction) {
X warning(format_s("Procedure %s was declared as a function [119]", name));
X mp->isfunction = 0;
X }
X } else if (debug > 0)
X warning(format_s("Procedure %s was never declared [120]", name));
X return mp;
X}
X
X
X
XStatic Expr *nullspecialfunc(mp)
XMeaning *mp;
X{
X warning(format_s("Function %s not yet supported [121]", mp->name));
X if (curtok == TOK_LPAR)
X skipparens();
X return makeexpr_long(0);
X}
X
XMeaning *makespecialfunc(name, handler)
Xchar *name;
XExpr *(*handler)();
X{
X Meaning *mp;
X
X if (!handler)
X handler = nullspecialfunc;
X mp = makestandardmeaning(MK_SPECIAL, name);
X mp->isfunction = 1;
X mp->handler = handler;
X return mp;
X}
X
X
X
XStatic Expr *nullstandardfunc(ex)
XExpr *ex;
X{
X warning(format_s("Function %s not yet supported [121]", ((Meaning *)ex->val.i)->name));
X return ex;
X}
X
XMeaning *makestandardfunc(name, handler)
Xchar *name;
XExpr *(*handler)();
X{
X Meaning *mp;
X
X if (!handler)
X handler = nullstandardfunc;
X mp = findstandardmeaning(MK_FUNCTION, name);
X if (mp) {
X mp->handler = handler;
X if (!mp->isfunction) {
X warning(format_s("Function %s was declared as a procedure [122]", name));
X mp->isfunction = 1;
X }
X } else if (debug > 0)
X warning(format_s("Function %s was never declared [123]", name));
X return mp;
X}
X
X
X
X
XStatic Expr *nullspecialvar(mp)
XMeaning *mp;
X{
X warning(format_s("Variable %s not yet supported [124]", mp->name));
X if (curtok == TOK_LPAR || curtok == TOK_LBR)
X skipparens();
X return makeexpr_var(mp);
X}
X
XMeaning *makespecialvar(name, handler)
Xchar *name;
XExpr *(*handler)();
X{
X Meaning *mp;
X
X if (!handler)
X handler = nullspecialvar;
X mp = makestandardmeaning(MK_SPVAR, name);
X mp->handler = handler;
X return mp;
X}
X
X
X
X
X
Xvoid setup_decl()
X{
X Meaning *mp, *mp2, *mp_turbo_shortint;
X Symbol *sym;
X Type *tp;
X int i;
X
X numimports = 0;
X firstimport = 0;
X permimports = NULL;
X stringceiling = stringceiling | 1; /* round up to odd */
X stringtypecachesize = (stringceiling + 1) >> 1;
X stringtypecache = ALLOC(stringtypecachesize, Type *, misc);
X curctxlast = NULL;
X curctx = NULL; /* the meta-ctx has no parent ctx */
X curctx = nullctx = makestandardmeaning(MK_MODULE, "SYSTEM");
X strlist_add(&permimports, "SYSTEM")->value = (long)nullctx;
X ptrbase = NULL;
X tempvars = NULL;
X stmttempvars = NULL;
X tempvarcount = 0;
X deferallptrs = 0;
X silentalreadydef = 0;
X varstructdecllist = NULL;
X nonloclabelcount = -1;
X for (i = 0; i < stringtypecachesize; i++)
X stringtypecache[i] = NULL;
X
X tp_integer = makestandardtype(TK_INTEGER, makestandardmeaning(MK_TYPE,
X (integer16) ? "LONGINT" : "INTEGER"));
X tp_integer->smin = makeexpr_long(MININT); /* "long" */
X tp_integer->smax = makeexpr_long(MAXINT);
X
X if (sizeof_int >= 32) {
X tp_int = tp_integer; /* "int" */
X } else {
X tp_int = makestandardtype(TK_INTEGER,
X (integer16 > 1) ? makestandardmeaning(MK_TYPE, "INTEGER")
X : NULL);
X tp_int->smin = makeexpr_long(min_sshort);
X tp_int->smax = makeexpr_long(max_sshort);
X }
X mp = makestandardmeaning(MK_TYPE, "C_INT");
X mp->type = tp_int;
X if (!tp_int->meaning)
X tp_int->meaning = mp;
X
X mp_unsigned = makestandardmeaning(MK_TYPE, "UNSIGNED");
X tp_unsigned = makestandardtype(TK_INTEGER, mp_unsigned);
X tp_unsigned->smin = makeexpr_long(0); /* "unsigned long" */
X tp_unsigned->smax = makeexpr_long(MAXINT);
X
X if (sizeof_int >= 32) {
X tp_uint = tp_unsigned; /* "unsigned int" */
X mp_uint = mp_unsigned;
X } else {
X mp_uint = makestandardmeaning(MK_TYPE, "C_UINT");
X tp_uint = makestandardtype(TK_INTEGER, mp_uint);
X tp_uint->smin = makeexpr_long(0);
X tp_uint->smax = makeexpr_long(MAXINT);
X }
X
X tp_sint = makestandardtype(TK_INTEGER, NULL);
X tp_sint->smin = copyexpr(tp_int->smin); /* "signed int" */
X tp_sint->smax = copyexpr(tp_int->smax);
X
X tp_char = makestandardtype(TK_CHAR, makestandardmeaning(MK_TYPE, "CHAR"));
X if (unsignedchar == 0) {
X tp_char->smin = makeexpr_long(-128); /* "char" */
X tp_char->smax = makeexpr_long(127);
X } else {
X tp_char->smin = makeexpr_long(0);
X tp_char->smax = makeexpr_long(255);
X }
X
X tp_charptr = makestandardtype(TK_POINTER, NULL); /* "unsigned char *" */
X tp_charptr->basetype = tp_char;
X tp_char->pointertype = tp_charptr;
X
X mp_schar = makestandardmeaning(MK_TYPE, "SCHAR"); /* "signed char" */
X tp_schar = makestandardtype(TK_CHAR, mp_schar);
X tp_schar->smin = makeexpr_long(-128);
X tp_schar->smax = makeexpr_long(127);
X
X mp_uchar = makestandardmeaning(MK_TYPE, "UCHAR"); /* "unsigned char" */
X tp_uchar = makestandardtype(TK_CHAR, mp_uchar);
X tp_uchar->smin = makeexpr_long(0);
X tp_uchar->smax = makeexpr_long(255);
X
X tp_boolean = makestandardtype(TK_BOOLEAN, makestandardmeaning(MK_TYPE, "BOOLEAN"));
X tp_boolean->smin = makeexpr_long(0); /* "boolean" */
X tp_boolean->smax = makeexpr_long(1);
X
X sym = findsymbol("Boolean");
X sym->flags |= SSYNONYM;
X strlist_append(&sym->symbolnames, "===")->value = (long)tp_boolean->meaning->sym;
X
X tp_real = makestandardtype(TK_REAL, makestandardmeaning(MK_TYPE, "REAL"));
X /* "float" or "double" */
X mp = makestandardmeaning(MK_TYPE, "LONGREAL");
X if (doublereals)
X mp->type = tp_longreal = tp_real;
X else
X tp_longreal = makestandardtype(TK_REAL, mp);
X
X tp_void = makestandardtype(TK_VOID, NULL); /* "void" */
X
X mp = makestandardmeaning(MK_TYPE, "SINGLE");
X if (doublereals)
X makestandardtype(TK_REAL, mp);
X else
X mp->type = tp_real;
X makestandardmeaning(MK_TYPE, "SHORTREAL")->type = mp->type;
X mp = makestandardmeaning(MK_TYPE, "DOUBLE");
X mp->type = tp_longreal;
X mp = makestandardmeaning(MK_TYPE, "EXTENDED");
X mp->type = tp_longreal; /* good enough */
X mp = makestandardmeaning(MK_TYPE, "QUADRUPLE");
X mp->type = tp_longreal; /* good enough */
X
X tp_sshort = makestandardtype(TK_SUBR, makestandardmeaning(MK_TYPE,
X (integer16 == 1) ? "INTEGER" : "SWORD"));
X tp_sshort->basetype = tp_integer; /* "short" */
X tp_sshort->smin = makeexpr_long(min_sshort);
X tp_sshort->smax = makeexpr_long(max_sshort);
X
X if (integer16) {
X if (integer16 != 2) {
X mp = makestandardmeaning(MK_TYPE, "SWORD");
X mp->type = tp_sshort;
X }
X } else {
X mp = makestandardmeaning(MK_TYPE, "LONGINT");
X mp->type = tp_integer;
X }
X
X tp_ushort = makestandardtype(TK_SUBR, makestandardmeaning(MK_TYPE, modula2 ? "UWORD" : "WORD"));
X tp_ushort->basetype = tp_integer; /* "unsigned short" */
X tp_ushort->smin = makeexpr_long(0);
X tp_ushort->smax = makeexpr_long(max_ushort);
X
X mp = makestandardmeaning(MK_TYPE, "CARDINAL");
X mp->type = (integer16) ? tp_ushort : tp_unsigned;
X mp = makestandardmeaning(MK_TYPE, "LONGCARD");
X mp->type = tp_unsigned;
X
X if (modula2) {
X mp = makestandardmeaning(MK_TYPE, "WORD");
X mp->type = tp_integer;
X } else {
X makestandardmeaning(MK_TYPE, "UWORD")->type = tp_ushort;
X }
X
X tp_sbyte = makestandardtype(TK_SUBR, NULL); /* "signed char" */
X tp_sbyte->basetype = tp_integer;
X tp_sbyte->smin = makeexpr_long(min_schar);
X tp_sbyte->smax = makeexpr_long(max_schar);
X
X mp_turbo_shortint = (which_lang == LANG_TURBO) ? makestandardmeaning(MK_TYPE, "SHORTINT") : NULL;
X mp = makestandardmeaning(MK_TYPE, "SBYTE");
X if (needsignedbyte || signedchars == 1 || hassignedchar) {
X mp->type = tp_sbyte;
X if (mp_turbo_shortint)
X mp_turbo_shortint->type = tp_sbyte;
X tp_sbyte->meaning = mp_turbo_shortint ? mp_turbo_shortint : mp;
X } else {
X mp->type = tp_sshort;
X if (mp_turbo_shortint)
X mp_turbo_shortint->type = tp_sshort;
X }
X
X tp_ubyte = makestandardtype(TK_SUBR, makestandardmeaning(MK_TYPE, "BYTE"));
X tp_ubyte->basetype = tp_integer; /* "unsigned char" */
X tp_ubyte->smin = makeexpr_long(0);
X tp_ubyte->smax = makeexpr_long(max_uchar);
X
X if (signedchars == 1)
X tp_abyte = tp_sbyte; /* "char" */
X else if (signedchars == 0)
X tp_abyte = tp_ubyte;
X else {
X tp_abyte = makestandardtype(TK_SUBR, NULL);
X tp_abyte->basetype = tp_integer;
X tp_abyte->smin = makeexpr_long(0);
X tp_abyte->smax = makeexpr_long(max_schar);
X }
X
X mp = makestandardmeaning(MK_TYPE, "POINTER");
X mp2 = makestandardmeaning(MK_TYPE, "ANYPTR");
X tp_anyptr = makestandardtype(TK_POINTER, (which_lang == LANG_HP) ? mp2 : mp);
X ((which_lang == LANG_HP) ? mp : mp2)->type = tp_anyptr;
X tp_anyptr->basetype = tp_void; /* "void *" */
X tp_void->pointertype = tp_anyptr;
X
X if (useAnyptrMacros == 1) {
X tp_special_anyptr = makestandardtype(TK_SUBR, NULL);
X tp_special_anyptr->basetype = tp_integer;
X tp_special_anyptr->smin = makeexpr_long(0);
X tp_special_anyptr->smax = makeexpr_long(max_schar);
X } else
X tp_special_anyptr = NULL;
X
X tp_proc = maketype(TK_PROCPTR);
X tp_proc->basetype = maketype(TK_FUNCTION);
X tp_proc->basetype->basetype = tp_void;
X tp_proc->escale = 1; /* saved "hasstaticlinks" */
X
X tp_str255 = makestandardtype(TK_STRING, NULL); /* "Char []" */
X tp_str255->basetype = tp_char;
X tp_str255->indextype = makestandardtype(TK_SUBR, NULL);
X tp_str255->indextype->basetype = tp_integer;
X tp_str255->indextype->smin = makeexpr_long(0);
X tp_str255->indextype->smax = makeexpr_long(stringceiling);
X
X tp_strptr = makestandardtype(TK_POINTER, NULL); /* "Char *" */
X tp_str255->pointertype = tp_strptr;
X tp_strptr->basetype = tp_str255;
X
X mp_string = makestandardmeaning(MK_TYPE, "STRING");
X tp = makestandardtype(TK_STRING, mp_string);
X tp->basetype = tp_char;
X tp->indextype = tp_str255->indextype;
X
X tp_smallset = maketype(TK_SMALLSET);
X tp_smallset->basetype = tp_integer;
X tp_smallset->indextype = tp_boolean;
X
X tp_text = makestandardtype(TK_POINTER, makestandardmeaning(MK_TYPE, "TEXT"));
X tp_text->basetype = makestandardtype(TK_FILE, NULL); /* "FILE *" */
X tp_text->basetype->basetype = tp_char;
X tp_text->basetype->pointertype = tp_text;
X
X tp_jmp_buf = makestandardtype(TK_SPECIAL, NULL);
X
X mp = makestandardmeaning(MK_TYPE, "INTERACTIVE");
X mp->type = tp_text;
X
X mp = makestandardmeaning(MK_TYPE, "BITSET");
X mp->type = makesettype(makesubrangetype(tp_integer, makeexpr_long(0),
X makeexpr_long(setbits-1)));
X mp->type->meaning = mp;
X
X mp = makestandardmeaning(MK_TYPE, "INTSET");
X mp->type = makesettype(makesubrangetype(tp_integer, makeexpr_long(0),
X makeexpr_long(defaultsetsize-1)));
X mp->type->meaning = mp;
X
X mp_input = makestandardmeaning(MK_VAR, "INPUT");
X mp_input->type = tp_text;
X mp_input->name = stralloc("stdin");
X ex_input = makeexpr_var(mp_input);
X
X mp_output = makestandardmeaning(MK_VAR, "OUTPUT");
X mp_output->type = tp_text;
X mp_output->name = stralloc("stdout");
X ex_output = makeexpr_var(mp_output);
X
X mp_stderr = makestandardmeaning(MK_VAR, "STDERR");
X mp_stderr->type = tp_text;
X mp_stderr->name = stralloc("stderr");
X
X mp_escapecode = makestandardmeaning(MK_VAR, "ESCAPECODE");
X mp_escapecode->type = tp_sshort;
X mp_escapecode->name = stralloc(name_ESCAPECODE);
X
X mp_ioresult = makestandardmeaning(MK_VAR, "IORESULT");
X mp_ioresult->type = tp_integer;
X mp_ioresult->name = stralloc(name_IORESULT);
X
X mp_false = makestandardmeaning(MK_CONST, "FALSE");
X mp_false->type = mp_false->val.type = tp_boolean;
X mp_false->val.i = 0;
X
X mp_true = makestandardmeaning(MK_CONST, "TRUE");
X mp_true->type = mp_true->val.type = tp_boolean;
X mp_true->val.i = 1;
X
X mp_maxint = makestandardmeaning(MK_CONST, "MAXINT");
X mp_maxint->type = mp_maxint->val.type = tp_integer;
X mp_maxint->val.i = MAXINT;
X mp_maxint->name = stralloc((integer16) ? "SHORT_MAX" :
X (sizeof_int >= 32) ? "INT_MAX" : "LONG_MAX");
X
X mp = makestandardmeaning(MK_CONST, "MAXLONGINT");
X mp->type = mp->val.type = tp_integer;
X mp->val.i = MAXINT;
X mp->name = stralloc("LONG_MAX");
X
X mp_minint = makestandardmeaning(MK_CONST, "MININT");
X mp_minint->type = mp_minint->val.type = tp_integer;
X mp_minint->val.i = MININT;
X mp_minint->name = stralloc((integer16) ? "SHORT_MIN" :
X (sizeof_int >= 32) ? "INT_MIN" : "LONG_MIN");
X
X mp = makestandardmeaning(MK_CONST, "MAXCHAR");
X mp->type = mp->val.type = tp_char;
X mp->val.i = 127;
X mp->name = stralloc("CHAR_MAX");
X
X mp = makestandardmeaning(MK_CONST, "MINCHAR");
X mp->type = mp->val.type = tp_char;
X mp->val.i = 0;
X mp->anyvarflag = 1;
X
X mp = makestandardmeaning(MK_CONST, "BELL");
X mp->type = mp->val.type = tp_char;
X mp->val.i = 7;
X mp->anyvarflag = 1;
X
X mp = makestandardmeaning(MK_CONST, "TAB");
X mp->type = mp->val.type = tp_char;
X mp->val.i = 9;
X mp->anyvarflag = 1;
X
X mp_str_hp = mp_str_turbo = NULL;
X mp_val_modula = mp_val_turbo = NULL;
X mp_blockread_ucsd = mp_blockread_turbo = NULL;
X mp_blockwrite_ucsd = mp_blockwrite_turbo = NULL;
X mp_dec_dec = mp_dec_turbo = NULL;
X}
X
X
X
X/* This makes sure that if A imports B and then C, C's interface is not
X parsed in the environment of B */
Xint push_imports()
X{
X int mark = firstimport;
X Meaning *mp;
X
X while (firstimport < numimports) {
X if (!strlist_cifind(permimports, importlist[firstimport]->sym->name)) {
X for (mp = importlist[firstimport]->cbase; mp; mp = mp->cnext)
X mp->isactive = 0;
X }
X firstimport++;
X }
X return mark;
X}
X
X
X
Xvoid pop_imports(mark)
Xint mark;
X{
X Meaning *mp;
X
X while (firstimport > mark) {
X firstimport--;
X for (mp = importlist[firstimport]->cbase; mp; mp = mp->cnext)
X mp->isactive = 1;
X }
X}
X
X
X
Xvoid import_ctx(ctx)
XMeaning *ctx;
X{
X Meaning *mp;
X int i;
X
X for (i = firstimport; i < numimports && importlist[i] != ctx; i++) ;
X if (i >= numimports) {
X if (numimports == MAXIMPORTS)
X error(format_d("Maximum of %d simultaneous imports exceeded", MAXIMPORTS));
X importlist[numimports++] = ctx;
X }
X for (mp = ctx->cbase; mp; mp = mp->cnext) {
X if (mp->exported)
X mp->isactive = 1;
X }
X}
X
X
X
Xvoid perm_import(ctx)
XMeaning *ctx;
X{
X Meaning *mp;
X
X /* Import permanently, as in Turbo's "system" unit */
X for (mp = ctx->cbase; mp; mp = mp->cnext) {
X if (mp->exported)
X mp->isactive = 1;
X }
X}
X
X
X
Xvoid unimport(mark)
Xint mark;
X{
X Meaning *mp;
X
X while (numimports > mark) {
X numimports--;
X if (!strlist_cifind(permimports, importlist[numimports]->sym->name)) {
X for (mp = importlist[numimports]->cbase; mp; mp = mp->cnext)
X mp->isactive = 0;
X }
X }
X}
X
X
X
X
Xvoid activatemeaning(mp)
XMeaning *mp;
X{
X Meaning *mp2;
X
X if (debug>1) fprintf(outf, "Reviving %s\n", curctxlast->name);
X mp->isactive = 1;
X if (mp->sym->mbase != mp) { /* move to front of symbol list */
X mp2 = mp->sym->mbase;
X for (;;) {
X if (!mp2) {
X /* Not on symbol list: must be a special kludge meaning */
X return;
X }
X if (mp2->snext == mp)
X break;
X mp2 = mp2->snext;
X }
X mp2->snext = mp->snext;
X mp->snext = mp->sym->mbase;
X mp->sym->mbase = mp;
X }
X}
X
X
X
Xvoid pushctx(ctx)
XMeaning *ctx;
X{
X struct ctxstack *top;
X
X top = ALLOC(1, struct ctxstack, ctxstacks);
X top->ctx = curctx;
X top->ctxlast = curctxlast;
X top->tempvars = tempvars;
X top->tempvarcount = tempvarcount;
X top->importmark = numimports;
X top->next = ctxtop;
X ctxtop = top;
X curctx = ctx;
X curctxlast = ctx->cbase;
X if (curctxlast) {
X activatemeaning(curctxlast);
X while (curctxlast->cnext) {
X curctxlast = curctxlast->cnext;
X activatemeaning(curctxlast);
X }
X }
X tempvars = NULL;
X tempvarcount = 0;
X if (blockkind != TOK_IMPORT && blockkind != TOK_EXPORT)
X progress();
X}
X
X
X
Xvoid popctx()
X{
X struct ctxstack *top;
X struct tempvarlist *tv;
X Meaning *mp;
X
X if (!strlist_cifind(permimports, curctx->sym->name)) {
X for (mp = curctx->cbase; mp; mp = mp->cnext) {
X if (debug>1) fprintf(outf, "Hiding %s\n", mp->name);
X mp->isactive = 0;
X }
X }
X top = ctxtop;
X ctxtop = top->next;
X curctx = top->ctx;
X curctxlast = top->ctxlast;
X while (tempvars) {
X tv = tempvars->next;
X FREE(tempvars);
X tempvars = tv;
X }
X tempvars = top->tempvars;
X tempvarcount = top->tempvarcount;
X unimport(top->importmark);
X FREE(top);
X if (blockkind != TOK_IMPORT && blockkind != TOK_EXPORT)
X progress();
X}
X
X
X
Xvoid forget_ctx(ctx, all)
XMeaning *ctx;
Xint all;
X{
X register Meaning *mp, **mpprev, *mp2, **mpp2;
X
X if (ctx->kind == MK_FUNCTION && ctx->isfunction && ctx->cbase)
X mpprev = &ctx->cbase->cnext; /* Skip return-value variable */
X else
X mpprev = &ctx->cbase;
X while ((mp = *mpprev) != NULL) {
X if (all ||
X (mp->kind != MK_PARAM &&
X mp->kind != MK_VARPARAM)) {
X *mpprev = mp->cnext;
X mpp2 = &mp->sym->mbase;
X while ((mp2 = *mpp2) != NULL && mp2 != mp)
X mpp2 = &mp2->snext;
X if (mp2)
X *mpp2 = mp2->snext;
X if (mp->kind == MK_CONST)
X free_value(&mp->val);
X freeexpr(mp->constdefn);
X if (mp->cbase)
X forget_ctx(mp, 1);
X if (mp->kind == MK_FUNCTION && mp->val.i)
X free_stmt((Stmt *)mp->val.i);
X strlist_empty(&mp->comments);
X if (mp->name)
X FREE(mp->name);
X if (mp->othername)
X FREE(mp->othername);
X FREE(mp);
X } else
X mpprev = &mp->cnext;
X }
X}
X
X
X
X
Xvoid handle_nameof()
X{
X Strlist *sl, *sl2;
X Symbol *sp;
X char *cp;
X
X for (sl = nameoflist; sl; sl = sl->next) {
X cp = my_strchr(sl->s, '.');
X if (cp) {
X sp = findsymbol(fixpascalname(cp + 1));
X sl2 = strlist_add(&sp->symbolnames,
X format_ds("%.*s", (int)(cp - sl->s), sl->s));
X } else {
X sp = findsymbol(fixpascalname(sl->s));
X sl2 = strlist_add(&sp->symbolnames, "");
X }
X sl2->value = sl->value;
X if (debug > 0)
X fprintf(outf, "symbol %s gets \"%s\" -> \"%s\"\n",
X sp->name, sl2->s, sl2->value);
X }
X strlist_empty(&nameoflist);
X}
X
X
X
XStatic void initmeaning(mp)
XMeaning *mp;
X{
X/* mp->serial = curserial = ++serialcount; */
X mp->cbase = NULL;
X mp->xnext = NULL;
X mp->othername = NULL;
X mp->type = NULL;
X mp->needvarstruct = 0;
X mp->varstructflag = 0;
X mp->wasdeclared = 0;
X mp->isforward = 0;
X mp->isfunction = 0;
X mp->istemporary = 0;
X mp->volatilequal = 0;
X mp->constqual = 0;
X mp->warnifused = (warnnames > 0);
X mp->constdefn = NULL;
X mp->val.i = 0;
X mp->val.s = NULL;
X mp->val.type = NULL;
X mp->refcount = 1;
X mp->anyvarflag = 0;
X mp->isactive = 1;
X mp->exported = 0;
X mp->handler = NULL;
X mp->dumped = 0;
X mp->isreturn = 0;
X mp->fakeparam = 0;
X mp->namedfile = 0;
X mp->bufferedfile = 0;
X mp->comments = NULL;
X}
X
X
X
Xint issafename(sp, isglobal, isdefine)
XSymbol *sp;
Xint isglobal, isdefine;
X{
X if (isdefine && curctx->kind != MK_FUNCTION) {
X if (sp->flags & FWDPARAM)
X return 0;
X }
X if ((sp->flags & AVOIDNAME) ||
X (isdefine && (sp->flags & AVOIDFIELD)) ||
X (isglobal && (sp->flags & AVOIDGLOB)))
X return 0;
X else
X return 1;
X}
X
X
X
Xstatic Meaning *enum_tname;
X
Xvoid setupmeaning(mp, sym, kind, namekind)
XMeaning *mp;
XSymbol *sym;
Xenum meaningkind kind, namekind;
X{
X char *name, *symfmt, *editfmt, *cp, *cp2;
X int altnum, isglobal, isdefine;
X Symbol *sym2;
X Strlist *sl;
X
X if (!sym)
X sym = findsymbol("Spam"); /* reduce crashes due to internal errors */
X if (sym->mbase && sym->mbase->ctx == curctx &&
X curctx != NULL && !silentalreadydef)
X alreadydef(sym);
X mp->sym = sym;
X mp->snext = sym->mbase;
X sym->mbase = mp;
X if (sym == curtoksym) {
X sym->kwtok = TOK_NONE;
X sym->flags &= ~KWPOSS;
X }
X mp->ctx = curctx;
X mp->kind = kind;
X if (pascalcasesens && curctx && curctx->sym && kind != MK_SYNONYM &&
X strlist_cifind(permimports, curctx->sym->name)) { /* a built-in name */
X Meaning *mp2;
X if (islower(sym->name[0]))
X sym2 = findsymbol(strupper(sym->name));
X else
X sym2 = findsymbol(strlower(sym->name));
X mp2 = addmeaning(sym2, MK_SYNONYM);
X mp2->xnext = mp;
X }
X if (kind == MK_VAR) {
X sl = strlist_find(varmacros, sym->name);
X if (sl) {
X kind = namekind = MK_VARMAC;
X mp->constdefn = (Expr *)sl->value;
X strlist_delete(&varmacros, sl);
X }
X }
X if (kind == MK_FUNCTION || kind == MK_SPECIAL) {
X sl = strlist_find(funcmacros, sym->name);
X if (sl) {
X mp->constdefn = (Expr *)sl->value;
X strlist_delete(&funcmacros, sl);
X }
X }
X if (kind == MK_VAR || kind == MK_VARREF || kind == MK_VARMAC ||
X kind == MK_TYPE || kind == MK_CONST || kind == MK_FUNCTION) {
X mp->exported = (blockkind == TOK_IMPORT || blockkind == TOK_EXPORT);
X if (blockkind == TOK_IMPORT)
X mp->wasdeclared = 1; /* suppress future declaration */
X } else
X mp->exported = 0;
X if (sym == curtoksym)
X name = curtokcase;
X else
X name = sym->name;
X isdefine = (namekind == MK_CONST);
X isglobal = (!curctx ||
X curctx->kind != MK_FUNCTION ||
X namekind == MK_FUNCTION ||
X namekind == MK_TYPE ||
X isdefine) &&
X (curctx != nullctx);
X mp->refcount = isglobal ? 1 : 0; /* make sure globals don't disappear */
X if (namekind == MK_SYNONYM)
X return;
X if (!mp->exported || !*exportsymbol)
X symfmt = "";
X else if (*export_symbol && my_strchr(name, '_'))
X symfmt = export_symbol;
X else
X symfmt = exportsymbol;
X wasaliased = 0;
X if (*externalias && !my_strchr(externalias, '%')) {
X register int i;
X name = format_s("%s", externalias);
X i = numparams;
X while (--i >= 0 && strcmp(rctable[i].name, "ALIAS")) ;
X if (i < 0 || !undooption(i, ""))
X *externalias = 0;
X wasaliased = 1;
X } else if (sym->symbolnames) {
X if (curctx) {
X if (debug > 2)
X fprintf(outf, "checking for \"%s\" of %s\n", curctx->name, sym->name);
X sl = strlist_cifind(sym->symbolnames, curctx->sym->name);
X if (sl) {
X if (debug > 2)
X fprintf(outf, "found \"%s\"\n", sl->value);
X name = (char *)sl->value;
X wasaliased = 1;
X }
X }
X if (!wasaliased) {
X if (debug > 2)
X fprintf(outf, "checking for \"\" of %s\n", sym->name);
X sl = strlist_find(sym->symbolnames, "");
X if (sl) {
X if (debug > 2)
X fprintf(outf, "found \"%s\"\n", sl->value);
X name = (char *)sl->value;
X wasaliased = 1;
X }
X }
X }
X if (!*symfmt || wasaliased)
X symfmt = "%s";
X altnum = -1;
X do {
X altnum++;
X cp = format_ss(symfmt, name, curctx ? curctx->name : "");
X switch (namekind) {
X
X case MK_CONST:
X editfmt = constformat;
X break;
X
X case MK_MODULE:
X editfmt = moduleformat;
X break;
X
X case MK_FUNCTION:
X editfmt = functionformat;
X break;
X
X case MK_VAR:
X case MK_VARPARAM:
X case MK_VARREF:
X case MK_VARMAC:
X case MK_SPVAR:
X editfmt = varformat;
X break;
X
X case MK_TYPE:
X editfmt = typeformat;
X break;
X
X case MK_VARIANT: /* A true kludge! */
X editfmt = enumformat;
X break;
X
X default:
X editfmt = "";
X }
X if (!*editfmt)
X editfmt = symbolformat;
X if (*editfmt)
X if (editfmt == enumformat)
X cp = format_ss(editfmt, cp,
X enum_tname ? enum_tname->name : "ENUM");
X else
X cp = format_ss(editfmt, cp,
X curctx ? curctx->name : "");
X if (dollar_idents == 2) {
X for (cp2 = cp; *cp2; cp2++)
X if (*cp2 == '$' || *cp2 == '%')
X *cp2 = '_';
X }
X sym2 = findsymbol(findaltname(cp, altnum));
X } while (!issafename(sym2, isglobal, isdefine) &&
X namekind != MK_MODULE && !wasaliased);
X mp->name = stralloc(sym2->name);
X if (sym2->flags & WARNNAME)
X note(format_s("A symbol named %s was defined [100]", mp->name));
X if (isglobal) {
X switch (namekind) { /* prevent further name conflicts */
X
X case MK_CONST:
X case MK_VARIANT:
X case MK_TYPE:
X sym2->flags |= AVOIDNAME;
X break;
X
X case MK_VAR:
X case MK_VARREF:
X case MK_FUNCTION:
X sym2->flags |= AVOIDGLOB;
X break;
X
X default:
X /* name is completely local */
X break;
X }
X }
X if (debug > 4)
X fprintf(outf, "Created meaning %s\n", mp->name);
X}
X
X
X
XMeaning *addmeaningas(sym, kind, namekind)
XSymbol *sym;
Xenum meaningkind kind, namekind;
X{
X Meaning *mp;
X
X mp = ALLOC(1, Meaning, meanings);
X initmeaning(mp);
X setupmeaning(mp, sym, kind, namekind);
X mp->cnext = NULL;
X if (curctx) {
X if (curctxlast)
X curctxlast->cnext = mp;
X else
X curctx->cbase = mp;
X curctxlast = mp;
X }
X return mp;
X}
X
X
X
XMeaning *addmeaning(sym, kind)
XSymbol *sym;
Xenum meaningkind kind;
X{
X return addmeaningas(sym, kind, kind);
X}
X
X
X
XMeaning *addmeaningafter(mpprev, sym, kind)
XMeaning *mpprev;
XSymbol *sym;
Xenum meaningkind kind;
X{
X Meaning *mp;
X
X if (!mpprev->cnext && mpprev->ctx == curctx)
X return addmeaning(sym, kind);
X mp = ALLOC(1, Meaning, meanings);
X initmeaning(mp);
X setupmeaning(mp, sym, kind, kind);
X mp->ctx = mpprev->ctx;
X mp->cnext = mpprev->cnext;
X mpprev->cnext = mp;
X return mp;
X}
X
X
Xvoid unaddmeaning(mp)
XMeaning *mp;
X{
X Meaning *prev;
X
X prev = mp->ctx;
X while (prev && prev != mp)
X prev = prev->cnext;
X if (prev)
X prev->cnext = mp->cnext;
X else
X mp->ctx = mp->cnext;
X if (!mp->cnext && mp->ctx == curctx)
X curctxlast = prev;
X}
X
X
Xvoid readdmeaning(mp)
XMeaning *mp;
X{
X mp->cnext = NULL;
X if (curctx) {
X if (curctxlast)
X curctxlast->cnext = mp;
X else
X curctx->cbase = mp;
X curctxlast = mp;
X }
X}
X
X
XMeaning *addfield(sym, flast, rectype, tname)
XSymbol *sym;
XMeaning ***flast;
XType *rectype;
XMeaning *tname;
X{
X Meaning *mp;
X int altnum;
X Symbol *sym2;
X Strlist *sl;
X char *name, *name2;
X
X mp = ALLOC(1, Meaning, meanings);
X initmeaning(mp);
X mp->sym = sym;
X if (sym) {
X mp->snext = sym->fbase;
X sym->fbase = mp;
X if (sym == curtoksym)
X name2 = curtokcase;
X else
X name2 = sym->name;
X name = name2;
X if (tname)
X sl = strlist_find(fieldmacros,
X format_ss("%s.%s", tname->sym->name, sym->name));
X else
X sl = NULL;
X if (sl) {
X mp->constdefn = (Expr *)sl->value;
X strlist_delete(&fieldmacros, sl);
X altnum = 0;
X } else {
X altnum = -1;
X do {
X altnum++;
X if (*fieldformat)
X name = format_ss(fieldformat, name2,
X tname && tname->name ? tname->name
X : "FIELD");
X sym2 = findsymbol(findaltname(name, altnum));
X } while (!issafename(sym2, 0, 0) ||
X ((sym2->flags & AVOIDFIELD) && !reusefieldnames));
X sym2->flags |= AVOIDFIELD;
X }
X mp->kind = MK_FIELD;
X mp->name = stralloc(findaltname(name, altnum));
X } else {
X mp->name = stralloc("(variant)");
X mp->kind = MK_VARIANT;
X }
X mp->cnext = NULL;
X **flast = mp;
X *flast = &(mp->cnext);
X mp->ctx = NULL;
X mp->rectype = rectype;
X mp->val.i = 0;
X return mp;
X}
X
X
X
X
X
Xint isfiletype(type)
XType *type;
X{
X return (type->kind == TK_POINTER &&
X type->basetype->kind == TK_FILE);
X}
X
X
XMeaning *isfilevar(ex)
XExpr *ex;
X{
X Meaning *mp;
X
X if (ex->kind == EK_VAR) {
X mp = (Meaning *)ex->val.i;
X if (mp->kind == MK_VAR)
X return mp;
X } else if (ex->kind == EK_DOT) {
X mp = (Meaning *)ex->val.i;
X if (mp && mp->kind == MK_FIELD)
X return mp;
X }
X return NULL;
X}
X
X
X
XType *findbasetype_(type, flags)
XType *type;
Xint flags;
X{
X long smin, smax;
X
X for (;;) {
X switch (type->kind) {
X
X case TK_POINTER:
X if (type->basetype == tp_void) { /* ANYPTR */
X if (tp_special_anyptr)
X return tp_special_anyptr; /* write "Anyptr" */
X if (!voidstar)
X return tp_abyte; /* write "char *", not "void *" */
X }
X switch (type->basetype->kind) {
X
X case TK_ARRAY: /* use basetype's basetype: */
X case TK_STRING: /* ^array[5] of array[3] of integer */
X case TK_SET: /* => int (*a)[3]; */
X if (stararrays == 1 ||
X !(flags & ODECL_FREEARRAY) ||
X type->basetype->structdefd) {
X type = type->basetype;
X flags &= ~ODECL_CHARSTAR;
X }
X break;
X
X default:
X break;
X }
X break;
X
X case TK_FUNCTION:
X case TK_STRING:
X case TK_SET:
X case TK_SMALLSET:
X case TK_SMALLARRAY:
X if (!type->basetype)
X return type;
X break;
X
X case TK_ARRAY:
X if (type->meaning && type->meaning->kind == MK_TYPE &&
X type->meaning->wasdeclared)
X return type;
X break;
X
X case TK_FILE:
X return tp_text->basetype;
X
X case TK_PROCPTR:
X return tp_proc;
X
X case TK_CPROCPTR:
X type = type->basetype->basetype;
X continue;
X
X case TK_ENUM:
X if (useenum)
X return type;
X else if (!enumbyte ||
X type->smax->kind != EK_CONST ||
X type->smax->val.i > 255)
X return tp_sshort;
X else if (type->smax->val.i > 127)
X return tp_ubyte;
X else
X return tp_abyte;
X
X case TK_BOOLEAN:
X if (*name_BOOLEAN)
X return type;
X else
X return tp_ubyte;
X
X case TK_SUBR:
X if (type == tp_abyte || type == tp_ubyte || type == tp_sbyte ||
X type == tp_ushort || type == tp_sshort) {
X return type;
X } else if ((type->basetype->kind == TK_ENUM && useenum) ||
X type->basetype->kind == TK_BOOLEAN && *name_BOOLEAN) {
X return type->basetype;
X } else {
X if (ord_range(type, &smin, &smax)) {
X if (squeezesubr != 0) {
X if (smin >= 0 && smax <= max_schar)
X return tp_abyte;
X else if (smin >= 0 && smax <= max_uchar)
X return tp_ubyte;
X else if (smin >= min_schar && smax <= max_schar &&
X (signedchars == 1 || hassignedchar))
X return tp_sbyte;
X else if (smin >= min_sshort && smax <= max_sshort)
X return tp_sshort;
X else if (smin >= 0 && smax <= max_ushort)
X return tp_ushort;
X else
X return tp_integer;
X } else {
X if (smin >= min_sshort && smax <= max_sshort)
X return tp_sshort;
X else
X return tp_integer;
X }
X } else
X return tp_integer;
X }
X
X case TK_CHAR:
X if (type == tp_schar &&
X (signedchars != 1 && !hassignedchar)) {
X return tp_sshort;
X }
X return type;
X
X default:
X return type;
X }
X type = type->basetype;
X }
X}
X
X
XType *findbasetype(type, flags)
XType *type;
Xint flags;
X{
X if (debug>1) {
X fprintf(outf, "findbasetype(");
X dumptypename(type, 1);
X fprintf(outf, ",%d) = ", flags);
X type = findbasetype_(type, flags);
X dumptypename(type, 1);
X fprintf(outf, "\n");
X return type;
X }
X return findbasetype_(type, flags);
X}
X
X
X
XExpr *arraysize(tp, incskipped)
XType *tp;
Xint incskipped;
X{
X Expr *ex, *minv, *maxv;
X int denom;
X
X ord_range_expr(tp->indextype, &minv, &maxv);
X if (maxv->kind == EK_VAR && maxv->val.i == (long)mp_maxint &&
X !exprdependsvar(minv, mp_maxint)) {
X return NULL;
X } else {
X ex = makeexpr_plus(makeexpr_minus(copyexpr(maxv),
X copyexpr(minv)),
X makeexpr_long(1));
X if (tp->smin && !incskipped) {
X ex = makeexpr_minus(ex, copyexpr(tp->smin));
X }
X if (tp->smax) {
X denom = (tp->basetype == tp_sshort) ? 16 : 8;
X denom >>= tp->escale;
X ex = makeexpr_div(makeexpr_plus(ex, makeexpr_long(denom-1)),
X makeexpr_long(denom));
X }
X return ex;
X }
X}
X
X
X
XType *promote_type(tp)
XType *tp;
X{
X Type *tp2;
X
X if (tp->kind == TK_ENUM) {
X if (promote_enums == 0 ||
X (promote_enums < 0 &&
X (useenum)))
X return tp;
X }
X if (tp->kind == TK_ENUM ||
X tp->kind == TK_SUBR ||
X tp->kind == TK_INTEGER ||
X tp->kind == TK_CHAR ||
X tp->kind == TK_BOOLEAN) {
X tp2 = findbasetype(tp, 0);
X if (tp2 == tp_ushort && sizeof_int == 16)
X return tp_uint;
X else if (tp2 == tp_sbyte || tp2 == tp_ubyte ||
X tp2 == tp_abyte || tp2 == tp_char ||
X tp2 == tp_sshort || tp2 == tp_ushort ||
X tp2 == tp_boolean || tp2->kind == TK_ENUM) {
X return tp_int;
X }
X }
X if (tp == tp_real)
X return tp_longreal;
X return tp;
X}
X
X
XType *promote_type_bin(t1, t2)
XType *t1, *t2;
X{
X t1 = promote_type(t1);
X t2 = promote_type(t2);
X if (t1 == tp_longreal || t2 == tp_longreal)
X return tp_longreal;
X if (t1 == tp_unsigned || t2 == tp_unsigned)
X return tp_unsigned;
X if (t1 == tp_integer || t2 == tp_integer) {
X if ((t1 == tp_uint || t2 == tp_uint) &&
X sizeof_int > 0 &&
X sizeof_int < (sizeof_long > 0 ? sizeof_long : 32))
X return tp_uint;
X return tp_integer;
X }
X if (t1 == tp_uint || t2 == tp_uint)
X return tp_uint;
X return t1;
X}
X
X
X
X#if 0
Xvoid predeclare_varstruct(mp)
XMeaning *mp;
X{
X if (mp->ctx &&
X mp->ctx->kind == MK_FUNCTION &&
X mp->ctx->varstructflag &&
X (usePPMacros != 0 || prototypes != 0) &&
X !strlist_find(varstructdecllist, mp->ctx->name)) {
X output("struct ");
X output(format_s(name_LOC, mp->ctx->name));
X output(" ;\n");
X strlist_insert(&varstructdecllist, mp->ctx->name);
X }
X}
X#endif
X
X
XStatic void declare_args(type, isheader, isforward)
XType *type;
Xint isheader, isforward;
X{
X Meaning *mp = type->fbase;
X Type *tp;
X int firstflag = 0;
X int usePP, dopromote, proto, showtypes, shownames;
X int staticlink;
X char *name;
X
X#if 1 /* This seems to work better! */
X isforward = !isheader;
X#endif
X usePP = (isforward && usePPMacros != 0);
X dopromote = (promoteargs == 1 ||
X (promoteargs < 0 && (usePP || !fullprototyping)));
X if (ansiC == 1 && blockkind != TOK_EXPORT)
X usePP = 0;
X if (usePP)
X proto = (prototypes) ? prototypes : 1;
X else
X proto = (isforward || fullprototyping) ? prototypes : 0;
X showtypes = (proto > 0);
X shownames = (proto == 1 || isheader);
X staticlink = (type->issigned ||
X (type->meaning &&
X type->meaning->ctx->kind == MK_FUNCTION &&
X type->meaning->ctx->varstructflag));
X if (mp || staticlink) {
X if (usePP)
X output(" PP(");
X output("(");
X if (showtypes || shownames) {
X firstflag = 0;
X while (mp) {
X if (firstflag++) output(",\002 ");
X name = (mp->othername && isheader) ? mp->othername : mp->name;
X tp = (mp->othername) ? mp->rectype : mp->type;
X if (!showtypes) {
X output(name);
X } else {
X output(storageclassname(varstorageclass(mp)));
X if (!shownames || (isforward && *name == '_')) {
X out_type(tp, 1);
X } else {
X if (dopromote)
X tp = promote_type(tp);
X outbasetype(tp, ODECL_CHARSTAR|ODECL_FREEARRAY);
X output(" ");
X outdeclarator(tp, name,
X ODECL_CHARSTAR|ODECL_FREEARRAY);
X }
X }
X if (isheader)
X mp->wasdeclared = showtypes;
X if (mp->type == tp_strptr && mp->anyvarflag) { /* VAR STRING parameter */
X output(",\002 ");
X if (showtypes) {
X if (useAnyptrMacros == 1 || useconsts == 2)
X output("Const ");
X else if (ansiC > 0)
X output("const ");
X output("int");
X }
X if (shownames) {
X if (showtypes)
X output(" ");
X output(format_s(name_STRMAX, mp->name));
X }
X }
X mp = mp->xnext;
X }
X if (staticlink) { /* sub-procedure with static link */
X if (firstflag++) output(",\002 ");
X if (type->issigned) {
X if (showtypes)
X if (tp_special_anyptr)
X output("Anyptr ");
X else if (voidstar)
X output("void *");
X else
X output("char *");
X if (shownames)
X output("_link");
X } else {
X mp = type->meaning->ctx;
X if (showtypes) {
X output("struct ");
X output(format_s(name_LOC, mp->name));
X output(" *");
X }
X if (shownames) {
X output(format_s(name_LINK, mp->name));
X }
X }
X }
X }
X output(")");
X if (usePP)
X output(")");
X } else {
X if (usePP)
X output(" PV()");
X else if (void_args)
X output("(void)");
X else
X output("()");
X }
X}
X
X
X
Xvoid outdeclarator(type, name, flags)
XType *type;
Xchar *name;
Xint flags;
X{
X int i, depth, anyptrs, anyarrays;
X Expr *dimen[30];
X Expr *ex, *maxv;
X Type *tp, *functype;
X Expr funcdummy; /* yow */
X
X anyptrs = 0;
X anyarrays = 0;
X functype = NULL;
X for (depth = 0, tp = type; tp; tp = tp->basetype) {
X switch (tp->kind) {
X
X case TK_POINTER:
X if (tp->basetype) {
X switch (tp->basetype->kind) {
X
X case TK_VOID:
X if (tp->basetype == tp_void &&
X tp_special_anyptr) {
X tp = tp_special_anyptr;
X continue;
X }
X break;
X
X case TK_ARRAY: /* ptr to array of x => ptr to x */
X case TK_STRING: /* or => array of x */
X case TK_SET:
X if (stararrays == 1 ||
X !(flags & ODECL_FREEARRAY) ||
X (tp->basetype->structdefd &&
X stararrays != 2)) {
X tp = tp->basetype;
X flags &= ~ODECL_CHARSTAR;
X } else {
X continue;
X }
X break;
X
X default:
X break;
X }
X }
X dimen[depth++] = NULL;
X anyptrs++;
X continue;
X
X case TK_ARRAY:
X flags &= ~ODECL_CHARSTAR;
X if (tp->meaning && tp->meaning->kind == MK_TYPE &&
X tp->meaning->wasdeclared)
X break;
X if (tp->structdefd) { /* conformant array */
X if (!variablearrays &&
X !(tp->basetype->kind == TK_ARRAY &&
X tp->basetype->structdefd)) /* avoid mult. notes */
X note("Conformant array code may not work in all compilers [101]");
X }
X ex = arraysize(tp, 1);
X if (!ex)
X ex = makeexpr_name("", tp_integer);
X dimen[depth++] = ex;
X anyarrays++;
X continue;
X
X case TK_SET:
X ord_range_expr(tp->indextype, NULL, &maxv);
X maxv = enum_to_int(copyexpr(maxv));
X if (ord_type(maxv->val.type)->kind == TK_CHAR)
X maxv->val.type = tp_integer;
X dimen[depth++] = makeexpr_plus(makeexpr_div(maxv, makeexpr_setbits()),
X makeexpr_long(2));
X break;
X
X case TK_STRING:
X if ((flags & ODECL_CHARSTAR) && stararrays == 1) {
X dimen[depth++] = NULL;
X } else {
X ord_range_expr(tp->indextype, NULL, &maxv);
X dimen[depth++] = makeexpr_plus(copyexpr(maxv), makeexpr_long(1));
X }
X continue;
X
X case TK_FILE:
X break;
X
X case TK_CPROCPTR:
X dimen[depth++] = NULL;
X anyptrs++;
X if (procptrprototypes)
X continue;
X dimen[depth++] = &funcdummy;
X break;
X
X case TK_FUNCTION:
X dimen[depth++] = &funcdummy;
X if (!functype)
X functype = tp;
X continue;
X
X default:
X break;
X }
X break;
X }
X if (!*name && depth && (spaceexprs > 0 ||
X (spaceexprs != 0 && !dimen[depth-1])))
X output(" "); /* spacing for abstract declarator */
X if ((flags & ODECL_FUNCTION) && anyptrs)
X output(" ");
X if (anyarrays > 1 && !(flags & ODECL_FUNCTION))
X output("\003");
X for (i = depth; --i >= 0; ) {
X if (!dimen[i])
X output("*");
X if (i > 0 &&
X ((dimen[i] && !dimen[i-1]) ||
X (dimen[i-1] && !dimen[i] && extraparens > 0)))
X output("(");
X }
X if (flags & ODECL_FUNCTION)
X output("\n");
X if (anyarrays > 1 && (flags & ODECL_FUNCTION))
X output("\003");
X output(name);
X for (i = 0; i < depth; i++) {
X if (i > 0 &&
X ((dimen[i] && !dimen[i-1]) ||
X (dimen[i-1] && !dimen[i] && extraparens > 0)))
X output(")");
X if (dimen[i]) {
X if (dimen[i] == &funcdummy) {
X if (lookback(1) == ')')
X output("\002");
X if (functype)
X declare_args(functype, (flags & ODECL_HEADER) != 0,
X (flags & ODECL_FORWARD) != 0);
X else
X output("()");
X } else {
X if (lookback(1) == ']')
X output("\002");
X output("[");
X if (!(flags & ODECL_FREEARRAY) || stararrays == 0 || i > 0)
X out_expr(dimen[i]);
X freeexpr(dimen[i]);
X output("]");
X }
X }
X }
X if (anyarrays > 1)
X output("\004");
X}
X
X
X
X
X
X
X/* Find out if types t1 and t2 will work out to be the same C type,
X for purposes of type-casting */
X
XType *canonicaltype(type)
XType *type;
X{
X if (type->kind == TK_SUBR || type->kind == TK_ENUM ||
X type->kind == TK_PROCPTR)
X type = findbasetype(type, 0);
X if (type == tp_char)
X return tp_ubyte;
X if (type->kind == TK_POINTER) {
X if (type->basetype->kind == TK_ARRAY ||
X type->basetype->kind == TK_STRING ||
X type->basetype->kind == TK_SET)
X return makepointertype(canonicaltype(type->basetype->basetype));
X else if (type->basetype == tp_void)
X return (voidstar) ? tp_anyptr : makepointertype(tp_abyte);
X else if (type->basetype->kind == TK_FILE)
X return tp_text;
X else
X return makepointertype(canonicaltype(type->basetype));
X }
X return type;
X}
X
X
Xint similartypes(t1, t2)
XType *t1, *t2;
X{
X t1 = canonicaltype(t1);
X t2 = canonicaltype(t2);
X return (t1 == t2);
X}
X
X
X
X
X
XStatic int checkstructconst(mp)
XMeaning *mp;
X{
X return (mp->kind == MK_VAR &&
X mp->constdefn &&
X mp->constdefn->kind == EK_CONST &&
X (mp->constdefn->val.type->kind == TK_ARRAY ||
X mp->constdefn->val.type->kind == TK_RECORD));
X}
X
X
XStatic int mixable(mp1, mp2, args, flags)
XMeaning *mp1, *mp2;
Xint args, flags;
X{
X Type *tp1 = mp1->type, *tp2 = mp2->type;
X
X if (mixvars == 0)
X return 0;
X if (mp1->kind == MK_FIELD &&
X (mp1->val.i || mp2->val.i) && mixfields == 0)
X return 0;
X if (checkstructconst(mp1) || checkstructconst(mp2))
X return 0;
X if (mp1->comments) {
X if (findcomment(mp1->comments, CMT_NOT | CMT_PRE, -1))
X return 0;
X }
X if (mp2->comments) {
X if (findcomment(mp2->comments, CMT_PRE, -1))
X return 0;
X }
X if ((mp1->constdefn && (mp1->kind == MK_VAR || mp1->kind == MK_VARREF)) ||
X (mp2->constdefn && (mp2->kind == MK_VAR || mp2->kind == MK_VARREF))) {
X if (mixinits == 0)
X return 0;
X if (mixinits != 1 &&
X (!mp1->constdefn || !mp2->constdefn))
END_OF_FILE
if test 49193 -ne `wc -c <'src/decl.c.1'`; then
echo shar: \"'src/decl.c.1'\" unpacked with wrong size!
fi
# end of 'src/decl.c.1'
fi
echo shar: End of archive 28 \(of 32\).
cp /dev/null ark28isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 32 archives.
echo "Now see PACKNOTES and the README"
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0