/* ventura.c - Module to output the data. */ #include #include #include #include #include #include "types.h" #include "docfmt.h" #include "text.h" #include "ventura.h" #include "process.h" #include "errstr.h" int VenLineOut(FILE * fpoutfile, char * pch, int wState); /* Formatting codes to output for ventura word formatting. */ char *pchVenparm=""; char *pchVenfunc=""; char *pchVenelem=""; char *pchVendefault=""; #define NUMFLAGTYPES 8 #define REGISTERS 0 #define REGRETURN 1 #define REGCONDITION 2 #define PARAMETERS 3 #define PARAMRETURN 4 #define FIELD1 5 #define FIELD2 6 #define FIELD3 7 /* "output" modes for the line out routines. These * signify what sort of formatting should be done. */ #define TEXT 0x0 #define PARM 0x1 #define FUNC 0x2 #define STRUCT 0x3 #define ELEMENT 0x4 #define OLDSTYLE 0x80 #define NEWSTYLE 0x40 /* * @doc VENTURA * @api void | VenturaBlockOut | Central entry point for outputing a * Ventura format outerlevel block. * * @parm aBlock * | pBlock | Pointer to block structure. * @parm FILE * | ofile | Output file pointer. * * @comm Call this to get something output in ventura. * */ void VenturaBlockOut( aBlock *pBlock, FILE *ofile) { VenfuncOut(pBlock, ofile); } /************************************************************* * * LINE OUT STUFF * *************************************************************/ /* @doc INTERNAL * * @func void | VentextOut | This outputs the given text lines. Uses * to expand formatting codes. * * @parm FILE * | file | Specifies the output file. * @parm aLine * | line | Specifies the text to output. * * @xref VenLineOut * */ void VentextOut( FILE *file, aLine *line, BOOL fLineSeps ) { int wMode = TEXT; for (; line != NULL; line = line->next) { wMode = VenLineOut( file, line->text, wMode ); if (fLineSeps) fprintf(file, "\n"); } if (wMode != TEXT) { fprintf(errfp, "Warning: Runaway formatting code with no close.\n"); fprintf(file, ""); // is this right? } } /* @doc INTERNAL * * @func void | VentextOutLnCol | This outputs the given text lines, * with each line separated by a newline. If a new paragraph occurs, it is * prefixed by the column prefix code

