|
|
/*
ventura.c - Module to output the data. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#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="<MI>"; char *pchVenfunc="<B>"; char *pchVenelem="<B>"; char *pchVendefault="<D>";
#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 * <f VenLineOut> 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, "<D>"); // 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 <p pColHead>. * * @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 <f VenLineOut> 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, "<D>\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 <f VenLineOut> on the next iteration * in order to continue the formatting code across a line break. * * @comm Reads and expands both old <p>foobar<d> style function * parameters and <p foobar> new-style parameters. * * This functions sends out character strings. Use <f VentextOut> and * <f VentextOut> for printing the aLine text storage data structures. * */ int VenLineOut(FILE * fpoutfile, char * pch, int wState) {
/*
* <p> is parm * <f> is function * <t> is struct/union reference * <e> is structure element reference * <m> is message * <d> is return to default * <p foobar> is param * <f foobar> is function * <t foobar> 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, "<D>"); // 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: <d foobar> encountered." " <d> is the only valid use for <d>.\n"); /* Here, just print the <d_ anyway. Then
* set no mode, continue. */ fprintf(fpoutfile, "<d "); } else { /* Oldstyle end of formatting encountered.
* Cancel the current mode, output * a return-to-normal code (ventura is nice * for this one thing, being consistent in * what constitues return-to-normal!) */ wState = TEXT; // reset mode
fprintf(fpoutfile, "<D>"); } 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, "<D>"); 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 * <f VenDoFlagList>. * * @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, "<_><MI>"); VentextOut( file, parm->name, FALSE ); fprintf( file, "<D>\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 * <f VenDoFlagList>. * * @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, "<B>" ); VentextOut( file, reg->name, FALSE ); fprintf( file, "<D>\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, ";<R>\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 {<R>\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;<R>\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, "{<R>\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 <f VenPrintFieldText> 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<B>", aachFieldNameTags[level]); VentextOut(file, type->name, FALSE); fprintf(file, "<D>\n\n"); #if 0
/* Print parameter type above? */ fprintf(file, "<_><MI>"); 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, "<B>%s<D>\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 <B>%s<D>:\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 <b>%s<d> %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, "<_><B>" ); VentextOut( file, func->name, FALSE ); fprintf( file, "<D>" );
DoFunctionBlockHeader: /* Print the function header line, with parameters */ fprintf(file, "("); for (parm = func->parm; parm != NULL; ) { fprintf(file, "<MI>"); VentextOut(file, parm->name, FALSE); fprintf(file, "<D>"); /* 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, "<_><B>"); VentextOut(file, func->name, FALSE); fprintf(file, "<D>");
/* 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, "<B>"); VentextOut(file, func->name, FALSE); fprintf(file, "<D>\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; }
|