SECTION IV - Source Code

advertisement
SECTION IV - Source Code
#include "k:\develop\admp\admp.h"
/***************************************************** ********************
admp
PROGRAM:
*
PURPOSE:
the purpose of this program is to generate documentation
*
for a given project.
*
ARGS:
the following command line args can be used
*
admp [-rAI-rf filenamel-rF] [-g phrase] [-p pid]
*
*
-rA
refresh -*
-- everything for a project if a pid is specified
*
-- everything for all projects if no pid is specified
*
-rf
filename -- full path of file to refresh for this pid
*
-RF
FILELIST -- refresh file list only for this pid
*
-g
search
all files in the project for a phrase if a pid is given
*
search all files if no pid is given
*
-p
pid -- project identifier
*
*************************************************************************/
void main(int argc, char *argv[])
char *phrase=NULLi
char *RefreshOption=NULLi
int pid=O;
int fid=Oi
int rf=Oi
int rA=Oi
int rF=Oi
int g=Oi
int P=Oi
int error=Oi
int i = 1i
int ReturnCode=SUCCESS_CODEi
char server[20] = "server"i
char database[20] = "admp"i
char user[ll] = "sa"i
char password[ll] = ""i
if(! (argc>2)) //got some args
{
error++i
else
{
while (i<argc)
{
i f (argv [i] [0] ==' -' )
{
i f (argv[i] [l]=='r')
{
i f (argv [i] [2] ==' A' )
{
rA++i
}
else i f (argv[i] [2]=='F')
{
rF++i
}
1
else i f (argv [i) [2] ==' f')
{
rf++i
i f ({i+l) <argc)
{
i f (argv [i+l] [0] ! =' - , )
{
fid = atoi(argv[i+l])i
i++i
else
error++j
}
else
{
error++i
}
else i f (argv[i] [1] =='g')
{
g++j
i f ({i+l) <argc)
{
i f (argv [i+l] [0] ==' -' )
{
error++j
else
phrase
argv[i+l]
j
else
error++j
}
}
else i f {argv[i] [l]=='p')
{
P++i
i f ((i+l) <argc)
{
i f (argv [i+l] [0] ! =' -')
{
pid = atoi{argv[i+l])i
else
{
error++j
}
else
error++j
2
else
{
Ilerror
error++;
}
Ilif
i++;
Ilwhile
if (error)
{
fprintf(stderr, "Error:
invalid command line args.II);
else
{
Ilgotta connect to the database
DB_Connect (server, database, user,password);
if (rA) Ilrefresh
{
i f (p)
{
RefreshProjectFileList(pid);
RefreshAllFunctions(pid);
}
else
{
fprintf{stderr,"Not done yet. II );
else i f (rf)
{
i f (p)
ReturnCode = RefreshProjectFile(pid, fid);
if (ReturnCode != SUCCESS_CODE)
{
fprintf(stderr,"ERROR: II);
else
{
fprintf(stderr,"ERROR:
option with -r not valid.");
else
fprintf{stderr,"ERROR:
option with -r not valid.");
DB_Disconnect();
3
4
#include "k:\develop\admp\admp.h"
1***************************************************** **************
All these will be elsewhere later
****************************************************** *************1
1*
#define SUCCESS CODE 1
#define FAILURE CODE 2
#define NOTFOUND CODE 3
#define FALSE 0
#define TRUE 1
*1
1***************************************************** **********************
FUNCTION:
*
Connect
PURPOSE:
*
connect to the database
RETURNS:
*
none
PARAMTERS: none
*
AUTHOR:
*
DWM
***************************************************************************/
/*void Connect()
{
EXEC SQL begin declare section;
char database [40] ="danieljr.admp";
EXEC SQL end declare section;
EXEC SQL CONNECT TO :database USER sa;
/***************************************************************************
FUNCTION:
*
Disconnect
PURPOSE:
*
disconnect from the database
RETURNS:
*
none
PARAMTERS: none
*
AUTHOR:
*
DWM
***************************************************************************/
I*void Disconnect()
{
EXEC SQL disconnect all;
/***************************************************************************
FUNCTION:
*
BeginTransaction
PURPOSE:
*
begin a transaction
RETURNS:
*
none
PARAMTERS: none
*
AUTHOR:
*
DWM
***************************************************************************/
/*void BeginTransaction()
1
{
EXEC SQL begin transaction();
/***************************************************************************
*
FUNCTION:
CommitTransaction
*
PURPOSE:
commit a transaction
*
RETURNS:
none
*
PARAMTERS: none
*
AUTHOR:
DWM
***************************************************************************/
/*void CommitTransaction()
{
EXEC SQL commit transaction();
/***************************************************************************
Rol IbackTransact ion
FUNCTION:
*
rollback a transaction
PURPOSE:
*
RETURNS:
none
*
PARAMTERS: none
*
AUTHOR:
DWM
*
***************************************************************************/
/*void RollbackTransaction()
{
EXEC SQL rollback transaction();
}
/***************************************************************
* FUNCTION:
RTrim
* PURPOSE:
*
* PARAMETERS:
This function is passed a char * and removes all
trailing spaces and \n's from the string.
char *stringl
* RETURN:
pointer to the string
* AUTHOR:
DWM
* NOTE:
****************************************************************/
/*char * RTrim (char *stringl)
{
int counter;
//MOD DWM to trim '\n's too!!!
counter = strlen(stringl);
if (counter-- > 0)
for ( ; (counter >= 0) && ((stringl[counter]=='
,)
I I (stringl[counter]=='\n'»
nter- -)
stringl[counter]
'\0' ;
//MOD DWM return the string
return stringl;
/***************************************************************
* FUNCTION:
LTrim
2
cou
* PURPOSE:
*
* PARAMETERS:
This function is passed a char * and removes all
leading spaces and \t's from the string.
char *stringl
* RETURN:
pointer to the string
* AUTHOR:
DWM
* NOTE:
****************************************************************/
/*char * LTrim (char *stringl)
{
unsigned int counter= 0;
if (counter < strlen(stringl»
{
for ( ; (counter <= strlen(stringl»
==' \t'»
counter++)
{
//just run up the counter
&& ((stringl[counter]=='
')
I I (stringl[counter]
strncpy(stringl, stringl+counter, strlen(stringl)-counter+l);
return stringl;
/***************************************************************
* FUNCTION:
StringToUpper
* PURPOSE:
* PARAMETERS:
this function converts a string to upper case
char *stringl
* RETURN:
pointer to the string
* AUTHOR:
DWM
* NOTE:
****************************************************************/
/*
char * StringToUpper(char *buffer)
{
char *ptr = NULL;
ptr = buffer;
while ( *ptr != '\0'
{
*ptr++ = toupper( *ptr );
return buffer;
/***************************************************************************
FUNCTION:
replaceCharOneWithCharTwo
PURPOSE:
replace all occurences of char one in string with char two
RETURNS:
the number of chars replaced
PARAMTERS: string -- this is what we replace the chars in
AUTHOR:
DWM
NOTE:
*
***************************************************************************/
/*int replaceCharOneWithCharTwo(char *string, char one, char two)
*
*
*
*
*
3
char *theQuote;
int return code
0;
while (1)
{
theQuote = strchr{string, one);
if (theQuote != NULL)
{
//we found a quote ... make it a space
*theQuote = two;
return_code++;
else
{
break;
}
/ /while
return return_code;
/********************************************************************
*********************************************************************/
/***************************************************************
* FUNCTION:
GetNextFileId
* PURPOSE:
This function get the next unique file identifier
available for the given project.
project_id -- the project for which we need a new
file id
file id -- the file id we find and pass back
*
* PARAMETERS:
*
*
* RETURN:
*
SUCCESS CODE
FAILURE CODE
we got a new file id
an error occured
* AUTHOR:
DWM
* NOTE:
****************************************************** **********/
int GetNextFileId(int project_id, int *file_id)
EXEC SQL begin declare section;
int DBfile_id=O;
int DBproject_id=O;
EXEC SQL end declare section;
//assume only one copy of this program running at once
EXEC SQL select ISNULL(MAX(file_id),O)+l into :DBfile_id from cfg-project_files
where project_id = : DBproject_id;
if (SqlCode != SqlSuccessCode)
return FAILURE_CODE;
else
{
4
*file_id = DBfile_id;
return SUCCESS_CODE;
1***************************************************** **********
* FUNCTION:
AddFileToProject
* PURPOSE:
*
*
*
* PARAMETERS:
*
This function adds a file with pat~ file-path to
the project identified by project_id. It does
this by inserting into the cfg-project_files
table.
project_id -- the project we are adding a file to
file-path -- the full path of the file
* RETURN:
SUCCESS CODE
we got a new file id
FAILURE
CODE
an error occured
*
* AUTHOR:
DWM
* NOTE:
****************************************************************/
int AddFileToProject(int project_id, char *file-path)
EXEC SQL begin declare section;
int DBproject_id=O;
int DBfile_id=O;
char DBfile-path[FILE_PATH_SIZE] ;
char DBfile_type[FILE_TYPE_SIZE];
EXEC SQL end declare section;
char drive [FILE_PATH_SIZE]="";
char dir[FILE_PATH_SIZE] ="";
char fname[FILE_PATH_SIZE]="I;
char ext [FILE_PATH_SIZE]="";
int ReturnCode = SUCCESS_CODE;
DBproject_id = project_id;
strcpy(DBfile-path, file-p ath );
//WARNING NT-specific function
_splitpath(DBfile-path, drive, dir, fname, ext);
if (strcmp(RTrim(StringToUpper(ext)), ".C")==O)
{
//straight C
strcpy (DBfile_type, "C");
else if (strcmp(RTrim(StringToUpper(ext)),I.SQC")==O)
{
//C with embedded SQL
strcpy(DBfile_type, "S");
else if (strcmp(RTrim(StringToUpper(ext)) ,".LIB")==O)
{
//include lib files, I won't ever do anything with them
//but at least I can print out the fact that they are in the project
strcpy (DBfile_type, ilL");
else
ReturnCode
NOTFOUND_CODE;
5
if (ReturnCode
SUCCESS_CODE)
{
if (GetNextFileId {proj ect_id, &DBfile_id)==SUCCESS_CODE)
{
EXEC SQL insert into cfg-project_files{project_id, file_id, file-p ath ,
file_type, last_refresh_date) valu~s{:DBproject_id, :DBfile_id,
:DBfile-path, :DBfile_type, getdate());
if (SqlCode != SqlSuccessCode)
{
ReturnCode
FAILURE_CODE;
}
else
{
ReturnCode
FAILURE_CODE;
return ReturnCode;
/***************************************************** *******
*
FUNCTION: RefreshProjectFileList
*
PURPOSE: Given a particular project, refresh the file list
*
found in the cfg-project_files list. As we refresh, we
delete files from our list that are no longer there, add
*
*
files that are new, and update the last refresh time on
*
files we already new about.
*
PARAMETERS: project_id -- the project whose file list we should
~
refresh
*
RETURN: SUCCESS CODE
it worked
FAILURE
CODE
there
was an error
*
*
NOTES:
*
AUTHOR: DWM
****************************************************************/
int RefreshProjectFileList(int project_id)
EXEC SQL begin declare section;
int DBproject_id = 0;
int DBfile_id =0;
char DBstartDate [DATE_SIZE] ="";
char DBmake_file [MAKE_FILE_SIZE] ="";
char DBfile-path[FILE_PATH_SIZE]="";
EXEC SQL end declare section;
FILE *MakeFilePtr = NULL;
char buffer[BUFFER_SIZE] = "" ,. //a line of input from the .mak file
char *TokenPosition = NULL;
char SourceToken[lO]="SOURCE=";
int NewSourceFileCount = 0;
int TotalSourceFileCount = 0;
int DeletedSourceFileCount = 0;
int UnchangedSourceFileCount = 0;
int ReturnCode = SUCCESS_CODE;
6
int CodeReturned = SUCCESS_CODEi
char
char
char
char
char
char
char
char
drive [FILE_PATH_SIZE] =""i
dir[FILE_PATH_SIZE]=""i
fname [FILE_PATH_SIZE] =""i
ext [FILE_PATH_SIZE]=""i
project_drive [FILE_PATH_SIZE] =""i
project_dir[FILE_PATH_SIZE]=""i
project_fname[FILE_PATH_SIZE]=""i
project_ext [FILE_PATH_SIZE]=""i
Ilgrab the path of the .mak file
EXEC SQL select make_file into :DBmake_file
from cfg-project where project_id = :DBproject_idi
//TODO: check sqlcode
Ilopen the file
i f ((MakeFilePtr = fopen (DBmake_file, "r")) == NULL)
{
fprintf(stderr, "ERROR: unable to open file: %s.\n",DBmake_file)i
ReturnCode
FAILURE_CODEi
else
/IWARNING: getdate is SQL-server specific
Ilgrab the date for later use
EXEC SQL select getdate() into :DBstartDatei
II from cfg-project where project_id = :DBproject_idi
Iistart a transaction ..... I wanna refresh everthing or nothing ...
BeginTransaction()i
Iithis loop will add files if needed and mark each one as I read it
while (1)
{
Ilgrab line a line
if (fgets(buffer,BUFFER_SIZE,MakeFilePtr)
NULL)
{
breaki
}
else
{
Iisee if there is a source file on this line
TokenPosition = strstr(buffer, SourceToken)i
if (TokenPosition == NULL)
{
continuei
TotalSourceFileCount++i
Ilassume the file name with full path is less than FILE_PATH_SIZE-1 cha
rs
strncpy(DBfile-path,TokenPosition+strlen(SourceToken),FILE_PATH_SIZE-1)
DBfile-path [FILE_PATH_SIZE-1]='\O'i
RTrim(DBfile-path ) i
7
Iisometimes the makefile will contain relative paths ....
II so if the directory is ".1" or ".\" then I should fill in
II the full path for use later
if (DBfile-path[O]=='. ')
{
EXEC SQL select make_file into :DBmake_file
from cfg-project where project_id = :DBproject_id;
IIWARNING NT-specific function
_splitpath(DBfile-path, drive, dir, fname, ext);
IIWARNING NT-specific function
_splitpath(DBmake_file, project_drive, project_dir, project_fname,
project_ext);
sprintf(DBfile-path,"%s%s%s%s",project_dir,dir+2,fname,ext);
replaceCharOneWithCharTwo(DBfile-path , '\\', 'I');
Ilcheck the database ... do we already know this file?
IIWARNING getdate() is SQL-server specific
EXEC SQL update cfg-project_files
set last_refresh_date = getdate()
where project_id = :DBproject_id and
file-path = :DBfile-path ;
if (SqlCode == SqlNotFoundCode)
{
Ilwe don't know this file ... lets add it
CodeReturned = AddFileToProject(DBproject_id, DBfile-path);
if (CodeReturned == NOTFOUND_CODE)
{
Iithis means that I didn't add the file because it
II was a type of file I don't understand (e.g. a .lib file)
else if (CodeReturned != SUCCESS_CODE)
ReturnCode
break;
else
{
NewSourceFileCount++;
else if (SqlCode != SqlSuccessCode)
{
Iisome sort of error
fprintf(stderr, "ERROR: refreshing file %s.\n\tError Code
, DBfile-path, SqICode);
ReturnCode=FAILURE_CODE;
break;
}
else
{
UnchangedSourceFileCount++;
}llelse
8
%d. \n"
}llwhile(l)
Ilclose the file
fclose(MakeFilePtr);
if (ReturnCode==SUCCESS_CODE)
{
III have to commit here or I will walk on myself
CommitTransaction();
Iinow delete all the files we had in the project before that we didn't just
II find in the .mak file
EXEC SQL declare DeleteProjectFileCurs cursor for
select file id
from cfg-project_files
where project_id = :DBproject_id and
last_refresh_date < :DBstartDate;
EXEC SQL open DeleteprojectFileCurs;
if (SqlCode == SqlSuccessCode)
BeginTransaction();
while(l)
{
EXEC SQL fetch DeleteprojectFileCurs into :DBfile_id;
if (SqlCode
SqlNotFoundCode)
{
break;
else if (SqlCode != SqlSuccessCode)
{
ReturnCode
break;
else
{
DeletedSourceFileCount++;
III have to
II before I
IITODO:
delete all of the records from the child tables
can delete from the parent
EXEC SQL delete from
where project_id
EXEC SQL delete from
where project_id
EXEC SQL delete from
where project_id
EXEC SQL delete from
where project_id
EXEC SQL delete from
where project_id
check slqcode after each of these
cfg_function_refs
= :DBproject_id and
cfg_function_header
= :DBproject_id and
cfg_function_mods
= :DBproject_id and
cfg_table_refs
= :DBproject_id and
cfg_function_defs
= :DBproject_id and
file id
file id
file id
file id
file id
}
}I/while
EXEC SQL close DeleteProjectFileCurs;
EXEC SQL delete from cfg-project_files
where project_id = :DBproject_id and last_refresh_date
te;
9
<
:DBstartDa
if (SglCode != SqlSuccessCode)
{
ReturnCode=FAILURE_CODE;
}
else if (SqlCode != SqlNotFoundCode)
{
ReturnCode=FAILURE_CODE;
if (ReturnCode == SUCCESS_CODE)
{
CommitTransaction();
printf("SUCCESS: %d files examined.\n",TotalSourceFileCount);
printf ("
%d files unchanged. \n", UnchangedSourceFileCount);
printf("
%d files added to project.\n", NewSourceFileCount);
printf("
%d files removed from project.\n", DeletedSourceFileCount
) ;
else
RollbackTransaction();
printf("FAILURE: project files not refreshed.");
return ReturnCode;
of function
}llend
1***************************************************** ********************
*
FUNCTION: GetNCNBlineCount
*
PURPOSE: Get the number of non-comment, non-blank lines in the function
*
which starts on the line before current position
*
in the open file refered to by fp
*
PARAMETERS: fp -- pointer to open file where function is
*
FirstLine -- the line of text above the current position in the
*
file
*
NCNBlineCount -- the count of NCNB lines that is returned
*
CommentLineCount -- the count of comment lines in the function that
*
is returned to the calling function
*
FunLen -- the total number of lines in the function that is returned
*
RETURN: SUCCESS CODE
it worked
*
FAILURE CODE -- there was an error
*
NOTES:
*
AUTHOR: DWM
****************************************************** **********1
int GetNCNBlineCount(FILE *fp, int project_id, int file_id, int function_id,
char *FirstLine, int *NCNBlineCount,int *CommentLineCount, long * FunLen)
int ReturnCode = SUCCESS_CODE;
int'InComments = FALSE;
char *EndOfCommentsPtr = NULL;
char *TokenPtr = NULL;
char buffer[BUFFER_SIZE]="";
char buffer_temp [BUFFER_SIZE] ="";
int testval=O;
10
int FoundCurly=O; //when I find my first curly brace, set this to true
enum Tokens {BottomOfStack, LeftBrace};
int done = FALSE;
unsigned int i = 0;
int Linel=TRUE;
/Ithis stack I will use for parsing
PromptStack *TokenStack
NULL;
(*NCNBlineCount) = 0;
(*FunLen) = 0;
(*CommentLineCount) = 0;
TokenStack = Base_PushPromptStack(TokenStack,BottomOfStack);
while (! done)
{
//grab a line from the file
i f (Linel)
{
strcpy(buffer, FirstLine);
Linel=FALSE;
}
else
{
if (fgets (buffer,BUFFER_SIZE,fp)
{
break;
}
(*FunLen)++;
NULL)
strcpy(buffer_temp, buffer);
if (InComments)
{
EndOfCommentsPtr = strstr(buffer, n*/n);
(*CommentLineCount)++;
if (EndOfCommentsPtr != NULL)
//found the end
{
InComments = FALSE;
}
}
else
{
LTrim (buffer) ;
if (buffer[O]=='I')
{
if (buffer[l]=='/')
{
//whole line is comments
(*CommentLineCount)++;
continue;
}
else if (buffer[l]=='*')
{
InComments = TRUE;
EndOfCommentsPtr = strstr(buffer, n*/n);
(*CommentLineCount)++;
if (EndOfCommentsPtr != NULL)
{
/Istarting comments
InComments = TRUE;
11
else if (buffer[OJ=='\n')
{
continue;
}
else
{
//found an NCNB line
(*NCNBlineCount)++;
//look for braces
for(i=O; ((i< (strlen(buffer))} && (!done}); i++)
{
if (buffer[i)==LEFT_BRACE)
{
TokenStack = Base_PushPromptStack(TokenStack,LeftBrace)i
FoundCurlY++i
else if (buffer[i)==RIGHT_BRACE)
{
if (TokenStack->state == LeftBrace)
{
TokenStack = Base_PopPromptStack(TokenStack)i
else
fprintf(stderr, "ERROR: invalid syntax in file.")i
}
if ((TokenStack->state == BottomOfStack}&&(FoundCurly»
{
done = TRUEi
}
}//for loop
//look for sql statements
FindTableRefs(fp, project_id, file_id, function_id,buffer);
} //else
//else
//while
TokenStack=Base_KillPromptStack(TokenStack) ;
return ReturnCodei
/************************************************************
*
*
*
*
*
*
*
FuNcTION: SkipFunctionBody
PURPOSE: Given a file pointer to an open file at the second line
of a fuction definition fill in the non-comment, non-blank
line counts for the function and advance the file pointer
past the function
PARAMETERS: fp -- the file pointer
FirstLine -- the first of the function definition
12
project_id -- the project this file belongs to
file id -- the identifier of the file
function id -- the ID of this function which is unique within
*
*
this project
*
FunctionLen -- the length of the function -1 in lines
*
RETURN: SUCCESS_CODE
it worked
FAILURE
CODE
there was an error
*
*
NOTES:
*
AUTHOR: DWM
***************************************************!** **********1
int SkipFunctionBody(FILE *fp, char *FirstLine,int project_id, int file_id, int function id
*
*
long *FunctionLen)
EXEC SQL begin declare sectioni
int DBncnb_line_count=Oi
int DBcomment_line_count=Oi
int DBproject_id = 0;
int DBfile_id = 0;
int DBfunction_id = 0;
EXEC SQL end declare section;
enum Tokens {LeftParen, RightParen, LeftBrace, RightBrace, LeftBracket,
RightBracket};
Iithis stack I will use for parsing
PromptStack *sPromptStack = NULL;
int CodeReturned = SUCCESS_CODE;
int ReturnCode
DBproject_id = project_id;
DBfile_id = file_id;
DBfunction_id
Ilget the LOC for the function and the total length in bytes for the
II
function (FunctionLen)
CodeReturned = GetNCNBlineCount(fp,project_id, file_id, function id, FirstLine,
&DBncnb_line_count,&DBcomment_line_count,FunctionLen) ;
Ilupdate the function to show these line counts
EXEC SQL update cfg_function_defs set ncnb_line_count = :DBncnb_line_count,
comment_line_count = :DBcomment_line_count
where project_id = :DBproject_id and file id
:DBfile id and
function id
:DBfunction_id;
IITODO check sqlcode
Ilif this is a sql
II tables between
file -- file_type == 'S' -- then parse all the references to
StartPos and StartPos + FunctionLen
IIFind all function calls between StartPos and StartPos
Ilfind
all modification comments denoted by MODtoken
return ReturnCode;
13
+
FunctionLen
1***************************************************** *******
FUNCTION:
FindTableRefs
*
PURPOSE:
Check to see if the line we are on has an sql statement on it
*
if it does, fill in the cfg_table_refs table with the
*
project,
file, function, table_name and whether it is
*
a
select,
an update, an insert or a delete
*
PARAMETERS:
fp
-the
file
pointer
*
buffer
-the
line
of text we are looking at in the file
*
project_id -- the project this file belongs to
file id -- the identifier of the file
function id -- the ID of this function which is unique within
this project
*
RETURN:
SUCCESS_CODE
-- it worked
*
FAILURE
CODE
-- there was an error
*
NOTFOUND
CODE
-- this is not a sql statement
*
NOTES:
*
AUTHOR: DWM
*
****************************************************** **********1
int FindTableRefs(FILE *fp, int project_id,int file_id,int function_id,char *buffer}
*
*
*
char buffer_temp[BUFFER_SIZE]=""j
long OrigFilePos=Oj
char *SQLPtr=NULLi
char *Tokenptr=NULL;
int Line1=TRUEj
int ReturnCode = NOTFOUND_CODEi
char SQLstatement[BUFFER_SIZE*3]=""i
char *SemiPtr=NULL;
fgetpos(fp, &OrigFilePos)i
strcpy(buffer_temp, buffer)i
SQLPtr = strstr (StringToUpper (buffer_temp) ,"EXEC SQL");
if (SQLPtr != NULL)
{ //we have found an sql statement ... put it into a string
while (1)
{
strcat(SQLstatement, buffer_temp);
SemiPtr = strstr(buffer_temp, ,,;,,);
if (SemiPtr == NULL)
{
//grab line a line
if (fgets(buffer_temp,BUFFER_SIZE,fp)
{
break;
else
{
break;
}
'} Ilwhile
Iiset the file pointer back to where it was
fsetpos(fp, &OrigFilePos);
Ilmake sure its all upper case
StringToUpper(SQLstatement);
14
NULL)
if (InsertNewSelectStatement{project_id, file_id, function_id, SQLstatement)==SUCCE
SS_CODE)
{
ReturnCode = SUCCESS_CODE;
else if (InsertNewInsertStatement(project_id, file_id, function_id, SQLstatement)==
SUCCESS_CODE)
{
ReturnCode = SUCCESS_CODE;
else if (InsertNewUpdateStatement{project_id, file_id, function_id, SQLstatement)==
SUCCESS_CODE)
{
ReturnCode = SUCCESS_CODE;
else if (InsertNewDeleteStatement(project_id, file_id, function_id, SQLstatement)==
SUCCESS_CODE)
{
ReturnCode
SUCCESS_CODE;
}
else
{
ReturnCode
}llif
else
{
ReturnCode
NOTFOUND_CODE;
return ReturnCode;
1***************************************************** *******
FUNCTION:
InsertNewSelectStatement
*
PURPOSE:
Check to see if the SQLstatement is a select statement
*
if it iss, fill in the cfg_table_refs table with the
*
project, file, function, table_name and 'SELECT'
*
PARAMETERS: project_id -- the project this file belongs to
*
file_id -- the identifier of the file
*
function id -- the ID of this function which is unique within
*
this project
*
SQLstatement -- the sql statement we are dealing with
*
RETURN: SUCCESS CODE
it worked
*
FAILURE CODE
there was an error
*
*
NOTES:
*
AUTHOR: DWM
****************************************************** **********1
int InsertNewSelectStatement(int project id,int file_id,int function_id,char *statement)
EXEC SQL begin declare section;
int DBproject_id = 0;
int DBfile_id = 0;
int DBfunction_id = 0;
char DBtable_name[TABLE_NAME SIZE]="";
15
char DBaction_id[ACTION_ID_SIZE)="";
EXEC SQL end declare section;
char SQLstatement[BUFFER_SIZE*3)="";
char *TokenPtr=NULL;
int state = 0;
//state 0 --> looking for select
//state 1 --> looking for from
//state 2 --> grabbing table names
int done=O;
int ReturnCode
SUCCESS_CODE;
int FirstTime = TRUE;
DBproject_id = project_id;
DBfunction_id = function_id;
DBfile_id = file_id;
strcpy(SQLstatement, statement);
StringToUpper(SQLstatement);
Tokenptr = strtok (SQLstatement , II ,\n\t");
while (! done)
{
i f (! FirstTime)
{
Tokenptr = strtok(NULL,
II
,\n\t");
FirstTime = FALSE;
if (TokenPtr != NULL)
{
switch (state)
{
case 0:
if (strcmp(TokenPtr, "SELECT") ==0)
{
state++;
}
break;
case 1:
if (strcmp(TokenPtr, "FROM") ==0)
{
state++;
}
break;
case 2:
if (strcrnp(TokenPtr, "WHERE") ==0)
{
done++;
}
else
{
strcpy(DBtable_name, TokenPtr);
EXEC SQL insert into cfg_table_refs(project_id, file_id, function i
d,
table_name,action_id) values (:DBproject_id, :DBfile_id,
:DBfunction_id, :DBtable_name, 'SELECT');
//TODO check sqlcode
break;
default:
16
ReturnCode
break;
FAILURE_CODE;
else
{
ReturnCode
break;
return ReturnCode;
/************************************************************
FUNCTION:
InsertNewDeleteStatement
*
PURPOSE:
Check to see if the SQLstatement is a delete statement
*
if it iss, fill in the cfg_table_refs table with the
*
project, file, function, table_name and 'DELETE'
*
PARAMETERS: project_id -- the project this file belongs to
*
file id -- the identifier of the file
*
function id -- the ID of this function which is unique within
*
this project
*
SQLstatement -- the sql statement we are dealing with
*
RETURN: SUCCESS CODE
it worked
FAILURE CODE
there was an error
*
NOTES:
*
AUTHOR: DWM
****************************************************************/
int InsertNewDeleteStatement(int project_id,int file_id,int function_id,char *statement)
*
*
EXEC SQL begin declare section;
int DBproject_id = 0;
int DBfile_id = 0;
int DBfunction_id = 0;
char DBtable_name[TABLE_NAME SIZE]="";
char DBaction_id[ACTION_ID_SIZE]="";
EXEC SQL end declare section;
char SQLstatement[BUFFER_SIZE*3]="";
char *TokenPtr=NULL;
//state 0 --> looking for select
int state = 0;
//state 1 --> looking for from
//state 2 --> grabbing table names
int done=O;
int ReturnCode
SUCCESS_CODE;
int FirstTime = TRUE;
DBproject_id = project_id;
DBfuriction_id = function_id;
DBfile_id = file_id;
strcpy(SQLstatement, statement);
StringToupper(SQLstatement);
TokenPtr = strtok(SQLstatement," ,\n\t");
17
------------------------------............
'r
while ( ! done)
{
i f (! FirstTime)
{
TokenPtr = strtok(NULL,
II
,\n\t");
FirstTime = FALSE;
if (TokenPtr != NULL)
{
switch (state)
{
case 0:
if (strcmp(TokenPtr, "DELETE") ==0)
{
state++;
break;
case 1:
if (strcmp (TokenPtr,
{
state++;
II
FROM II ) ==0)
break;
case 2:
if (strcmp(TokenPtr, "WHERE") ==0)
{
done++;
~
I
else
strcpy(DBtable_name, TokenPtr);
EXEC SQL insert into cfg_table_refs(project_id, file_id, function i
d,
table_name,action_id) values (:DBproject_id, :DBfile_id,
:DBfunction_id, :DBtable_name, 'DELETE');
//TODO check sqlcode
1
I
break;
default:
ReturnCode
break;
J
I
I
I
FAILURE_CODE;
}
else
{
ReturnCode
break;
return ReturnCode;
I
/************************************************************
FUNCTION:
InsertNewUpdateStatement
*
PURPOSE:
Check
to see if the SQLstatement is a update statement
*
if
it iss, fill in the cfg_table_refs table with the
*
project,
file, function, table_name and 'UPDATE'
*
18
*
*
*
*
*
*
*
*
*
PARAMETERS: project_id -- the project this file belongs to
file id -- the identifier of the file
function id -- the ID of this function which is unique within
this project
SQLstatement -- the sql statement we are dealing with
RETURN: SUCCESS CODE
FAILURE CODE
NOTES:
AUTHOR: DWM
it worked
there was an error
****************************************************************/
int InsertNewUpdateStatement(int project_id,int file_id,int function_id,char *statement)
EXEC SQL begin declare sectionj
int DBproject_id = OJ
in~ DBfile_id = 0;
int DBfunction_id = 0;
char DBtable_name[TABLE_NAME SIZE]="";
char DBaction_id[ACTION_ID_SIZE]="";
EXEC SQL end declare section;
char SQLstatement[BUFFER_SIZE*3]="";
char *TokenPtr=NULL;
int state = 0;
//state 0 --> looking for select
//state 1 --> looking for from
//state 2 --> grabbing table names
int done=O;
int ReturnCode
SUCCESS_CODE;
int FirstTime = TRUE;
DBproject_id = project_id;
DBfunction_id = function_id;
DBfile_id = file_id;
strcpy(SQLstatement, statement);
StringToUpper(SQLstatement);
TokenPtr = strtok(SQLstatement, " ,\n\t");
while (! done)
{
i f (! FirstTime)
{
TokenPtr = strtok(NULL, " ,\n\t");
FirstTime = FALSE;
if (TokenPtr != NULL)
{
switch (state)
{
case 0:
if (strcmp(TokenPtr, "UPDATE") ==0)
{
state++;
}
break;
case 1:
strcpy(DBtable_name, TokenPtr);
EXEC SQL insert into cfg_table_refs(project_id, file_id, function_id,
table_name,action_id) values (:DBproject_id, :DBfile_id,
19
---------:DBfunction_id, :DBtable_name, 'UPDATE');
//TODO check sqlcode
done++;
break;
default:
ReturnCode
break;
}
else
{
ReturnCode
break;
FAILURE_CODE;
return ReturnCode;
/************************************************************
InsertNewInsertStatement
FUNCTION:
*
Check
to see if the SQLstatement is a insert statement
PURPOSE:
*
if
it iss, fill in the cfg_table_refs table with the
*
project, file, function, table_name and 'INSERT'
*
PARAMETERS: project_id -- the project this file belongs to
*
file id -- the identifier of the file
*
function id -- the ID of this function which is unique within
*
this project
*
SQLstatement -- the sql statement we are dealing with
*
it worked
RETURN: SUCCESS CODE
there
was an error
FAILURE
CODE
*
*
NOTES:
*
AUTHOR: DWM
****************************************************************/
int InsertNewInsertStatement(int project_id,int file_id,int function_id,char *statement)
*
EXEC SQL begin declare section;
int DBproject_id = 0;
int DBfile_id = 0;
int DBfunction_id = 0;
char DBtable_name[TABLE_NAME SIZE]="";
char DBaction_id[ACTION_ID_SIZE]="";
EXEC SQL end declare section;
char SQLstatement[BUFFER_SIZE*3]="";
char *TokenPtr=NULL;
//state 0 --> looking for select
int state = 0;
//state 1 --> looking for from
//state 2 --> grabbing table names
int done=O;
SUCCESS_CODE;
int ReturnCode
int FirstTime = TRUE;
DBproject_id = project_id;
DBfunction_id = function_id;
DBfile_id = file id;
strcpy(SQLstatement, statement);
20
StringToUpper(SQLstatement);
TokenPtr = strtok(SQLstatement," ,\n\t(II);
while ( ! done)
{
i f (! FirstTime)
{
TokenPtr = strtok(NULL," ,\n\t(II);
}
FirstTime = FALSE;
if (TokenPtr != NULL)
{
switch (state)
{
case 0:
if (strcmp(TokenPtr, "INSERT") ==0)
{
state++;
break;
case 1:
if (strcmp(TokenPtr, "INTO") ==0)
{
state++;
break;
case 2:
strcpy(DBtable_name, TokenPtr);
EXEC SQL insert into cfg_table_refs(project_id, file_id, function_id,
table_name,action_id) values (:DBproject_id, :DBfile_id,
:DBfunction_id, :DBtable_name, 'INSERT');
//TODO check sqlcode
done++;
break;
default:
ReturnCode
FAILURE_CODE;
break;
}
else
{
ReturnCode
break;
return ReturnCode;
21
#include "k:\develop\admp\admp.h"
j***************************************************** *******
FUNCTION:
FindFunctionDefinition
PURPOSE:
Given a pointer to a file which is open to the
second line of a function definition, extract the
name of the function.
PARAMETERS:
fp -- the file pointer
FirstLIne -- the first line of text of the function def
function name -- the name of the function (this will
be returned )
*
NumOfLines -- the number of lines we have moved forward
*
in the file .... if we are successful this will be 0
*
RETURN: SUCCESS CODE -- it worked
*
FAILURE CODE -- best guess is this isn't a function after all
*
NOTES:
if we fail and don't think its a function, the file pointer will
*
be advanced past whatever it is.
If we are successful the
*
file pointer will be left as it was to start with.
* AUTHOR: DWM
*
*
*
*
*
*
*
*
****************************************************************/
int FindFunctionDefinition(FILE *fp, char *FirstLine,char *function_name, long * NumOf Lines)
int ReturnCode = SUCCESS_CODE;
char *token = NULL;
char *prevToken = NULL;
char buffer[BUFFER_SIZE]="";
char *SemiPtr=NULL;
char *BracePtr=NULL;
long OrigFilePos=O;
int Linel=TRUE;
//long FilePos=O;
fgetpos(fp,&OrigFilePos);
//fgetpos(fp,Filepos);
//get the function definition .... try to see it at least could be valid
strcpy(buffer, FirstLine);
//with any luck I am sitting at a function definition
token = strtok(FirstLine," \t\n");
//token should be a type .... I could validate it he
re ..... if I wanted to ....
token = strtok(NULL," \t\n(");
(*NumOfLines) =0;
I/might be a * sitting there by itself
if (token == NULL)
{
return FAILURE_CODE;
if (strcmp(token, "*")==0)
token = strtok(NULL," \t\n(");
if (token == NULL)
{
return FAILURE_CODE;
//might be a * stuck to my function name
if (token [0] == '*')
strcpy(function_name, token+l);
1
else
strcpy{function_name, token);
Ilif I find a semi-colon before I find a brace then this is a prototype
while (l)
{
i f (!Linel)
{
if (fgets{buffer,BUFFER_SIZE,fp)
NULL)
{
break;
}
(*NumOfLines) ++;
Linel=FALSE;
SemiPtr = strchr{buffer, ';');
BracePtr = strchr{buffer, LEFT_BRACE);
if «SemiPtr == NULL)&&(BracePtr == NULL»
{
continue;
}
else if {(SemiPtr
NULL)&&{BracePtr != NULL»
{
break; Iisuccess
else if «SemiPtr != NULL)&&(BracePtr != NULL)&&{SemiPtr>BracePtr»
{
break; Iisuccess
else
{
ReturnCode
break;
if{ReturnCode == SUCCESS_CODE)
{
fsetpos{fp,&OrigFilePos) ;
(*NumOfLines) = 0;
return ReturnCode;
1***************************************************** *******
*
FUNCTION:
ctionId '
*
PURPOSE: lookup the FunctionId for this function within the
*
given project
*
PARAMETERS:
*
RETURN: SUCCESS CODE -- it worked
*
FAILURE CODE -- there was an error
*
NOT FOUND CODE -- function not in the project
2
*
NOTES:
*
AUTHOR: DWM
****************************************************************/
int GetFunctionId(int project_id, int file_id, char *function_name, int *function_id)
EXEC SQL begin declare section;
int DBproject_id=O;
char DBfunction_name[FUNCTION_NAME SIZE]="";
int DBfunction_id=O;
int DBfile_id=O;
EXEC SQL end declare section;
int ReturnCode = SUCCESS_CODE;
DBproject_id = project_id;
DBfile id=file_id;
strcpy(DBfunction_name, function_name);
EXEC SQL select function_id into :DBfunction id
from cfg_function_defs where project_id = :DBproject_id and
file id = :DBfile id and function name
:DBfunction_name;
if (SqlCode == SqlNotFoundCode)
{
ReturnCode
NOTFOUND_CODE;
else if (SqlCode != SqlSuccessCode)
{
ReturnCode=FAILURE_CODE;
else
{
*function id
DBfunction_id;
return ReturnCode;
1***************************************************** **********
* FUNCTION:
GetNextFunctionId
* PURPOSE:
This function gets the next unique function identifier
available for the given project.
project_id -- the project for which we need a new
file id
function id -- the file id we find and pass back
* PARAMETERS:
*
* RETURN:
SUCCESS CODE
FAILURE CODE
DWM
we got a new file id
an error occured
* AUTHOR:
* NOTE:
****************************************************************/
int GetNextFunctionId(int project_id, int *function_id)
EXEC SQL begin declare section;
int DBfunction_id=O;
int DBproject_id=O;
EXEC SQL end declare section;
3
//assume only one copy of this program running at once
EXEC SQL select ISNULL(MAX(function_id),O)+l into :DBfunction id
from cfg_function_defs
where project_id = :DBproject_id;
if (SqlCode != SqlSuccessCode)
{
return FAILURE_CODE;
else
{
*function_id = DBfunction_id;
return SUCCESS_CODE;
/************************************************************
AddFunctionToProject
* FUNCTION:
This function adds a function to the project
PURPOSE:
*
and returns its function id
*
* PARAMETERS: project_id -- the project to add the function to
file id -- the file where the function is found
*
function name -- the name of the function
*
line id -- the line on which the function starts
*
function_id -- the unique function identifier assigned
to this function and passed back to the calling function
*
RETURN:
SUCCESS
CODE
it worked
*
FAILURE
CODE
-there
was an error
*
NOTES:
*
AUTHOR:
DWM
*
****************************************************************/
int AddFunctionToProject(int project_id, int file_id, char *function_name, int line_id,
int *function_id)
EXEC SQL begin declare section;
int DBproject_id=O;
char DBfunction_name[FUNCTION_NAME SIZE]="";
int DBfunction_id=O;
int DBfile_id=O;
int DBline_id=O;
EXEC SQL end declare section;
int ReturnCode = SUCCESS_CODE;
DBproject_id=project_id;
strcpy(DBfunction_name, function_name);
DBfile id
file_id;
DBline_id = line_id;
if (GetNextFunctionId(project_id, &DBfunction_id)==SUCCESS_CODE)
{
EXEC SQL insert into cfg_function_defs(project_id, file_id, function_id,
line_id,function_name) values (:DBproject_id, :DBfile_id, :DBfunction_id,
:DBline_id, :DBfunction_name);
if (SqlCode != SqlSuccessCode)
{
FAILURE_CODE;
ReturnCode
}
else
4
ReturnCode
FAILURE_CODE;
*function_id = DBfunction_id;
return ReturnCode;
/************************************************************
*
FUNCTION:
RefreshFunctionHeader
*
PURPOSE:
This function puts the function header found in
*
comment into the database
*
PARAMETERS: project_id -- the project we are dealing with
*
file id -- the file where the function is found
*
function id -- the id of the function
comment -- the function header
*
Comment Len -- some unused argument
*
RETURN:
SUCCESS CODE
it worked
*
*
FAILURE CODE -- there was an error
*
NOTES:
AUTHOR:
DWM
*
****************************************************************/
int RefreshFunctionHeader(int project_id, int file_id, int function_id,
char * comment , long CommentLen)
EXEC SQL begin declare section;
char DBcomment[COMMENT_SIZE]="I1;
int DBproject_id=O;
int DBfile_id=O;
int DBfunction_id=O;
EXEC SQL end declare section;
FILE *fp = NULL;
char *EndOfCommentsPtr
NULL;
int InComments = FALSE;
long BytesRead = 0;
char buffer [BUFFER_SIZE] ="";
int ReturnCode = SUCCESS_CODE;
/*
DBproject_id = project_id;
DBfile_id = file_id;
DBfunction_id = function_id;
strcpy(DBcomment,comment);
//open the file
i f ((fp = fopen (fileyath, "r") )
NULL)
fprintf(stderr,"ERROR: unable to open file:
ReturnCode = FAILURE_CODE;
%s.\n",fileyath);
else //file is open
{
'if (fseek(fp, Startpos,SEEK_SET) !=O)
fprintf(stderr,"ERROR: failure manipulating file.\n");
//get the function definition .... try to see it at least could be valid
while (1)
{
//grab a line from the file
if (fgets(buffer,BUFFER_SIZE,fp)
NULL)
5
{
ReturnCode=FAILURE_CODE;
break;
}
else
{
if (InComments)
{
EndOfCommentsPtr = strstr(buffer, "*1");
if (EndOfCommentsPtr != NULL)
Ilfound the end
Iladjust my length by the amount left on the line
II minus the length of my comment token
InComments = FALSE;
*I I I
1*
strcat(DBcomment, buffer);
else
LTrim (buffer) ;
if (buffer[O]=='I')
{
if (buffer[l]=='I')
{
Ilwhole line is comments
strcat(DBcomment, buffer);
continue;
else if (buffer[l]=='*')
{
InComments = TRUE;
strcat(DBcomment, buffer);
EndOfCommentsPtr = strstr(buffer, "* I
if (EndOfCommentsPtr != NULL)
{
Ilfound the end
InComments = FALSE;
}
*1 II
1*
else if (buffer[O]=='\n')
{
strcat{DBcomment, buffer);
continue;
else
{
Ilfound the end
break;
Ilwhile
Iithese chars will mess me up ....
*1
replaceCharOneWithCharTwo(DBcomment, ,\"', '&');
replaceCharOneWithCharTwo{DBcomment, '\' " '?');
replaceCharOneWithCharTwo(DBcomment, ,\t', , ,);
/ Iprintf (" %s ", DBcomment) ;
III
should have the comment so just insert it
6
II) ;
EXEC SQL insert into cfg_function_header(project_id, file_id, function_id,
identifier, comment) values (:DBproject_id, :DBfile_id, :DBfunction_id,
'HEADER', :DBcomrnent);
strcpy(DBcomment, "");
jjTODO check sqlcode here
II
}
return ReturnCode;
1***************************************************** *******
FUNCTION:
GetCommentAndNumLines
*
PURPOSE:
*
This function grabs a comment block from the file
*
the file must open and the file pointer sitting
*
at the second line of the comment block. The
first line of the comment block is passed in.
*
*
The comment length in number of lines is passed
back
*
PARAMETERS: fp -- the file pointer
*
FirstLine -- the firstline of the comment block
*
comment -- the comment block we found
*
*
CommentLength -- the length of the block we found in lines
RETURN:
SUCCESS CODE
it worked
*
FAILURE CODE
*
there was an error
*
NOTES:
AUTHOR:
DWM
*
****************************************************** **********1
int GetCommentAndNumLines(FILE *fp, char *FirstLine,char *comment, long *CommentLength)
{
int ReturnCode = SUCCESS_CODE;
int InComments = FALSE;
char *EndOfCommentsPtr = NULL;
char buffer[BUFFER_SIZE]="";
int NumOfLines=O;
long FilePos = 0;
int Line1 = TRUE;
Ilopen the file
1* comment out for test
i f ((fp = fopen (fileJlath, "r") )
NULL)
{
fprintf(stderr,"ERROR: unable to open file: %s.\n",fileJlath);
ReturnCode
FAILURE_CODE;
else
{
II
II
if (fgets (buffer, BUFFER_SIZE, fp)==NULL)
return ReturnCode;
*CommentLength = 0;
if (fseek(fp, CommentStartpos,SEEK_SET) !=O)
fprintf(stderr,"ERROR: failure manipulating file.\n");
*1
while (1)
{
Ilget our position
fgetpos(fp, &FilePos);
Ilgrab a line from the file
7
i f (Linel)
{
strcpy(buffer, FirstLine);
Linel = FALSE;
else
if(fgets(buffer,BUFFER_SIZE,fp)
{
break;
NULL)
NumOfLines++;
if (InComments)
{
strcat(comment, buffer);
EndOfCommentsPtr = strstr(buffer, "*/");
if (EndOfCommentsPtr != NULL)
{
InComments = FALSE;
else
{
LTrim (buffer) ;
if (buffer[D]=='/')
{
if (buffer[l]=='/')
{
//whole line is comments
strcat(comment, buffer);
continue;
}
else if (buffer[l]=='*')
{
InComments = TRUE;
EndOfCommentsPtr = strstr(buffer, "*/");
if (EndOfCommentsPtr != NULL)
{
//found the end
InComments = FALSE;
strcat(comment, buffer);
else if (buffer[D]=='\n')
{
continue;
else
{
//found the end
/II read an extra line that doesn't count
i f (NumOfLines)
NumOfLines--;
//set the position of the file back to what it was before the
//last read
fsetpos(fp, &FilePos);
break;
8
/ /while
(*CommentLength)=NumOfLines;
II
I I fclose (fp) i
} comment out for testing
return ReturnCode;
/************************************************************
*
*
*
*
*
*
*
*
*
1<
FUNCTION: RefreshProjectFile
PURPOSE: Given a project and a file, refresh the function headers
function definitions, function references, table references,
and modification history for the functions found in that file
PARAMETERS: project_id -- the project whose file list we should
refresh
RETURN: SUCCESS CODE
it worked
FAILURE CODE
there was an error
NOTES:
AUTHOR: DWM
****************************************************************/
int RefreshProjectFile(int project_id, int file_id)
EXEC SQL begin declare section;
int DBproject_id = 0;
int DBfile_id = 0;
char DBfileyath[FILE_PATH_SIZE]="I;
char DBfile_type[FILE_TYPE_SIZE] ="";
EXEC SQL end declare section;
int line_id = 0;
char buffer [BUFFER_SIZE] ="";
char buffer_temp [BUFFER_SIZE] ="";
char function_name[FUNCTION_NAME_SIZE]="";
char comment [COMMENT_SIZE] ;
int ReturnCode = SUCCESS_CODE;
int CodeReturned = SUCCESS_CODE;
int FoundComments = FALSE;
int function_id = 0;
FILE *SourceFilePtr = NULL;
long FunctionHeaderFilePosition =0;
long CommentLength=O;
long FunctionDefinitionPosition =0;
FILE *FunctionDefinitionFilePtr = NULL;
long FunctionLength=O;
long testval=O;
long CurrentLine=O;
long NumLines=O;
DBproject_id = project_id;
DBfile_id
=
file_id;
EXEC SQL select fileyath, file_type
into :DBfileyath, :DBfile_type
from cfgyroject_files
where project_id = :DBproject_id and file id
9
RTrim(DBfile-path ) i
RTrim(DBfile_type) ;
EXEC SQL delete from cfg_function_refs
where project_id = :DBproject_id and file id
:DBfile_id;
EXEC SQL delete from cfg_function_header
where project_id = :DBproject_id and file id
:DBfile_id;
EXEC SQL delete from cfg_function_mods
where project_id = :DBproject_id and file id
:DBfile_id;
EXEC SQL delete from cfg_table_refs
where project_id = :DBproject_id and file id
:DBfile_id;
EXEC SQL delete from cfg_function_defs
where project_id = :DBproject_id and file id
:DBfile_id;
IITODO: check slqcode a
if ((SqlCode == SqlSuccessCode) I I (SqlCode == SqlNotFoundCode»
I lopen the file
if ((SourceFilePtr = fopen (DBfile-path, "r"» == NULL)
{
fprintf(stderr,"ERROR: unable to open file: %s.\n",DBfile-p ath );
ReturnCode
FAILURE_CODE;
else
while (1)
{
Ilgrab a line from the file
fgetpos(SourceFilePtr, &testval);
if (fgets(buffer,BUFFER_SIZE,SourceFilePtr)
NULL)
{
break;
}
else
{
strcpy(buffer_temp, buffer);
CurrentLine++;
testval = strlen(buffer);
fgetpos(SourceFilePtr, &testval);
Ilif the line starts with a # sign then I don't need it
i f (LTrim(buffer) [0]=='#')
{
III had found some comments, but apparently they were not
II associated with a function
if (FoundComments)
{
FoundComments = FALSE;
strcpy(comment,"");
}
continue;
}
Ilif
it's just a line feed, ignore it
else i f (LTrim(buffer) [0] ==' \n' )
{
continue;
}
Ilif this line is a comment, or begins with one then it is part of
II the header
else i f ((strncmp (LTrim(buffer) , "I I" ,2) ==0) II (strncmp (LTrim(buffer) ,
*",2)==0»
10
II
I
if (FoundComments)
{
fprintf(stderr,"ERROR: Found Unexpected Comments.\n");
}
else
{
Ilget the file position of the beginning of the comments
1* Having trouble with this .... just pass the darn thing a line number
fgetpos(SourceFilePtr,&FunctionHeaderFilePosition);
FunctionHeaderFilePosition = FunctionHeaderFilePosition -strlen
(buffer)-l;
Ilbackup up to the beginning of the comments
if (fseek(SourceFilePtr, FunctionHeaderFilePosition, SEEK_SET ) !=O
fprintf(stderr,"ERROR:
failure manipulating file.\n");
*1
GetCommentAndNumLines(SourceFilePtr, buffer, comment,&NumLines)
IITODO
check ret code
CurrentLine = CurrentLine + NumLines;
FoundComments=TRUE;
Ilis this a prototype? or a function definition or something else?
else if (strncmp(StringToUpper(LTrim(buffer_temp)), "EXEC SQL",8)==0)
{
Iisome sort of goofy sql statement
III
had found some comments, but apparently they were not
associated with a function
if (FoundComments)
{
II
FoundComments = FALSE;
strcpy(comment,"");
continue;
else
{
if (FindFunctionDefinition(SourceFilePtr, buffer, function_name,
&N
'umLines)==SUCCESS_CODE)
CurrentLine = CurrentLine + NumLines;
Ilget the function_id for this function if it already exists
CodeReturned = GetFunctionld (proj ect_id, file_id, function name
I
&function_id);
if (CodeReturned == FAILURE_CODE)
{
fprintf(stderr, "ERROR: Failure getting function id.\n");
else
{
if (CodeReturned == NOTFOUND_CODE)
{
CodeReturned = AddFunctionToProject(project_id, file id
11
, function_name, CurrentLine, &function_id)i
}
if (CodeReturned == SUCCESS_CODE)
{
Ilfunction already exists
Ilif we found comments previously then lets grab them
if (FoundComments)
{
CodeReturned
RefreshFunctionHeader(project_id, fi
comment, CommentLength)i
IITODO: check this return code
FoundComments = FALSEi
strcpy(comment,"")i
CodeReturned
Current Line
SkipFunctionBody(SourceFilePtr, buffer,
function_id, &FunctionLength)i
Current Line + FunctionLengthi
IITODO: check this return code
Iladjust our position in the file so we are past this f
unction
else
{
fprintf(stderr,"ERROR:
encountered really bad code.\n"
) i
FoundComments = FALSEi
strcpy(comment,"")i
else
lias near as I can tell it is not a function definition
II so I don't care what it is
FoundComments = FALSEi
strcpy(comment,"")i CurrentLine
Ilwhile
fclose(SourceFilePtr)i
Ilelse
else
{
ReturnCode
FAILURE_CODEi
return ReturnCode;
Ilend of function
/************************************************************
12
Current Line
+
NumLinesi
*
*
*
*
*
*
*
*
*
FUNCTION: RefreshAllFunctions
PURPOSE: Given a project, refresh the function headers
function definitions, function references, table references,
and modification history for all functions found in the project
PARAMETERS: project_id -- the project whose functions we should
refresh
RETURN: SUCCESS CODE
it worked
FAILURE CODE
there was an error
NOTES:
AUTHOR: DWM
*
****************************************************************/
int RefreshAllFunctions(int project_id)
EXEC SQL begin declare section;
int DBproject_id=O;
int DBfile_id=O;
char DBfileyath[FILE_PATH_SIZE]="";
char DBfile_type[FILE_TYPE_SIZE]="";
char DBfileyath_temp[FILE_PATH_SIZE]="";
int FileMatches = 0;
EXEC SQL end declare section;
char
char
char
char
drive [FILE_PATH_SIZE] ="";
dir[FILE_PATH_SIZE]="";
fname[FILE_PATH_SIZE]="";
ext [FILE_PATH_SIZE]="";
int ReturnCode = SUCCESS_CODE;
EXEC SQL declare GetFileCursor cursor for
select file_id, fileyath, file_type from cfgyroject_files
where project_id = :DBproject_id and file_type in ('S', 'C');
EXEC SQL open GetFileCursor;
//TODO check sqlcode
while(l)
{
EXEC SQL fetch GetFileCursor into :DBfile_id,
if (SqlCode == SqlNotFoundCode)
{
ReturnCode
break;
SUCCESS_CODE;
}
else if (SqlCode != SqlSuccessCode)
{
ReturnCode
break;
FAILURE_CODE;
else
{
if (strcmp(DBfile_type, "C")==O)
{
//WARNING NT-specific function
13
:DBfileyath,
:DBfile_type;
_splitpath(DBfile-path, drive, dir, fname, ext);
StringToUpper(fname) ;
sprintf(DBfile-path_temp, "!!rs!!rs.SQC", "!!r", fname);
EXEC SQL select count(*) into :FileMatches
from cfg-project_files
where file-path like :DBfile-path_temp and
file_type = 'S';
i f (FileMatches)
{
FileMatches
o·,
continue;
ReturnCode
RefreshProjectFile(DBproject_id,DBfile_id);
EXEC SQL close GetFileCursor;
return ReturnCode;
14
#include "k:\develop\adml\admlmss.h"
#include "\develop\admp\varszs.h"
#include "\develop\admp\admpsql.h"
#define
#define
#define
#define
#define
LEFT_BRACE ,{,
RIGHT BRACE 'l'
MODtoken MOD
SQLtoken EXEC SQL
BUFFER SIZE 1000
1
#define
#define
#define
#define
#define
#define
#define
MAKE- FILE- SIZE 101
FILE PATH SIZE 151
FILE TYPE SIZE 2
FUNCTION- NAME- SIZE 51
COMMENT SIZE 100000
TABLE NAME SIZE 51
ACTION ID SIZE 21
"\
.....
c
v
#define DATE SIZE 20
1
int RefreshProjectFileList(int project_id);
int RefreshAllFunctions(int project_id);
void Connect();
void Disconnect();
void BeginTransaction() ;
void CommitTransaction() ;
void RollbackTransaction() ;
char * RTrim (char *stringl);
char * LTrim (char *stringl);
char * StringToUpper(char *buffer);
int replaceCharOneWithCharTwo(char *string, char one, char two);
int GetNextFileld(int project_id, int *file_id);
int AddFileToProject(int project_id, char *file-path);
int RefreshProjectFileList(int project_id);
int GetNCNBlineCount(FILE *fp, int project_id, int file_id, int function id,
char *FirstLine, int *NCNBlineCount,int *CommentLineCount, long *FunLen);
int SkipFunctionBody(FILE *fp, char *FirstLine,int project_id, int file_id, int function id
long *FunctionLen) ;
int FindFunctionDefinition(FILE *fp, char *FirstLine,char *function_name, long * NumOf Lines)
int GetFunctionld(int project_id, int file_id, char *function_name, int *function_id);
int GetNextFunctionld(int project_id, int *function_id);
int AddFunctionToProject(int project_id, int file_id, char *function_name, int line_id,
int *function_id);
int RefreshFunctionHeader(int project_id, int file_id, int function id,
char * comment , long CommentLen);
int GetCommentAndNumLines(FILE *fp, char *FirstLine,char *comment, long *CommentLength);
int
int
int
int
RefreshProjectFile(int project_id, int file_id)
RefreshAllFunctions(int project_id);
FindTableRefs(FILE *fp, int project_id,int file_id,int function id,char *buffer);
InsertNewSelectStatement(int project_id,int file_id,int function_id,char *SQLstatement)
int InsertNewUpdateStatement(int project_id,int file_id,int function_id,char *SQLstatement)
int InsertNewDeleteStatement(int project_id,int file_id,int function_id,char *SQLstatement)
int InsertNewlnsertStatement(int project_id,int file_id,int function_id,char *SQLstatement)
1
#ifndef B PROMPT
#define B PROMPT 1
1* Define our prompt node structure type */
struct PStack
{
int statej
struct PStack *linkj
};
typedef struct PStack PromptStackj
=====================================================
II
Macro Definitions
II
Function Prototypes
===================================================
PromptStack *Base_PushPromptStack( PromptStack *stack, int item )j
PromptStack *Base_PopPromptStack( PromptStack *stack )j
PromptStack *Base_KillPromptStack( PromptStack *stack )j
II --- End of file b-Frompt.h -----------------------------------------------#endif
1
#include
#include
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<ctype.h>
<string.h>
<time.h>
IIK:\develop\ahtl\ahtl.h ll
/***************************************************** ************************
Function: Base_PushPromptStack
Description:
This function will push a prompt item onto the prompt stack. Do
this operation when your program wishes to move forward through the
prompt list.
Arguments:
stack
item
the existing prompt stack
the item to push onto the stack
Returns:
SUCCESS CODE
FAILURE CODE
Exits:
None.
the push was successful
Unsuccessful
*****************************************************************************/
PromptStack *Base_pushPromptStack( PromptStack *stack, int item)
{
PromptStack *pNewNode;
/* Create the new node. If failure, bailout and report error */
( ( pNewNode
( PromptStack * )malloc( sizeof( PromptStack ) )
== NULL )
if
/* If we couldn't allocate the memory required, return a NULL */
return NULL;
/* Assign this node's prompt state */
pNewNode->state = item;
/* Put it at the top of the stack */
pNewNode->link = stack;
stack = pNewNode;
return stack;
/* Base_PushPromptStack */
/*****************************************************************************
Function: Base_PopPromptStack
Description:
This function will pop a prompt item off the prompt stack. Do
this operation when your program wishes to move forward through the
prompt list.
1
Arguments:
stack
item
the existing prompt stack
the item popped off the stack
Returns:
SUCCESS CODE
FAILURE CODE
Exits:
None.
the pop was successful
Unsuccessful
****************************************************~* ***********************1
PromptStack *Base_PopPromptStack( PromptStack *stack )
{
PromptStack *pTmpPtr;
i f ( stack
== NULL
{
return NULL;
}
1* Save old pointer *1
pTmpPtr = stack;
1* Restore the pointer *1
stack = stack->link;
free ( ( PromptStack * )pTmpPtr );
return stack;
1* Base_PopPromptStack *1
/*****************************************************************************
Function: Base_KillPromptStack
Description:
This function will delete the entire stack and recycle the memory
used by it. Call this function when you are completely done with
a prompt stack.
Arguments:
stack
the existing prompt stack
Returns:
None.
Exits:
None.
****************************************************** ***********************1
PromptStack *Base_KiIIPromptStack( PromptStack *stack )
{
PromptStack *pTmpPtr;
1* Traverse through the stack and pop all the elements off *1
pTmpPtr = stack;
while ( pTmpPtr l= NULL
{
Base_PopPromptStack( pTmpPtr );
pTmpptr = pTmpPtr->link;
2
free( stack );
return NULL;
/* Base_KillPromptStack */
3
Download