Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1370 lines
31 KiB

/*
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;
}