1 | /***************************************
2 | $Header: /home/amb/cxref/RCS/warn-raw.c 1.26 1999/01/24 16:53:50 amb Exp $
3 |
4 | C Cross Referencing & Documentation tool. Version 1.5.
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]=='$')
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]=='$')
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]=='$')
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 | }