1    | /***************************************
2    |   $Header: /home/amb/cxref/RCS/warn-raw.c 1.27 1999/03/19 17:37:51 amb Exp $
3    | 
4    |   C Cross Referencing & Documentation tool. Version 1.5a.
5    | 
6    |   Writes the raw information and / or warnings out.
7    |   ******************/ /******************
8    |   Written by Andrew M. Bishop
9    | 
10   |   This file Copyright 1995,96,97,99 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   |   ***************************************/
15   | 
16   | #include <stdlib.h>
17   | #include <stdio.h>
18   | #include <string.h>
19   | 
20   | #include "datatype.h"
21   | #include "cxref.h"
22   | #include "memory.h"
23   | 
24   | static void WriteWarnRawFilePart(File file);
25   | static void WriteWarnRawInclude(Include inc);
26   | static void WriteWarnRawSubInclude(Include inc,int depth);
27   | static void WriteWarnRawDefine(Define def);
28   | static void WriteWarnRawTypedef(Typedef type);
29   | static void WriteWarnRawStructUnion(StructUnion su, int depth,StructUnion base);
30   | static void WriteWarnRawVariable(Variable var);
31   | static void WriteWarnRawFunction(Function func);
32   | 
33   | /*+ Output option. +*/
34   | extern int option_warn,option_raw,option_xref,option_index;
35   | 
36   | /*+ The name of the current file. +*/
37   | static char* filename=NULL;
38   | 
39   | /*++++++++++++++++++++++++++++++++++++++
40   |   Write the raw / warning output for a complete File structure and all components.
41   | 
42   |   File file The File structure to output.
43   |   ++++++++++++++++++++++++++++++++++++++*/
44   | 
45   | void WriteWarnRawFile(File file)
46   | {
47   |  Include   inc =file->includes;
48   |  Define    def =file->defines;
49   |  Typedef   type=file->typedefs;
50   |  Variable  var=file->variables;
51   |  Function  func=file->functions;
52   | 
53   |  filename=file->name;
54   | 
55   |  /*+ The file structure is broken into its components and they are each written out. +*/
56   | 
57   |  if(option_raw)
58   |     printf("----------------------------------------\n");
59   | 
60   |  WriteWarnRawFilePart(file);
61   | 
62   |  while(inc)
63   |    {
64   |     WriteWarnRawInclude(inc);
65   |     inc=inc->next;
66   |    }
67   | 
68   |  while(def)
69   |    {
70   |     WriteWarnRawDefine(def);
71   |     def=def->next;
72   |    }
73   | 
74   |  while(type)
75   |    {
76   |     WriteWarnRawTypedef(type);
77   |     type=type->next;
78   |    }
79   | 
80   |  while(var)
81   |    {
82   |     WriteWarnRawVariable(var);
83   |     var=var->next;
84   |    }
85   | 
86   |  while(func)
87   |    {
88   |     WriteWarnRawFunction(func);
89   |     func=func->next;
90   |    }
91   | 
92   |  if(option_raw)
93   |     printf("----------------------------------------\n\n");
94   | }
95   | 
96   | 
97   | /*++++++++++++++++++++++++++++++++++++++
98   |   Write a File structure out.
99   | 
100  |   File file The File structure to output.
101  |   ++++++++++++++++++++++++++++++++++++++*/
102  | 
103  | static void WriteWarnRawFilePart(File file)
104  | {
105  |  int i;
106  | 
107  |  if(option_raw)
108  |     printf("FILE : '%s'\n",file->name);
109  | 
110  |  if(file->comment && option_raw)
111  |     printf("<<<\n%s\n>>>\n",file->comment);
112  | 
113  |  if(option_warn&WARN_COMMENT && !file->comment)
114  |     printf("Warning %16s : File does not have a comment.\n",filename);
115  | 
116  |  if(option_xref&XREF_FILE)
117  |    {
118  |     if(option_raw)
119  |        for(i=0;i<file->inc_in->n;i++)
120  |           printf("Included in %s\n",file->inc_in->s[i]);
121  | 
122  |     if(option_warn&WARN_XREF)
123  |       {
124  |        int len=strlen(file->name)-2;
125  |        if(!file->inc_in->n && !strcmp(&file->name[len],".h"))
126  |           printf("Warning %16s : Header file %s is not included in any files.\n",filename,file->name);
127  |        if( file->inc_in->n && !strcmp(&file->name[len],".c"))
128  |           printf("Warning %16s : Source file %s is included in another file.\n",filename,file->name);
129  |       }
130  |    }
131  | 
132  |  if(option_xref&XREF_FUNC)
133  |     for(i=0;i<file->f_refs->n;i++)
134  |       {
135  |        if(option_raw)
136  |           if(file->f_refs->s2[i])
137  |              printf("References Function %s : %s\n",file->f_refs->s1[i],file->f_refs->s2[i]);
138  |           else
139  |              printf("References Function %s\n",file->f_refs->s1[i]);
140  |        if(option_warn&WARN_XREF && !file->f_refs->s2[i])
141  |           printf("Warning %16s : File references function %s() whose definition is unknown.\n",filename,file->f_refs->s1[i]);
142  |       }
143  | 
144  |  if(option_xref&XREF_VAR)
145  |     for(i=0;i<file->v_refs->n;i++)
146  |       {
147  |        if(option_raw)
148  |           if(file->v_refs->s2[i])
149  |              printf("References Variable %s : %s\n",file->v_refs->s1[i],file->v_refs->s2[i]);
150  |           else
151  |              printf("References Variable %s\n",file->v_refs->s1[i]);
152  |        if(option_warn&WARN_XREF && !file->v_refs->s2[i])
153  |           printf("Warning %16s : File references variable %s whose definition is unknown.\n",filename,file->v_refs->s1[i]);
154  |       }
155  | }
156  | 
157  | 
158  | /*++++++++++++++++++++++++++++++++++++++
159  |   Write an Include structure out.
160  | 
161  |   Include inc The Include structure to output.
162  |   ++++++++++++++++++++++++++++++++++++++*/
163  | 
164  | static void WriteWarnRawInclude(Include inc)
165  | {
166  |  if(option_raw)
167  |     printf("\nINCLUDES : '%s' [%s file]\n",inc->name,(inc->scope==GLOBAL?"System":"Local"));
168  | 
169  |  if(inc->comment && option_raw)
170  |     printf("<<<\n%s\n>>>\n",inc->comment);
171  |  if(option_warn&WARN_COMMENT && !inc->comment)
172  |     printf("Warning %16s : #Include %s does not have a comment.\n",filename,inc->name);
173  | 
174  |  if(option_raw && inc->includes)
175  |     WriteWarnRawSubInclude(inc->includes,1);
176  | }
177  | 
178  | 
179  | /*++++++++++++++++++++++++++++++++++++++
180  |   Write an Sub-Include structure out.
181  | 
182  |   Include inc The Include structure to output.
183  | 
184  |   int depth The depth of the include hierarchy.
185  |   ++++++++++++++++++++++++++++++++++++++*/
186  | 
187  | static void WriteWarnRawSubInclude(Include inc,int depth)
188  | {
189  |  int i;
190  | 
191  |  while(inc)
192  |    {
193  |     for(i=0;i<depth;i++) printf("   ");
194  |     printf("INCLUDES : '%s' [%s file]\n",inc->name,(inc->scope==GLOBAL?"System":"Local"));
195  | 
196  |     if(inc->includes)
197  |        WriteWarnRawSubInclude(inc->includes,depth+1);
198  | 
199  |     inc=inc->next;
200  |    }
201  | }
202  | 
203  | 
204  | /*++++++++++++++++++++++++++++++++++++++
205  |   Write a Define structure out.
206  | 
207  |   Define def The Define structure to output.
208  |   ++++++++++++++++++++++++++++++++++++++*/
209  | 
210  | static void WriteWarnRawDefine(Define def)
211  | {
212  |  int i;
213  | 
214  |  if(option_raw)
215  |    {
216  |     printf("\nDEFINES : '%s' ",def->name);
217  | 
218  |     if(def->value)
219  |        printf("= %s",def->value);
220  | 
221  |     if(def->args->n)
222  |       {
223  |        printf("(");
224  |        for(i=0;i<def->args->n;i++)
225  |           printf(i?",%s":"%s",def->args->s1[i]);
226  |        printf(")");
227  |       }
228  | 
229  |     printf("\n");
230  |    }
231  | 
232  |  if(def->comment && option_raw)
233  |     printf("<<<\n%s\n>>>\n",def->comment);
234  |  if(option_warn&WARN_COMMENT && !def->comment)
235  |     printf("Warning %16s : #Define %s does not have a comment.\n",filename,def->name);
236  | 
237  |  if(option_raw)
238  |     printf("Defined: %s:%d\n",filename,def->lineno);
239  | 
240  |  for(i=0;i<def->args->n;i++)
241  |    {
242  |     if(option_raw)
243  |        if(def->args->s2[i])
244  |           printf("Arguments: %s <<<%s>>>\n",def->args->s1[i],def->args->s2[i]);
245  |        else
246  |           printf("Arguments: %s\n",def->args->s1[i]);
247  |     if(option_warn&WARN_COMMENT && !def->args->s2[i])
248  |        printf("Warning %16s : #Define %s has an argument %s with no comment.\n",filename,def->name,def->args->s1[i]);
249  |    }
250  | }
251  | 
252  | 
253  | /*++++++++++++++++++++++++++++++++++++++
254  |   Write a Typedef structure out.
255  | 
256  |   Typedef type The Typedef structure to output.
257  |   ++++++++++++++++++++++++++++++++++++++*/
258  | 
259  | static void WriteWarnRawTypedef(Typedef type)
260  | {
261  |  if(option_raw)
262  |     if(type->type)
263  |        printf("\nTYPEDEF : '%s'\n",type->name);
264  |     else
265  |        printf("\nTYPE : '%s'\n",type->name);
266  | 
267  |  if(type->comment && option_raw)
268  |     printf("<<<\n%s\n>>>\n",type->comment);
269  |  if(option_warn&WARN_COMMENT && !type->comment)
270  |     printf("Warning %16s : Type %s does not have a comment.\n",filename,type->name);
271  | 
272  |  if(option_raw)
273  |     printf("Defined: %s:%d\n",filename,type->lineno);
274  | 
275  |  if(option_raw)
276  |     if(type->type)
277  |        printf("Type: %s\n",type->type);
278  | 
279  |  if(option_raw)
280  |     if(type->typexref)
281  |        printf("See: %s %s\n",type->typexref->type?"Typedef":"Type",type->typexref->name);
282  | 
283  |  if(type->sutype)
284  |     WriteWarnRawStructUnion(type->sutype,0,type->sutype);
285  | }
286  | 
287  | 
288  | /*++++++++++++++++++++++++++++++++++++++
289  |   Write a structure / union / enum out.
290  | 
291  |   StructUnion su The structure / union / enum to write.
292  | 
293  |   int depth The depth within the structure.
294  | 
295  |   StructUnion base The base struct union that this one is part of.
296  |   ++++++++++++++++++++++++++++++++++++++*/
297  | 
298  | static void WriteWarnRawStructUnion(StructUnion su, int depth,StructUnion base)
299  | {
300  |  int i;
301  |  char* splitsu=NULL;
302  | 
303  |  if(option_warn&WARN_COMMENT && depth && !su->comment)
304  |     printf("Struct/Union component %s in %s does not have a comment.\n",su->name,base->name);
305  | 
306  |  splitsu=strstr(su->name,"{...}");
307  |  if(splitsu) splitsu[-1]=0;
308  | 
309  |  if(option_raw)
310  |    {
311  |     for(i=0;i<depth;i++) printf("   ");
312  |     if(depth && su->comment && !su->comps)
313  |        printf("%s; <<<%s>>>\n",su->name,su->comment);
314  |     else if(!depth || su->comps)
315  |        printf("%s\n",su->name);
316  |     else
317  |        printf("%s;\n",su->name);
318  |    }
319  | 
320  |  if(!depth || su->comps)
321  |    {
322  |     if(option_raw)
323  |       {
324  |        for(i=0;i<depth;i++) printf("   ");
325  |        printf("  {\n");
326  |       }
327  |     for(i=0;i<su->n_comp;i++)
328  |        WriteWarnRawStructUnion(su->comps[i],depth+1,base);
329  |     if(option_raw)
330  |       {
331  |        for(i=0;i<depth;i++) printf("   ");
332  |        printf("  }\n");
333  |        if(splitsu)
334  |          {
335  |           for(i=0;i<depth;i++) printf("   ");
336  |           if(depth && su->comment)
337  |              printf("%s; <<<%s>>>\n",splitsu[5]?&splitsu[6]:"",su->comment);
338  |           else
339  |              printf("%s;\n",splitsu[5]?&splitsu[6]:"");
340  |          }
341  |       }
342  |    }
343  | 
344  |  if(splitsu) splitsu[-1]=' ';
345  | }
346  | 
347  | 
348  | /*++++++++++++++++++++++++++++++++++++++
349  |   Write a Variable structure out.
350  | 
351  |   Variable var The Variable structure to output.
352  |   ++++++++++++++++++++++++++++++++++++++*/
353  | 
354  | static void WriteWarnRawVariable(Variable var)
355  | {
356  |  int i;
357  | 
358  |  if(option_raw)
359  |    {
360  |     int done=0;
361  | 
362  |     printf("\nVARIABLE : %s [",var->name);
363  |     if(var->scope&LOCAL)    done=printf("Local");
364  |     if(var->scope&GLOBAL)   done=printf("Global");
365  |     if(var->scope&EXTERNAL) done=printf("%sExternal",done?" and ":"");
366  |     if(var->scope&EXTERN_H) done=printf("%sExternal from header file",done?" and ":"");
367  |     if(var->scope&EXTERN_F)      printf("%sExternal within function",done?" and ":"");
368  |     printf("]\n");
369  | 
370  |     if(var->comment)
371  |        printf("<<<\n%s\n>>>\n",var->comment);
372  |    }
373  | 
374  |  if(option_warn&WARN_COMMENT && !var->comment && (var->scope&(GLOBAL|LOCAL|EXTERNAL|EXTERN_F) || option_raw))
375  |     printf("Warning %16s : Variable %s does not have a comment.\n",filename,var->name);
376  | 
377  |  if(option_raw)
378  |     printf("Defined: %s:%d\n",var->incfrom?var->incfrom:filename,var->lineno);
379  | 
380  |  if(option_raw)
381  |     printf("Type: %s\n",var->type);
382  | 
383  |  if(option_raw && var->incfrom)
384  |     printf("Included from: %s\n",var->incfrom);
385  | 
386  |  if(option_xref&XREF_VAR)
387  |    {
388  |     if(option_raw)
389  |       {
390  |        if(var->scope&(EXTERNAL|EXTERN_F) && var->defined)
391  |           printf("Declared global in '%s'\n",var->defined);
392  | 
393  |        if(var->scope&(GLOBAL|LOCAL))
394  |          {
395  |           for(i=0;i<var->visible->n;i++)
396  |              if(var->visible->s1[i][0]=='$' && !var->visible->s1[i][1])
397  |                 printf("Visible in %s\n",var->visible->s2[i]);
398  |              else
399  |                 printf("Visible in %s : %s\n",var->visible->s1[i],var->visible->s2[i]);
400  | 
401  |           for(i=0;i<var->used->n;i++)
402  |              if(var->used->s1[i][0]=='$' && !var->used->s1[i][1])
403  |                 printf("Used in %s\n",var->used->s2[i]);
404  |              else
405  |                 printf("Used in %s : %s\n",var->used->s1[i],var->used->s2[i]);
406  |          }
407  |       }
408  | 
409  |     if(option_warn&WARN_XREF)
410  |       {
411  |        if(var->scope&(EXTERNAL|EXTERN_F) && !var->defined)
412  |           printf("Warning %16s : Variable %s has an unknown global definition.\n",filename,var->name);
413  | 
414  |        if(var->scope&(GLOBAL|LOCAL|EXTERNAL|EXTERN_F) && !var->used->n)
415  |           printf("Warning %16s : Variable %s is not used anywhere.\n",filename,var->name);
416  | 
417  |        if(var->scope&(GLOBAL|EXTERNAL|EXTERN_F) && var->used->n)
418  |          {
419  |           int is_used_elsewhere=0,is_used_here=0;
420  |           for(i=0;i<var->used->n;i++)
421  |              if(!strcmp(filename,var->used->s2[i]))
422  |                 is_used_here=1;
423  |              else
424  |                 is_used_elsewhere=1;
425  |           if(!is_used_elsewhere)
426  |              printf("Warning %16s : Variable %s is %s but only used in this file.\n",filename,var->name,var->scope&GLOBAL?"global":"extern");
427  |           if(!is_used_here)
428  |              printf("Warning %16s : Variable %s is %s but not used in this file.\n",filename,var->name,var->scope&GLOBAL?"global":"extern");
429  |          }
430  |       }
431  |    }
432  | }
433  | 
434  | 
435  | /*++++++++++++++++++++++++++++++++++++++
436  |   Write a Function structure out.
437  | 
438  |   Function func The Function structure to output.
439  |   ++++++++++++++++++++++++++++++++++++++*/
440  | 
441  | static void WriteWarnRawFunction(Function func)
442  | {
443  |  int i;
444  | 
445  |  if(option_raw)
446  |    {
447  |     int done=0;
448  | 
449  |     printf("\nFUNCTION : %s [",func->name);
450  |     if(func->scope&LOCAL)    done=printf("Local");
451  |     if(func->scope&GLOBAL)   done=printf("Global");
452  |     if(func->scope&EXTERNAL) done=printf("External");
453  |     if(func->scope&INLINED)       printf("%sInline",done?" and ":"");
454  |     printf("]\n");
455  | 
456  |     if(func->comment)
457  |        printf("<<<\n%s\n>>>\n",func->comment);
458  |    }
459  | 
460  |  if(option_warn&WARN_COMMENT && !func->comment)
461  |     printf("Warning %16s : Function %s() does not have a comment.\n",filename,func->name);
462  | 
463  |  if(option_raw)
464  |     printf("Defined: %s:%d\n",filename,func->lineno);
465  | 
466  |  if(option_xref&XREF_FUNC)
467  |    {
468  |     if(func->protofile && option_raw)
469  |        printf("Prototyped in %s\n",func->protofile);
470  |     if(option_warn&WARN_XREF && !func->protofile)
471  |        printf("Warning %16s : Function %s() is not prototyped.\n",filename,func->name);
472  |    }
473  | 
474  |  if(option_raw)
475  |     if(func->cret)
476  |        printf("Type: %s <<<%s>>>\n",func->type,func->cret);
477  |     else
478  |        printf("Type: %s\n",func->type);
479  |  if(option_warn&WARN_COMMENT && !func->cret && strncmp("void ",func->type,5))
480  |     printf("Warning %16s : Function %s() has a return value with no comment.\n",filename,func->name);
481  | 
482  |  for(i=0;i<func->args->n;i++)
483  |    {
484  |     if(option_raw)
485  |        if(func->args->s2[i])
486  |           printf("Arguments: %s <<<%s>>>\n",func->args->s1[i],func->args->s2[i]);
487  |        else
488  |           printf("Arguments: %s\n",func->args->s1[i]);
489  |     if(option_warn&WARN_COMMENT && !func->args->s2[i] && strcmp("void",func->args->s1[i]))
490  |        printf("Warning %16s : Function %s() has an argument %s with no comment.\n",filename,func->name,func->args->s1[i]);
491  |    }
492  | 
493  |  if(option_raw && func->incfrom)
494  |     printf("Included from: %s\n",func->incfrom);
495  | 
496  |  if(option_xref&XREF_FUNC)
497  |    {
498  |     for(i=0;i<func->calls->n;i++)
499  |       {
500  |        if(option_raw)
501  |           if(func->calls->s2[i])
502  |              printf("Calls %s : %s\n",func->calls->s1[i],func->calls->s2[i]);
503  |           else
504  |              printf("Calls %s\n",func->calls->s1[i]);
505  | #if 0 /* Too verbose */
506  |        if(option_warn&WARN_XREF && !func->calls->s2[i])
507  |           printf("Warning %16s : Function %s() calls function %s() whose definition is unknown.\n",filename,func->name,func->calls->s1[i]);
508  | #endif
509  |       }
510  | 
511  |     if(option_raw)
512  |        for(i=0;i<func->called->n;i++)
513  |           printf("Called from %s : %s\n",func->called->s1[i],func->called->s2[i]);
514  | 
515  |     if(option_raw)
516  |        for(i=0;i<func->used->n;i++)
517  |          {
518  |           if(func->used->s1[i][0]=='$' && !func->used->s1[i][1])
519  |              printf("Used in %s\n",func->used->s2[i]);
520  |           else
521  |              printf("Used in %s : %s\n",func->used->s1[i],func->used->s2[i]);
522  |          }
523  | 
524  |     for(i=0;i<func->f_refs->n;i++)
525  |       {
526  |        if(option_raw)
527  |           if(func->f_refs->s2[i])
528  |              printf("References Function %s : %s\n",func->f_refs->s1[i],func->f_refs->s2[i]);
529  |           else
530  |              printf("References Function %s\n",func->f_refs->s1[i]);
531  |        if(option_warn&WARN_XREF && !func->f_refs->s2[i])
532  |           printf("Warning %16s : Function %s() references function %s() whose definition is unknown.\n",filename,func->name,func->f_refs->s1[i]);
533  |       }
534  |    }
535  | 
536  |  if(option_xref&XREF_VAR)
537  |     for(i=0;i<func->v_refs->n;i++)
538  |       {
539  |        if(option_raw)
540  |           if(func->v_refs->s2[i])
541  |              printf("References Variable %s : %s\n",func->v_refs->s1[i],func->v_refs->s2[i]);
542  |           else
543  |              printf("References Variable %s\n",func->v_refs->s1[i]);
544  |        if(option_warn&WARN_XREF && !func->v_refs->s2[i])
545  |           printf("Warning %16s : Function %s() references variable %s whose definition is unknown.\n",filename,func->name,func->v_refs->s1[i]);
546  |       }
547  | 
548  | 
549  |  if(option_warn&WARN_XREF)
550  |    {
551  |     if(!func->used->n && !func->called->n)
552  |        printf("Warning %16s : Function %s() is not used anywhere.\n",filename,func->name);
553  | 
554  |     if(func->scope&GLOBAL && (func->called->n || func->used->n))
555  |       {
556  |        int is_used_elsewhere=0;
557  |        for(i=0;i<func->called->n;i++)
558  |           if(strcmp(func->called->s2[i],filename))
559  |             {is_used_elsewhere=1;break;}
560  |        for(i=0;i<func->used->n;i++)
561  |           if(strcmp(func->used->s2[i],filename))
562  |             {is_used_elsewhere=1;break;}
563  |        if(!is_used_elsewhere)
564  |           printf("Warning %16s : Function %s() is global but is only used in this file.\n",filename,func->name);
565  |       }
566  |    }
567  | }
568  | 
569  | 
570  | /*++++++++++++++++++++++++++++++++++++++
571  |   Write out a raw version of the appendix.
572  | 
573  |   StringList files The list of files to write.
574  | 
575  |   StringList2 funcs The list of functions to write.
576  | 
577  |   StringList2 vars The list of variables to write.
578  | 
579  |   StringList2 types The list of types to write.
580  |   ++++++++++++++++++++++++++++++++++++++*/
581  | 
582  | void WriteWarnRawAppendix(StringList files,StringList2 funcs,StringList2 vars,StringList2 types)
583  | {
584  |  int i;
585  | 
586  |  /* Write out the appendix of files. */
587  | 
588  |  if(option_index&INDEX_FILE)
589  |     if(files->n)
590  |       {
591  |        printf("\nAppendix - Files\n\n");
592  |        for(i=0;i<files->n;i++)
593  |           printf("%s\n",files->s[i]);
594  |       }
595  |     else
596  |        if(option_warn&WARN_XREF)
597  |           printf("Warning Index : No global files to index.\n");
598  | 
599  |  /* Write out the appendix of functions. */
600  | 
601  |  if(option_index&INDEX_FUNC)
602  |     if(funcs->n)
603  |       {
604  |        printf("\nAppendix - Global Functions\n\n");
605  |        for(i=0;i<funcs->n;i++)
606  |           printf("%s : %s\n",funcs->s1[i],funcs->s2[i]);
607  |       }
608  |     else
609  |        if(option_warn&WARN_XREF)
610  |           printf("Warning Index : No global functions to index.\n");
611  | 
612  |  /* Write out the appendix of variables. */
613  | 
614  |  if(option_index&INDEX_VAR)
615  |     if(vars->n)
616  |       {
617  |        printf("\nAppendix - Global Variables\n\n");
618  |        for(i=0;i<vars->n;i++)
619  |           printf("%s : %s\n",vars->s1[i],vars->s2[i]);
620  |       }
621  |     else
622  |        if(option_warn&WARN_XREF)
623  |           printf("Warning Index : No global variables to index.\n");
624  | 
625  |  /* Write out the appendix of types. */
626  | 
627  |  if(option_index&INDEX_TYPE)
628  |     if(types->n)
629  |       {
630  |        printf("\nAppendix - Defined Types\n\n");
631  |        for(i=0;i<types->n;i++)
632  |           printf("%s : %s\n",types->s1[i],types->s2[i]);
633  |       }
634  |     else
635  |        if(option_warn&WARN_XREF)
636  |           printf("Warning Index : No types to index.\n");
637  | }
638  | 
639  | 
640  | /*++++++++++++++++++++++++++++++++++++++
641  |   Decide if to copy or skip the next line.
642  | 
643  |   int CopyOrSkip Returns the number of characters to skip.
644  | 
645  |   char *string The string that starts the next line.
646  | 
647  |   char *type The type of file we are outputing.
648  | 
649  |   int *copy Returns true if we are to copy the line verbatim.
650  | 
651  |   int *skip Returns true if we are to skip the line.
652  |   ++++++++++++++++++++++++++++++++++++++*/
653  | 
654  | int CopyOrSkip(char *string,char *type,int *copy,int *skip)
655  | {
656  |  char *p=string;
657  |  int s=0;
658  | 
659  |  if(*p=='\n')
660  |     p++;
661  |  while(*p==' ' || *p=='\t')
662  |     p++;
663  | 
664  |  *copy=*skip=0;
665  | 
666  |  switch(*type)
667  |     {
668  |     case 'h': /* html */
669  |      if(!strncmp(p,"+html+",s=6) || !strncmp(p,"-latex-",s=7) || !strncmp(p,"-sgml-",s=6) || !strncmp(p,"-rtf-",s=5))
670  |         *copy=1;
671  |      if(!strncmp(p,"-html-",s=6) || !strncmp(p,"+latex+",s=7) || !strncmp(p,"+sgml+",s=6) || !strncmp(p,"+rtf+",s=5) || !strncmp(p,"+none+",s=6))
672  |         *skip=1;
673  |      break;
674  |     case 'l': /* latex */
675  |      if(!strncmp(p,"-html-",s=6) || !strncmp(p,"+latex+",s=7) || !strncmp(p,"-sgml-",s=6) || !strncmp(p,"-rtf-",s=5))
676  |         *copy=1;
677  |      if(!strncmp(p,"+html+",s=6) || !strncmp(p,"-latex-",s=7) || !strncmp(p,"+sgml+",s=6) || !strncmp(p,"+rtf+",s=5) || !strncmp(p,"+none+",s=6))
678  |         *skip=1;
679  |      break;
680  |     case 's': /* sgml */
681  |      if(!strncmp(p,"-html-",s=6) || !strncmp(p,"-latex-",s=7) || !strncmp(p,"+sgml+",s=6) || !strncmp(p,"-rtf-",s=5))
682  |         *copy=1;
683  |      if(!strncmp(p,"+html+",s=6) || !strncmp(p,"+latex+",s=7) || !strncmp(p,"-sgml-",s=6) || !strncmp(p,"+rtf+",s=5) || !strncmp(p,"+none+",s=6))
684  |         *skip=1;
685  |      break;
686  |     case 'r': /* rtf */
687  |      if(!strncmp(p,"-html-",s=6) || !strncmp(p,"-latex-",s=7) || !strncmp(p,"-sgml-",s=6) || !strncmp(p,"+rtf+",s=5))
688  |         *copy=1;
689  |      if(!strncmp(p,"+html+",s=6) || !strncmp(p,"+latex+",s=7) || !strncmp(p,"+sgml+",s=6) || !strncmp(p,"-rtf-",s=5) || !strncmp(p,"+none+",s=6))
690  |         *skip=1;
691  |      break;
692  |     }
693  | 
694  |  if(*copy)
695  |     return(p-string+s);
696  |  else
697  |     return(0);
698  | }