1739 lines
42 KiB
C
1739 lines
42 KiB
C
/*
|
|
readext.c Read Extract file.
|
|
|
|
|
|
Copyright (c) 1989, Microsoft. All Rights Reserved.
|
|
|
|
10-09-89 Matt Saettler
|
|
10-11-89 Version 1.0
|
|
10-11-89 MHS New Extract codes
|
|
...
|
|
10-15-89 Completed Autodoc style comments.
|
|
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <search.h>
|
|
#include <io.h>
|
|
#include <direct.h>
|
|
#include <ctype.h>
|
|
|
|
#include "types.h"
|
|
#include "readext.h"
|
|
#include "text.h"
|
|
#include "docfmt.h"
|
|
#include "process.h"
|
|
#include "misc.h"
|
|
#include "rtf.h"
|
|
#include "errstr.h"
|
|
|
|
int curFieldLevel=0;
|
|
|
|
void getDocLevel(aBlock *pBlock, EXTFile *pExt);
|
|
void getSrcLine(aBlock *pBlock, EXTFile *pExt);
|
|
|
|
struct codes_struct Codes[]=
|
|
{
|
|
// Heading level stuff
|
|
|
|
TG_BEGINBLOCK , T2_BEGINBLOCK , "BEGINBLOCK", 0,
|
|
TG_ENDBLOCK , T2_ENDBLOCK , "ENDBLOCK", 0,
|
|
TG_ENDBLOCK , T2_ENDCALLBACK , "ENDCALLBACK", 0,
|
|
TG_DOCLEVEL , T2_DOCLEVEL , "DOCLEVEL", 0,
|
|
TG_SRCLINE , T2_SRCLINE , "SRCLINE", 0,
|
|
|
|
TG_BEGINHEAD , T2_BEGINHEAD , "BeginHead", 0,
|
|
TG_EXTRACTID , T2_EXTRACTID , "ExtractID", 0,
|
|
TG_EXTRACTVER , T2_EXTRACTVER , "ExtractVer", 0,
|
|
TG_EXTRACTDATE , T2_EXTRACTDATE , "ExtractDate", 0,
|
|
TG_ENDHEAD , T2_ENDHEAD , "EndHead", 0,
|
|
|
|
TG_BEGINHEADER , T2_BEGINHEADER , "BeginHeader", 0,
|
|
TG_ENDHEADER , T2_ENDHEADER , "EndHeader", 0,
|
|
|
|
// API (function) block
|
|
TG_TYPE , T2_FUNCTYPE , "ApiType", 0,
|
|
TG_NAME , T2_FUNCNAME , "ApiName", 0,
|
|
TG_DESC , T2_FUNCDESC , "ApiDesc", 0,
|
|
TG_PARMTYPE , T2_PARMTYPE , "ApiParmType", 0,
|
|
TG_PARMNAME , T2_PARMNAME , "ApiParmName", 0,
|
|
TG_PARMDESC , T2_PARMDESC , "ApiParmDesc", 0,
|
|
TG_FLAGNAME , T2_FLAGNAMEPARM , "ApiFlagNameParm", 0,
|
|
TG_FLAGDESC , T2_FLAGDESCPARM , "ApiFlagDescParm", 0,
|
|
|
|
TG_FLAGNAME , T2_FLAGNAMERTN , "ApiFlagNameRtn", 0,
|
|
TG_FLAGDESC , T2_FLAGDESCRTN , "APIFlagDescRtn", 0,
|
|
TG_RTNDESC , T2_RTNDESC , "ApiRtnDesc", 0,
|
|
TG_COMMENT , T2_COMMENT , "ApiComment", 0,
|
|
TG_XREF , T2_XREF , "ApiXref", 0,
|
|
TG_USES , T2_USES , "ApiUses", 0,
|
|
|
|
// callback block
|
|
TG_TYPE , T2_CBTYPE , "CBTYPE", 0,
|
|
TG_NAME , T2_CBNAME , "CBNAME", 0,
|
|
TG_DESC , T2_CBDESC , "CBDESC", 0,
|
|
TG_PARMTYPE , T2_CBPARMTYPE , "CBPARMTYPE", 0,
|
|
TG_PARMNAME , T2_CBPARMNAME , "CBPARMNAME", 0,
|
|
TG_PARMDESC , T2_CBPARMDESC , "CBPARMDESC", 0,
|
|
TG_FLAGNAME , T2_CBFLAGNAMEPARM , "CBFLAGNAMEPARM", 0,
|
|
TG_FLAGDESC , T2_CBFLAGDESCPARM , "CBFLAGDESCPARM", 0,
|
|
TG_RTNDESC , T2_CBRTNDESC , "CBRTNDESC", 0,
|
|
TG_FLAGNAME , T2_CBFLAGNAMERTN , "CBFLAGNAMERTN", 0,
|
|
TG_FLAGDESC , T2_CBFLAGDESCRTN , "CBFLAGDESCRTN", 0,
|
|
TG_COMMENT , T2_CBCOMMENT , "CBCOMMENT", 0,
|
|
TG_XREF , T2_CBXREF , "CBXref", 0,
|
|
TG_USES , T2_CBUSES , "CBUses", 0,
|
|
|
|
TG_REGNAME , T2_CBREGNAME , "CBRegNAME", 0,
|
|
TG_REGDESC , T2_CBREGDESC , "CBRegDESC", 0,
|
|
TG_REGNAME , T2_CBFLAGNAMEREG , "CBFLAGNAMEReg", 0,
|
|
TG_REGDESC , T2_CBFLAGDESCREG , "CBFLAGDESCReg", 0,
|
|
|
|
#ifdef WARPAINT
|
|
// Interrupt Block
|
|
|
|
TG_TYPE , T2_INTTYPE , "INTTYPE", 0,
|
|
TG_NAME , T2_INTNAME , "INTNAME", 0,
|
|
TG_DESC , T2_INTDESC , "INTDESC", 0,
|
|
//TG_PARMTYPE , T2_INTPARMTYPE , "INTPARMTYPE", 0,
|
|
//TG_PARMNAME , T2_INTPARMNAME , "INTPARMNAME", 0,
|
|
//TG_PARMDESC , T2_INTPARMDESC , "INTPARMDESC", 0,
|
|
//TG_FLAGNAME , T2_INTFLAGNAMEPARM , "INTFLAGNAMEPARM", 0,
|
|
//TG_FLAGDESC , T2_INTFLAGDESCPARM , "INTFLAGDESCPARM", 0,
|
|
TG_RTNDESC , T2_INTRTNDESC , "INTRTNDESC", 0,
|
|
TG_FLAGNAME , T2_INTFLAGNAMERTN , "INTFLAGNAMERTN", 0,
|
|
TG_FLAGDESC , T2_INTFLAGDESCRTN , "INTFLAGDESCRTN", 0,
|
|
TG_COMMENT , T2_INTCOMMENT , "INTCOMMENT", 0,
|
|
TG_XREF , T2_INTXREF , "INTXref", 0,
|
|
TG_USES , T2_INTUSES , "INTUses", 0,
|
|
|
|
TG_REGNAME , T2_INTREGNAME , "INTRegNAME", 0,
|
|
TG_REGDESC , T2_INTREGDESC , "INTRegDESC", 0,
|
|
TG_FLAGNAME , T2_INTFLAGNAMEREGRTN , "INTFLAGNAMERegRtn", 0,
|
|
TG_FLAGDESC , T2_INTFLAGDESCREGRTN , "IntFLAGDESCRegRtn", 0,
|
|
TG_FLAGNAME , T2_INTFLAGNAMEREG , "INTFLAGNAMEReg", 0,
|
|
TG_FLAGDESC , T2_INTFLAGDESCREG , "IntFLAGDESCReg", 0,
|
|
|
|
#endif
|
|
|
|
// Asm Block
|
|
TG_TYPE , T2_ASMTYPE , "ASMTYPE", 0,
|
|
TG_NAME , T2_ASMNAME , "ASMNAME", 0,
|
|
TG_DESC , T2_ASMDESC , "ASMDESC", 0,
|
|
TG_PARMTYPE , T2_ASMPARMTYPE , "ASMPARMTYPE", 0,
|
|
TG_PARMNAME , T2_ASMPARMNAME , "ASMPARMNAME", 0,
|
|
TG_PARMDESC , T2_ASMPARMDESC , "ASMPARMDESC", 0,
|
|
TG_FLAGNAME , T2_ASMFLAGNAMEPARM , "ASMFLAGNAMEPARM", 0,
|
|
TG_FLAGDESC , T2_ASMFLAGDESCPARM , "ASMFLAGDESCPARM", 0,
|
|
TG_RTNDESC , T2_ASMRTNDESC , "ASMRTNDESC", 0,
|
|
TG_FLAGNAME , T2_ASMFLAGNAMERTN , "ASMFLAGNAMERTN", 0,
|
|
TG_FLAGDESC , T2_ASMFLAGDESCRTN , "ASMFLAGDESCRTN", 0,
|
|
TG_COMMENT , T2_ASMCOMMENT , "ASMCOMMENT", 0,
|
|
TG_XREF , T2_ASMXREF , "ASMXref", 0,
|
|
TG_USES , T2_ASMUSES , "ASMUses", 0,
|
|
|
|
TG_REGNAME , T2_ASMREGNAMERTN , "ASMRegNAMERtn", 0,
|
|
TG_REGDESC , T2_ASMREGDESCRTN , "ASMRegDESCRtn", 0,
|
|
TG_REGNAME , T2_ASMREGNAME , "ASMRegNAME", 0,
|
|
TG_REGDESC , T2_ASMREGDESC , "ASMRegDESC", 0,
|
|
TG_FLAGNAME , T2_ASMFLAGNAMEREGRTN , "ASMFLAGNAMERegRtn", 0,
|
|
TG_FLAGDESC , T2_ASMFLAGDESCREGRTN , "AsmFLAGDESCRegRtn", 0,
|
|
TG_FLAGNAME , T2_ASMFLAGNAMEREG , "ASMFLAGNAMEReg", 0,
|
|
TG_FLAGDESC , T2_ASMFLAGDESCREG , "AsmFLAGDESCReg", 0,
|
|
TG_COND , T2_ASMCOND , "AsmCond", 0,
|
|
|
|
// Asm CallBack Block
|
|
TG_TYPE , T2_ASMCBTYPE , "ASMCBTYPE", 0,
|
|
TG_NAME , T2_ASMCBNAME , "ASMCBNAME", 0,
|
|
TG_DESC , T2_ASMCBDESC , "ASMCBDESC", 0,
|
|
TG_PARMTYPE , T2_ASMPARMTYPE , "ASMCBPARMTYPE", 0,
|
|
TG_PARMNAME , T2_ASMCBPARMNAME , "ASMCBPARMNAME", 0,
|
|
TG_PARMDESC , T2_ASMCBPARMDESC , "ASMCBPARMDESC", 0,
|
|
TG_FLAGNAME , T2_ASMCBFLAGNAMEPARM , "ASMCBFLAGNAMEPARM", 0,
|
|
TG_FLAGDESC , T2_ASMCBFLAGDESCPARM , "ASMCBFLAGDESCPARM", 0,
|
|
TG_RTNDESC , T2_ASMCBRTNDESC , "ASMCBRTNDESC", 0,
|
|
TG_FLAGNAME , T2_ASMCBFLAGNAMERTN , "ASMCBFLAGNAMERTN", 0,
|
|
TG_FLAGDESC , T2_ASMCBFLAGDESCRTN , "ASMCBFLAGDESCRTN", 0,
|
|
TG_COMMENT , T2_ASMCBCOMMENT , "ASMCBCOMMENT", 0,
|
|
TG_XREF , T2_ASMCBXREF , "ASMCBXref", 0,
|
|
TG_USES , T2_ASMCBUSES , "ASMCBUses", 0,
|
|
|
|
TG_REGNAME , T2_ASMCBREGNAMERTN , "ASMCBRegNAMERtn", 0,
|
|
TG_REGDESC , T2_ASMCBREGDESCRTN , "ASMCBRegDESCRtn", 0,
|
|
TG_REGNAME , T2_ASMCBREGNAME , "ASMCBRegNAME", 0,
|
|
TG_REGDESC , T2_ASMCBREGDESC , "ASMCBRegDESC", 0,
|
|
TG_FLAGNAME , T2_ASMCBFLAGNAMEREGRTN, "ASMCBFLAGNAMERegRtn", 0,
|
|
TG_FLAGDESC , T2_ASMCBFLAGDESCREGRTN, "AsmCBFLAGDESCRegRtn", 0,
|
|
TG_FLAGNAME , T2_ASMCBFLAGNAMEREG , "ASMCBFLAGNAMEReg", 0,
|
|
TG_FLAGDESC , T2_ASMCBFLAGDESCREG , "AsmCBFLAGDESCReg", 0,
|
|
TG_COND , T2_ASMCBCOND , "AsmCBCond", 0,
|
|
|
|
// Message Block
|
|
TG_TYPE , T2_MSGTYPE , "MSGTYPE", 0,
|
|
TG_NAME , T2_MSGNAME , "MSGNAME", 0,
|
|
TG_DESC , T2_MSGDESC , "MSGDESC", 0,
|
|
TG_PARMTYPE , T2_MSGPARMTYPE , "MSGPARMTYPE", 0,
|
|
TG_PARMNAME , T2_MSGPARMNAME , "MSGPARMNAME", 0,
|
|
TG_PARMDESC , T2_MSGPARMDESC , "MSGPARMDESC", 0,
|
|
TG_FLAGNAME , T2_MSGFLAGNAMEPARM , "MSGFLAGNAMEPARM", 0,
|
|
TG_FLAGDESC , T2_MSGFLAGDESCPARM , "MSGFLAGDESCPARM", 0,
|
|
TG_RTNDESC , T2_MSGRTNDESC , "MSGRTNDESC", 0,
|
|
TG_FLAGNAME , T2_MSGFLAGNAMERTN , "MSGFLAGNAMERTN", 0,
|
|
TG_FLAGDESC , T2_MSGFLAGDESCRTN , "MSGFLAGDESCRTN", 0,
|
|
TG_COMMENT , T2_MSGCOMMENT , "MSGCOMMENT", 0,
|
|
TG_XREF , T2_MSGXREF , "MsgXref", 0,
|
|
TG_USES , T2_MSGUSES , "MSGUses", 0,
|
|
|
|
TG_REGNAME , T2_MSGREGNAME , "MsgRegNAME", 0,
|
|
TG_REGDESC , T2_MSGREGDESC , "MsgRegDESC", 0,
|
|
TG_FLAGNAME , T2_MSGFLAGNAMEREG , "MsgFLAGNAMEReg", 0,
|
|
TG_FLAGDESC , T2_MSGFLAGDESCREG , "MsgFLAGDESCReg", 0,
|
|
|
|
// Typedef struct Block
|
|
TG_NAME , T2_STRUCTNAME , "STRUCTNAME", 0,
|
|
TG_DESC , T2_STRUCTDESC , "STRUCTDESC", 0,
|
|
TG_FIELDTYPE , T2_STRUCTFIELDTYPE , "STRUCTFIELDTYPE", 0,
|
|
TG_FIELDNAME , T2_STRUCTFIELDNAME , "STRUCTFIELDNAME", 0,
|
|
TG_FIELDDESC , T2_STRUCTFIELDDESC , "STRUCTFIELDDESC", 0,
|
|
TG_FLAGNAME , T2_STRUCTFLAGNAME , "STRUCTFLAGNAME", 0,
|
|
TG_FLAGDESC , T2_STRUCTFLAGDESC , "STRUCTFLAGDESC", 0,
|
|
|
|
TG_NAME , T2_STRUCTSTRUCTNAME , "structstructName", 0,
|
|
TG_DESC , T2_STRUCTSTRUCTDESC , "structstructDesc", 0,
|
|
TG_ENDBLOCK , T2_STRUCTSTRUCTEND , "structstructEnd", 0,
|
|
|
|
|
|
TG_NAME , T2_STRUCTUNIONNAME , "structunionName", 0,
|
|
TG_DESC , T2_STRUCTUNIONDESC , "structunionDesc", 0,
|
|
TG_ENDBLOCK , T2_STRUCTUNIONEND , "structunionEnd", 0,
|
|
|
|
TG_OTHERTYPE , T2_STRUCTOTHERTYPE , "STRUCTOTHERTYPE", 0,
|
|
TG_OTHERNAME , T2_STRUCTOTHERNAME , "STRUCTOTHERNAME", 0,
|
|
TG_OTHERDESC , T2_STRUCTOTHERDESC , "structotherdesc", 0,
|
|
|
|
TG_TAG , T2_STRUCTTAGNAME , "STRUCTTAGNAME", 0,
|
|
|
|
TG_COMMENT , T2_STRUCTCOMMENT , "STRUCTCOMMENT", 0,
|
|
TG_XREF , T2_STRUCTXREF , "STRUCTXref", 0,
|
|
|
|
// Typedef union Block
|
|
TG_NAME , T2_UNIONNAME , "UNIONNAME", 0,
|
|
TG_DESC , T2_UNIONDESC , "UNIONDESC", 0,
|
|
TG_FIELDTYPE , T2_UNIONFIELDTYPE , "UNIONFIELDTYPE", 0,
|
|
TG_FIELDNAME , T2_UNIONFIELDNAME , "UNIONFIELDNAME", 0,
|
|
TG_FIELDDESC , T2_UNIONFIELDDESC , "UNIONFIELDDESC", 0,
|
|
TG_FLAGNAME , T2_UNIONFLAGNAME , "UNIONFLAGNAME", 0,
|
|
TG_FLAGDESC , T2_UNIONFLAGDESC , "UNIONFLAGDESC", 0,
|
|
|
|
TG_NAME , T2_UNIONSTRUCTNAME , "UNIONstructName", 0,
|
|
TG_DESC , T2_UNIONSTRUCTDESC , "UNIONstructDesc", 0,
|
|
TG_ENDBLOCK , T2_UNIONSTRUCTEND , "UNIONstructEnd", 0,
|
|
|
|
|
|
TG_NAME , T2_UNIONUNIONNAME , "UNIONunionName", 0,
|
|
TG_DESC , T2_UNIONUNIONDESC , "UNIONunionDesc", 0,
|
|
TG_ENDBLOCK , T2_UNIONUNIONEND , "UNIONunionEnd", 0,
|
|
|
|
TG_OTHERTYPE , T2_UNIONOTHERTYPE , "UNIONOTHERTYPE", 0,
|
|
TG_OTHERNAME , T2_UNIONOTHERNAME , "UNIONOTHERNAME", 0,
|
|
TG_OTHERDESC , T2_UNIONOTHERDESC , "UNIONOTHERDESC", 0,
|
|
|
|
TG_TAG , T2_UNIONTAGNAME , "UNIONTAGNAME", 0,
|
|
|
|
TG_COMMENT , T2_UNIONCOMMENT , "UNIONCOMMENT", 0,
|
|
TG_XREF , T2_UNIONXREF , "UNIONXref", 0,
|
|
|
|
// end marker
|
|
0 , 0 , 0, 0
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func char * | nextText | This updates the curlinepos for
|
|
* the specified Extracted file.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted structure.
|
|
*
|
|
*/
|
|
void nextText( EXTFile *pExt )
|
|
{
|
|
if( !pExt)
|
|
return;
|
|
|
|
while( (pExt->lineBuffer[pExt->curlinepos] != '\n') &&
|
|
(pExt->lineBuffer[pExt->curlinepos] != '\0') &&
|
|
(pExt->lineBuffer[pExt->curlinepos] != '\t') &&
|
|
(pExt->lineBuffer[pExt->curlinepos] != ' ') )
|
|
{
|
|
pExt->curlinepos++;
|
|
}
|
|
while( (pExt->lineBuffer[pExt->curlinepos] != '\n') &&
|
|
(pExt->lineBuffer[pExt->curlinepos] != '\0') &&
|
|
( (pExt->lineBuffer[pExt->curlinepos] == '\t') ||
|
|
(pExt->lineBuffer[pExt->curlinepos] == ' ') ) )
|
|
{
|
|
pExt->curlinepos++;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func DWORD | getTag | This function finds the possible tag in the
|
|
* lineBuffer.
|
|
*
|
|
* @rdesc The return value is the command of the tag in the line buffer.
|
|
* It is NULL if the tag is not found.
|
|
*
|
|
* @flag loword | Uniquely identifies the tag.
|
|
*
|
|
* @flag TYPE(loword) | Type of the tag.
|
|
*
|
|
* @flag hiword | Group of the tag.
|
|
*
|
|
* @xref _getTag
|
|
*/
|
|
DWORD getTag( EXTFile *pExt )
|
|
{
|
|
if(pExt->curtag)
|
|
return(pExt->curtag);
|
|
|
|
pExt->curlinepos=0;
|
|
|
|
while( (pExt->lineBuffer[pExt->curlinepos] != '@') &&
|
|
(pExt->lineBuffer[pExt->curlinepos] != '\n') &&
|
|
(pExt->lineBuffer[pExt->curlinepos] != '\0') &&
|
|
( (pExt->lineBuffer[pExt->curlinepos] == '\t') ||
|
|
(pExt->lineBuffer[pExt->curlinepos] == ' ') ) ) {
|
|
pExt->curlinepos++;
|
|
}
|
|
|
|
if( pExt->lineBuffer[pExt->curlinepos] == '@' )
|
|
{
|
|
pExt->curlinepos++;
|
|
pExt->curtag=_getTag(pExt);
|
|
return(pExt->curtag);
|
|
|
|
}
|
|
else if( pExt->lineBuffer[pExt->curlinepos] == '\n' )
|
|
{
|
|
pExt->lineBuffer[pExt->curlinepos] = '\0';
|
|
return( 0 );
|
|
}
|
|
else
|
|
return( 0 );
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func DWORD | _getTag | This function returns the command value of the
|
|
* tag on the buffer.
|
|
*
|
|
* @rdesc The return value is the command of the tag in the line buffer.
|
|
* It is NULL if the tag is not found.
|
|
*
|
|
* @flag loword | Uniquely identifies the tag.
|
|
*
|
|
* @flag TYPE(loword) | Type of the tag.
|
|
*
|
|
* @flag hiword | Group of the tag.
|
|
*
|
|
*/
|
|
DWORD
|
|
_getTag(EXTFile *pExt)
|
|
{
|
|
int cur_command;
|
|
|
|
for(cur_command=0;Codes[cur_command].pchcommand != NULL; cur_command++)
|
|
{ /* we are still comparing a valid command... */
|
|
if(strnicmp(pExt->lineBuffer+ pExt->curlinepos,Codes[cur_command].pchcommand,Codes[cur_command].size)==0)
|
|
{ /* we found a match */
|
|
pExt->curlinepos+=Codes[cur_command].size;
|
|
|
|
return( ( (DWORD)Codes[cur_command].icommand << 16L) +
|
|
( (DWORD)Codes[cur_command].igeneral) );
|
|
}
|
|
}
|
|
/* didn't match any known tag */
|
|
return(0);
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func int | initreadext | This function is used to initialize the
|
|
* Read External functions. It must be called before any of the readext
|
|
* functions are called.
|
|
*
|
|
* @rdesc This function returs TRUE if the initialization was successful.
|
|
*
|
|
*/
|
|
int
|
|
initreadext()
|
|
{
|
|
int cur_command;
|
|
|
|
for(cur_command=0;Codes[cur_command].pchcommand != NULL; cur_command++)
|
|
{ /* we are still comparing a valid command... */
|
|
Codes[cur_command].size=strlen(Codes[cur_command].pchcommand);
|
|
}
|
|
/* INIT OK */
|
|
return(TRUE);
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func int | processText | This function takes the text for the
|
|
* already found tag. (starting at the given point) and puts it
|
|
* into the specified place.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @parm aLine * | place | Specifies the place to store the text.
|
|
*
|
|
* @rdesc The return value is non zero if there was an error
|
|
* while processing the file.
|
|
*/
|
|
int processText( EXTFile *pExt, aLine **place )
|
|
{
|
|
int ok;
|
|
aLine * line;
|
|
|
|
if( place == NULL )
|
|
{
|
|
return( ST_ERROR );
|
|
}
|
|
|
|
/* if we have more text on line left place into
|
|
aLine
|
|
*/
|
|
if( pExt->lineBuffer[pExt->curlinepos])
|
|
{
|
|
line = lineMake( pExt->lineBuffer + pExt->curlinepos );
|
|
if( line == NULL )
|
|
{
|
|
return( ST_MEMORY );
|
|
}
|
|
lineAdd( place, line );
|
|
}
|
|
|
|
/* get rest of text for this tag. */
|
|
ok = getLine(pExt);
|
|
while( ok && ( !getTag(pExt) ) )
|
|
{
|
|
line = lineMake( pExt->lineBuffer );
|
|
if( line == NULL )
|
|
{
|
|
return( ST_MEMORY );
|
|
}
|
|
lineAdd( place, line );
|
|
ok = getLine( pExt );
|
|
}
|
|
if( !ok )
|
|
return( ST_ERROR_EOF );
|
|
else
|
|
return( 0 );
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func char * | getFlag | This function gets a list of Flag blocks
|
|
* from the file. The flag blocks are stored in the list.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @parm aFlag * * | flag | Specifies the head of the list to place
|
|
* the list of flags.
|
|
*
|
|
* @rdesc The return value is non zero if there was an error
|
|
* while processing the file.
|
|
*/
|
|
int getFlag( EXTFile *pExt, aFlag * * flag )
|
|
{
|
|
int rtn;
|
|
int ok, nStatus;
|
|
char * text;
|
|
char * tag;
|
|
int itag;
|
|
int startType;
|
|
DWORD dTag;
|
|
aFlag *curFlag;
|
|
aFlag *tFlag;
|
|
|
|
if( flag == NULL )
|
|
return( ST_ERROR );
|
|
|
|
/* find begin of flag */
|
|
itag=(int)getTag(pExt);
|
|
startType=TYPE(itag);
|
|
if( itag != TG_FLAGNAME )
|
|
return( ST_BADOBJ );
|
|
|
|
curFlag=flagAlloc();
|
|
if( curFlag == NULL )
|
|
return( ST_MEMORY );
|
|
|
|
if(!*flag)
|
|
*flag =curFlag;
|
|
else
|
|
{
|
|
tFlag=*flag;
|
|
while(tFlag->next)
|
|
{
|
|
tFlag=tFlag->next;
|
|
}
|
|
tFlag->next=curFlag;
|
|
}
|
|
|
|
nStatus = processText( pExt, &((curFlag)->name) );
|
|
if( nStatus)
|
|
return( nStatus );
|
|
|
|
/* find desc of flag */
|
|
itag=(int)getTag(pExt);
|
|
if( itag == TG_FLAGDESC )
|
|
{
|
|
nStatus = processText( pExt, &((curFlag)->desc) );
|
|
if( nStatus)
|
|
return( nStatus );
|
|
}
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func char * | getField | This function gets a list of Field blocks
|
|
* from the file. The blocks are stored in the list.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @parm aField * * | field | Specifies the head of the list to place
|
|
* the list of fields.
|
|
*
|
|
* @rdesc The return value is non zero if there was an error
|
|
* while processing the file.
|
|
*/
|
|
int getSUType( EXTFile *pExt, aField * * field )
|
|
{
|
|
int rtn;
|
|
int ok, nStatus;
|
|
// char * text;
|
|
// char * tag;
|
|
int itag;
|
|
// int startType;
|
|
DWORD dTag;
|
|
aField *curfield;
|
|
aField *tfield;
|
|
aType *curtype;
|
|
|
|
if( field == NULL )
|
|
return( ST_ERROR );
|
|
|
|
/* find begin of flag */
|
|
itag=(int)getTag(pExt);
|
|
// startType=TYPE(itag);
|
|
|
|
|
|
if( itag != TG_FIELDTYPE )
|
|
return( ST_BADOBJ );
|
|
|
|
curfield=fieldAlloc();
|
|
if( curfield == NULL )
|
|
return( ST_MEMORY );
|
|
|
|
|
|
if(!*field)
|
|
*field =curfield;
|
|
else
|
|
{
|
|
tfield=*field;
|
|
while(tfield->next)
|
|
{
|
|
tfield=tfield->next;
|
|
}
|
|
tfield->next=curfield;
|
|
}
|
|
|
|
curfield->wType=FIELD_TYPE;
|
|
curtype=typeAlloc();
|
|
if(curtype == NULL)
|
|
return (ST_MEMORY);
|
|
|
|
curtype->level=curFieldLevel;
|
|
curfield->ptr=(void *)curtype;
|
|
|
|
nStatus = processText( pExt, &((curtype)->type) );
|
|
if( nStatus)
|
|
return( nStatus );
|
|
|
|
/* find name of field */
|
|
itag=(int)getTag(pExt);
|
|
if( itag == TG_FIELDNAME )
|
|
{
|
|
nStatus = processText( pExt, &((curtype)->name) );
|
|
if( nStatus)
|
|
return( nStatus );
|
|
}
|
|
else
|
|
return( ST_BADOBJ );
|
|
|
|
/* find desc of field */
|
|
itag=(int)getTag(pExt);
|
|
if( itag == TG_FIELDDESC )
|
|
{
|
|
nStatus = processText( pExt, &((curtype)->desc) );
|
|
if( nStatus)
|
|
return( nStatus );
|
|
}
|
|
else
|
|
return( ST_BADOBJ );
|
|
|
|
/* process flags and other info */
|
|
nStatus = 0;
|
|
itag=(int)getTag(pExt);
|
|
while( (nStatus == 0) &&
|
|
( itag == TG_FLAGNAME) )
|
|
{
|
|
nStatus = getFlag( pExt, &((curtype)->flag) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
itag=(int)getTag(pExt);
|
|
}
|
|
|
|
return(nStatus);
|
|
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func char * | getReg | This function gets a list of register blocks
|
|
* from the file.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @parm aReg ** | reg | Specifies the head of the list of reg blocks
|
|
* to save.
|
|
*
|
|
* @rdesc The return value is non zero if there was an error
|
|
* while processing the file.
|
|
*/
|
|
int getReg( EXTFile *pExt, aReg * * reg )
|
|
{
|
|
int nStatus;
|
|
aFlag * flag;
|
|
aReg * curreg;
|
|
int itag;
|
|
int startType;
|
|
|
|
|
|
assert(reg);
|
|
assert(pExt);
|
|
|
|
/* find name of parameter */
|
|
|
|
itag=(int)getTag(pExt);
|
|
startType=TYPE((DWORD)itag);
|
|
|
|
if( itag != TG_REGNAME )
|
|
{
|
|
fprintf(errfp,"Error: Tag not regname at line %d in %s\n",
|
|
pExt->curlineno,
|
|
pExt->EXTFilename);
|
|
return( ST_BADOBJ );
|
|
}
|
|
|
|
curreg = regAlloc();
|
|
if( curreg == NULL )
|
|
return( ST_MEMORY );
|
|
|
|
regAdd(reg, curreg);
|
|
|
|
// itag = (int)getTag(pExt);
|
|
if( itag == TG_REGNAME)
|
|
{
|
|
nStatus = processText( pExt, &((curreg)->name) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
else
|
|
assert(TRUE); // what are we doing here?
|
|
|
|
/* find desc of parameter */
|
|
itag = (int)getTag(pExt);
|
|
if( itag == TG_REGDESC )
|
|
{
|
|
nStatus = processText( pExt, &((curreg)->desc) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
else
|
|
fprintf(errfp,"Warning: Register without Description at line %d in %s\n",
|
|
pExt->curlineno,
|
|
pExt->EXTFilename);
|
|
|
|
/* process flags and other info */
|
|
nStatus = 0;
|
|
itag=(int)getTag(pExt);
|
|
while( (nStatus == 0) &&
|
|
( itag == TG_FLAGNAME) )
|
|
{
|
|
nStatus = getFlag( pExt, &((curreg)->flag) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
itag=(int)getTag(pExt);
|
|
}
|
|
|
|
return(nStatus);
|
|
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func char * | getCond | This function gets a Conditional block
|
|
* from the file.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @parm aCond ** | ppCond | Specifies the head of the list of Cond blocks
|
|
* to save.
|
|
*
|
|
* @rdesc The return value is non zero if there was an error
|
|
* while processing the file.
|
|
*/
|
|
int getCond( EXTFile *pExt, aCond * * ppCond )
|
|
{
|
|
int nStatus;
|
|
aFlag * flag;
|
|
aCond * curcond;
|
|
// aReg * curreg;
|
|
int itag;
|
|
int startType;
|
|
|
|
|
|
assert(ppCond);
|
|
assert(pExt);
|
|
|
|
/* find name of parameter */
|
|
|
|
itag=(int)getTag(pExt);
|
|
startType=TYPE((DWORD)itag);
|
|
|
|
if( itag != TG_COND )
|
|
{
|
|
fprintf(errfp,"Error: Tag not Cond at line %d in %s\n",
|
|
pExt->curlineno,
|
|
pExt->EXTFilename);
|
|
return( ST_BADOBJ );
|
|
}
|
|
|
|
curcond= condAlloc();
|
|
if( curcond == NULL )
|
|
return( ST_MEMORY );
|
|
|
|
condAdd(ppCond, curcond);
|
|
|
|
// itag = (int)getTag(pExt);
|
|
if( itag == TG_COND)
|
|
{
|
|
nextText( pExt );
|
|
nStatus = processText( pExt, &((curcond)->desc) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
else
|
|
assert(TRUE); // what are we doing here?
|
|
|
|
/* process regs and other info */
|
|
nStatus = 0;
|
|
itag=(int)getTag(pExt);
|
|
while( (nStatus == 0) &&
|
|
( itag == TG_REGNAME) )
|
|
{
|
|
nStatus = getReg( pExt, &((curcond)->regs) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
itag=(int)getTag(pExt);
|
|
}
|
|
|
|
return(nStatus);
|
|
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func char * | getParm | This function gets a list of parameter blocks
|
|
* from the file.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @parm aParm ** | parm | Specifies the head of the list.
|
|
*
|
|
* @rdesc The return value is non zero if there was an error
|
|
* while processing the file.
|
|
*/
|
|
int getParm( EXTFile *pExt, aParm * * parm )
|
|
{
|
|
int nStatus;
|
|
aFlag * flag;
|
|
aParm * curparm;
|
|
int itag;
|
|
int startType;
|
|
|
|
assert(parm);
|
|
assert(pExt);
|
|
|
|
/* find name of parameter */
|
|
|
|
itag=(int)getTag(pExt);
|
|
startType=TYPE((DWORD)itag);
|
|
|
|
if( itag != TG_PARMTYPE )
|
|
return( ST_BADOBJ );
|
|
|
|
curparm = parmAlloc();
|
|
if( curparm == NULL )
|
|
return( ST_MEMORY );
|
|
|
|
parmAdd(parm, curparm);
|
|
|
|
/* find type of parameter */
|
|
if( itag == TG_PARMTYPE )
|
|
{
|
|
nStatus = processText( pExt, &((curparm)->type) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
|
|
itag = (int)getTag(pExt);
|
|
if( itag == TG_PARMNAME)
|
|
{
|
|
nStatus = processText( pExt, &((curparm)->name) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
|
|
/* find desc of parameter */
|
|
itag = (int)getTag(pExt);
|
|
if( itag == TG_PARMDESC )
|
|
{
|
|
nStatus = processText( pExt, &((curparm)->desc) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
|
|
/* process flags and other info */
|
|
nStatus = 0;
|
|
itag=(int)getTag(pExt);
|
|
while( (nStatus == 0) &&
|
|
( itag == TG_FLAGNAME) )
|
|
{
|
|
nStatus = getFlag( pExt, &((curparm)->flag) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
itag=(int)getTag(pExt);
|
|
}
|
|
|
|
return(nStatus);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func char * | getParm | This function gets a list of parameter blocks
|
|
* from the file.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @parm aParm ** | parm | Specifies the head of the list.
|
|
*
|
|
* @rdesc The return value is non zero if there was an error
|
|
* while processing the file.
|
|
*/
|
|
int getOther( EXTFile *pExt, aOther * * other )
|
|
{
|
|
int nStatus;
|
|
aOther * curother;
|
|
int itag;
|
|
int startType;
|
|
|
|
assert(other);
|
|
assert(pExt);
|
|
|
|
/* find name of parameter */
|
|
|
|
itag=(int)getTag(pExt);
|
|
startType=TYPE((DWORD)itag);
|
|
|
|
if( itag != TG_OTHERTYPE )
|
|
return( ST_BADOBJ );
|
|
|
|
curother = otherAlloc();
|
|
if( curother == NULL )
|
|
return( ST_MEMORY );
|
|
|
|
otherAdd(other, curother);
|
|
|
|
/* find type of other */
|
|
nStatus = processText( pExt, &((curother)->type) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
itag = (int)getTag(pExt);
|
|
nStatus = processText( pExt, &((curother)->name) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
|
|
/* find [optional] desc of other */
|
|
itag = (int)getTag(pExt);
|
|
if( itag == TG_OTHERDESC )
|
|
{
|
|
nStatus = processText( pExt, &((curother)->desc) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
|
|
return(nStatus);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func char * | getSU | This function gets a list of SU blocks
|
|
* from the file.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @parm aField * * | pField | Specifies the head of the list.
|
|
*
|
|
* @rdesc The return value is non zero if there was an error
|
|
* while processing the file.
|
|
*/
|
|
int getSU(EXTFile *pExt, aField **field)
|
|
{
|
|
int rtn;
|
|
int ok, nStatus;
|
|
// char * text;
|
|
// char * tag;
|
|
int itag;
|
|
// int startType;
|
|
DWORD dtag;
|
|
aField *curfield;
|
|
aField *tfield;
|
|
aSU *curSU;
|
|
int startType;
|
|
|
|
if( field == NULL )
|
|
return( ST_ERROR );
|
|
|
|
curfield=fieldAlloc();
|
|
if( curfield == NULL )
|
|
return( ST_MEMORY );
|
|
|
|
if(!*field)
|
|
*field =curfield;
|
|
else
|
|
{
|
|
tfield=*field;
|
|
while(tfield->next)
|
|
{
|
|
tfield=tfield->next;
|
|
}
|
|
tfield->next=curfield;
|
|
}
|
|
|
|
/* find begin of SU block */
|
|
dtag=getTag(pExt);
|
|
|
|
// since struct and union prefixes are the same, we only need to
|
|
// check for combo each ( ss, su, us, uu)
|
|
if(HIWORD(dtag) == T2_UNIONUNIONNAME)
|
|
curfield->wType=FIELD_UNION;
|
|
else if(HIWORD(dtag) == T2_STRUCTSTRUCTNAME)
|
|
curfield->wType=FIELD_STRUCT;
|
|
else
|
|
{
|
|
fprintf(errfp, "Unrecognized block type in getSU().\n");
|
|
fprintf(errfp,"Line %d. File %s\n",pExt->curlineno,pExt->EXTFilename);
|
|
}
|
|
|
|
curSU=SUAlloc();
|
|
if(curSU == NULL)
|
|
return (ST_MEMORY);
|
|
|
|
|
|
curSU->level=curFieldLevel;
|
|
curfield->ptr=(void *)curSU;
|
|
|
|
nStatus = processText( pExt, &((curSU)->name) );
|
|
if( nStatus)
|
|
return( nStatus );
|
|
|
|
|
|
/* find [optional] desc of SU */
|
|
itag=(int)getTag(pExt);
|
|
if( itag == TG_DESC )
|
|
{
|
|
nStatus = processText( pExt, &((curSU)->desc) );
|
|
if( nStatus)
|
|
return( nStatus );
|
|
}
|
|
|
|
/* process parms and other info */
|
|
nStatus = 0;
|
|
while( (nStatus == 0) )
|
|
{
|
|
|
|
itag=(int)getTag(pExt);
|
|
if(itag==TG_ENDBLOCK)
|
|
{
|
|
// this is a nested thing, so eat ENDBLOCK
|
|
getLine(pExt);
|
|
break;
|
|
}
|
|
|
|
switch(itag)
|
|
{
|
|
case TG_FIELDTYPE:
|
|
{
|
|
nStatus = getSUType(pExt, &(curSU->field) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
break;
|
|
|
|
case TG_NAME:
|
|
{
|
|
/* handles multiple parms */
|
|
curFieldLevel++;
|
|
nStatus = getSU(pExt, &(curSU->field) );
|
|
curFieldLevel--;
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
break;
|
|
default:
|
|
fprintf(errfp,"Unrecognized Tag on line %d\n%s",
|
|
pExt->curlineno,
|
|
pExt->lineBuffer
|
|
);
|
|
nStatus = ST_BADOBJ;
|
|
}
|
|
|
|
}
|
|
|
|
return( nStatus );
|
|
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func char * | getSUBlock | This function gets a list of SU blocks
|
|
* from the file.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @parm aBlock * | pBlock | Specifies the head of the list.
|
|
*
|
|
* @rdesc The return value is non zero if there was an error
|
|
* while processing the file.
|
|
*/
|
|
int getSUBlock(EXTFile *pExt, aBlock *pBlock)
|
|
{
|
|
int ok, nStatus;
|
|
int itag;
|
|
DWORD dtag;
|
|
int startType;
|
|
int fendRtn;
|
|
aBlock *pB2;
|
|
|
|
/* find begin of function */
|
|
dtag=getTag(pExt);
|
|
startType=TYPE(dtag);
|
|
|
|
if( HIWORD(dtag) == T2_STRUCTNAME )
|
|
{
|
|
pBlock->blockType=STRUCTBLOCK;
|
|
}
|
|
else if( HIWORD(dtag) == T2_UNIONNAME )
|
|
{
|
|
pBlock->blockType=UNIONBLOCK;
|
|
}
|
|
else
|
|
{
|
|
fprintf(errfp, "Unrecognized block type in getSUBlock().\n");
|
|
fprintf(errfp,"Line %d. File %s\n",pExt->curlineno,pExt->EXTFilename);
|
|
return( ST_BADOBJ );
|
|
}
|
|
|
|
/* find name of function */
|
|
itag=(int)getTag(pExt);
|
|
if( itag == TG_NAME )
|
|
{
|
|
nStatus = processText( pExt, &( pBlock->name) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
if(verbose>1)
|
|
fprintf(errfp, "%-30s",pBlock->name->text);
|
|
}
|
|
|
|
/* find description of function */
|
|
itag=(int)getTag(pExt);
|
|
if( itag == TG_DESC )
|
|
{
|
|
nStatus = processText( pExt, &( pBlock->desc) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
|
|
/* process parms and other info */
|
|
nStatus = 0;
|
|
while( (nStatus == 0) )
|
|
{
|
|
|
|
itag=(int)getTag(pExt);
|
|
if(itag==TG_ENDBLOCK)
|
|
break;
|
|
|
|
switch(itag)
|
|
{
|
|
case TG_FIELDTYPE:
|
|
{
|
|
nStatus = getSUType(pExt, &(pBlock->field) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
break;
|
|
|
|
case TG_NAME:
|
|
{
|
|
curFieldLevel++;
|
|
/* handles multiple parms */
|
|
nStatus = getSU(pExt, &(pBlock->field) );
|
|
curFieldLevel--;
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
break;
|
|
|
|
case TG_OTHERTYPE:
|
|
{
|
|
/* handles multiple parms */
|
|
nStatus = getOther(pExt, &(pBlock->other) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
break;
|
|
|
|
case TG_TAG:
|
|
{
|
|
nextText( pExt );
|
|
nStatus = processText( pExt, &(pBlock->tagname) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
}
|
|
break;
|
|
case TG_COMMENT:
|
|
{
|
|
nextText( pExt );
|
|
nStatus = processText( pExt, &(pBlock->comment) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
}
|
|
break;
|
|
case TG_XREF:
|
|
{
|
|
nextText( pExt );
|
|
nStatus = processText( pExt, &(pBlock->xref) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
}
|
|
break;
|
|
default:
|
|
fprintf(errfp,"Unrecognized Tag on line %d\n%s",
|
|
pExt->curlineno,
|
|
pExt->lineBuffer
|
|
);
|
|
nStatus = ST_BADOBJ;
|
|
}
|
|
|
|
}
|
|
|
|
return( nStatus );
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func char * | getFuncBlock | This function gets a list of function blocks
|
|
* from the file.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @parm aBlock * | pBlock | Specifies the head of the list.
|
|
*
|
|
* @rdesc The return value is non zero if there was an error
|
|
* while processing the file.
|
|
*/
|
|
int getFuncBlock(EXTFile *pExt, aBlock *pBlock)
|
|
{
|
|
int ok, nStatus;
|
|
int itag;
|
|
DWORD dtag;
|
|
int startType;
|
|
int fendRtn;
|
|
aBlock *pB2;
|
|
|
|
/* find begin of function */
|
|
dtag=getTag(pExt);
|
|
startType=TYPE(dtag);
|
|
|
|
if( HIWORD(dtag) == T2_FUNCTYPE )
|
|
{
|
|
pBlock->blockType=FUNCTION;
|
|
}
|
|
else if( HIWORD(dtag) == T2_CBTYPE )
|
|
{
|
|
pBlock->blockType=CALLBACK;
|
|
}
|
|
else if( HIWORD(dtag) == T2_MSGNAME )
|
|
{
|
|
pBlock->blockType=MESSAGE;
|
|
}
|
|
#ifdef WARPAINT
|
|
else if( HIWORD(dtag) == T2_INTNAME )
|
|
{
|
|
pBlock->blockType=INTBLOCK;
|
|
}
|
|
#endif
|
|
else if( HIWORD(dtag) == T2_ASMNAME )
|
|
{
|
|
pBlock->blockType=MASMBLOCK;
|
|
}
|
|
else if( HIWORD(dtag) == T2_ASMCBNAME )
|
|
{
|
|
pBlock->blockType=MASMCBBLOCK;
|
|
}
|
|
else
|
|
{
|
|
fprintf(errfp, "Unrecognized block type in getFuncBlock().\n");
|
|
fprintf(errfp,"Line %d. File %s\n",pExt->curlineno,pExt->EXTFilename);
|
|
return( ST_BADOBJ );
|
|
}
|
|
|
|
/* find type of function */
|
|
itag=(int)getTag(pExt);
|
|
if( itag == TG_TYPE )
|
|
{
|
|
nStatus = processText( pExt, &( pBlock->type) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
|
|
/* find name of function */
|
|
itag=(int)getTag(pExt);
|
|
if( itag == TG_NAME )
|
|
{
|
|
nStatus = processText( pExt, &( pBlock->name) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
if(verbose>1)
|
|
fprintf(errfp, "%-30s",pBlock->name->text);
|
|
}
|
|
|
|
/* find description of function */
|
|
itag=(int)getTag(pExt);
|
|
if( itag == TG_DESC )
|
|
{
|
|
nStatus = processText( pExt, &( pBlock->desc) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
|
|
/* process parms and other info */
|
|
nStatus = 0;
|
|
while( (nStatus == 0) )
|
|
{
|
|
// itag=TYPE(getTag(pExt));
|
|
// if(itag != startType || itag == T2_TYPEBLOCK )
|
|
// break;
|
|
|
|
itag=(int)getTag(pExt);
|
|
if(itag==TG_ENDBLOCK)
|
|
break;
|
|
|
|
switch(itag)
|
|
{
|
|
case TG_REGNAME:
|
|
{
|
|
assert(!pBlock->rtndesc);
|
|
|
|
/* handles multiple regss */
|
|
nStatus = getReg(pExt, &(pBlock->reg) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
break;
|
|
|
|
case TG_PARMTYPE:
|
|
{
|
|
assert(!pBlock->rtndesc);
|
|
|
|
/* handles multiple parms */
|
|
nStatus = getParm(pExt, &(pBlock->parm) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
break;
|
|
|
|
case TG_RTNDESC:
|
|
{
|
|
/* does'nt handle multiple return desc */
|
|
|
|
// assert(!pBlock->rtndesc);
|
|
|
|
nextText( pExt );
|
|
nStatus = processText( pExt, &( pBlock->rtndesc) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
fendRtn=FALSE;
|
|
while(!fendRtn)
|
|
{
|
|
itag=(int)getTag(pExt);
|
|
switch(itag)
|
|
{
|
|
case TG_FLAGNAME:
|
|
/* handles multiple flags */
|
|
#if 0
|
|
if(pBlock->blockType==MASMBLOCK ||
|
|
pBlock->blockType == INTBLOCK
|
|
)
|
|
{
|
|
fprintf(errfp,"Warning: Return flags in return block. Not allowed in this block type.\n");
|
|
fprintf(errfp,"Line %d. File %s\n",pExt->curlineno,pExt->EXTFilename);
|
|
}
|
|
#endif
|
|
nStatus = getFlag( pExt, &(pBlock->rtnflag) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
break;
|
|
case TG_REGNAME:
|
|
/* handles multiple regss */
|
|
#if 0
|
|
if(pBlock->blockType==MASMBLOCK ||
|
|
pBlock->blockType == INTBLOCK
|
|
)
|
|
{
|
|
fprintf(errfp,"Warning: Register in return block. Not allowed in this block type.\n");
|
|
fprintf(errfp,"Line %d. File %s\n",pExt->curlineno,pExt->EXTFilename);
|
|
}
|
|
#endif
|
|
nStatus = getReg(pExt, &(pBlock->rtnreg) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
break;
|
|
default:
|
|
fendRtn=TRUE;
|
|
break;
|
|
|
|
} // switch
|
|
} // while
|
|
} // Return
|
|
break;
|
|
case TG_COMMENT:
|
|
{
|
|
nextText( pExt );
|
|
nStatus = processText( pExt, &(pBlock->comment) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
}
|
|
break;
|
|
case TG_COND:
|
|
{
|
|
nStatus = getCond( pExt, &(pBlock->cond) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
break;
|
|
case TG_USES:
|
|
{
|
|
nextText( pExt );
|
|
nStatus = processText( pExt, &(pBlock->uses) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
}
|
|
break;
|
|
case TG_XREF:
|
|
{
|
|
nextText( pExt );
|
|
nStatus = processText( pExt, &(pBlock->xref) );
|
|
if( nStatus )
|
|
return( nStatus );
|
|
|
|
}
|
|
break;
|
|
case TG_NAME:
|
|
case TG_TYPE:
|
|
{
|
|
/* check to make sure CB and not FUNC or MSG */
|
|
pB2=newBlock();
|
|
pB2->blockType=CALLBACK;
|
|
|
|
if(verbose>1) fprintf(errfp,"\nCallback: ");
|
|
nStatus = getFuncBlock( pExt , pB2);
|
|
if(!pBlock->cb) /* head */
|
|
pBlock->cb=pB2;
|
|
else
|
|
{ /* insert at head */
|
|
pB2->next=pBlock->cb;
|
|
pBlock->cb=pB2;
|
|
}
|
|
if(nStatus )
|
|
return(nStatus);
|
|
|
|
/* eat end line */
|
|
getLine(pExt);
|
|
|
|
}
|
|
break;
|
|
default:
|
|
fprintf(errfp,"Unrecognized Tag on line %d\n%s",
|
|
pExt->curlineno,
|
|
pExt->lineBuffer
|
|
);
|
|
nStatus = ST_BADOBJ;
|
|
}
|
|
|
|
}
|
|
|
|
return( nStatus );
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func aBlock * | newBlock | This function allocates a new Block
|
|
*
|
|
*/
|
|
aBlock *
|
|
newBlock()
|
|
{
|
|
aBlock *pBlock;
|
|
pBlock=(aBlock *)clear_alloc(sizeof (aBlock));
|
|
return(pBlock);
|
|
|
|
}
|
|
|
|
#if 0
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func aBlock * | newBlock | This function allocates a new Block
|
|
*
|
|
*/
|
|
void
|
|
freeBlock(aBlock * pBlock)
|
|
{
|
|
assert(pBlock);
|
|
if(pBlock->srcfile)
|
|
my_free(pBlock->srcfile);
|
|
|
|
if(pBlock->doclevel)
|
|
lineDestroy(pBlock->doclevel);
|
|
|
|
if(pBlock->name)
|
|
lineDestroy(pBlock->name);
|
|
|
|
if(pBlock->type)
|
|
lineDestroy(pBlock->type);
|
|
|
|
if(pBlock->desc)
|
|
lineDestroy(pBlock->desc);
|
|
|
|
if(pBlock->parm)
|
|
parmDestroy(pBlock->parm);
|
|
|
|
if(pBlock->reg)
|
|
regDestroy(pBlock->reg);
|
|
|
|
if(pBlock->rtndesc)
|
|
lineDestroy(pBlock->rtndesc);
|
|
|
|
if(pBlock->rtnflag)
|
|
flagDestroy(pBlock->rtnflag);
|
|
|
|
if(pBlock->rtnreg)
|
|
regDestroy(pBlock->rtnreg);
|
|
|
|
if(pBlock->cond)
|
|
condDestroy(pBlock->cond);
|
|
|
|
if(pBlock->comment)
|
|
lineDestroy(pBlock->comment);
|
|
|
|
if(pBlock->cb)
|
|
freeBlock(pBlock->cb);
|
|
|
|
if(pBlock->xref)
|
|
lineDestroy(pBlock->xref);
|
|
|
|
if(pBlock->uses)
|
|
lineDestroy(pBlock->uses);
|
|
|
|
return;
|
|
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func aBlock * | getBlock | This function gets a block of documentation
|
|
* from the file.
|
|
*
|
|
* @parm EXTFile * | pExt | Specifies the Extracted file to process.
|
|
*
|
|
* @rdesc The return value is the block from the file or NULL if an error
|
|
* occured while processing the file.
|
|
*/
|
|
aBlock * getBlock(EXTFile * pExt)
|
|
{
|
|
int ok, nStatus;
|
|
int itag;
|
|
aBlock *pcurBlock;
|
|
|
|
/* find begin of block */
|
|
ok = TRUE;
|
|
while( ok && ((int)getTag(pExt) != TG_BEGINBLOCK ))
|
|
ok = getLine(pExt);
|
|
|
|
if( !ok )
|
|
return( NULL );
|
|
|
|
pcurBlock=newBlock();
|
|
|
|
/* get to next tag. */
|
|
ok = getLine(pExt );
|
|
while( ok && ( !getTag(pExt) ) )
|
|
ok = getLine( pExt );
|
|
|
|
if( !ok )
|
|
return( NULL );
|
|
|
|
|
|
itag=(int)getTag(pExt);
|
|
|
|
if(itag == TG_DOCLEVEL) /* set doclevel */
|
|
{
|
|
getDocLevel(pcurBlock, pExt);
|
|
itag=(int)getTag(pExt);
|
|
}
|
|
|
|
|
|
if(itag == TG_SRCLINE) /* set source file, line */
|
|
{
|
|
getSrcLine(pcurBlock, pExt);
|
|
itag=(int)getTag(pExt);
|
|
}
|
|
|
|
itag=HIWORD(getTag(pExt));
|
|
switch(itag)
|
|
{
|
|
case T2_STRUCTNAME:
|
|
case T2_UNIONNAME:
|
|
{
|
|
nStatus = getSUBlock(pExt, pcurBlock );
|
|
}
|
|
break;
|
|
|
|
case T2_FUNCTYPE:
|
|
case T2_FUNCNAME:
|
|
{
|
|
pcurBlock->blockType = FUNCTION;
|
|
nStatus = getFuncBlock(pExt, pcurBlock );
|
|
}
|
|
break;
|
|
|
|
case T2_MSGTYPE:
|
|
case T2_MSGNAME:
|
|
|
|
{
|
|
pcurBlock->blockType = MESSAGE;
|
|
nStatus = getFuncBlock(pExt, pcurBlock );
|
|
}
|
|
break;
|
|
#ifdef WARPAINT
|
|
case T2_INTTYPE:
|
|
case T2_INTNAME:
|
|
{
|
|
pcurBlock->blockType = INTBLOCK;
|
|
nStatus = getFuncBlock(pExt, pcurBlock );
|
|
}
|
|
break;
|
|
#endif
|
|
case T2_ASMTYPE:
|
|
case T2_ASMNAME:
|
|
{
|
|
pcurBlock->blockType = MASMBLOCK;
|
|
nStatus = getFuncBlock(pExt, pcurBlock );
|
|
}
|
|
break;
|
|
case T2_ASMCBTYPE:
|
|
case T2_ASMCBNAME:
|
|
{
|
|
pcurBlock->blockType = MASMCBBLOCK;
|
|
nStatus = getFuncBlock(pExt, pcurBlock );
|
|
}
|
|
break;
|
|
default:
|
|
|
|
{
|
|
fprintf(errfp,"Unrecognized Block Tag at line %d of %s\n",
|
|
pExt->curlineno,
|
|
pExt->EXTFilename);
|
|
pcurBlock->blockType = 0;
|
|
nStatus = ST_BADOBJ;
|
|
}
|
|
break;
|
|
}
|
|
/* eat text until end block */
|
|
ok = TRUE;
|
|
while( ok && ((int)getTag(pExt) != TG_ENDBLOCK ))
|
|
{
|
|
fprintf(errfp,"Warning: unexpected tags before end of block at line %d of %s\n",
|
|
pExt->curlineno,
|
|
pExt->EXTFilename);
|
|
ok = getLine(pExt);
|
|
}
|
|
|
|
/* read past end block */
|
|
ok = getLine(pExt);
|
|
|
|
if( nStatus == 0 )
|
|
{
|
|
ok = TRUE;
|
|
}
|
|
else if( nStatus == ST_BADOBJ )
|
|
{
|
|
error(WARN2, pExt->EXTFilename, pExt->curlineno );
|
|
nStatus = 0;
|
|
ok = TRUE;
|
|
}
|
|
else
|
|
return( NULL );
|
|
|
|
return(pcurBlock);
|
|
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func void | getDocLevel | This function parses the DOCLEVEL extract tag
|
|
* and fills in the information in the block.
|
|
*
|
|
* @parm aBlock * | pBlock | Specifies the block.
|
|
*
|
|
* @parm EXTFile *| pExt | Specifies the Extracted file.
|
|
*
|
|
*/
|
|
|
|
void getDocLevel(aBlock *pBlock, EXTFile *pExt)
|
|
{
|
|
aLine *pLine;
|
|
char *pch;
|
|
char *spch;
|
|
|
|
assert(pBlock);
|
|
assert(pExt);
|
|
|
|
pch=pExt->lineBuffer + pExt->curlinepos;
|
|
while(*pch)
|
|
{
|
|
while(isspace(*pch))
|
|
++pch;
|
|
spch=pch;
|
|
while(*pch && !isspace(*pch))
|
|
++pch;
|
|
if(*pch)
|
|
{
|
|
*pch='\0';
|
|
pLine=lineMake(spch);
|
|
if(pBlock->doclevel)
|
|
pLine->next=pBlock->doclevel;
|
|
pBlock->doclevel=pLine;
|
|
++pch;
|
|
}
|
|
}
|
|
getLine(pExt);
|
|
}
|
|
|
|
/*
|
|
* @doc INTERNAL READEXT
|
|
*
|
|
* @func void | getSrcLine | This function parses the SRCLINE extract tag
|
|
* and fills in the information in the block.
|
|
*
|
|
* @parm aBlock * | pBlock | Specifies the block.
|
|
*
|
|
* @parm EXTFile *| pExt | Specifies the Extracted file.
|
|
*
|
|
*/
|
|
void getSrcLine(aBlock *pBlock, EXTFile *pExt)
|
|
{
|
|
char *pch;
|
|
char *spch;
|
|
|
|
assert(pBlock);
|
|
assert(pExt);
|
|
|
|
pch=pExt->lineBuffer + pExt->curlinepos;
|
|
while(isspace(*pch))
|
|
++pch;
|
|
spch=pch;
|
|
while(!isspace(*pch))
|
|
++pch;
|
|
*pch='\0';
|
|
pBlock->srcfile=cp_alloc(spch);
|
|
|
|
++pch;
|
|
while(isspace(*pch))
|
|
++pch;
|
|
pBlock->srcline=atoi(pch);
|
|
|
|
getLine(pExt);
|
|
}
|