/* asnout.c * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * File Name: asnout.c * * Author: James Ostell * * Version Creation Date: 3/4/91 * * $Revision: 6.3 $ * * File Description: * Routines for outputing ASN.1 parse trees from asntool * * Modifications: * -------------------------------------------------------------------------- * Date Name Description of modification * ------- ---------- ----------------------------------------------------- * 3/4/91 Kans Stricter typecasting for GNU C and C++ * * $Log: asnout.c,v $ * Revision 6.3 2009/10/02 19:28:19 kans * address clang static analyzer warnings * * Revision 6.2 2001/01/10 17:42:47 beloslyu * fix to resolve the problem with buggy optimizer of Forte compiler on Solaris/Intel * * Revision 6.1 1999/03/11 23:43:17 kans * fprintf casts * * Revision 6.0 1997/08/25 18:10:14 madden * Revision changed to 6.0 * * Revision 5.1 1996/12/03 21:43:48 vakatov * Adopted for 32-bit MS-Windows DLLs * * Revision 5.0 1996/05/28 14:00:29 ostell * Set to revision 5.0 * * Revision 4.0 1995/07/26 13:47:38 ostell * force revision to 4.0 * * Revision 2.3 1995/05/15 18:38:28 ostell * added Log line * * * ========================================================================== */ /***************************************************************************** * * asnout.c * routines to output a set of modules to a header file * *****************************************************************************/ #include "asnbuild.h" #ifdef WIN_MSWIN static char * headerlines[] = { #else static CharPtr headerlines[] = { #endif "/***********************************************************************\n", "*\n", "*", "*\n", "* Automatic header module from ASNTOOL\n", "*\n", "************************************************************************/\n", "\n", "#ifndef _ASNTOOL_\n", "#include \n", "#endif\n", "\n"}; /***************************************************************************** * * void AsnOutput(filename) * in loader file, pointers are repesented as numbers * -32000 = NULL * -32001 = &avn[0] * any other negative number &avn[positive number] * 0 or any positive number = &at[number] * * *****************************************************************************/ NLM_EXTERN void AsnOutput (CharPtr filename, AsnModulePtr amp, Boolean loader, Int2 maxDefineLength) { FILE *fp, *ld; int i, numvalue = 0, numtype = 0, nummod = 0, j; AsnProc p; AsnModulePtr curr_mod; AsnTypePtr curr_type, atp; AsnTmpTypePtr attp, attp2; AsnTmpValuePtr attvp; AsnValxNodePtr atvp; Int2 isa; char buf[200]; char * pnt; CharPtr ptr; StringCpy(buf, filename); fp = fopen(buf, "w"); if (fp == NULL) { AsnIoErrorMsg(NULL, 82, buf); return; } pnt = buf; while (* pnt != '\0') pnt++; while ((pnt > buf) && (*pnt != '.')) pnt--; pnt++; if (loader) *pnt = 'l'; pnt++; if (amp->filename != NULL) /* the $Revision extension */ { if (StringLen(amp->filename) <= 1) { *pnt = '0'; pnt++; } StringMove(pnt, amp->filename); MemFree(amp->filename); /* get rid of the extension */ } amp->filename = StringSave(buf); if (loader) ld = fopen(buf, "w"); else ld = NULL; for (i = 0; i < 12; i++) fprintf(fp, "%s", headerlines[i]); fprintf(fp, "static char * asnfilename = \"%s\";\n", buf); curr_mod = amp; p.curr_tmptype = &p.root_tmptype; /* fake node to start */ p.curr_tmpvalue = &p.root_tmpvalue; p.root_tmptype.next = NULL; p.root_tmpvalue.next = NULL; while (curr_mod != NULL) { nummod++; curr_type = curr_mod->types; while (curr_type != NULL) { curr_type = AsnOutAddType(&p, curr_type); } curr_mod = curr_mod->next; } /******************** set index values ***************************/ attvp = p.root_tmpvalue.next; while (attvp != NULL) { attvp->index = numvalue; numvalue++; attvp = attvp->next; } attp = p.root_tmptype.next; while (attp != NULL) { attp->index = numtype; numtype++; attp = attp->next; } /****************** write values *********************************/ if (loader) /* always put in all pointers and counts */ { fprintf(ld, "%d %d %d\n", numvalue, numtype, nummod); fprintf(fp, "static AsnValxNodePtr avn;\n"); fprintf(fp, "static AsnTypePtr at;\n"); fprintf(fp, "static AsnModulePtr amp;\n"); } if (numvalue) { if (! loader) fprintf(fp, "static AsnValxNode avnx[%d] = {\n", numvalue); attvp = p.root_tmpvalue.next; while (attvp != NULL) { atvp = attvp->val; if (! loader) { fprintf(fp, " {%d,", atvp->valueisa); if (atvp->name == NULL) fprintf(fp, "NULL,"); else fprintf(fp, "\"%s\" ,", atvp->name); fprintf(fp,"%ld,", (long) atvp->intvalue); if (atvp->realvalue == (FloatHi) 0.0) fprintf(fp,"0.0,"); else fprintf(fp,"%f,", atvp->realvalue); if (atvp->next == NULL) fprintf(fp, "NULL }"); else fprintf(fp, "&avnx[%d] }", AsnOutFindValue(&p, atvp->next)); if (attvp->next == NULL) fprintf(fp, " };\n\n"); else fprintf(fp, " ,\n"); } else { fprintf(ld, "%d ", atvp->valueisa); if (atvp->name == NULL) fprintf(ld, "-32000 "); else fprintf(ld, "%s ", atvp->name); fprintf(ld,"%ld ", (long) atvp->intvalue); if (atvp->realvalue == (FloatHi) 0.0) fprintf(ld,"0.0 "); else fprintf(ld,"%f ", atvp->realvalue); if (atvp->next == NULL) fprintf(ld, "-32000\n"); else { j = AsnOutFindValue(&p, atvp->next); if (j == 0) j = 32001; fprintf(ld, "-%d\n", j); } } attvp = attvp->next; } } /****************** write types *********************************/ if (! loader) fprintf(fp, "static AsnType atx[%d] = {\n", numtype); attp = p.root_tmptype.next; while (attp != NULL) { atp = attp->ptr; isa = atp->isa; if (! loader) { fprintf(fp, " {%d,", isa); if (atp->name == NULL) fprintf(fp, " NULL,"); else fprintf(fp, " \"%s\" ,", atp->name); fprintf(fp, "%d,%d,", atp->tagclass, atp->tagnumber); if (ISA_BASETYPE(isa)) /* primitive type, fake it */ fprintf(fp, "0,0,0,0,0,0,NULL,NULL,NULL,0,NULL}"); else { if (atp->implicit) i = 1; else i = 0; fprintf(fp,"%d,", i); if (atp->optional) i = 1; else i = 0; fprintf(fp,"%d,", i); if (atp->hasdefault) i = 1; else i = 0; fprintf(fp,"%d,", i); if (atp->exported) i = 1; else i = 0; fprintf(fp,"%d,", i); if (atp->imported) i = 1; else i = 0; fprintf(fp, "%d,", i); fprintf(fp, "0,"); /* resolved is FALSE */ if (atp->defaultvalue == NULL) fprintf(fp, "NULL,"); else fprintf(fp, "&avnx[%d],", AsnOutFindValue(&p, atp->defaultvalue)); attp2 = AsnOutFindType(&p, atp->type); if (attp2 == NULL) /* imported */ fprintf(fp, "NULL,"); else fprintf(fp, "&atx[%d],", attp2->index); if (atp->type != NULL) isa = atp->type->isa; /* get base type */ else isa = -32000; if ((atp->branch == NULL) || (atp->imported)) fprintf(fp, "NULL,"); else if ((isa == INTEGER_TYPE) || (isa == ENUM_TYPE)) fprintf(fp, "&avnx[%d],", AsnOutFindValue(&p, (AsnValxNodePtr) atp->branch)); else { attp2 = AsnOutFindType(&p, (AsnTypePtr) atp->branch); fprintf(fp, "&atx[%d],", attp2->index); } fprintf(fp, "0,"); /* ->tmp */ if (atp->next == NULL) fprintf(fp, "NULL}"); else { attp2 = AsnOutFindType(&p, atp->next); fprintf(fp, "&atx[%d]}", attp2->index); } } if (attp->next == NULL) fprintf(fp, " };\n\n"); else fprintf(fp, " ,\n"); } else { fprintf(ld, "%d ", isa); if (atp->name == NULL) fprintf(ld, "-32000 "); else { ptr = atp->name; pnt = buf; while (*ptr != '\0') /* fix SEQ OF, SET OF */ { *pnt = *ptr; if (*ptr == ' ') *pnt = '!'; ptr++; pnt++; } *pnt = '\0'; fprintf(ld, "%s ", buf); } fprintf(ld, "%d %d ", atp->tagclass, atp->tagnumber); if (ISA_BASETYPE(isa)) /* primitive type, fake it */ fprintf(ld, "0 0 0 0 0 -32000 -32000 -32000 -32000\n"); else { if (atp->implicit) i = 1; else i = 0; fprintf(ld,"%d ", i); if (atp->optional) i = 1; else i = 0; fprintf(ld,"%d ", i); if (atp->hasdefault) i = 1; else i = 0; fprintf(ld,"%d ", i); if (atp->exported) i = 1; else i = 0; fprintf(ld,"%d ", i); if (atp->imported) i = 1; else i = 0; fprintf(ld, "%d ", i); if (atp->defaultvalue == NULL) fprintf(ld, "-32000 "); else { j = AsnOutFindValue(&p, atp->defaultvalue); if (j == 0) j = 32001; fprintf(ld, "-%d ", j); } attp2 = AsnOutFindType(&p, atp->type); if (attp2 == NULL) /* imported */ fprintf(ld, "-32000 "); else fprintf(ld, "%d ", attp2->index); if (atp->type != NULL) isa = atp->type->isa; /* get base type */ else isa = -32000; if ((atp->branch == NULL) || (atp->imported)) fprintf(ld, "-32000 "); else if ((isa == INTEGER_TYPE) || (isa == ENUM_TYPE)) { j = AsnOutFindValue(&p, (AsnValxNodePtr) atp->branch); if (j == 0) j = 32001; fprintf(ld, "-%d ", j); } else { attp2 = AsnOutFindType(&p, (AsnTypePtr) atp->branch); fprintf(ld, "%d ", attp2->index); } if (atp->next == NULL) fprintf(ld, "-32000\n"); else { attp2 = AsnOutFindType(&p, atp->next); fprintf(ld, "%d\n", attp2->index); } } } attp = attp->next; } /*********************** print the modules ***********************/ if (! loader) fprintf(fp, "static AsnModule ampx[%d] = {\n", nummod); i = 1; curr_mod = amp; while (curr_mod != NULL) { if (! loader) { fprintf(fp, " { \"%s\" ,", curr_mod->modulename); if (curr_mod->filename == NULL) fprintf(fp, " NULL,"); else fprintf(fp, " \"%s\",", curr_mod->filename); attp = AsnOutFindType(&p, curr_mod->types); fprintf(fp, "&atx[%d],", attp->index); fprintf(fp, "NULL,"); if (curr_mod->next == NULL) { fprintf(fp, "NULL,0,0}"); fprintf(fp, " };\n\n"); } else fprintf(fp, "&x[%d],0,0} ,\n", i); } else { fprintf(ld, "%s ", curr_mod->modulename); if (curr_mod->filename == NULL) fprintf(ld, "-32000 "); else fprintf(ld, "%s ", curr_mod->filename); attp = AsnOutFindType(&p, curr_mod->types); fprintf(ld, "%d ", attp->index); if (curr_mod->next == NULL) fprintf(ld, "-32000\n"); else fprintf(ld, "%d\n", i); } i++; curr_mod = curr_mod->next; } if (loader) fclose(ld); else { if (numvalue) fprintf(fp, "static AsnValxNodePtr avn = avnx;\n"); else fprintf(fp, "static AsnValxNodePtr avn = NULL;\n"); fprintf(fp, "static AsnTypePtr at = atx;\n"); fprintf(fp, "static AsnModulePtr amp = ampx;\n\n"); } curr_mod = amp; while (curr_mod != NULL) { atp = curr_mod->types; fprintf(fp, "\n\n/**************************************************\n"); fprintf(fp, "*\n"); fprintf(fp, "* Defines for Module %s\n", curr_mod->modulename); fprintf(fp, "*\n"); fprintf(fp, "**************************************************/\n"); while (atp != NULL) { if (! atp->imported) /* must be defined elsewhere */ AsnOutDefineType(fp, &p, atp, maxDefineLength); atp = atp->next; } curr_mod = curr_mod->next; } fclose(fp); return; } /***************************************************************************** * * void AsnOutDefineType(fp, app, atp, maxDefineLength) * *****************************************************************************/ NLM_EXTERN void AsnOutDefineType (FILE *fp, AsnProcPtr app, AsnTypePtr atp, Int2 maxDefineLength) { char buf[200]; AsnOutDefineElement(fp, app, atp, buf, NULL, maxDefineLength); return; } /***************************************************************************** * * void AsnOutDefineElement(fp, app, atp, buf, pnt, maxDefineLength) * *****************************************************************************/ NLM_EXTERN void AsnOutDefineElement (FILE *fp, AsnProcPtr app, AsnTypePtr atp, CharPtr buf, CharPtr pnt, Int2 maxDefineLength) { CharPtr to, from, symbol; AsnTmpTypePtr attp; Boolean first; int i; if (pnt == NULL) first = TRUE; else first = FALSE; while (atp != NULL) { to = pnt; if (atp->name != NULL) { from = atp->name; if (first) to = buf; else { *to = '_'; to++; } while (*from != '\0') { if (first) *to = TO_UPPER(*from); else *to = *from; if (*to == '-') *to = '_'; to++; from++; } *to = '\0'; attp = AsnOutFindType(app, atp); if (first) fprintf(fp, "\n"); symbol = to; i = maxDefineLength; /* max symbol length */ while ((i) && (symbol > buf)) { i--; symbol--; } if (symbol != buf && StrChr(symbol, '_') != NULL) /* longer than maxDefineLength */ { while (*symbol != '_') /* end neatly */ symbol++; symbol++; } fprintf(fp, "#define %s &at[%d]\n", symbol, attp->index); } switch(atp->type->isa) { case SEQ_TYPE: case SET_TYPE: case CHOICE_TYPE: AsnOutDefineElement(fp, app, (AsnTypePtr) atp->branch, buf, to, maxDefineLength); break; case SEQOF_TYPE: case SETOF_TYPE: StringCpy(to, "_E"); symbol = to + 2; i = maxDefineLength; /* max symbol length */ while ((i) && (symbol > buf)) { i--; symbol--; } if (symbol != buf) /* longer than maxDefineLength */ { while (*symbol != '_') /* end neatly */ symbol++; symbol++; } attp = AsnOutFindType(app, (AsnTypePtr) atp->branch); fprintf(fp, "#define %s &at[%d]\n", symbol, attp->index); switch (((AsnTypePtr)atp->branch)->type->isa) { case CHOICE_TYPE: case SET_TYPE: case SEQ_TYPE: case SEQOF_TYPE: case SETOF_TYPE: AsnOutDefineElement(fp, app, (AsnTypePtr) atp->branch, buf, to+2, maxDefineLength); break; default: break; } break; default: break; } if (first) return; atp = atp->next; } return; } /***************************************************************************** * * Int2 AsnOutFindValue(app, avnp) * returns index of a value node ptr * *****************************************************************************/ NLM_EXTERN Int2 AsnOutFindValue (AsnProcPtr app, AsnValxNodePtr avnp) { AsnTmpValuePtr attvp; attvp = app->root_tmpvalue.next; while (attvp != NULL) { if (attvp->val == avnp) return attvp->index; attvp = attvp->next; } return -32000; } /***************************************************************************** * * AsnTypePtr AsnOutAddType(AsnProcPtr, AsnTypePtr) * builds temporaries for this type * returns the next type * *****************************************************************************/ NLM_EXTERN AsnTypePtr AsnOutAddType (AsnProcPtr app, AsnTypePtr atp) { AsnTypePtr atp2; AsnTypePtr next; if (atp == NULL) /* protection */ return NULL; if (! AsnOutNewType(app, atp)) /* already have it */ { if (ISA_BASETYPE(atp->isa)) return NULL; return atp->next; } if (ISA_BASETYPE(atp->isa)) /* all done if primitive */ return NULL; if (atp->type == NULL) /* externally defined type */ return atp->next; /* no more to do */ switch (atp->type->isa) /* load any subvalues */ { case INTEGER_TYPE: if (atp->branch == NULL) /* not named */ break; case ENUM_TYPE: AsnOutNewValueChain(app, (AsnValxNodePtr) atp->branch); break; case SETOF_TYPE: case SEQOF_TYPE: case SEQ_TYPE: case SET_TYPE: case CHOICE_TYPE: atp2 = (AsnTypePtr) atp->branch; while (atp2 != NULL) atp2 = AsnOutAddType(app, atp2); break; default: break; } if (atp->hasdefault) AsnOutNewValueChain(app, atp->defaultvalue); AsnOutAddType(app, atp->type); next = atp->next; return next; } /***************************************************************************** * * Boolean AsnOutNewType(app, atp) * if type is on tmp list already, returns FALSE * if not, adds it, and returns TRUE * *****************************************************************************/ NLM_EXTERN Boolean AsnOutNewType (AsnProcPtr app, AsnTypePtr atp) { AsnTmpTypePtr attp; attp = AsnOutFindType(app, atp); if (attp != NULL) /* have it already */ return FALSE; /* not found, add it */ attp = (AsnTmpTypePtr) MemNew(sizeof(AsnTmpType)); app->curr_tmptype->next = attp; app->curr_tmptype = attp; attp->ptr = atp; return TRUE; } /***************************************************************************** * * AsnTmpTypePtr AsnOutFindType(app, atp) * returns a pointer to the tmptype matching atp * *****************************************************************************/ NLM_EXTERN AsnTmpTypePtr AsnOutFindType (AsnProcPtr app, AsnTypePtr atp) { AsnTmpTypePtr attp; if (atp == NULL) /* imported, no type set */ return NULL; attp = app->root_tmptype.next; while (attp != NULL) { if (attp->ptr == atp) /* found it */ return attp; attp = attp->next; } return attp; /* didn't find it */ } /***************************************************************************** * * void AsnOutNewValueChain(app, avnp) * values are always used by just one type * *****************************************************************************/ NLM_EXTERN void AsnOutNewValueChain (AsnProcPtr app, AsnValxNodePtr avnp) { AsnTmpValuePtr curr; curr = app->curr_tmpvalue; while (avnp != NULL) { curr->next = (AsnTmpValuePtr) MemNew(sizeof(AsnTmpValue)); curr = curr->next; curr->val = avnp; avnp = avnp->next; } app->curr_tmpvalue = curr; return; }