don't check when its clang masquerading as gcc
[AROS.git] / tools / cxref / rtf.c
blob6f02e148badab9bb1ab9fc28bbe21fc720c791bb
1 /***************************************
2 $Header$
4 C Cross Referencing & Documentation tool. Version 1.5f.
6 Writes the RTF output.
7 ******************/ /******************
8 Written by Andrew M. Bishop
10 This file Copyright 1995,96,97,98,2001,04 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 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
23 #include "memory.h"
24 #include "datatype.h"
25 #include "cxref.h"
27 /*+ The name of the output rtf file. +*/
28 #define RTF_FILE ".rtf"
29 #define RTF_FILE_BACKUP ".rtf~"
31 /*+ The name of the output rtf file that contains the appendix. +*/
32 #define RTF_APDX ".apdx"
34 #define STYLE_NORM "\\s0\\f0\\fs24"
35 #define STYLE_H1 "\\s1\\f0\\fs40\\b\\sb400\\sa200\\keepn\\keep"
36 #define STYLE_H2 "\\s2\\f0\\fs32\\b\\sb200\\sa100\\keepn\\keep"
37 #define STYLE_H3 "\\s3\\f0\\fs28\\b\\sb100\\sa100\\keepn\\keep"
38 #define STYLE_H4 "\\s4\\f0\\fs24\\b\\sb100\\sa50\\keepn\\keep"
39 #define STYLE_TT "\\s5\\f1\\fs20\\ql\\sb50\\sa50"
40 #define STYLE_IND "\\s6\\f0\\fs24\\ql\\li720"
42 /*+ The comments are to be inserted verbatim. +*/
43 extern int option_verbatim_comments;
45 /*+ The name of the directory for the output. +*/
46 extern char* option_odir;
48 /*+ The base name of the file for the output. +*/
49 extern char* option_name;
51 /*+ The information about the cxref run, +*/
52 extern char *run_command, /*+ the command line options. +*/
53 *run_cpp_command; /*+ the cpp command and options. +*/
55 static void WriteRTFFilePart(File file);
56 static void WriteRTFInclude(Include inc);
57 static void WriteRTFSubInclude(Include inc,int depth);
58 static void WriteRTFDefine(Define def);
59 static void WriteRTFTypedef(Typedef type,char* filename);
60 static void WriteRTFStructUnion(StructUnion su,int depth);
61 static void WriteRTFVariable(Variable var,char* filename);
62 static void WriteRTFFunction(Function func,char* filename);
63 static void WriteRTFPreamble(FILE *f);
64 static void WriteRTFPostamble(FILE *f);
66 static char* rtf(char* c,int verbatim);
68 /*+ The output file for the RTF. +*/
69 static FILE* of;
72 /*++++++++++++++++++++++++++++++++++++++
73 Write an RTF file for a complete File structure and all components.
75 File file The File structure to output.
76 ++++++++++++++++++++++++++++++++++++++*/
78 void WriteRTFFile(File file)
80 char* ofile;
82 /* Open the file */
84 ofile=ConcatStrings(4,option_odir,"/",file->name,RTF_FILE);
86 of=fopen(ofile,"w");
87 if(!of)
89 struct stat stat_buf;
90 int i,ofl=strlen(ofile);
92 for(i=strlen(option_odir)+1;i<ofl;i++)
93 if(ofile[i]=='/')
95 ofile[i]=0;
96 if(stat(ofile,&stat_buf))
97 mkdir(ofile,S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
98 ofile[i]='/';
101 of=fopen(ofile,"w");
104 if(!of)
105 {fprintf(stderr,"cxref: Failed to open the RTF output file '%s'\r\n",ofile);exit(1);}
107 /* Write out a header. */
109 WriteRTFPreamble(of);
111 /*+ The file structure is broken into its components and they are each written out. +*/
113 WriteRTFFilePart(file);
115 if(file->includes)
117 Include inc =file->includes;
118 fprintf(of,"{" STYLE_H2 " Included Files\\par}\r\n");
120 WriteRTFInclude(inc);
122 while((inc=inc->next));
125 if(file->defines)
127 Define def =file->defines;
128 fprintf(of,"{" STYLE_H2 " Preprocessor definitions\\par}\r\n");
130 WriteRTFDefine(def);
132 while((def=def->next));
135 if(file->typedefs)
137 Typedef type=file->typedefs;
138 fprintf(of,"{" STYLE_H2 " Type definitions\\par}\r\n");
140 WriteRTFTypedef(type,file->name);
142 while((type=type->next));
145 if(file->variables)
147 int any_to_mention=0;
148 Variable var=file->variables;
151 if(var->scope&(GLOBAL|LOCAL|EXTERNAL|EXTERN_F))
152 any_to_mention=1;
154 while((var=var->next));
156 if(any_to_mention)
158 Variable var=file->variables;
159 fprintf(of,"{" STYLE_H2 " Variables\\par}\r\n");
161 if(var->scope&GLOBAL)
162 WriteRTFVariable(var,file->name);
164 while((var=var->next));
165 var=file->variables;
167 if(var->scope&(EXTERNAL|EXTERN_F) && !(var->scope&GLOBAL))
169 fprintf(of,"{" STYLE_H3 " External Variables\\par}\r\n");
170 WriteRTFVariable(var,file->name);
173 while((var=var->next));
174 var=file->variables;
176 if(var->scope&LOCAL)
178 fprintf(of,"{" STYLE_H3 " Local Variables\\par}\r\n");
179 WriteRTFVariable(var,file->name);
182 while((var=var->next));
186 if(file->functions)
188 Function func=file->functions;
189 fprintf(of,"{" STYLE_H2 " Functions\\par}\r\n");
191 if(func->scope&(GLOBAL|EXTERNAL))
192 WriteRTFFunction(func,file->name);
194 while((func=func->next));
195 func=file->functions;
197 if(func->scope&LOCAL)
198 WriteRTFFunction(func,file->name);
200 while((func=func->next));
203 /* Write out a trailer. */
205 WriteRTFPostamble(of);
207 fclose(of);
209 /* Clear the memory in rtf() */
211 rtf(NULL,0); rtf(NULL,0); rtf(NULL,0); rtf(NULL,0);
215 /*++++++++++++++++++++++++++++++++++++++
216 Write a File structure out.
218 File file The File to output.
219 ++++++++++++++++++++++++++++++++++++++*/
221 static void WriteRTFFilePart(File file)
223 int i;
225 fprintf(of,"{" STYLE_H1 " File %s\\par}\r\n",rtf(file->name,0));
227 if(file->comment)
229 if(option_verbatim_comments)
230 fprintf(of,"{" STYLE_TT "%s\\par}\r\n",rtf(file->comment,1));
231 else
233 char *rcs1=strstr(file->comment,"$Header"),*rcs2=NULL;
234 if(rcs1)
236 rcs2=strstr(&rcs1[1],"$");
237 if(rcs2)
239 rcs2[0]=0;
240 fprintf(of,"{\\b RCS %s}\\par\r\n",rtf(&rcs1[1],0));
241 rcs2[0]='$';
244 if(rcs2)
245 fprintf(of,"%s\\par\r\n",rtf(&rcs2[2],0));
246 else
247 fprintf(of,"%s\\par\r\n",rtf(file->comment,0));
251 if(file->inc_in->n)
253 int i;
255 fprintf(of,"\\trowd\\trgaph120\\cellx1440\\cellx9000\r\n\\intbl\\plain\r\n");
256 for(i=0;i<file->inc_in->n;i++)
258 if(i==0) fprintf(of,"Included in:");
259 fprintf(of,"\\cell %s\\cell\\row\r\n",rtf(file->inc_in->s[i],0));
261 fprintf(of,"\\intbl0\r\n");
264 if(file->f_refs->n || file->v_refs->n)
266 fprintf(of,"\\trowd\\trgaph120\\cellx1440\\cellx5220\\cellx9000\r\n\\intbl\\plain\r\n");
268 if(file->f_refs->n)
270 int others=0;
272 fprintf(of,"Refs Func:");
274 for(i=0;i<file->f_refs->n;i++)
275 if(file->f_refs->s2[i])
276 fprintf(of,"\\cell %s()\\cell %s\\cell\\row\r\n",rtf(file->f_refs->s1[i],0),rtf(file->f_refs->s2[i],0));
277 else
278 others++;
280 if(others)
282 fprintf(of,"\\cell ");
283 for(i=0;i<file->f_refs->n;i++)
284 if(!file->f_refs->s2[i])
285 fprintf(of,--others?"%s(), ":"%s()",rtf(file->f_refs->s1[i],0));
286 fprintf(of,"\\cell\\cell\\row\r\n");
290 if(file->v_refs->n)
292 int others=0;
294 fprintf(of,"Refs Var:");
296 for(i=0;i<file->v_refs->n;i++)
297 if(file->v_refs->s2[i])
298 fprintf(of,"\\cell %s\\cell %s\\cell\\row\r\n",rtf(file->v_refs->s1[i],0),rtf(file->v_refs->s2[i],0));
299 else
300 others++;
302 if(others)
304 fprintf(of,"\\cell ");
305 for(i=0;i<file->v_refs->n;i++)
306 if(!file->v_refs->s2[i])
307 fprintf(of,--others?" %s,":" %s",rtf(file->v_refs->s1[i],0));
308 fprintf(of,"\\cell\\cell\\row\r\n");
311 fprintf(of,"\\intbl0\r\n");
316 /*++++++++++++++++++++++++++++++++++++++
317 Write an Include structure out.
319 Include inc The Include structure to output.
320 ++++++++++++++++++++++++++++++++++++++*/
322 static void WriteRTFInclude(Include inc)
324 if(inc->comment)
325 fprintf(of,"%s\\par\r\n",rtf(inc->comment,0));
327 if(inc->scope==LOCAL)
328 fprintf(of,"{" STYLE_TT " #include \"%s\"\\par}\r\n",rtf(inc->name,0));
329 else
330 fprintf(of,"{" STYLE_TT " #include <%s>\\par}\r\n",rtf(inc->name,0));
332 if(inc->includes)
333 WriteRTFSubInclude(inc->includes,1);
337 /*++++++++++++++++++++++++++++++++++++++
338 Write an Sub Include structure out. (An include structure that is included from another file.)
340 Include inc The Include structure to output.
342 int depth The depth of the include hierarchy.
343 ++++++++++++++++++++++++++++++++++++++*/
345 static void WriteRTFSubInclude(Include inc,int depth)
347 int i;
349 while(inc)
351 for(i=0;i<depth;i++)
352 fprintf(of,"\t");
354 if(inc->scope==LOCAL)
355 fprintf(of,"{" STYLE_TT " #include \"%s\"\\par}\r\n",rtf(inc->name,0));
356 else
357 fprintf(of,"{" STYLE_TT " #include <%s>\\par}\r\n",rtf(inc->name,0));
359 if(inc->includes)
360 WriteRTFSubInclude(inc->includes,depth+1);
362 inc=inc->next;
367 /*++++++++++++++++++++++++++++++++++++++
368 Write a Define structure out.
370 Define def The Define structure to output.
371 ++++++++++++++++++++++++++++++++++++++*/
373 static void WriteRTFDefine(Define def)
375 int i;
376 int pargs=0;
378 if(def->comment)
379 fprintf(of,"%s\\par\r\n",rtf(def->comment,0));
381 fprintf(of,"{" STYLE_TT " #define %s",rtf(def->name,0));
383 if(def->value)
384 fprintf(of," %s",rtf(def->value,0));
386 if(def->args->n)
388 fprintf(of,"( ");
389 for(i=0;i<def->args->n;i++)
390 fprintf(of,i?", %s":"%s",rtf(def->args->s1[i],0));
391 fprintf(of," )");
393 fprintf(of,"\\par}\r\n");
395 for(i=0;i<def->args->n;i++)
396 if(def->args->s2[i])
397 pargs=1;
399 if(pargs)
401 for(i=0;i<def->args->n;i++)
402 fprintf(of,"{" STYLE_TT "%s\\par}\r\n{" STYLE_IND " %s\\par}\r\n",rtf(def->args->s1[i],0),def->args->s2[i]?rtf(def->args->s2[i],0):"");
407 /*++++++++++++++++++++++++++++++++++++++
408 Write a Typedef structure out.
410 Typedef type The Typedef structure to output.
412 char* filename The name of the file that is being processed (required for the cross reference label).
413 ++++++++++++++++++++++++++++++++++++++*/
415 static void WriteRTFTypedef(Typedef type,char* filename)
417 if(type->type)
418 fprintf(of,"{" STYLE_H3 " Typedef %s\\par}\r\n",rtf(type->name,0));
419 else
420 fprintf(of,"{" STYLE_H3 " Type %s\\par}\r\n",rtf(type->name,0));
422 if(type->comment)
423 fprintf(of,"%s\\par\r\n",rtf(type->comment,0));
425 if(type->type)
426 fprintf(of,"{" STYLE_TT " typedef %s\\par}\r\n",rtf(type->type,0));
428 if(type->sutype)
430 fprintf(of,"\\trowd\\trgaph120\\cellx2880\\cellx9000\r\n\\intbl\\plain\r\n");
431 WriteRTFStructUnion(type->sutype,0);
432 fprintf(of,"\\intbl0\r\n");
434 else
435 if(type->typexref)
437 if(type->typexref->type)
438 fprintf(of,"See:\tTypedef %s\\par\r\n",rtf(type->typexref->name,0));
439 else
440 if(!strncmp("enum",type->typexref->name,4))
441 fprintf(of,"See\tType %s\\par\r\n",rtf(type->typexref->name,0));
442 else
443 if(!strncmp("union",type->typexref->name,5))
444 fprintf(of,"See:\tType %s\\par\r\n",rtf(type->typexref->name,0));
445 else
446 if(!strncmp("struct",type->typexref->name,6))
447 fprintf(of,"See:\tType %s\\par\r\n",rtf(type->typexref->name,0));
452 /*++++++++++++++++++++++++++++++++++++++
453 Write a structure / union structure out.
455 StructUnion su The structure / union to write.
457 int depth The current depth within the structure.
458 ++++++++++++++++++++++++++++++++++++++*/
460 static void WriteRTFStructUnion(StructUnion su, int depth)
462 int i;
463 char* splitsu=NULL;
465 splitsu=strstr(su->name,"{...}");
466 if(splitsu) splitsu[-1]=0;
468 for(i=0;i<depth;i++)
469 fprintf(of,"\t");
471 if(depth && su->comment && !su->comps)
472 fprintf(of,"{" STYLE_TT " %s;}\\cell %s\\cell\\row\r\n",rtf(su->name,0),rtf(su->comment,0));
473 else if(!depth || su->comps)
474 fprintf(of,"{" STYLE_TT " %s}\\cell\\cell\\row\r\n",rtf(su->name,0));
475 else
476 fprintf(of,"{" STYLE_TT " %s;}\\cell\\cell\\row\r\n",rtf(su->name,0));
478 if(!depth || su->comps)
480 for(i=0;i<depth;i++)
481 fprintf(of,"\t");
482 fprintf(of,"{" STYLE_TT " \\{}\\cell\\cell\\row\r\n");
484 for(i=0;i<su->n_comp;i++)
485 WriteRTFStructUnion(su->comps[i],depth+1);
487 for(i=0;i<depth;i++)
488 fprintf(of,"\t");
489 fprintf(of,"{" STYLE_TT " \\}}\\cell\\cell\\row\r\n");
490 if(splitsu)
492 for(i=0;i<depth;i++)
493 fprintf(of,"\t");
494 if(depth && su->comment)
495 fprintf(of,"{" STYLE_TT " %s;}\\cell %s\\par\r\n",splitsu[5]?rtf(&splitsu[6],0):"",rtf(su->comment,0));
496 else
497 fprintf(of,"{" STYLE_TT " %s;}\\cell\\cell\\row\r\n",splitsu[5]?rtf(&splitsu[6],0):"");
501 if(splitsu) splitsu[-1]=' ';
505 /*++++++++++++++++++++++++++++++++++++++
506 Write a Variable structure out.
508 Variable var The Variable structure to output.
510 char* filename The name of the file that is being processed (required for the cross reference label).
511 ++++++++++++++++++++++++++++++++++++++*/
513 static void WriteRTFVariable(Variable var,char* filename)
515 int i;
517 if(var->scope&GLOBAL)
518 fprintf(of,"{" STYLE_H3 " Variable %s\\par}\r\n",rtf(var->name,0));
519 else
520 fprintf(of,"{" STYLE_H4 " Variable %s\\par}\r\n",rtf(var->name,0));
522 if(var->comment)
523 fprintf(of,"%s\\par\r\n",rtf(var->comment,0));
525 fprintf(of,"{" STYLE_TT " ");
527 if(var->scope&LOCAL)
528 fprintf(of,"static ");
529 else
530 if(!(var->scope&GLOBAL) && var->scope&(EXTERNAL|EXTERN_F))
531 fprintf(of,"extern ");
533 fprintf(of,"%s\\par}\r\n",rtf(var->type,0));
535 if(var->scope&(GLOBAL|LOCAL))
537 if(var->incfrom || var->used->n || var->visible->n)
539 fprintf(of,"\\trowd\\trgaph120\\cellx1440\\cellx5220\\cellx9000\r\n\\intbl\\plain\r\n");
541 if(var->incfrom)
542 fprintf(of,"Inc. from:\\cell %s\\cell\\row\r\n",rtf(var->incfrom,0));
544 for(i=0;i<var->visible->n;i++)
546 if(i==0) fprintf(of,"Visible in:");
547 if(var->visible->s1[i][0]=='$' && !var->visible->s1[i][1])
548 fprintf(of,"\\cell %s\\cell\\cell\\row\r\n",rtf(var->visible->s2[i],0));
549 else
550 fprintf(of,"\\cell %s()\\cell %s\\cell\\row\r\n",rtf(var->visible->s1[i],0),rtf(var->visible->s2[i],0));
553 for(i=0;i<var->used->n;i++)
555 if(i==0) fprintf(of,"Used in:");
556 if(var->used->s1[i][0]=='$' && !var->used->s1[i][1])
557 fprintf(of,"\\cell %s\\cell\\cell\\row\r\n",rtf(var->used->s2[i],0));
558 else
559 if(var->scope&LOCAL)
560 fprintf(of,"\\cell %s()\\cell\\cell\\row\r\n",rtf(var->used->s1[i],0));
561 else
562 fprintf(of,"\\cell %s()\\cell %s\\cell\\row\r\n",rtf(var->used->s1[i],0),rtf(var->used->s2[i],0));
564 fprintf(of,"\\intbl0\r\n");
567 else
568 if(var->scope&(EXTERNAL|EXTERN_F) && var->defined)
570 fprintf(of,"\\trowd\\trgaph120\\cellx1440\\cellx5220\r\n\\intbl\\plain\r\n");
571 fprintf(of,"Defined in:\\cell %s\\cell\\row\r\n",rtf(var->defined,0));
572 fprintf(of,"\\intbl0\r\n");
577 /*++++++++++++++++++++++++++++++++++++++
578 Write a Function structure out.
580 Function func The Function structure to output.
582 char* filename The name of the file that is being processed (required for the cross reference label).
583 ++++++++++++++++++++++++++++++++++++++*/
585 static void WriteRTFFunction(Function func,char* filename)
587 int i,pret,pargs;
588 char* comment2=NULL,*type;
590 if(func->scope&(GLOBAL|EXTERNAL))
591 fprintf(of,"{" STYLE_H3 " Global Function %s()\\par}\r\n",rtf(func->name,0));
592 else
593 fprintf(of,"{" STYLE_H3 " Local Function %s()\\par}\r\n",rtf(func->name,0));
595 if(func->comment)
597 if(option_verbatim_comments)
598 fprintf(of,"{" STYLE_TT "%s\\par}\r\n",rtf(func->comment,1));
599 else
601 comment2=strstr(func->comment,"\r\n\r\n");
602 if(comment2)
603 comment2[0]=0;
604 fprintf(of,"%s\\par\r\n",rtf(func->comment,0));
608 fprintf(of,"{" STYLE_TT " ");
610 if(func->scope&LOCAL)
611 fprintf(of,"static ");
612 if(func->scope&INLINED)
613 fprintf(of,"inline ");
615 if((type=strstr(func->type,"()")))
616 type[0]=0;
617 fprintf(of,"%s ( ",rtf(func->type,0));
619 for(i=0;i<func->args->n;i++)
620 fprintf(of,i?", %s":"%s",rtf(func->args->s1[i],0));
622 if(type)
623 {fprintf(of," %s\\par}\r\n",&type[1]);type[0]='(';}
624 else
625 fprintf(of," )\\par}\r\n");
627 pret =strncmp("void ",func->type,5) && func->cret;
628 for(pargs=0,i=0;i<func->args->n;i++)
629 pargs = pargs || ( strcmp("void",func->args->s1[i]) && func->args->s2[i] );
631 if(pret || pargs)
633 if(pret)
634 fprintf(of,"{" STYLE_TT " %s\\par}\r\n{" STYLE_IND " %s\\par}\r\n",rtf(func->type,0),func->cret?rtf(func->cret,0):"");
635 if(pargs)
636 for(i=0;i<func->args->n;i++)
637 fprintf(of,"{" STYLE_TT " %s\\par}\r\n{" STYLE_IND " %s\\par}\r\n",rtf(func->args->s1[i],0),func->args->s2[i]?rtf(func->args->s2[i],0):"");
640 if(comment2)
642 fprintf(of,"%s\\par\r\n",rtf(&comment2[2],0));
643 comment2[0]='\n';
646 if(func->protofile || func->incfrom || func->calls->n || func->called->n || func->used->n || func->f_refs->n || func->v_refs->n)
648 fprintf(of,"\\trowd\\trgaph120\\cellx1440\\cellx5220\\cellx9000\r\n\\intbl\\plain\r\n");
650 if(func->protofile)
651 fprintf(of,"Prototype:\\cell %s\\cell\\cell\\row\r\n",rtf(func->protofile,0));
653 if(func->incfrom)
654 fprintf(of,"Inc. from:\\cell %s\\cell\\cell\\row\r\n",rtf(func->incfrom,0));
656 if(func->calls->n)
658 int others=0;
660 fprintf(of,"Calls: ");
662 for(i=0;i<func->calls->n;i++)
663 if(func->calls->s2[i])
664 fprintf(of,"\\cell %s()\\cell %s\\cell\\row\r\n",rtf(func->calls->s1[i],0),rtf(func->calls->s2[i],0));
665 else
666 others++;
668 if(others)
670 fprintf(of,"\\cell ");
671 for(i=0;i<func->calls->n;i++)
672 if(!func->calls->s2[i])
673 fprintf(of,--others?" %s(),":" %s()",rtf(func->calls->s1[i],0));
674 fprintf(of,"\\cell\\cell\\row\r\n");
678 if(func->called->n)
680 for(i=0;i<func->called->n;i++)
682 if(i==0)
683 fprintf(of,"Called by:");
684 fprintf(of,"\\cell %s()\\cell %s\\cell\\row\r\n",rtf(func->called->s1[i],0),rtf(func->called->s2[i],0));
688 if(func->used->n)
690 for(i=0;i<func->used->n;i++)
692 if(i==0)
693 fprintf(of,"Used in:");
694 if(func->used->s1[i][0]=='$' && !func->used->s1[i][1])
695 fprintf(of,"\\cell %s\\cell\\cell\\row\r\n",rtf(func->used->s2[i],0));
696 else
697 fprintf(of,"\\cell %s()\\cell %s\\cell\\row\r\n",rtf(func->used->s1[i],0),rtf(func->used->s2[i],0));
701 if(func->f_refs->n)
703 int others=0;
705 fprintf(of,"Refs Func:");
707 for(i=0;i<func->f_refs->n;i++)
708 if(func->f_refs->s2[i])
709 fprintf(of,"\\cell %s()\\cell %s\\cell\\row\r\n",rtf(func->f_refs->s1[i],0),rtf(func->f_refs->s2[i],0));
710 else
711 others++;
713 if(others)
715 fprintf(of,"\\cell ");
716 for(i=0;i<func->f_refs->n;i++)
717 if(!func->f_refs->s2[i])
718 fprintf(of,--others?" %s(),":" %s()",rtf(func->f_refs->s1[i],0));
719 fprintf(of,"\\cell\\cell\\row\r\n");
723 if(func->v_refs->n)
725 int others=0;
727 fprintf(of,"Refs Var:");
729 for(i=0;i<func->v_refs->n;i++)
730 if(func->v_refs->s2[i])
731 fprintf(of,"\\cell %s\\cell %s\\cell\\row\r\n",rtf(func->v_refs->s1[i],0),rtf(func->v_refs->s2[i],0));
732 else
733 others++;
735 if(others)
737 fprintf(of,"\\cell ");
738 for(i=0;i<func->v_refs->n;i++)
739 if(!func->v_refs->s2[i])
740 fprintf(of,--others?" %s,":" %s",rtf(func->v_refs->s1[i],0));
741 fprintf(of,"\\cell\\cell\\row\r\n");
744 fprintf(of,"\\intbl0\r\n");
749 /*++++++++++++++++++++++++++++++++++++++
750 Write out the appendix information.
752 StringList files The list of files to write.
754 StringList2 funcs The list of functions to write.
756 StringList2 vars The list of variables to write.
758 StringList2 types The list of types to write.
759 ++++++++++++++++++++++++++++++++++++++*/
761 void WriteRTFAppendix(StringList files,StringList2 funcs,StringList2 vars,StringList2 types)
763 char* ofile;
764 int i;
766 /* Open the file */
768 ofile=ConcatStrings(5,option_odir,"/",option_name,RTF_APDX,RTF_FILE);
770 of=fopen(ofile,"w");
772 if(!of)
773 {fprintf(stderr,"cxref: Failed to open the RTF appendix file '%s'\r\n",ofile);exit(1);}
775 /* Write the header out */
777 WriteRTFPreamble(of);
779 fprintf(of,"{" STYLE_H1 " Cross References\\par}\r\n");
781 /* Write out the appendix of files. */
783 if(files->n)
785 fprintf(of,"{" STYLE_H2 " Files\\par}\r\n");
786 fprintf(of,"\\trowd\\trgaph120\\cellx4500\r\n\\intbl\\plain\r\n");
787 for(i=0;i<files->n;i++)
788 fprintf(of,"%s\\cell\\row\r\n",rtf(files->s[i],0));
789 fprintf(of,"\\intbl0\r\n");
792 /* Write out the appendix of functions. */
794 if(funcs->n)
796 fprintf(of,"{" STYLE_H2 " Global Functions\\par}\r\n");
797 fprintf(of,"\\trowd\\trgaph120\\cellx4500\\cellx9000\r\n\\intbl\\plain\r\n");
798 for(i=0;i<funcs->n;i++)
799 fprintf(of,"%s\\cell %s\\cell\\row\r\n",rtf(funcs->s1[i],0),rtf(funcs->s2[i],0));
800 fprintf(of,"\\intbl0\r\n");
803 /* Write out the appendix of variables. */
805 if(vars->n)
807 fprintf(of,"{" STYLE_H2 " Global Variables\\par}\r\n");
808 fprintf(of,"\\trowd\\trgaph120\\cellx4500\\cellx9000\r\n\\intbl\\plain\r\n");
809 for(i=0;i<vars->n;i++)
810 fprintf(of,"%s\\cell %s\\cell\\row\r\n",rtf(vars->s1[i],0),rtf(vars->s2[i],0));
811 fprintf(of,"\\intbl0\r\n");
814 /* Write out the appendix of types. */
816 if(types->n)
818 fprintf(of,"{" STYLE_H2 " Defined Types\\par}\r\n");
819 fprintf(of,"\\trowd\\trgaph120\\cellx4500\\cellx9000\r\n\\intbl\\plain\r\n");
820 for(i=0;i<types->n;i++)
822 if(!strncmp("enum",types->s1[i],4))
823 fprintf(of,"%s\\cell %s\\cell\\row\r\n",rtf(types->s1[i],0),rtf(types->s2[i],0));
824 else
825 if(!strncmp("union",types->s1[i],5))
826 fprintf(of,"%s\\cell %s\\cell\\row\r\n",rtf(types->s1[i],0),rtf(types->s2[i],0));
827 else
828 if(!strncmp("struct",types->s1[i],6))
829 fprintf(of,"%s\\cell %s\\cell\\row\r\n",rtf(types->s1[i],0),rtf(types->s2[i],0));
830 else
831 fprintf(of,"%s\\cell %s\\cell\\row\r\n",rtf(types->s1[i],0),rtf(types->s2[i],0));
833 fprintf(of,"\\intbl0\r\n");
836 /* Finish up. */
838 WriteRTFPostamble(of);
840 fclose(of);
842 /* Clear the memory in rtf(,0) */
844 rtf(NULL,0); rtf(NULL,0); rtf(NULL,0); rtf(NULL,0);
848 /*++++++++++++++++++++++++++++++++++++++
849 Write out the head of an RTF file.
851 FILE *f The file to write to.
852 ++++++++++++++++++++++++++++++++++++++*/
854 static void WriteRTFPreamble(FILE *f)
856 fputs("{\\rtf\\ansi\r\n",f);
857 fputs("\\deff0\r\n",f);
858 fputs("{\\fonttbl\r\n",f);
859 fputs("{\\f0\\froman Times New Roman;}\r\n",f);
860 fputs("{\\f1\\fmodern Courier New;}\r\n",f);
861 fputs("}\r\n",f);
862 fputs("{\\stylesheet\r\n",f);
863 fputs("{" STYLE_NORM " Normal;}\r\n",f);
864 fputs("{" STYLE_H1 " Heading 1;}\r\n",f);
865 fputs("{" STYLE_H2 " Heading 2;}\r\n",f);
866 fputs("{" STYLE_H3 " Heading 3;}\r\n",f);
867 fputs("{" STYLE_H4 " Heading 4;}\r\n",f);
868 fputs("{" STYLE_TT " Code;}\r\n",f);
869 fputs("}\r\n",f);
871 fputs("{\\info{\\comment This RTF file generated by cxref. cxref program (c) Andrew M. Bishop 1995,96,97,98,99.}}\r\n",f);
873 if(!strcmp("A4",PAGE))
874 fputs("\\paperw11880\\paperh16848\\margl1440\\margr1440\\margt1440\\margb1440\r\n",f);
875 else
876 fputs("\\paperw12240\\paperh15840\\margl1440\\margr1440\\margt1440\\margb1440\r\n",f);
878 fputs("\\sectd\\plain\r\n" STYLE_NORM "\r\n",f);
882 /*++++++++++++++++++++++++++++++++++++++
883 Write out the tail of an RTF file.
885 FILE *f The file to write to.
886 ++++++++++++++++++++++++++++++++++++++*/
888 static void WriteRTFPostamble(FILE *f)
890 fputs("}\r\n",f);
894 /*++++++++++++++++++++++++++++++++++++++
895 Delete the RTF file and main file reference that belong to the named file.
897 char *name The name of the file to delete.
898 ++++++++++++++++++++++++++++++++++++++*/
900 void WriteRTFFileDelete(char *name)
902 char *ofile;
904 ofile=ConcatStrings(4,option_odir,"/",name,RTF_FILE);
905 unlink(ofile);
909 /*++++++++++++++++++++++++++++++++++++++
910 Make the input string safe to output as RTF ( not \, { or } ).
912 char* rtf Returns a safe RTF string.
914 char* c A non-safe RTF string.
916 int verbatim Set to true inside a verbatim environment.
918 The function can only be called four times in each fprintf() since it returns one of only four static strings.
919 ++++++++++++++++++++++++++++++++++++++*/
921 static char* rtf(char* c,int verbatim)
923 static char safe[4][256],*malloced[4]={NULL,NULL,NULL,NULL};
924 static int which=0;
925 int copy=0,skip=0;
926 int i=0,j=0,delta=4,len=256-delta;
927 char *ret;
929 which=(which+1)%4;
930 ret=safe[which];
932 safe[which][0]=0;
934 if(malloced[which])
935 {Free(malloced[which]);malloced[which]=NULL;}
937 if(c)
939 i=CopyOrSkip(c,"rtf",&copy,&skip);
941 while(1)
943 for(;j<len && c[i];i++)
945 if(copy)
946 {ret[j++]=c[i]; if(c[i]=='\n') copy=0;}
947 else if(skip)
948 { if(c[i]=='\n') skip=0;}
949 else if(!verbatim && (j==0 || ret[j-1]==' ') && (c[i]==' ' || c[i]=='\t' || c[i]=='\n'))
951 else
952 switch(c[i])
954 case '\\':
955 case '{':
956 case '}':
957 ret[j++]='\\';
958 ret[j++]=c[i];
959 break;
960 case '\t':
961 if(!verbatim)
962 ret[j++]=c[i];
963 else
964 ret[j++]=' ';
965 break;
966 case '\n':
967 if(verbatim)
968 ret[j++]='\\',ret[j++]='p',ret[j++]='a',ret[j++]='r';
969 else
970 ret[j++]=' ';
971 break;
972 default:
973 ret[j++]=c[i];
975 if(c[i]=='\n')
976 i+=CopyOrSkip(c+i,"rtf",&copy,&skip);
979 if(c[i]) /* Not finished */
981 if(malloced[which])
982 malloced[which]=Realloc(malloced[which],len+delta+256);
983 else
984 {malloced[which]=Malloc(len+delta+256); strncpy(malloced[which],ret,(unsigned)j);}
985 ret=malloced[which];
986 len+=256;
988 else
990 ret[j]=0;
992 if(!verbatim && j--)
993 while(ret[j]==' ')
994 ret[j--]=0;
996 break;
1001 return(ret);