1 | /*************************************** 2 | $Header: /home/amb/cxref/RCS/latex.c 1.30 1998/12/22 14:25:50 amb Exp $ 3 | 4 | C Cross Referencing & Documentation tool. Version 1.5. 5 | 6 | Writes the Latex output. 7 | ******************/ /****************** 8 | Written by Andrew M. Bishop 9 | 10 | This file Copyright 1995,96,97,98 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 | #include <sys/types.h> 20 | #include <sys/stat.h> 21 | #include <unistd.h> 22 | 23 | #ifndef min 24 | #define min(x,y) ( (x) < (y) ? (x) : (y) ) 25 | #endif 26 | 27 | #include "memory.h" 28 | #include "datatype.h" 29 | #include "cxref.h" 30 | 31 | /*+ The name of the output tex file that includes each of the others. +*/ 32 | #define LATEX_FILE ".tex" 33 | #define LATEX_FILE_BACKUP ".tex~" 34 | 35 | /*+ The name of the output tex file that contains the appendix. +*/ 36 | #define LATEX_APDX ".apdx" 37 | 38 | /*+ The comments are to be inserted verbatim. +*/ 39 | extern int option_verbatim_comments; 40 | 41 | /*+ The type of LaTeX output to produce. +*/ 42 | extern int option_latex; 43 | 44 | /*+ The name of the directory for the output. +*/ 45 | extern char* option_odir; 46 | 47 | /*+ The base name of the file for the output. +*/ 48 | extern char* option_name; 49 | 50 | extern char *latex_fonts_style,*latex_page_style,*latex_cxref_style; 51 | 52 | static void WriteLatexFilePart(File file); 53 | static void WriteLatexInclude(Include inc); 54 | static void WriteLatexSubInclude(Include inc,int depth); 55 | static void WriteLatexDefine(Define def); 56 | static void WriteLatexTypedef(Typedef type,char* filename); 57 | static void WriteLatexStructUnion(StructUnion su,int depth); 58 | static void WriteLatexVariable(Variable var,char* filename); 59 | static void WriteLatexFunction(Function func,char* filename); 60 | 61 | static void WriteLatexDocument(char* name,int appendix); 62 | static void WriteLatexTemplate(char* name); 63 | 64 | static char* latex(char* c); 65 | 66 | /*+ The output file for the latex. +*/ 67 | static FILE* of; 68 | 69 | /*+ Counts the lines in a table to insert breaks. +*/ 70 | static int countlines=0; 71 | 72 | 73 | /*++++++++++++++++++++++++++++++++++++++ 74 | Write a Latex file for a complete File structure and all components. 75 | 76 | File file The File structure to output. 77 | ++++++++++++++++++++++++++++++++++++++*/ 78 | 79 | void WriteLatexFile(File file) 80 | { 81 | char* ofile; 82 | 83 | /* Write the including file. */ 84 | 85 | WriteLatexDocument(file->name,0); 86 | 87 | /* Open the file */ 88 | 89 | ofile=ConcatStrings(4,option_odir,"/",file->name,LATEX_FILE); 90 | 91 | of=fopen(ofile,"w"); 92 | if(!of) 93 | { 94 | struct stat stat_buf; 95 | int i,ofl=strlen(ofile); 96 | 97 | for(i=strlen(option_odir)+1;i<ofl;i++) 98 | if(ofile[i]=='/') 99 | { 100 | ofile[i]=0; 101 | if(stat(ofile,&stat_buf)) 102 | mkdir(ofile,S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); 103 | ofile[i]='/'; 104 | } 105 | 106 | of=fopen(ofile,"w"); 107 | } 108 | 109 | if(!of) 110 | {fprintf(stderr,"cxref: Failed to open the LaTeX output file '%s'\n",ofile);exit(1);} 111 | 112 | /* Write out a header. */ 113 | 114 | fputs("% This LaTeX file generated by cxref\n",of); 115 | fputs("% cxref program (c) Andrew M. Bishop 1995,96,97.\n",of); 116 | fputs("\n",of); 117 | 118 | /*+ The file structure is broken into its components and they are each written out. +*/ 119 | 120 | WriteLatexFilePart(file); 121 | 122 | if(file->includes) 123 | { 124 | Include inc =file->includes; 125 | fprintf(of,"\n\\subsection*{Included Files}\n\n"); 126 | do{ 127 | if(inc!=file->includes) 128 | fprintf(of,"\\medskip\n"); 129 | WriteLatexInclude(inc); 130 | } 131 | while((inc=inc->next)); 132 | } 133 | 134 | if(file->defines) 135 | { 136 | Define def =file->defines; 137 | fprintf(of,"\n\\subsection*{Preprocessor definitions}\n\n"); 138 | do{ 139 | if(def!=file->defines) 140 | fprintf(of,"\\medskip\n"); 141 | WriteLatexDefine(def); 142 | } 143 | while((def=def->next)); 144 | } 145 | 146 | if(file->typedefs) 147 | { 148 | Typedef type=file->typedefs; 149 | fprintf(of,"\n\\subsection{Type definitions}\n\n"); 150 | do{ 151 | WriteLatexTypedef(type,file->name); 152 | } 153 | while((type=type->next)); 154 | } 155 | 156 | if(file->variables) 157 | { 158 | int any_to_mention=0; 159 | Variable var=file->variables; 160 | 161 | do{ 162 | if(var->scope&(GLOBAL|LOCAL|EXTERNAL|EXTERN_F)) 163 | any_to_mention=1; 164 | } 165 | while((var=var->next)); 166 | 167 | if(any_to_mention) 168 | { 169 | int first_ext=1,first_local=1; 170 | Variable var=file->variables; 171 | fprintf(of,"\n\\subsection{Variables}\n\n"); 172 | do{ 173 | if(var->scope&GLOBAL) 174 | WriteLatexVariable(var,file->name); 175 | } 176 | while((var=var->next)); 177 | var=file->variables; 178 | do{ 179 | if(var->scope&(EXTERNAL|EXTERN_F) && !(var->scope&GLOBAL)) 180 | { 181 | if(first_ext) 182 | {fprintf(of,"\n\\subsubsection{External Variables}\n\n"); first_ext=0;} 183 | else 184 | fprintf(of,"\\medskip\n"); 185 | WriteLatexVariable(var,file->name); 186 | } 187 | } 188 | while((var=var->next)); 189 | var=file->variables; 190 | do{ 191 | if(var->scope&LOCAL) 192 | { 193 | if(first_local) 194 | {fprintf(of,"\n\\subsubsection{Local Variables}\n\n"); first_local=0;} 195 | else 196 | fprintf(of,"\\medskip\n"); 197 | WriteLatexVariable(var,file->name); 198 | } 199 | } 200 | while((var=var->next)); 201 | } 202 | } 203 | 204 | if(file->functions) 205 | { 206 | Function func=file->functions; 207 | fprintf(of,"\n\\subsection{Functions}\n\n"); 208 | do{ 209 | if(func->scope&(GLOBAL|EXTERNAL)) 210 | WriteLatexFunction(func,file->name); 211 | } 212 | while((func=func->next)); 213 | func=file->functions; 214 | do{ 215 | if(func->scope&LOCAL) 216 | WriteLatexFunction(func,file->name); 217 | } 218 | while((func=func->next)); 219 | } 220 | 221 | fclose(of); 222 | 223 | /* Clear the memory in latex() */ 224 | 225 | latex(NULL); latex(NULL); latex(NULL); latex(NULL); 226 | } 227 | 228 | 229 | /*++++++++++++++++++++++++++++++++++++++ 230 | Write a File structure out. 231 | 232 | File file The File to output. 233 | ++++++++++++++++++++++++++++++++++++++*/ 234 | 235 | static void WriteLatexFilePart(File file) 236 | { 237 | int i; 238 | 239 | fprintf(of,"\\markboth{File %s}{File %s}\n",latex(file->name),latex(file->name)); 240 | fprintf(of,"\\section{File %s}\n",latex(file->name)); 241 | fprintf(of,"\\label{file_%s}\n\n",file->name); 242 | 243 | if(file->comment) 244 | if(option_verbatim_comments) 245 | fprintf(of,"\\begin{verbatim}\n%s\n\\end{verbatim}\n\n",latex(file->comment)); 246 | else 247 | { 248 | char *rcs1=strstr(file->comment,"$Header"),*rcs2=NULL; 249 | if(rcs1) 250 | { 251 | rcs2=strstr(&rcs1[1],"$"); 252 | if(rcs2) 253 | { 254 | rcs2[0]=0; 255 | fprintf(of,"{\\bf RCS %s}\n\n",latex(&rcs1[1])); 256 | fprintf(of,"\\smallskip\n"); 257 | rcs2[0]='$'; 258 | } 259 | } 260 | if(rcs2) 261 | fprintf(of,"%s\n\n",latex(&rcs2[2])); 262 | else 263 | fprintf(of,"%s\n\n",latex(file->comment)); 264 | } 265 | 266 | if(file->inc_in->n) 267 | { 268 | int i; 269 | 270 | if(file->comment) 271 | fprintf(of,"\\medskip\n"); 272 | fprintf(of,"\\begin{cxreftabii}\nIncluded in:"); 273 | for(i=0;i<file->inc_in->n;i++) 274 | {/* Allow a break in every 8 (or so) items to allow the table to break over the page. */ 275 | if(min(i,file->inc_in->n-i)%8 == 4) 276 | fprintf(of,"\\cxreftabbreak{cxreftabii}\n"); 277 | fprintf(of,"\\ & %s & \\cxreffile{%s}\\\\\n",latex(file->inc_in->s[i]),file->inc_in->s[i]); 278 | } 279 | fprintf(of,"\\end{cxreftabii}\n\n"); 280 | } 281 | 282 | if(file->f_refs->n || file->v_refs->n) 283 | { 284 | int tabcount=0; 285 | fprintf(of,"\\smallskip\n"); 286 | fprintf(of,"\\begin{cxreftabiii}\n"); 287 | 288 | if(file->f_refs->n) 289 | { 290 | int others=0; 291 | 292 | fprintf(of,"Refs Func:"); 293 | 294 | for(i=0;i<file->f_refs->n;i++) 295 | if(file->f_refs->s2[i]) 296 | { 297 | fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(file->f_refs->s1[i]),latex(file->f_refs->s2[i]),file->f_refs->s1[i],file->f_refs->s2[i]); 298 | if(++tabcount%8 == 4) 299 | fprintf(of,"\\cxreftabbreak{cxreftabiii}\n"); 300 | } 301 | else 302 | others++; 303 | 304 | if(others) 305 | { 306 | fprintf(of,"\\ & \\cxreftabiiispan{"); 307 | for(i=0;i<file->f_refs->n;i++) 308 | if(!file->f_refs->s2[i]) 309 | fprintf(of,--others?"%s(), ":"%s()",latex(file->f_refs->s1[i])); 310 | fprintf(of,"} &\\\\\n"); 311 | } 312 | } 313 | 314 | if(file->v_refs->n) 315 | { 316 | int others=0; 317 | 318 | fprintf(of,"Refs Var:"); 319 | 320 | for(i=0;i<file->v_refs->n;i++) 321 | if(file->v_refs->s2[i]) 322 | { 323 | fprintf(of,"\\ & %s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(file->v_refs->s1[i]),latex(file->v_refs->s2[i]),file->v_refs->s1[i],file->v_refs->s2[i]); 324 | if(++tabcount%8 == 4) 325 | fprintf(of,"\\cxreftabbreak{cxreftabiii}\n"); 326 | } 327 | else 328 | others++; 329 | 330 | if(others) 331 | { 332 | fprintf(of,"\\ & \\cxreftabiiispan{"); 333 | for(i=0;i<file->v_refs->n;i++) 334 | if(!file->v_refs->s2[i]) 335 | fprintf(of,--others?" %s,":" %s",latex(file->v_refs->s1[i])); 336 | fprintf(of,"} &\\\\\n"); 337 | } 338 | } 339 | 340 | fprintf(of,"\\end{cxreftabiii}\n\n"); 341 | } 342 | } 343 | 344 | 345 | /*++++++++++++++++++++++++++++++++++++++ 346 | Write an Include structure out. 347 | 348 | Include inc The Include structure to output. 349 | ++++++++++++++++++++++++++++++++++++++*/ 350 | 351 | static void WriteLatexInclude(Include inc) 352 | { 353 | if(inc->comment) 354 | fprintf(of,"%s\n\n\\smallskip\n",latex(inc->comment)); 355 | 356 | fprintf(of,"\\begin{cxreftabi}\n"); countlines=1; 357 | 358 | if(inc->scope==LOCAL) 359 | fprintf(of,"{\\stt \\#include \"%s\"} &\\cxreffile{%s}\\\\\n",latex(inc->name),inc->name); 360 | else 361 | fprintf(of,"{\\stt \\#include <%s>} &\\\\\n",latex(inc->name)); 362 | 363 | if(inc->includes) 364 | WriteLatexSubInclude(inc->includes,1); 365 | 366 | fprintf(of,"\\end{cxreftabi}\n\n"); 367 | } 368 | 369 | 370 | /*++++++++++++++++++++++++++++++++++++++ 371 | Write an Sub Include structure out. (An include structure that is included from another file.) 372 | 373 | Include inc The Include structure to output. 374 | 375 | int depth The depth of the include hierarchy. 376 | ++++++++++++++++++++++++++++++++++++++*/ 377 | 378 | static void WriteLatexSubInclude(Include inc,int depth) 379 | { 380 | while(inc) 381 | { 382 | if(countlines++%8==4) 383 | fprintf(of,"\\cxreftabbreak{cxreftabi}\n"); 384 | 385 | fprintf(of,"\\hspace*{%3.1fin}",0.2*depth); 386 | 387 | if(inc->scope==LOCAL) 388 | fprintf(of,"{\\stt \\#include \"%s\"} &\\cxreffile{%s}\\\\\n",latex(inc->name),inc->name); 389 | else 390 | fprintf(of,"{\\stt \\#include <%s>} &\\\\\n",latex(inc->name)); 391 | 392 | if(inc->includes) 393 | WriteLatexSubInclude(inc->includes,depth+1); 394 | 395 | inc=inc->next; 396 | } 397 | } 398 | 399 | 400 | /*++++++++++++++++++++++++++++++++++++++ 401 | Write a Define structure out. 402 | 403 | Define def The Define structure to output. 404 | ++++++++++++++++++++++++++++++++++++++*/ 405 | 406 | static void WriteLatexDefine(Define def) 407 | { 408 | int i; 409 | int pargs=0; 410 | 411 | if(def->comment) 412 | fprintf(of,"%s\n\n\\smallskip\n",latex(def->comment)); 413 | 414 | fprintf(of,"{\\stt \\#define %s",latex(def->name)); 415 | 416 | if(def->value) 417 | fprintf(of," %s",latex(def->value)); 418 | 419 | if(def->args->n) 420 | { 421 | fprintf(of,"( "); 422 | for(i=0;i<def->args->n;i++) 423 | fprintf(of,i?", %s":"%s",latex(def->args->s1[i])); 424 | fprintf(of," )"); 425 | } 426 | fprintf(of,"}\n\n"); 427 | 428 | for(i=0;i<def->args->n;i++) 429 | if(def->args->s2[i]) 430 | pargs=1; 431 | 432 | if(pargs) 433 | { 434 | fprintf(of,"\\smallskip\n"); 435 | fprintf(of,"\\begin{cxrefarglist}\n"); 436 | for(i=0;i<def->args->n;i++) 437 | fprintf(of,"\\cxrefargitem{%s} %s\n",latex(def->args->s1[i]),def->args->s2[i]?latex(def->args->s2[i]):"\\ "); 438 | fprintf(of,"\\end{cxrefarglist}\n\n"); 439 | } 440 | } 441 | 442 | 443 | /*++++++++++++++++++++++++++++++++++++++ 444 | Write a Typedef structure out. 445 | 446 | Typedef type The Typedef structure to output. 447 | 448 | char* filename The name of the file that is being processed (required for the cross reference label). 449 | ++++++++++++++++++++++++++++++++++++++*/ 450 | 451 | static void WriteLatexTypedef(Typedef type,char* filename) 452 | { 453 | if(type->type) 454 | fprintf(of,"\n\\subsubsection{Typedef %s}\n",latex(type->name)); 455 | else 456 | fprintf(of,"\n\\subsubsection{Type %s}\n",latex(type->name)); 457 | 458 | if(!strncmp("enum",type->name,4)) 459 | fprintf(of,"\\label{type_enum_%s_%s}\n\n",&type->name[5],filename); 460 | else 461 | if(!strncmp("union",type->name,5)) 462 | fprintf(of,"\\label{type_union_%s_%s}\n\n",&type->name[6],filename); 463 | else 464 | if(!strncmp("struct",type->name,6)) 465 | fprintf(of,"\\label{type_struct_%s_%s}\n\n",&type->name[7],filename); 466 | else 467 | fprintf(of,"\\label{type_%s_%s}\n\n",type->name,filename); 468 | 469 | if(type->comment) 470 | fprintf(of,"%s\n\n\\smallskip\n",latex(type->comment)); 471 | 472 | if(type->type) 473 | fprintf(of,"{\\stt typedef %s}\n\n",latex(type->type)); 474 | 475 | if(type->sutype) 476 | { 477 | fprintf(of,"\\smallskip\n"); 478 | fprintf(of,"\\begin{cxreftabiia}\n"); countlines=0; 479 | WriteLatexStructUnion(type->sutype,0); 480 | fprintf(of,"\\end{cxreftabiia}\n\n"); 481 | } 482 | else 483 | if(type->typexref) 484 | { 485 | fprintf(of,"\\smallskip\n"); 486 | fprintf(of,"\\begin{cxreftabii}\n"); 487 | if(type->typexref->type) 488 | fprintf(of,"See:& Typedef %s & \\cxreftype{%s}{%s}\\\\\n",latex(type->typexref->name),type->typexref->name,filename); 489 | else 490 | if(!strncmp("enum",type->typexref->name,4)) 491 | fprintf(of,"See:& Type %s & \\cxreftype{enum_%s}{%s}\\\\\n",latex(type->typexref->name),&type->typexref->name[5],filename); 492 | else 493 | if(!strncmp("union",type->typexref->name,5)) 494 | fprintf(of,"See:& Type %s & \\cxreftype{union_%s}{%s}\\\\\n",latex(type->typexref->name),&type->typexref->name[6],filename); 495 | else 496 | if(!strncmp("struct",type->typexref->name,6)) 497 | fprintf(of,"See:& Type %s & \\cxreftype{struct_%s}{%s}\\\\\n",latex(type->typexref->name),&type->typexref->name[7],filename); 498 | fprintf(of,"\\end{cxreftabii}\n\n"); 499 | } 500 | } 501 | 502 | 503 | /*++++++++++++++++++++++++++++++++++++++ 504 | Write a structure / union structure out. 505 | 506 | StructUnion su The structure / union to write. 507 | 508 | int depth The current depth within the structure. 509 | ++++++++++++++++++++++++++++++++++++++*/ 510 | 511 | static void WriteLatexStructUnion(StructUnion su, int depth) 512 | { 513 | int i; 514 | char* splitsu=NULL; 515 | 516 | splitsu=strstr(su->name,"{...}"); 517 | if(splitsu) splitsu[-1]=0; 518 | 519 | if(countlines++%8==4) 520 | fprintf(of,"\\cxreftabbreak{cxreftabiia}\n"); 521 | fprintf(of,"\\hspace*{%3.1fin}",0.2*depth); 522 | 523 | if(depth && su->comment && !su->comps) 524 | fprintf(of,"{\\stt %s;} & %s \\\\\n",latex(su->name),latex(su->comment)); 525 | else if(!depth || su->comps) 526 | fprintf(of,"{\\stt %s} &\\\\\n",latex(su->name)); 527 | else 528 | fprintf(of,"{\\stt %s;} &\\\\\n",latex(su->name)); 529 | 530 | if(!depth || su->comps) 531 | { 532 | fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth); 533 | fprintf(of,"{\\stt \\{} &\\\\\n"); 534 | 535 | for(i=0;i<su->n_comp;i++) 536 | WriteLatexStructUnion(su->comps[i],depth+1); 537 | 538 | fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth); 539 | fprintf(of,"{\\stt \\}} &\\\\\n"); 540 | if(splitsu) 541 | { 542 | fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth); 543 | if(depth && su->comment) 544 | fprintf(of,"{\\stt %s;} & %s \\\\\n",splitsu[5]?latex(&splitsu[6]):"",latex(su->comment)); 545 | else 546 | fprintf(of,"{\\stt %s;} &\\\\\n",splitsu[5]?latex(&splitsu[6]):""); 547 | } 548 | } 549 | 550 | if(splitsu) splitsu[-1]=' '; 551 | } 552 | 553 | 554 | /*++++++++++++++++++++++++++++++++++++++ 555 | Write a Variable structure out. 556 | 557 | Variable var The Variable structure to output. 558 | 559 | char* filename The name of the file that is being processed (required for the cross reference label). 560 | ++++++++++++++++++++++++++++++++++++++*/ 561 | 562 | static void WriteLatexVariable(Variable var,char* filename) 563 | { 564 | int i; 565 | 566 | if(var->scope&GLOBAL) 567 | fprintf(of,"\n\\subsubsection{Variable %s}\n",latex(var->name)); 568 | else 569 | fprintf(of,"{\\bf %s}\n",latex(var->name)); 570 | 571 | fprintf(of,"\\label{var_%s_%s}\n\n",var->name,filename); 572 | 573 | if(var->comment) 574 | fprintf(of,"%s\n\n\\smallskip\n",latex(var->comment)); 575 | 576 | fprintf(of,"{\\stt "); 577 | 578 | if(var->scope&LOCAL) 579 | fprintf(of,"static "); 580 | else 581 | if(!(var->scope&GLOBAL) && var->scope&(EXTERNAL|EXTERN_F)) 582 | fprintf(of,"extern "); 583 | 584 | fprintf(of,"%s}\n\n",latex(var->type)); 585 | 586 | if(var->scope&(GLOBAL|LOCAL)) 587 | { 588 | if(var->incfrom || var->used->n || var->visible->n) 589 | { 590 | fprintf(of,"\\smallskip\n"); 591 | fprintf(of,"\\begin{cxreftabiii}\n"); 592 | 593 | if(var->incfrom) 594 | fprintf(of,"Inc. from:& %s & \\ & \\cxrefvar{%s}{%s}\\\\\n",latex(var->incfrom),var->name,var->incfrom); 595 | 596 | for(i=0;i<var->visible->n;i++) 597 | { 598 | if(min(i,var->visible->n+var->used->n-i)%8 == 4) 599 | fprintf(of,"\\cxreftabbreak{cxreftabiii}\n"); 600 | if(i==0) fprintf(of,"Visible in:"); 601 | if(var->visible->s1[i][0]=='$') 602 | fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(var->visible->s2[i]),var->visible->s2[i]); 603 | else 604 | fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(var->visible->s1[i]),latex(var->visible->s2[i]),var->visible->s1[i],var->visible->s2[i]); 605 | } 606 | 607 | for(i=0;i<var->used->n;i++) 608 | { 609 | if(min(i,var->visible->n+var->used->n-i)%8 == 4) 610 | fprintf(of,"\\cxreftabbreak{cxreftabiii}\n"); 611 | if(i==0) fprintf(of,"Used in:"); 612 | if(var->used->s1[i][0]=='$') 613 | fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(var->used->s2[i]),var->used->s2[i]); 614 | else 615 | if(var->scope&LOCAL) 616 | fprintf(of,"\\ & %s() & \\ & \\cxreffunc{%s}{%s}\\\\\n",latex(var->used->s1[i]),var->used->s1[i],var->used->s2[i]); 617 | else 618 | fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(var->used->s1[i]),latex(var->used->s2[i]),var->used->s1[i],var->used->s2[i]); 619 | } 620 | 621 | fprintf(of,"\\end{cxreftabiii}\n\n"); 622 | } 623 | } 624 | else 625 | if(var->scope&(EXTERNAL|EXTERN_F) && var->defined) 626 | { 627 | fprintf(of,"\\smallskip\n"); 628 | fprintf(of,"\\begin{cxreftabiii}\n"); 629 | fprintf(of,"Defined in:& %s & \\ & \\cxrefvar{%s}{%s}\\\\\n",latex(var->defined),var->name,var->defined); 630 | fprintf(of,"\\end{cxreftabiii}\n\n"); 631 | } 632 | } 633 | 634 | 635 | /*++++++++++++++++++++++++++++++++++++++ 636 | Write a Function structure out. 637 | 638 | Function func The Function structure to output. 639 | 640 | char* filename The name of the file that is being processed (required for the cross reference label). 641 | ++++++++++++++++++++++++++++++++++++++*/ 642 | 643 | static void WriteLatexFunction(Function func,char* filename) 644 | { 645 | int i,pret,pargs; 646 | char* comment2=NULL,*type; 647 | 648 | if(func->scope&GLOBAL) 649 | fprintf(of,"\n\\subsubsection{Global Function %s()}\n",latex(func->name)); 650 | else 651 | fprintf(of,"\n\\subsubsection{Local Function %s()}\n",latex(func->name)); 652 | fprintf(of,"\\label{func_%s_%s}\n\n",func->name,filename); 653 | 654 | if(func->comment) 655 | if(option_verbatim_comments) 656 | fprintf(of,"\\begin{verbatim}\n%s\n\\end{verbatim}\n\n",latex(func->comment)); 657 | else 658 | { 659 | comment2=strstr(func->comment,"\n\n"); 660 | if(comment2) 661 | comment2[0]=0; 662 | fprintf(of,"%s\n\n",latex(func->comment)); 663 | fprintf(of,"\\smallskip\n"); 664 | } 665 | 666 | fprintf(of,"{\\stt "); 667 | 668 | if(func->scope&LOCAL) 669 | fprintf(of,"static "); 670 | if(func->scope&INLINED) 671 | fprintf(of,"inline "); 672 | 673 | if((type=strstr(func->type,"()"))) 674 | type[0]=0; 675 | fprintf(of,"%s ( ",latex(func->type)); 676 | 677 | for(i=0;i<func->args->n;i++) 678 | fprintf(of,i?", %s":"%s",latex(func->args->s1[i])); 679 | 680 | if(type) 681 | {fprintf(of," %s}\n\n",&type[1]);type[0]='(';} 682 | else 683 | fprintf(of," )}\n\n"); 684 | 685 | pret =strncmp("void ",func->type,5) && func->cret; 686 | for(pargs=0,i=0;i<func->args->n;i++) 687 | pargs = pargs || ( strcmp("void",func->args->s1[i]) && func->args->s2[i] ); 688 | 689 | if(pret || pargs) 690 | { 691 | fprintf(of,"\\smallskip\n"); 692 | fprintf(of,"\\begin{cxrefarglist}\n"); 693 | if(pret) 694 | fprintf(of,"\\cxrefargitem{%s} %s\n",latex(func->type),func->cret?latex(func->cret):"\\ "); 695 | if(pargs) 696 | for(i=0;i<func->args->n;i++) 697 | fprintf(of,"\\cxrefargitem{%s} %s\n",latex(func->args->s1[i]),func->args->s2[i]?latex(func->args->s2[i]):"\\ "); 698 | fprintf(of,"\\end{cxrefarglist}\n\n"); 699 | } 700 | 701 | if(comment2) 702 | { 703 | fprintf(of,"\\smallskip\n"); 704 | fprintf(of,"%s\n\n",latex(&comment2[2])); 705 | comment2[0]='\n'; 706 | } 707 | 708 | if(func->protofile || func->incfrom || func->calls->n || func->called->n || func->used->n || func->f_refs->n || func->v_refs->n) 709 | { 710 | int tabcount=func->protofile?1:0; 711 | fprintf(of,"\\smallskip\n"); 712 | fprintf(of,"\\begin{cxreftabiii}\n"); 713 | 714 | if(func->protofile) 715 | fprintf(of,"Prototype:& %s & \\ & \\cxreffile{%s}\\\\\n",latex(func->protofile),func->protofile); 716 | 717 | if(func->incfrom) 718 | fprintf(of,"Inc. from:& %s & \\ & \\cxreffunc{%s}{%s}\\\\\n",latex(func->incfrom),func->name,func->incfrom); 719 | 720 | if(func->calls->n) 721 | { 722 | int others=0; 723 | 724 | fprintf(of,"Calls:"); 725 | 726 | for(i=0;i<func->calls->n;i++) 727 | if(func->calls->s2[i]) 728 | { 729 | fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->calls->s1[i]),latex(func->calls->s2[i]),func->calls->s1[i],func->calls->s2[i]); 730 | if(++tabcount%8 == 4) 731 | fprintf(of,"\\cxreftabbreak{cxreftabiii}\n"); 732 | } 733 | else 734 | others++; 735 | 736 | if(others) 737 | { 738 | fprintf(of,"\\ & \\cxreftabiiispan{"); 739 | for(i=0;i<func->calls->n;i++) 740 | if(!func->calls->s2[i]) 741 | fprintf(of,--others?" %s(),":" %s()",latex(func->calls->s1[i])); 742 | fprintf(of,"} &\\\\\n"); 743 | } 744 | } 745 | 746 | if(func->called->n) 747 | { 748 | fprintf(of,"Called by:"); 749 | 750 | for(i=0;i<func->called->n;i++) 751 | { 752 | fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->called->s1[i]),latex(func->called->s2[i]),func->called->s1[i],func->called->s2[i]); 753 | if(++tabcount%8 == 4) 754 | fprintf(of,"\\cxreftabbreak{cxreftabiii}\n"); 755 | } 756 | } 757 | 758 | if(func->used->n) 759 | { 760 | fprintf(of,"Used in:"); 761 | 762 | for(i=0;i<func->used->n;i++) 763 | { 764 | if(func->used->s1[i][0]=='$') 765 | fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(func->used->s2[i]),func->used->s2[i]); 766 | else 767 | fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->used->s1[i]),latex(func->used->s2[i]),func->used->s1[i],func->used->s2[i]); 768 | if(++tabcount%8 == 4) 769 | fprintf(of,"\\cxreftabbreak{cxreftabiii}\n"); 770 | } 771 | } 772 | 773 | if(func->f_refs->n) 774 | { 775 | int others=0; 776 | 777 | fprintf(of,"Refs Func:"); 778 | 779 | for(i=0;i<func->f_refs->n;i++) 780 | if(func->f_refs->s2[i]) 781 | { 782 | fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->f_refs->s1[i]),latex(func->f_refs->s2[i]),func->f_refs->s1[i],func->f_refs->s2[i]); 783 | if(++tabcount%8 == 4) 784 | fprintf(of,"\\cxreftabbreak{cxreftabiii}\n"); 785 | } 786 | else 787 | others++; 788 | 789 | if(others) 790 | { 791 | fprintf(of,"\\ & \\cxreftabiiispan{"); 792 | for(i=0;i<func->f_refs->n;i++) 793 | if(!func->f_refs->s2[i]) 794 | fprintf(of,--others?" %s(),":" %s()",latex(func->f_refs->s1[i])); 795 | fprintf(of,"} &\\\\\n"); 796 | } 797 | } 798 | 799 | if(func->v_refs->n) 800 | { 801 | int others=0; 802 | 803 | fprintf(of,"Refs Var:"); 804 | 805 | for(i=0;i<func->v_refs->n;i++) 806 | if(func->v_refs->s2[i]) 807 | { 808 | fprintf(of,"\\ & %s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(func->v_refs->s1[i]),latex(func->v_refs->s2[i]),func->v_refs->s1[i],func->v_refs->s2[i]); 809 | if(++tabcount%8 == 4) 810 | fprintf(of,"\\cxreftabbreak{cxreftabiii}\n"); 811 | } 812 | else 813 | others++; 814 | 815 | if(others) 816 | { 817 | fprintf(of,"\\ & \\cxreftabiiispan{"); 818 | for(i=0;i<func->v_refs->n;i++) 819 | if(!func->v_refs->s2[i]) 820 | fprintf(of,--others?" %s,":" %s",latex(func->v_refs->s1[i])); 821 | fprintf(of,"} &\\\\\n"); 822 | } 823 | } 824 | 825 | fprintf(of,"\\end{cxreftabiii}\n\n"); 826 | } 827 | } 828 | 829 | 830 | /*++++++++++++++++++++++++++++++++++++++ 831 | Write out a file that will include the current information. 832 | 833 | char* name The name of the file (without the LaTeX extension). 834 | 835 | int appendix set to non-zero if the appendix file is to be added, else a normal source file. 836 | ++++++++++++++++++++++++++++++++++++++*/ 837 | 838 | static void WriteLatexDocument(char* name,int appendix) 839 | { 840 | FILE *in,*out; 841 | char line[256]; 842 | int seen=0; 843 | char *inc_file,*ofile,*ifile; 844 | 845 | inc_file=ConcatStrings(4,"\\input{",name,LATEX_FILE,"}\n"); 846 | ifile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE); 847 | ofile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE_BACKUP); 848 | 849 | in =fopen(ifile,"r"); 850 | if(!in) 851 | { 852 | WriteLatexTemplate(ifile); 853 | in =fopen(ifile,"r"); 854 | } 855 | 856 | out=fopen(ofile,"w"); 857 | 858 | if(!out) 859 | {fprintf(stderr,"cxref: Failed to open the main LaTeX output file '%s'\n",ofile);exit(1);} 860 | 861 | while(fgets(line,256,in)) 862 | { 863 | if(!strcmp(inc_file,line) || 864 | (line[0]=='%' && !strcmp(inc_file,line+1)) || 865 | (line[0]=='%' && line[1]==' ' && !strcmp(inc_file,line+2))) 866 | {seen=1;break;} 867 | if(line[0]=='%' && !strcmp("% End-Of-Source-Files\n",line)) 868 | { 869 | if(appendix) 870 | { 871 | fputs(line,out); 872 | fputs("\n",out); 873 | fputs("% Appendix\n",out); 874 | fputs("\n",out); 875 | fputs("\\appendix\n",out); 876 | fputs("\\markboth{Appendix}{Appendix}\n",out); 877 | fputs(inc_file,out); 878 | } 879 | else 880 | { 881 | fputs(inc_file,out); 882 | fputs("\n",out); 883 | fputs(line,out); 884 | } 885 | } 886 | else 887 | fputs(line,out); 888 | } 889 | 890 | fclose(in); 891 | fclose(out); 892 | 893 | if(!seen) 894 | { 895 | unlink(ifile); 896 | rename(ofile,ifile); 897 | } 898 | else 899 | unlink(ofile); 900 | } 901 | 902 | 903 | /*++++++++++++++++++++++++++++++++++++++ 904 | Write out the standard template for the main LaTeX file. 905 | This sets up the page styles, and includes markers for the start and end of included source code. 906 | 907 | char* name The name of the file to write the template to. 908 | ++++++++++++++++++++++++++++++++++++++*/ 909 | 910 | static void WriteLatexTemplate(char* name) 911 | { 912 | FILE *template; 913 | struct stat stat_buf; 914 | char* fname; 915 | 916 | template=fopen(name,"w"); 917 | 918 | if(!template) 919 | {fprintf(stderr,"cxref: Failed to open the main LaTeX output file '%s'\n",name);exit(1);} 920 | 921 | fputs("% This LaTeX file generated by cxref\n",template); 922 | fputs("% cxref program (c) Andrew M. Bishop 1995,96,97,98.\n",template); 923 | fputs("\n",template); 924 | if(option_latex==1) 925 | fputs("\\documentstyle[fonts,page,cxref]{report}\n",template); 926 | else 927 | { 928 | fputs("\\documentclass{report}\n",template); 929 | fputs("\\usepackage{fonts,page,cxref}\n",template); 930 | } 931 | fputs("\\pagestyle{myheadings}\n",template); 932 | fputs("\n",template); 933 | fputs("\\begin{document}\n",template); 934 | fputs("\n",template); 935 | fputs("% Contents (Optional, either here or at end)\n",template); 936 | fputs("\n",template); 937 | fputs("%\\markboth{Contents}{Contents}\n",template); 938 | fputs("%\\tableofcontents\n",template); 939 | fputs("\n",template); 940 | fputs("\\chapter{Source Files}\n",template); 941 | fputs("\n",template); 942 | fputs("% Begin-Of-Source-Files\n",template); 943 | fputs("\n",template); 944 | fputs("% End-Of-Source-Files\n",template); 945 | fputs("\n",template); 946 | fputs("% Contents (Optional, either here or at beginning)\n",template); 947 | fputs("\n",template); 948 | fputs("\\markboth{Contents}{Contents}\n",template); 949 | fputs("\\tableofcontents\n",template); 950 | fputs("\n",template); 951 | fputs("\\end{document}\n",template); 952 | 953 | fclose(template); 954 | 955 | fname=ConcatStrings(2,option_odir,"/fonts.sty"); 956 | if(stat(fname,&stat_buf)) 957 | { 958 | FILE* file=fopen(fname,"w"); 959 | if(!file) 960 | {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);} 961 | fputs(latex_fonts_style,file); 962 | fclose(file); 963 | } 964 | 965 | fname=ConcatStrings(2,option_odir,"/page.sty"); 966 | if(stat(fname,&stat_buf)) 967 | { 968 | FILE* file=fopen(fname,"w"); 969 | if(!file) 970 | {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);} 971 | fputs(latex_page_style,file); 972 | fclose(file); 973 | } 974 | 975 | fname=ConcatStrings(2,option_odir,"/cxref.sty"); 976 | if(stat(fname,&stat_buf)) 977 | { 978 | FILE* file=fopen(fname,"w"); 979 | if(!file) 980 | {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);} 981 | fputs(latex_cxref_style,file); 982 | fclose(file); 983 | } 984 | } 985 | 986 | 987 | /*++++++++++++++++++++++++++++++++++++++ 988 | Write out the appendix information. 989 | 990 | StringList files The list of files to write. 991 | 992 | StringList2 funcs The list of functions to write. 993 | 994 | StringList2 vars The list of variables to write. 995 | 996 | StringList2 types The list of types to write. 997 | ++++++++++++++++++++++++++++++++++++++*/ 998 | 999 | void WriteLatexAppendix(StringList files,StringList2 funcs,StringList2 vars,StringList2 types) 1000 | { 1001 | char* ofile; 1002 | int i; 1003 | 1004 | /* Write the bits to the including file. */ 1005 | 1006 | WriteLatexDocument(ConcatStrings(2,option_name,LATEX_APDX),1); 1007 | 1008 | /* Open the file */ 1009 | 1010 | ofile=ConcatStrings(5,option_odir,"/",option_name,LATEX_APDX,LATEX_FILE); 1011 | 1012 | of=fopen(ofile,"w"); 1013 | 1014 | if(!of) 1015 | {fprintf(stderr,"cxref: Failed to open the LaTeX appendix file '%s'\n",ofile);exit(1);} 1016 | 1017 | /* Write the file structure out */ 1018 | 1019 | fprintf(of,"\\chapter{Cross References}\n"); 1020 | 1021 | /* Write out the appendix of files. */ 1022 | 1023 | if(files->n) 1024 | { 1025 | fprintf(of,"\n\\section{Files}\n"); 1026 | fprintf(of,"\\label{appendix_file}\n\n"); 1027 | fprintf(of,"\\begin{cxreftabiib}\n"); 1028 | for(i=0;i<files->n;i++) 1029 | { 1030 | if(min(i,files->n-i)%8 == 4) 1031 | fprintf(of,"\\cxreftabbreak{cxreftabiib}\n"); 1032 | fprintf(of,"%s & \\ & \\cxreffile{%s}\\\\\n",latex(files->s[i]),files->s[i]); 1033 | } 1034 | fprintf(of,"\\end{cxreftabiib}\n\n"); 1035 | } 1036 | 1037 | /* Write out the appendix of functions. */ 1038 | 1039 | if(funcs->n) 1040 | { 1041 | fprintf(of,"\n\\section{Global Functions}\n"); 1042 | fprintf(of,"\\label{appendix_func}\n\n"); 1043 | fprintf(of,"\\begin{cxreftabiib}\n"); 1044 | for(i=0;i<funcs->n;i++) 1045 | { 1046 | if(min(i,funcs->n-i)%8 == 4) 1047 | fprintf(of,"\\cxreftabbreak{cxreftabiib}\n"); 1048 | fprintf(of,"%s & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(funcs->s1[i]),latex(funcs->s2[i]),funcs->s1[i],funcs->s2[i]); 1049 | } 1050 | fprintf(of,"\\end{cxreftabiib}\n\n"); 1051 | } 1052 | 1053 | /* Write out the appendix of variables. */ 1054 | 1055 | if(vars->n) 1056 | { 1057 | fprintf(of,"\n\\section{Global Variables}\n"); 1058 | fprintf(of,"\\label{appendix_var}\n\n"); 1059 | fprintf(of,"\\begin{cxreftabiib}\n"); 1060 | for(i=0;i<vars->n;i++) 1061 | { 1062 | if(min(i,vars->n-i)%8 == 4) 1063 | fprintf(of,"\\cxreftabbreak{cxreftabiib}\n"); 1064 | fprintf(of,"%s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(vars->s1[i]),latex(vars->s2[i]),vars->s1[i],vars->s2[i]); 1065 | } 1066 | fprintf(of,"\\end{cxreftabiib}\n\n"); 1067 | } 1068 | 1069 | /* Write out the appendix of types. */ 1070 | 1071 | if(types->n) 1072 | { 1073 | fprintf(of,"\n\\section{Defined Types}\n"); 1074 | fprintf(of,"\\label{appendix_type}\n\n"); 1075 | fprintf(of,"\\begin{cxreftabiib}\n"); 1076 | for(i=0;i<types->n;i++) 1077 | { 1078 | if(min(i,types->n-i)%8 == 4) 1079 | fprintf(of,"\\cxreftabbreak{cxreftabiib}\n"); 1080 | if(!strncmp("enum",types->s1[i],4)) 1081 | fprintf(of,"%s & %s & \\cxreftype{enum_%s}{%s}\\\\\n",latex(types->s1[i]),latex(types->s2[i]),&types->s1[i][5],types->s2[i]); 1082 | else 1083 | if(!strncmp("union",types->s1[i],5)) 1084 | fprintf(of,"%s & %s & \\cxreftype{union_%s}{%s}\\\\\n",latex(types->s1[i]),latex(types->s2[i]),&types->s1[i][6],types->s2[i]); 1085 | else 1086 | if(!strncmp("struct",types->s1[i],6)) 1087 | fprintf(of,"%s & %s & \\cxreftype{struct_%s}{%s}\\\\\n",latex(types->s1[i]),latex(types->s2[i]),&types->s1[i][7],types->s2[i]); 1088 | else 1089 | fprintf(of,"%s & %s & \\cxreftype{%s}{%s}\\\\\n",latex(types->s1[i]),latex(types->s2[i]),types->s1[i],types->s2[i]); 1090 | } 1091 | fprintf(of,"\\end{cxreftabiib}\n\n"); 1092 | } 1093 | 1094 | fclose(of); 1095 | 1096 | /* Clear the memory in latex() */ 1097 | 1098 | latex(NULL); latex(NULL); latex(NULL); latex(NULL); 1099 | } 1100 | 1101 | 1102 | /*++++++++++++++++++++++++++++++++++++++ 1103 | Delete the latex file and main file reference that belong to the named file. 1104 | 1105 | char *name The name of the file to delete. 1106 | ++++++++++++++++++++++++++++++++++++++*/ 1107 | 1108 | void WriteLatexFileDelete(char *name) 1109 | { 1110 | FILE *in,*out; 1111 | char line[256]; 1112 | int seen=0; 1113 | char *inc_file,*ofile,*ifile; 1114 | 1115 | ofile=ConcatStrings(4,option_odir,"/",name,LATEX_FILE); 1116 | unlink(ofile); 1117 | 1118 | inc_file=ConcatStrings(4,"\\input{",name,LATEX_FILE,"}\n"); 1119 | ifile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE); 1120 | ofile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE_BACKUP); 1121 | 1122 | in =fopen(ifile,"r"); 1123 | out=fopen(ofile,"w"); 1124 | 1125 | if(in && !out) 1126 | {fprintf(stderr,"cxref: Failed to open the main LaTeX output file '%s'\n",ofile);fclose(in);} 1127 | else if(in) 1128 | { 1129 | while(fgets(line,256,in)) 1130 | { 1131 | if(!strcmp(inc_file,line) || 1132 | (line[0]=='%' && !strcmp(inc_file,line+1)) || 1133 | (line[0]=='%' && line[1]==' ' && !strcmp(inc_file,line+2))) 1134 | seen=1; 1135 | else 1136 | fputs(line,out); 1137 | } 1138 | 1139 | fclose(in); 1140 | fclose(out); 1141 | 1142 | if(seen) 1143 | { 1144 | unlink(ifile); 1145 | rename(ofile,ifile); 1146 | } 1147 | else 1148 | unlink(ofile); 1149 | } 1150 | else if(out) 1151 | { 1152 | fclose(out); 1153 | unlink(ofile); 1154 | } 1155 | } 1156 | 1157 | 1158 | /*++++++++++++++++++++++++++++++++++++++ 1159 | Make the input string safe to output as LaTeX ( not #, $, %, &, \, ^, _, {, }, <, > or ~ ). 1160 | 1161 | char* latex Returns a safe LaTeX string. 1162 | 1163 | char* c A non-safe LaTeX string. 1164 | 1165 | The function can only be called four times in each fprintf() since it returns one of only four static strings. 1166 | ++++++++++++++++++++++++++++++++++++++*/ 1167 | 1168 | static char* latex(char* c) 1169 | { 1170 | static char safe[4][256],*malloced[4]={NULL,NULL,NULL,NULL}; 1171 | static int which=0; 1172 | int copy=0,skip=0; 1173 | int i=0,j=0,delta=13,len=256-delta; 1174 | char* ret; 1175 | 1176 | which=(which+1)%4; 1177 | ret=safe[which]; 1178 | 1179 | safe[which][0]=0; 1180 | 1181 | if(malloced[which]) 1182 | {Free(malloced[which]);malloced[which]=NULL;} 1183 | 1184 | if(c) 1185 | while(1) 1186 | { 1187 | for(;j<len && c[i];i++) 1188 | { 1189 | if(copy) 1190 | {ret[j++]=c[i]; if(c[i]=='\n') copy=0;} 1191 | else if(skip) 1192 | { if(c[i]=='\n') skip=0;} 1193 | else 1194 | switch(c[i]) 1195 | { 1196 | case '<': 1197 | case '>': 1198 | ret[j++]='$'; 1199 | ret[j++]=c[i]; 1200 | ret[j++]='$'; 1201 | break; 1202 | case '\\': 1203 | strcpy(&ret[j],"$\\backslash$");j+=12; 1204 | break; 1205 | case '~': 1206 | strcpy(&ret[j],"$\\sim$");j+=6; 1207 | break; 1208 | case '^': 1209 | strcpy(&ret[j],"$\\wedge$");j+=8; 1210 | break; 1211 | case '#': 1212 | case '$': 1213 | case '%': 1214 | case '&': 1215 | case '_': 1216 | case '{': 1217 | case '}': 1218 | ret[j++]='\\'; 1219 | ret[j++]=c[i]; 1220 | break; 1221 | default: 1222 | ret[j++]=c[i]; 1223 | } 1224 | if(c[i]=='\n') 1225 | i+=CopyOrSkip(c+i,"latex",©,&skip); 1226 | } 1227 | 1228 | if(c[i]) /* Not finished */ 1229 | { 1230 | if(malloced[which]) 1231 | malloced[which]=Realloc(malloced[which],len+delta+256); 1232 | else 1233 | {malloced[which]=Malloc(len+delta+256); strncpy(malloced[which],ret,(unsigned)j);} 1234 | ret=malloced[which]; 1235 | len+=256; 1236 | } 1237 | else 1238 | {ret[j]=0; break;} 1239 | } 1240 | 1241 | return(ret); 1242 | }