1 /***************************************
4 C Cross Referencing & Documentation tool. Version 1.5e.
6 Cross referencing of functions.
7 ******************/ /******************
8 Written by Andrew M. Bishop
10 This file Copyright 1995,96,97,98,99,2000,01,02 Andrew M. Bishop
11 It may be distributed under the GNU Public License, version 2, or
12 any higher version. See section COPYING of the GNU Public license
13 for conditions under which this file may be redistributed.
14 ***************************************/
16 /*+ The names of the function cross reference files. +*/
17 #define XREF_FUNC_FILE ".function"
18 #define XREF_FUNC_BACKUP ".function~"
20 /*+ The names of the variable cross reference files. +*/
21 #define XREF_VAR_FILE ".variable"
22 #define XREF_VAR_BACKUP ".variable~"
24 /*+ The names of the include cross reference files. +*/
25 #define XREF_INC_FILE ".include"
26 #define XREF_INC_BACKUP ".include~"
28 /*+ The names of the type cross reference files. +*/
29 #define XREF_TYPE_FILE ".typedef"
30 #define XREF_TYPE_BACKUP ".typedef~"
38 #define TYPE_MAX_LEN 256 /*+ The maximum type definition length +*/
39 #define FUNC_MAX_LEN 64 /*+ The maximum function name length. +*/
40 #if defined(PATH_MAX) && defined(NAME_MAX)
41 #define FILE_MAX_LEN (PATH_MAX+NAME_MAX) /*+ The maximum filename length. +*/
42 #elif defined(PATH_MAX)
43 #define FILE_MAX_LEN (PATH_MAX+256) /*+ The maximum filename length. +*/
45 #define FILE_MAX_LEN 512 /*+ The maximum filename length. +*/
52 /*+ The name of the directory for the output. +*/
53 extern char* option_odir
;
55 /*+ The base name of the file for the output. +*/
56 extern char* option_name
;
58 /*+ The option for cross referencing. +*/
59 extern int option_xref
;
61 /*+ The option for indexing. +*/
62 extern int option_index
;
64 static void check_for_called(File file
,char* called
,char* caller
,char* filename
);
65 static void check_for_caller(File file
,char* called
,char* filename
);
66 static void check_for_var(File file
,char* variable
,char* filename
,int scope
,char* funcname
);
67 static int check_for_var_func(File file
,Variable var
,Function func
);
68 static void fixup_extern_var(Variable var
,StringList2 refs
);
70 /*++++++++++++++++++++++++++++++++++++++
71 Cross reference the functions, variables and includes that are used in this file
72 with the global functions, variables and includes. The types that are defined are also listed here.
74 File file The file structure containing the information.
76 int outputs Set to true if any cross referencing to produce outputs is required.
77 ++++++++++++++++++++++++++++++++++++++*/
79 void CrossReference(File file
,int outputs
)
84 /* Format: filename [[%]include1] [[%]include2] ... : Files include1, include2, ... are included in filename;
85 those with a % are local. */
87 if(option_xref
&XREF_FILE
) /* First do the files */
91 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_INC_FILE
);
92 ofile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_INC_BACKUP
);
98 {fprintf(stderr
,"cxref: Failed to open the include cross reference file '%s'\n",ofile
);exit(1);}
100 fprintf(out
,"%s",file
->name
);
101 for(inc
=file
->includes
;inc
;inc
=inc
->next
)
102 fprintf(out
," %s%s",inc
->scope
==LOCAL
?"%":"",inc
->name
);
107 char include
[FILE_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1],ch
;
109 while(fscanf(in
,"%s%c",filename
,&ch
)==2)
111 int diff_file
=strcmp(filename
,file
->name
);
114 fprintf(out
,"%s",filename
);
118 fscanf(in
,"%s%c",include
,&ch
);
121 fprintf(out
," %s",include
);
124 if(include
[0]=='%' && !strcmp(&include
[1],file
->name
))
125 AddToStringList(file
->inc_in
,filename
,1,1);
140 /* Format: filename funcname scope [[%][&]funcname1] [[%][&]funcname2] ... : The function funcname in file filename
141 calls or references functions funcname1, funcname2 ... ; those with a % are local, with a & are references. */
142 /* Format: filename $ 0 [[%]&funcname1] [[%]&funcname2] ... : The file references functions funcname1, funcname2 ... ;
143 those with a % are local. */
145 if(option_xref
&XREF_FUNC
) /* Now do the functions */
150 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_FUNC_FILE
);
151 ofile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_FUNC_BACKUP
);
153 in
=fopen(ifile
,"r");
154 out
=fopen(ofile
,"w");
157 {fprintf(stderr
,"cxref: Failed to open the functional cross reference file '%s'\n",ofile
);exit(1);}
159 for(i
=0;i
<file
->f_refs
->n
;i
++)
160 check_for_called(file
,ConcatStrings(2,"&",file
->f_refs
->s1
[i
]),NULL
,file
->name
);
162 for(func
=file
->functions
;func
;func
=func
->next
)
164 for(i
=0;i
<func
->calls
->n
;i
++)
165 check_for_called(file
,func
->calls
->s1
[i
],func
->name
,file
->name
);
166 for(i
=0;i
<func
->f_refs
->n
;i
++)
167 check_for_called(file
,ConcatStrings(2,"&",func
->f_refs
->s1
[i
]),func
->name
,file
->name
);
170 for(func
=file
->functions
;func
;func
=func
->next
)
171 check_for_caller(file
,func
->name
,file
->name
);
175 fprintf(out
,"%s $ 0",file
->name
);
176 for(i
=0;i
<file
->f_refs
->n
;i
++)
178 if(file
->f_refs
->s2
[i
])
179 fprintf(out
," %%&%s",file
->f_refs
->s1
[i
]);
181 fprintf(out
," &%s",file
->f_refs
->s1
[i
]);
186 for(func
=file
->functions
;func
;func
=func
->next
)
188 fprintf(out
,"%s %s %d",file
->name
,func
->name
,func
->scope
);
189 for(i
=0;i
<func
->calls
->n
;i
++)
191 if(func
->calls
->s2
[i
])
192 fprintf(out
," %%%s",func
->calls
->s1
[i
]);
194 fprintf(out
," %s",func
->calls
->s1
[i
]);
196 for(i
=0;i
<func
->f_refs
->n
;i
++)
198 if(func
->f_refs
->s2
[i
])
199 fprintf(out
," %%&%s",func
->f_refs
->s1
[i
]);
201 fprintf(out
," &%s",func
->f_refs
->s1
[i
]);
208 char ch
,funcname
[FUNC_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1],called
[FUNC_MAX_LEN
+1];
211 while(fscanf(in
,"%s %s %d%c",filename
,funcname
,&scope
,&ch
)==4)
213 int diff_file
=strcmp(filename
,file
->name
);
218 if(funcname
[0]!='$' || funcname
[1]!=0)
219 check_for_caller(file
,funcname
,filename
);
220 fprintf(out
,"%s %s %d",filename
,funcname
,scope
);
225 fscanf(in
,"%s%c",called
,&ch
);
233 if(funcname
[0]!='$' || funcname
[1]!=0)
234 check_for_called(file
,called
,funcname
,filename
);
236 check_for_called(file
,called
,NULL
,filename
);
239 fprintf(out
," %s",called
);
255 /* Format: filename varname scope [$] [[%]funcname1] [[%]funcname2] ... : variable varname is used in
256 the file filename if $, and functions funcname1, funcname2 ... Those with a % are local. */
258 if(option_xref
&XREF_VAR
) /* Now do the variables */
263 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_VAR_FILE
);
264 ofile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_VAR_BACKUP
);
266 in
=fopen(ifile
,"r");
267 out
=fopen(ofile
,"w");
270 {fprintf(stderr
,"cxref: Failed to open the variable cross reference file '%s'\n",ofile
);exit(1);}
272 for(var
=file
->variables
;var
;var
=var
->next
)
274 check_for_var(file
,var
->name
,file
->name
,var
->scope
,NULL
);
275 fprintf(out
,"%s %s %d",file
->name
,var
->name
,var
->scope
);
276 if(check_for_var_func(file
,var
,NULL
))
278 for(func
=file
->functions
;func
;func
=func
->next
)
279 if(check_for_var_func(file
,var
,func
))
280 fprintf(out
," %s%s",func
->scope
==LOCAL
?"%":"",func
->name
);
286 char varname
[FUNC_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1],funcname
[FUNC_MAX_LEN
+1],ch
;
289 while(fscanf(in
,"%s %s %d%c",filename
,varname
,&scope
,&ch
)==4)
291 int diff_file
=strcmp(filename
,file
->name
);
297 check_for_var(file
,varname
,filename
,scope
,NULL
);
298 fprintf(out
,"%s %s %d",filename
,varname
,scope
);
303 fscanf(in
,"%s%c",funcname
,&ch
);
312 check_for_var(file
,varname
,filename
,scope
,&funcname
[1]);
314 check_for_var(file
,varname
,filename
,scope
,funcname
);
317 fprintf(out
," %s",funcname
);
329 /* We must fix the location of the extern variables now since it was not known earlier. */
333 fixup_extern_var(file
->variables
,file
->v_refs
);
334 for(func
=file
->functions
;func
;func
=func
->next
)
335 fixup_extern_var(file
->variables
,func
->v_refs
);
342 /* Format: filename typename type... : For a typedef type. */
343 /* Format: filename # type... : For a non typedef type. */
345 if(option_xref
&XREF_TYPE
) /* Now do the types */
349 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_TYPE_FILE
);
350 ofile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_TYPE_BACKUP
);
352 in
=fopen(ifile
,"r");
353 out
=fopen(ofile
,"w");
356 {fprintf(stderr
,"cxref: Failed to open the typedef reference file '%s'\n",ofile
);exit(1);}
358 for(type
=file
->typedefs
;type
;type
=type
->next
)
360 fprintf(out
,"%s %s %s\n",file
->name
,type
->name
,type
->type
);
362 fprintf(out
,"%s # %s\n",file
->name
,type
->name
);
366 char typename
[TYPE_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1];
368 while(fscanf(in
,"%s %s",filename
,typename
)==2)
370 int diff_file
=strcmp(filename
,file
->name
);
373 fprintf(out
,"%s %s",filename
,typename
);
375 fgets(typename
,TYPE_MAX_LEN
,in
);
391 /*++++++++++++++++++++++++++++++++++++++
392 Check through all of the functions in this file to see if any of them are called or referenced.
394 File file The file structure.
396 char* called The function that is called.
398 char* caller The function that the called function is called from.
400 char* filename The file that the function is called from.
401 ++++++++++++++++++++++++++++++++++++++*/
403 static void check_for_called(File file
,char* called
,char* caller
,char* filename
)
407 /* Check for function calls */
410 for(func
=file
->functions
;func
;func
=func
->next
)
412 if(!strcmp(called
,func
->name
))
413 AddToStringList2(func
->called
,caller
,filename
,1,1);
416 /* Check for function references */
419 for(func
=file
->functions
;func
;func
=func
->next
)
421 if(!strcmp(&called
[1],func
->name
))
424 AddToStringList2(func
->used
,caller
,filename
,1,1);
426 AddToStringList2(func
->used
,"$",filename
,1,0);
432 /*++++++++++++++++++++++++++++++++++++++
433 Check through all of the functions in this file to see if any of them are callers or referencers.
435 File file The file structure.
437 char* called The function that is called.
439 char* filename The file that the called function is in.
440 ++++++++++++++++++++++++++++++++++++++*/
442 static void check_for_caller(File file
,char* called
,char* filename
)
447 /* Check the functions that are called. */
449 for(func
=file
->functions
;func
;func
=func
->next
)
450 for(i
=0;i
<func
->calls
->n
;i
++)
451 if(!strcmp(called
,func
->calls
->s1
[i
]))
452 if(!func
->calls
->s2
[i
])
453 func
->calls
->s2
[i
]=MallocString(filename
);
455 /* Check the functions that are referenced. */
457 for(i
=0;i
<file
->f_refs
->n
;i
++)
458 if(!strcmp(called
,file
->f_refs
->s1
[i
]))
459 if(!file
->f_refs
->s2
[i
])
460 file
->f_refs
->s2
[i
]=MallocString(filename
);
462 for(func
=file
->functions
;func
;func
=func
->next
)
463 for(i
=0;i
<func
->f_refs
->n
;i
++)
464 if(!strcmp(called
,func
->f_refs
->s1
[i
]))
465 if(!func
->f_refs
->s2
[i
])
466 func
->f_refs
->s2
[i
]=MallocString(filename
);
470 /*++++++++++++++++++++++++++++++++++++++
471 Check through all of the variables in this file to see if any of them are extern usage of others.
473 File file The file structure.
475 char* variable The global variable name.
477 char* filename The file that the variable is used in.
479 int scope The scope of the variable in the foreign file.
481 char* funcname The name of a function that uses the variable.
482 ++++++++++++++++++++++++++++++++++++++*/
484 static void check_for_var(File file
,char* variable
,char* filename
,int scope
,char* funcname
)
490 if(!(scope
&(GLOBAL
|EXTERNAL
|EXTERN_H
)))
493 for(var
=file
->variables
;var
;var
=var
->next
)
494 if((scope
&GLOBAL
&& var
->scope
&(EXTERNAL
|EXTERN_H
|EXTERN_F
)) ||
495 (scope
&(GLOBAL
|EXTERNAL
|EXTERN_H
) && var
->scope
&GLOBAL
))
496 if(!strcmp(variable
,var
->name
))
498 if(scope
&GLOBAL
&& var
->scope
&(EXTERNAL
|EXTERN_H
|EXTERN_F
))
499 var
->defined
=MallocString(filename
);
501 if(scope
&(GLOBAL
|EXTERNAL
|EXTERN_H
) && var
->scope
&GLOBAL
)
502 AddToStringList2(var
->visible
,"$",filename
,1,0);
507 for(var
=file
->variables
;var
;var
=var
->next
)
508 if(!strcmp(variable
,var
->name
))
510 if(funcname
[0]=='$' && !funcname
[1])
511 AddToStringList2(var
->used
,"$",filename
,1,0);
514 AddToStringList2(var
->used
,funcname
,filename
,1,1);
516 if(scope
&EXTERN_F
&& var
->scope
&GLOBAL
)
517 AddToStringList2(var
->visible
,funcname
,filename
,1,1);
524 /*++++++++++++++++++++++++++++++++++++++
525 Check through the function to see if it uses the variable, if func is NULL then check the file.
527 int check_for_var_func Returns 1 if the variable is referenced from the function or file.
529 File file The file that the function belongs to.
531 Variable var The variable that may be referenced.
533 Function func The function that is to be checked.
534 ++++++++++++++++++++++++++++++++++++++*/
536 static int check_for_var_func(File file
,Variable var
,Function func
)
542 for(i
=0;i
<func
->v_refs
->n
;i
++)
543 if(!strcmp(var
->name
,func
->v_refs
->s1
[i
]))
545 AddToStringList2(var
->used
,func
->name
,file
->name
,1,1);
546 if(var
->scope
&(GLOBAL
|LOCAL
))
547 func
->v_refs
->s2
[i
]=MallocString(file
->name
);
550 if(func
->v_refs
->s2
[i
]) Free(func
->v_refs
->s2
[i
]);
551 func
->v_refs
->s2
[i
]=MallocString("$");
558 for(i
=0;i
<file
->v_refs
->n
;i
++)
559 if(!strcmp(var
->name
,file
->v_refs
->s1
[i
]))
561 AddToStringList2(var
->used
,"$",file
->name
,1,0);
562 if(var
->scope
&(GLOBAL
|LOCAL
))
563 file
->v_refs
->s2
[i
]=MallocString(file
->name
);
566 if(file
->v_refs
->s2
[i
]) Free(file
->v_refs
->s2
[i
]);
567 file
->v_refs
->s2
[i
]=MallocString("$");
577 /*++++++++++++++++++++++++++++++++++++++
578 We can only now put in the location of the external variables that we found were used.
579 Previously we did not know the location of their global definition.
581 Variable var The list of variables for this file.
583 StringList2 refs A list of variable references from a file or a function.
584 ++++++++++++++++++++++++++++++++++++++*/
586 static void fixup_extern_var(Variable var
,StringList2 refs
)
591 for(i
=0;i
<refs
->n
;i
++)
593 if(refs
->s2
[i
][0]=='$' && !refs
->s2
[i
][1])
594 for(v
=var
;v
;v
=v
->next
)
595 if(v
->scope
&(EXTERNAL
|EXTERN_H
|EXTERN_F
) && !strcmp(refs
->s1
[i
],v
->name
))
600 refs
->s2
[i
]=MallocString(v
->defined
);
605 refs
->s1
[i
]=MallocString(v
->name
);
616 /*++++++++++++++++++++++++++++++++++++++
617 Create the appendix of files, global functions, global variables and types.
619 StringList files The list of files to create.
621 StringList2 funcs The list of functions to create.
623 StringList2 vars The list of variables to create.
625 StringList2 types The list of types to create.
626 ++++++++++++++++++++++++++++++++++++++*/
628 void CreateAppendix(StringList files
,StringList2 funcs
,StringList2 vars
,StringList2 types
)
633 if(option_index
&INDEX_FILE
) /* First do the files */
635 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_INC_FILE
);
637 in
=fopen(ifile
,"r");
641 char include
[FILE_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1],ch
;
643 while(fscanf(in
,"%s%c",filename
,&ch
)==2)
645 AddToStringList(files
,filename
,1,1);
647 fscanf(in
,"%s%c",include
,&ch
);
654 if(option_index
&INDEX_FUNC
) /* Now do the functions */
656 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_FUNC_FILE
);
658 in
=fopen(ifile
,"r");
662 char ch
,caller
[FUNC_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1],called
[FUNC_MAX_LEN
+1];
665 while(fscanf(in
,"%s %s %d%c",filename
,caller
,&scope
,&ch
)==4)
668 AddToStringList2(funcs
,caller
,filename
,1,1);
670 fscanf(in
,"%s%c",called
,&ch
);
677 if(option_index
&INDEX_VAR
) /* Now do the variables */
679 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_VAR_FILE
);
681 in
=fopen(ifile
,"r");
685 char variable
[FUNC_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1],funcname
[FUNC_MAX_LEN
+1],ch
;
688 while(fscanf(in
,"%s %s %d%c",filename
,variable
,&scope
,&ch
)==4)
691 AddToStringList2(vars
,variable
,filename
,1,1);
693 fscanf(in
,"%s%c",funcname
,&ch
);
700 if(option_index
&INDEX_TYPE
) /* Now do the types */
702 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_TYPE_FILE
);
704 in
=fopen(ifile
,"r");
708 char typename
[TYPE_MAX_LEN
],filename
[FILE_MAX_LEN
+1];
710 while(fscanf(in
,"%s %s",filename
,typename
)==2)
714 fgets(typename
,TYPE_MAX_LEN
,in
);
715 typename
[strlen(typename
)-1]=0;
716 AddToStringList2(types
,&typename
[1],filename
,1,1);
720 AddToStringList2(types
,typename
,filename
,1,1);
721 fgets(typename
,TYPE_MAX_LEN
,in
);
731 /*++++++++++++++++++++++++++++++++++++++
732 Delete the named file from the cross reference database.
734 char *name The name of the file that is to be deleted.
735 ++++++++++++++++++++++++++++++++++++++*/
737 void CrossReferenceDelete(char *name
)
742 /* First do the files */
744 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_INC_FILE
);
745 ofile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_INC_BACKUP
);
747 in
=fopen(ifile
,"r");
748 out
=fopen(ofile
,"w");
751 {fprintf(stderr
,"cxref: Failed to open the include cross reference file '%s'\n",ofile
);fclose(in
);}
754 char include
[FILE_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1],ch
;
756 while(fscanf(in
,"%s%c",filename
,&ch
)==2)
758 int diff_file
=strcmp(filename
,name
);
761 fprintf(out
,"%s",filename
);
765 fscanf(in
,"%s%c",include
,&ch
);
768 fprintf(out
," %s",include
);
787 /* Now do the functions */
789 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_FUNC_FILE
);
790 ofile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_FUNC_BACKUP
);
792 in
=fopen(ifile
,"r");
793 out
=fopen(ofile
,"w");
796 {fprintf(stderr
,"cxref: Failed to open the functional cross reference file '%s'\n",ofile
);fclose(in
);}
799 char ch
,funcname
[FUNC_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1],called
[FUNC_MAX_LEN
+1];
802 while(fscanf(in
,"%s %s %d%c",filename
,funcname
,&scope
,&ch
)==4)
804 int diff_file
=strcmp(filename
,name
);
807 fprintf(out
,"%s %s %d",filename
,funcname
,scope
);
811 fscanf(in
,"%s%c",called
,&ch
);
813 fprintf(out
," %s",called
);
832 /* Now do the variables */
834 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_VAR_FILE
);
835 ofile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_VAR_BACKUP
);
837 in
=fopen(ifile
,"r");
838 out
=fopen(ofile
,"w");
841 {fprintf(stderr
,"cxref: Failed to open the variable cross reference file '%s'\n",ofile
);fclose(in
);}
844 char varname
[FUNC_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1],funcname
[FUNC_MAX_LEN
+1],ch
;
847 while(fscanf(in
,"%s %s %d%c",filename
,varname
,&scope
,&ch
)==4)
849 int diff_file
=strcmp(filename
,name
);
852 fprintf(out
,"%s %s %d",filename
,varname
,scope
);
856 fscanf(in
,"%s%c",funcname
,&ch
);
859 fprintf(out
," %s",funcname
);
878 /* Now do the types */
880 ifile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_TYPE_FILE
);
881 ofile
=ConcatStrings(4,option_odir
,"/",option_name
,XREF_TYPE_BACKUP
);
883 in
=fopen(ifile
,"r");
884 out
=fopen(ofile
,"w");
887 {fprintf(stderr
,"cxref: Failed to open the typedef reference file '%s'\n",ofile
);fclose(in
);}
890 char typename
[TYPE_MAX_LEN
+1],filename
[FILE_MAX_LEN
+1];
892 while(fscanf(in
,"%s %s",filename
,typename
)==2)
894 int diff_file
=strcmp(filename
,name
);
897 fprintf(out
,"%s %s",filename
,typename
);
899 fgets(typename
,TYPE_MAX_LEN
,in
);