. * * @parm FILE * | file | Specifies the output file. * @parm aLine * | line | Specifies the text lines to output. * @parm char * | pColHead | Column header string to prefix new * paragraphs with. * * @comm Uses to expand formatting codes. * * @xref VentextOut, VenLineOut * */ void VentextOutLnCol( FILE *file, aLine *line, char *pColHead ) { int wMode = TEXT; for (; line != NULL; line = line->next) { if (*(line->text) == '\0') { /* Print warning if a formatting code is being * continued across a para boundry. */ if (wMode != TEXT) { fprintf(errfp, "Warning: formatting code" "crosses paragraph boundry.\n"); } /* blank line, need new paragraph header */ fprintf(file, "\n%s", pColHead); } else { /* Otherwise, normal line, print the line as usual */ wMode = VenLineOut(file, line->text, wMode); fprintf(file, "\n"); } } if (wMode != TEXT) { fprintf(errfp, "Warning: Runaway formatting code with no" "close before para end.\n"); fprintf(file, "\n"); // is this right? } } /* * @doc INTERNAL * * @func int | VenLineOut | Output the given text line, expanding any * character/word formatting control codes to the appropriate ventura * control codes. * * @parm FILE * | fpoutfile | Output file pointer. * @parm char * | line | Specifies the text to output. * @parm int | wState | Specifies the current line output * state, either TEXT, FUNC, STRUCTURE, or PARM. This value should initially * be TEXT. * * @rdesc Returns the line output state at the end of the text line. * This value should be passed to on the next iteration * in order to continue the formatting code across a line break. * * @comm Reads and expands both old

foobar style function * parameters and

new-style parameters. * * This functions sends out character strings. Use and * for printing the aLine text storage data structures. * */ int VenLineOut(FILE * fpoutfile, char * pch, int wState) { /* *

is parm * is function * is struct/union reference * is structure element reference * is message * is return to default *

is param * is function * is structure/union */ BOOL iStyle; char chFormat; char *pchTemp; /* Loop over all chars on line */ while(*pch) { /* Convert tabs into spaces. */ if(*pch == '\t') *pch=' '; /* Skip non-printing chars */ if (((*pch) & 0x80) || (*pch < ' ')) { pch++; continue; } /* Check and see if this is a formatting prefix character. */ if (*pch == '<') { pch++; if (!*pch) /* Warning! Unexpected EOS */ continue; chFormat = *pch; /* Move the character pointer to the characters following * the formatting, and determine the type of formatting code * in use, old or new style. */ pch++; // skip the formatting character if (*pch == '>') { pch++; iStyle = OLDSTYLE; } else { /* For a new style formatting code, there must be * either a EOL or whitespace following the code * character. Make sure this is the case. If not, * then this isn't a formatting code, so * just print the characters out. */ if (*pch && !isspace(*pch)) { fprintf(errfp,"Warning: New-style formatting " "code without whitespace.\nCode ignored but text printed.\n"); /* Write out the characters, but * don't enter a formatting state. */ putc('<', fpoutfile); putc(chFormat, fpoutfile); continue; // the while (*pch) } /* Otherwise, this a new style def. Suck * up any whitespace present. */ iStyle = NEWSTYLE; /* Chew up whitespace */ while (*pch && isspace(*pch)) pch++; } /* Now I'm pointing to the start of the string * that the formatting should be applied to. * Check that a formatting code is not already * in effect, cancel it if so. */ if (!(chFormat == 'd' || chFormat == 'D') && wState != TEXT) { fprintf(errfp, "Error: Nested formatting codes.\n"); fprintf(fpoutfile, ""); // HACK HACK! wState = TEXT; } /* Now setup the output state as appropriate, setting * the wState variable and outputting any leader chars * required. */ switch (chFormat) { case 'P': case 'p': /* Parameter formatting. Output the * leader codes and setup wState. */ wState = iStyle | PARM; fprintf(fpoutfile, pchVenparm); break; case 'E': case 'e': /* Data structure element formatting. Output the * leader codes and setup wState. */ wState = iStyle | ELEMENT; fprintf(fpoutfile, pchVenelem); /* Skip over the structure notation (struct.element). */ pchTemp = pch; while (*pchTemp++ != '>') { if (*pchTemp == '.') pch = ++pchTemp; } break; case 'F': case 'f': /* Function formatting. Output & setup state */ wState = iStyle | FUNC; fprintf(fpoutfile, pchVenfunc); break; case 'D': case 'd': if (iStyle == NEWSTYLE) { fprintf(errfp,"Error: encountered." " is the only valid use for .\n"); /* Here, just print the "); } break; case 'T': case 't': case 'M': case 'm': /* Structure definition */ wState = iStyle | STRUCT; fprintf(fpoutfile, pchVenfunc); break; default: /* Unrecognized code. Barf. */ fprintf(errfp, "Error: unrecognized" " formatting code.\n"); /* Simulate the output and set no mode */ if (iStyle == NEWSTYLE) fprintf(fpoutfile, "<%c ", chFormat); else fprintf(fpoutfile, "<%c>", chFormat); break; } // switch for '<' formating codes } // if *pch == '<' /* If the character is a new-style close end formatting * indicator, clear the current mode to text and send out the * the ventura return-to-default code. * * If there is no current mode, then just output the chracter? */ else if (*pch == '>') { if (wState != TEXT) { if (wState & OLDSTYLE) { fprintf(errfp, "Warning: new style close in " "oldstyle formatting.\nIgnoring close, writing char.\n"); putc(*pch, fpoutfile); } else { /* Cancel the current mode */ fprintf(fpoutfile, ""); wState = TEXT; } } else { fprintf(errfp, "Warning: Standalone '>' " "encountered.\n"); putc(*pch, fpoutfile); } pch++; // skip the '>' } else { /* Just print the character */ putc(*pch, fpoutfile); pch++; } } // while (*pch); /* We're done! Return the current output state */ return wState; } /**************************************************** * * XREFS * ****************************************************/ /* * @doc INTERNAL * @func void | VenDoXrefs | Process and print the cross reference * list for a function or message block. * * @parm FILE * | file | Specifies the output file. * @parm aLine * | line | The line of cross references to print. * */ void VenDoXrefs( FILE *file, aLine *line) { char ach[80]; int i; char *p; if (line == NULL) { fprintf(errfp, "NULL line passed to VenDoXrefs\n"); return; } /* Header line */ fprintf( file, "@HO = See Also\n\n" ); while (line != NULL) { /* skip whitespace */ for (p = line->text; isspace(*p); p++); while (*p) { i = 0; while (*p && !(*p == ',' || isspace(*p))) ach[i++] = *p++; if (i > 0) { ach[i] = '\0'; fprintf(file, "%s", ach); } while (*p && (*p == ',' || isspace(*p))) p++; if (*p) fprintf(file, ", "); } /* while *p */ fprintf(file, "\n"); line = line->next; if (line) fprintf(file, " "); } /* while line != NULL */ fprintf(file, "\n"); } /**************************************************** * * FLAGS * ****************************************************/ /* * @doc INTERNAL * * @func void | VenDoFlagList | Print the flag list of a parameter, * register, or return description. * * @parm aFlag * | flag | Pointer to flag list to be printed. * * @parm FILE * | file | Specifies the file to print to. * * @parm WORD | wType | This parameter may be one of the following, * depending on the type of flag list being produced: * * @flag REGISTERS | This is a normal input register declaration, below * a ASM or ASM callback function declaration. * @flag REGRETURN | This is a register return declaration beneath * a return description. This is not part of a conditional * block. * @flag REGCONDITION | This is a register return declaration beneath * a return conditional block. * @flag PARAMETERS | This is a normal parameter declaration beneath * an API, or API Callback function or Message declaration. * @flag PARAMRETURN | This is a return flag list declaration beneath * a return block in an API or API callback, or a Message return. */ void VenDoFlagList( aFlag *flag, FILE *file, int wType ) { static char *aszFlagNameOut[NUMFLAGTYPES] = { "@RFLAG = ", // registers "@RFLAG = ", // reg return "@RFLAG = ", // reg condition return "@FLAG = ", // param flag "@PARM = ", // param return "@FLAG = ", // level 1 field "@L2FLAG = ", // level 2 field "@L3FLAG = ", // level 3 field }; static char *aszFlagDescOut[NUMFLAGTYPES] = { "@RFLDESC = ", // registers "@RFLDESC = ", // reg return "@RFLDESC = ", // reg condition return "@FLDESC = ", // param flag "@PDESC = ", // param return "@FLDESC = ", // level 1 field "@L2FLDESC = ", // level 2 field "@L3FLDESC = ", // level 3 field }; if (!flag) { fprintf(errfp, "Warning: NULL Flag sent to VenDoFlaglist\n"); return; } assert(wType < NUMFLAGTYPES); /* loop over the flag list */ for ( ; flag != NULL; flag = flag->next) { /* Do flag name */ fprintf(file, aszFlagNameOut[wType]); VentextOut( file, flag->name, FALSE ); fprintf( file, "\n\n" ); /* Do the description */ fprintf(file, aszFlagDescOut[wType]); VentextOutLnCol(file, flag->desc, aszFlagNameOut[wType]); fprintf( file, "\n" ); } // for flag list } /**************************************************** * * PARMS * ****************************************************/ /* * @doc INTERNAL * @func void | VenDoParmList | Print the parameter list of a function * block. * * @parm aBlock * | pBlock | Specifies the enclosing block of the * parameter list. * @parm aParm * | parm | The parameter list to print. * @parm FILE * | file | Specifies the file to use for output. * * @comm Prints the given parameter list. If parameters within the * list contain a flag list, the flag list is printed using * . * * @xref VenDoFlagList * */ void VenDoParmList( aBlock *pBlock, aParm *parm, FILE *file ) { if (!parm) { fprintf(file, "None\n\n"); } else { /* Loop over the parameter list of the message */ for (; parm != NULL; parm = parm->next) { /* Print first col, param type and name */ fprintf( file, "@PARM = " ); VentextOut( file, parm->type, FALSE ); fprintf( file, "<_>"); VentextOut( file, parm->name, FALSE ); fprintf( file, "\n\n" ); /* Do second column, the description */ fprintf( file, "@PDESC = " ); VentextOutLnCol( file, parm->desc, "@PDESC = "); // VentextOutLnCol( file, parm->desc, "@PDESC"); fprintf( file, "\n" ); /* Print the parameter's flags, if any */ if (parm->flag != NULL) { VenDoFlagList(parm->flag, file, PARAMETERS); } } // for parm list } /* Close off the parameter list */ fprintf(file, "@LE = \n\n"); } /**************************************************** * * REGS AND CONDITIONALS * ****************************************************/ /* * @doc INTERNAL * @func void | VenDoRegList | Print a register list. * * @parm aBlock * | pBlock | Specifies the enclosing block of the * parameter list. * @parm aReg * | reg | The register list to print. * @parm FILE * | file | Specifies the file to use for output. * * @parm WORD | wType | This parameter may be one of the following, * depending on the type of register list being produced: * * @flag REGISTERS | This is a normal input register declaration, below * a ASM or ASM callback function declaration. * @flag REGRETURN | This is a register return declaration beneath * a return description. This is not part of a conditional * block. * @flag REGCONDITION | This is a register return declaration beneath * a return conditional block. * * @comm Prints the given register list. If registers within the * list contain a flag list, the flag list is printed using * . * * @xref VenDoFlagList * */ void VenDoRegList( aBlock *pBlock, aReg *reg, FILE *file, int wType) { static char *aszRegNameOut[] = { "@RNAME = ", // registers "@RNAME = ", // reg return "@RNAME = ", // reg condition return }; static char *aszRegDescOut[] = { "@RDESC = ", // registers "@RDESC = ", // reg return "@RDESC = ", // reg condition return }; assert(wType == REGISTERS || wType == REGRETURN || wType == REGCONDITION); if (reg == NULL) { fprintf(file, "None\n\n"); } else { /* Loop over the register list of the message */ for (; reg != NULL; reg = reg->next) { /* Print first col, reg name */ fprintf( file, aszRegNameOut[wType]); /* Print the register name */ fprintf( file, "" ); VentextOut( file, reg->name, FALSE ); fprintf( file, "\n\n" ); /* Do second column, the description */ fprintf( file, aszRegDescOut[wType] ); VentextOutLnCol( file, reg->desc, aszRegDescOut[wType] ); fprintf( file, "\n" ); /* Print the parameter's flags, if any */ if (reg->flag != NULL) { VenDoFlagList(reg->flag, file, wType); } } // for reg list } fprintf(file, "@LE = \n\n"); } /* * @doc INTERNAL * * @func void | VenDoCondList | Print a conditional register list. * * @parm aBlock * | pBlock | Specifies the enclosing block of the * register list. * * @parm aCond * | cond | The conditional list to print. * * @parm FILE * | file | Specifies the file to use for output. * * @comm Prints the given conditional list. For each conditional * block, the text is printed, followed by the the list of registers * (and their associated tags) for the conditional block. * * @xref VenDoRegList, VenDoFlagList * */ void VenDoCondList( aBlock *pBlock, aCond *cond, FILE *file) { assert(cond != NULL); /* Loop over the register list of the message */ for (; cond != NULL; cond = cond->next) { /* Print out the conditional tag text.. */ fprintf( file, "@COND = "); VentextOutLnCol(file, cond->desc, "@COND = "); fprintf( file, "\n"); /* Now print the conditional's registers (and subseqent flags) */ VenDoRegList(pBlock, cond->regs, file, REGCONDITION); } // for conditional list fprintf(file, "@LE = \n\n"); } /******************************************************* * * STRUCTS * *******************************************************/ /* * VenPrintFieldText(aType *type, FILE *file) * * Prints the text of a field for a structure courier dump. This proc * only prints the name and type of structure fields at the appropriate * indent levels. * */ void VenPrintFieldText(aType *type, FILE *file) { int i; for (i = type->level + 1; i > 0; i--) fprintf(file, " "); VentextOut(file, type->type, FALSE); fprintf(file, " "); VentextOut(file, type->name, FALSE); fprintf(file, ";\n"); /* Flags? */ } /* * VenPrintSubstructText(aSU *su, file, wType) * * Prints a courier dump of a sub-structure or sub-union at the * appropriate indent level. Does not print any description text. * * wType must indicate whether this is a union or structure, being * either FIELD_STRUCT or FIELD_UNION. * */ void VenPrintSubstructText(aSU *su, FILE *file, int wType) { int i; aField *field; /* Do struct/union and brace of sub-structure */ for (i = su->level; i > 0; i--) fprintf(file, " "); fprintf(file, "%s {\n", wType == FIELD_STRUCT ? "struct" : "union"); field = su->field; if (field) { while (field) { switch (field->wType) { case FIELD_TYPE: VenPrintFieldText((aType *) field->ptr, file); break; case FIELD_STRUCT: case FIELD_UNION: VenPrintSubstructText((aSU *) field->ptr, file, field->wType); break; } field = field->next; } } /* Do closing brace and title of sub-structure */ for (i = su->level; i > 0; i--) fprintf(file, " "); fprintf(file, "} %s;\n", su->name->text); } /* * VenPrintStructText(pBlock, file, wType) * * Prints a courier dump of the text of a structure/union outerlevel * block. Does not print any description fields or flags. * * wType indicates whether the block is a structure or union, either * FIELD_STRUCT or FIELD_UNION. * */ void VenPrintStructText(aBlock *pBlock, FILE *file) { aField *curf; aLine *tag; curf = pBlock->field; tag = pBlock->tagname; fprintf(file, "@EX = typedef %s ", pBlock->blockType == STRUCTBLOCK ? "struct" : "union"); if (tag) fprintf(file, "%s ", tag->text); fprintf(file, "{\n"); while (curf) { switch (curf->wType) { case FIELD_TYPE: VenPrintFieldText((aType *) curf->ptr, file); break; case FIELD_STRUCT: case FIELD_UNION: VenPrintSubstructText((aSU *) curf->ptr, file, curf->wType); break; default: assert(FALSE); break; } curf = curf->next; } fprintf(file, "} %s;\n\n", pBlock->name->text); /* Now print out the othernames? */ } /********* DESCRIPTION DUMPS ************/ #define NUMFIELDLEVELS 3 char *aachFieldNameTags[NUMFIELDLEVELS] = { "@PARM = ", "@L2PARM = ", "@L3PARM = " }; char *aachFieldDescTags[NUMFIELDLEVELS] = { "@PDESC = ", "@L2PDESC = ", "@L3PDESC = " }; int aiFlagTypes[NUMFIELDLEVELS] = { FIELD1, FIELD2, FIELD3 }; /* * @doc INTERNAL * * @api void | VenPrintFieldDesc | This function prints the * descriptions of a field entry in a structure. The printout is done * using the standard @parm tags (and associated flag tags). * * @parm aType * | type | Points to a type structure which contains * the field information. * * @parm FILE * | file | Specifies the output file. * * @comm Use this function to output the names/descriptions of fields. * Use to output a similated text dump of the * structure definition. * * Note that the use of this function requires an @LE tag be output when * the list of parameters has been ended. * */ void VenPrintFieldDesc(aType *type, FILE *file) { int level; level = type->level; if (level >= NUMFIELDLEVELS) level = NUMFIELDLEVELS - 1; /* Print the field type and name in the first column, formatted */ fprintf(file, "%s", aachFieldNameTags[level]); VentextOut(file, type->name, FALSE); fprintf(file, "\n\n"); #if 0 /* Print parameter type above? */ fprintf(file, "<_>"); VentextOut(file, type->name, FALSE); fprintf(file, "\n\n"); #endif /* Do the second column, description text */ fprintf(file, aachFieldDescTags[level]); VentextOutLnCol(file, type->desc, aachFieldDescTags[level]); putc('\n', file); /* Do the flag list, if any */ if (type->flag != NULL) { VenDoFlagList(type->flag, file, aiFlagTypes[level]); } /* Now, somewhere, a @LE = needs to be output! */ } void VenPrintSubstructDesc(aSU *su, FILE *file, int wType) { aField *field; int level; int levelStruct; /* Limit level to the number of nesting levels supported by Ventura */ level = min(NUMFIELDLEVELS - 1, su->level); levelStruct = level - 1; /* For the sub-structure, print out a little blurb for * the sub-structure/union itself, as well as the optional * description text that may come with a sub-structure. */ fprintf(file, aachFieldNameTags[levelStruct]); fprintf(file, "%s\n\n", su->name->text); if (su->desc) { fprintf(file, aachFieldDescTags[levelStruct]); VentextOutLnCol(file, su->desc, aachFieldDescTags[levelStruct]); putc('\n', file); } /* Now print the sub-fields */ fprintf(file, aachFieldDescTags[levelStruct]); fprintf(file, "The following sub-fields are contained in %s %s:\n\n", wType == FIELD_STRUCT ? "structure" : "union", su->name->text); /* Now do each field of the sub-structure */ field = su->field; if (field) { while (field) { switch (field->wType) { case FIELD_TYPE: VenPrintFieldDesc((aType *) field->ptr, file); break; case FIELD_STRUCT: case FIELD_UNION: VenPrintSubstructDesc((aSU *) field->ptr, file, field->wType); break; } field = field->next; } } /* Print a closing blurb */ fprintf(file, aachFieldNameTags[levelStruct]); fprintf(file, "End of sub-fields for %s %s.\n\n", wType == FIELD_STRUCT ? "structure" : "union", su->name->text); } void VenDoStructDescriptions(aBlock *pBlock, FILE *file) { aField *cur; /* Look through the field list, printing each field as it is * encountered using @parm tags... */ fprintf(file, "@HO = Fields\n\n"); fprintf(file, "The %s %s has the following fields:\n\n", pBlock->name->text, pBlock->blockType == STRUCTBLOCK ? "structure" : "union"); /* Dump the structure */ cur = pBlock->field; if (cur == NULL) { fprintf(file, "None\n\n"); return; } while (cur) { switch (cur->wType) { case FIELD_TYPE: VenPrintFieldDesc((aType *) cur->ptr, file); break; case FIELD_STRUCT: case FIELD_UNION: VenPrintSubstructDesc((aSU *) cur->ptr, file, cur->wType); break; default: assert(FALSE); break; } cur = cur->next; } /* Close off the param list */ fprintf(file, "@LE = \n\n"); /* Print out othertypes? */ } /********************************************************* * * DOC BLOCK * *********************************************************/ /* * @doc INTERNAL * @func void | VenfuncOut | This outputs the function information. * * @parm aBlock * | func | Specifies a pointer to the function * information. The type of the block is determined by looking at the * blocktype field. * * @parm FILE * | file | Specifies the output file. * * @comm This function may be called recursively to deal with callback * procedures. It handles most anything. * */ void VenfuncOut( aBlock *func, FILE *file ) { aParm *parm; aBlock *pCb; int type; /* Pointer to tag header type - depends on block type */ char *pIntHeader; static char achCbHeader[] = "@HU ="; static char achFuncHeader[] = "@HO ="; if( func == NULL || file == NULL) { fprintf(errfp, "Bogus params to VenFuncOut!\n"); return; } /* Get the blocktype for this block, do different things according to * type. */ type = func->blockType; /* * DO THE BLOCK HEADER */ switch (type) { case FUNCTION: /* use interior headers of normal level */ pIntHeader = achFuncHeader; /* Block header */ fprintf(file, "@HR = "); VentextOut(file, func->name, FALSE); fprintf(file, "\n\n"); /* Setup API description */ fprintf( file, "@HO = Syntax\n\n" ); VentextOut( file, func->type, FALSE ); fprintf( file, "<_>" ); VentextOut( file, func->name, FALSE ); fprintf( file, "" ); DoFunctionBlockHeader: /* Print the function header line, with parameters */ fprintf(file, "("); for (parm = func->parm; parm != NULL; ) { fprintf(file, ""); VentextOut(file, parm->name, FALSE); fprintf(file, ""); /* Advance */ parm = parm->next; if (parm != NULL) fprintf(file, ", "); } fprintf(file, ")\n\n"); // fprintf(file, "\n\n"); break; case CALLBACK: /* Use callback interior header styles */ pIntHeader = achCbHeader; /* Print function header setup */ fprintf(file, "@HO = Callback\n\n"); VentextOut(file, func->type, FALSE); fprintf(file, "<_>"); VentextOut(file, func->name, FALSE); fprintf(file, ""); /* Get the parameter list done the same way as with a normal * function. Cheat by using a goto to the above code. */ goto DoFunctionBlockHeader; break; case MESSAGE: pIntHeader = achFuncHeader; /* Print message header setup */ fprintf(file, "@HR = "); VentextOut(file, func->name, FALSE); fprintf(file, "\n\n"); // fprintf(file, "@HO = Description\n\n"); break; case MASMBLOCK: pIntHeader = achFuncHeader; /* Print MASM block header setup */ fprintf(file, "@HR = "); VentextOut(file, func->name, FALSE); fprintf(file, "\n\n"); break; case MASMCBBLOCK: pIntHeader = achCbHeader; /* Print MASM block header setup */ fprintf(file, "@HO = Callback\n\n"); /* BOLD THE CALLBACK NAME? */ fprintf(file, ""); VentextOut(file, func->name, FALSE); fprintf(file, "\n\n"); break; case STRUCTBLOCK: case UNIONBLOCK: pIntHeader = achFuncHeader; /* Print message header setup */ fprintf(file, "@HR = "); VentextOut(file, func->name, FALSE); fprintf(file, "\n\n"); // fprintf(file, "@HO = Description\n\n"); break; // case UNIONBLOCK: // break; default: fprintf(errfp, "Ventura: Unknown block type\n"); return; } // switch type /* * DO DESCRIPTION */ if (func->desc != NULL) { VentextOut( file, func->desc, TRUE ); fprintf( file, "\n" ); } /* * DO STRUCTURE/UNION FIELDS */ if (func->field != NULL) { /* Print structure dump in courier */ VenPrintStructText(func, file); /* Print out the fields with descriptions & flags in table * format. */ VenDoStructDescriptions(func, file); } if (func->other) { /* RTFOtherOut(file, func->other); */ } /* * DO PARAMETER OR REGISTER LISTS */ switch (type) { case FUNCTION: case CALLBACK: case MESSAGE: fprintf(file, "%s Parameters\n\n", pIntHeader); VenDoParmList(func, func->parm, file); assert(func->reg == NULL); break; case MASMBLOCK: case MASMCBBLOCK: fprintf(file, "%s Registers\n\n", pIntHeader); /* Print the register list in input register declaration format */ VenDoRegList(func, func->reg, file, REGISTERS); assert(func->parm == NULL); break; } /* * DO RETURN DESCRIPTION */ if( func->rtndesc != NULL ) { fprintf( file, "%s Return Value\n\n", pIntHeader ); /* Print the return description text */ VentextOut(file, func->rtndesc, TRUE); fprintf(file, "\n"); switch (type) { case MESSAGE: case FUNCTION: case CALLBACK: if (func->rtnflag != NULL) { VenDoFlagList(func->rtnflag, file, PARAMRETURN); fprintf(file, "@LE = \n\n"); } break; case MASMBLOCK: case MASMCBBLOCK: /* Process any available register tags */ if (func->rtnreg != NULL) { VenDoRegList(func, func->rtnreg, file, REGRETURN); } /* Now do the conditional list */ if (func->cond != NULL) { VenDoCondList(func, func->cond, file); } break; default: assert(0); break; } // switch } /* * DO USES TAG */ if (func->uses != NULL) { fprintf(file, "%s Uses\n\n", pIntHeader); VentextOut(file, func->uses, TRUE); fprintf(file, "\n@LE = \n\n"); } /* * DO COMMENT BLOCK */ if( func->comment != NULL ) { fprintf( file, "%s Comments\n\n", pIntHeader ); VentextOut( file, func->comment, TRUE ); fprintf( file, "\n" ); } /* * DO ANY CALLBACKS */ for (pCb = func->cb; pCb != NULL; pCb = pCb->next) { VenfuncOut( pCb, file ); } /* * DO CROSS REFERENCES */ if (func->xref != NULL) { VenDoXrefs(file, func->xref); } /* Done. Whew! */ } /**************************************************** * * RANDOM STUFF TO SUPPORT RTF FILES * ****************************************************/ void VenFileInit(FILE * phoutfile, logentry *curlog) { return; } void VenFileProcess(FILE * phoutfile, files curfile) { copyfile(phoutfile,curfile->filename); return; } void VenFileDone(FILE * phoutfile, files headfile) { return; } void VenLogInit(FILE * phoutfile, logentry * * pheadlog) { return; } void VenLogProcess(FILE * phoutfile, logentry * curlog) { return; } void VenLogDone(FILE * phoutfile, logentry * headlog) { return; }