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 | }