"Fossies" - the Fresh Open Source Software Archive 
Member "cpost.c" (9 May 1995, 31573 Bytes) of package /linux/misc/old/cpost.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "cpost.c" see the
Fossies "Dox" file reference documentation.
1 /*------------------------------------------------------------------
2 * cPost.c : c language formatter
3 *------------------------------------------------------------------
4 * 10-10-91 originally by Patrick J. Mueller
5 * 12-03-92 converted from cBook to cPost
6 *------------------------------------------------------------------*/
7
8 #define PROGRAM_VERS "1.4"
9 #define PROGRAM_NAME "cPost"
10 #define PROGRAM_YEAR "1994"
11 #define PROGRAM_AUTH "Patrick J. Mueller"
12 #define PROGRAM_ADDR "(pmuellr@vnet.ibm.com)"
13 #define PROGRAM_ENVV "CPOST"
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <stdarg.h>
19 #include <signal.h>
20 #include <time.h>
21
22 #include "parsearg.h"
23
24 #include "ctok.h"
25 #define DEFINE_GLOBALS
26 #include "cpost.h"
27 #include "tokfile.h"
28
29 #include "cposthdr.h"
30
31 /*---------------------------------------------------------------
32 * global variables
33 *---------------------------------------------------------------*/
34 int AllDone = 0;
35
36 static char *ReservedTokens[] =
37 {
38 /*---------------------------------------------------------------
39 * data types
40 *---------------------------------------------------------------*/
41 "auto", "char", "const", "double", "enum", "extern", "float", "int",
42 "long", "register", "short", "signed", "static", "struct", "union",
43 "unsigned", "void", "volatile",
44
45 /*---------------------------------------------------------------
46 * other keywords
47 *---------------------------------------------------------------*/
48 "break", "case", "continue", "default", "do", "else", "for", "goto",
49 "if", "return", "sizeof", "switch", "typedef", "while",
50
51 /*---------------------------------------------------------------
52 * saa c extensions
53 *---------------------------------------------------------------*/
54 "_Packed","_System","_Optlink", "_Far16", "_Cdecl", "_Pascal"
55 };
56
57 /*------------------------------------------------------------------
58 * c++ reserved words
59 *------------------------------------------------------------------*/
60 static char *CppReservedTokens[] =
61 {
62 "catch", "class", "delete", "friend", "inline", "new", "operator",
63 "private", "protected", "public", "template", "this", "throw", "try",
64 "virtual"
65 };
66
67
68 /*------------------------------------------------------------------
69 * generate an error message and exit
70 *------------------------------------------------------------------*/
71 void cPostError(
72 int exitCode,
73 char *format,
74 ...
75 )
76 {
77 va_list vlist;
78
79 fprintf(stderr,"%s : ",PROGRAM_NAME);
80
81 va_start(vlist,format);
82 vfprintf(stderr,format,vlist);
83 va_end(vlist);
84
85 fprintf(stderr,"\n");
86
87 if (exitCode)
88 exit(exitCode);
89 }
90
91 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
92 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
93
94 /*------------------------------------------------------------------
95 * print some help, assuming me is argv[0]
96 *------------------------------------------------------------------*/
97 static void Usage(void)
98 {
99 fprintf(stderr,"%s %s by %s %s\n",PROGRAM_NAME,PROGRAM_VERS,PROGRAM_AUTH,PROGRAM_ADDR);
100 fprintf(stderr,"\n");
101 fprintf(stderr,"usage:\n");
102 fprintf(stderr," %s <options> <filespec> <filespec> ...\n",PROGRAM_NAME);
103 fprintf(stderr,"is used to produce a listing of C language files in PostScript\n");
104 fprintf(stderr,"format. The PostScript output is written to stdout.\n\n");
105 fprintf(stderr,"where:\n");
106 fprintf(stderr," <filespec> is a filespec matching C language files.\n\n");
107 fprintf(stderr,"Valid options are:\n");
108 fprintf(stderr," -b[+|-] - enable/disable bracketing around braces\n");
109 fprintf(stderr," -cext1,ext2,... - treat files with extention ext1 and ext2 as C files\n");
110 fprintf(stderr," -d[+|-] - enable/disable duplex\n");
111 fprintf(stderr," -hext1,ext2,... - treat files with extention ext1 and ext2 as H files\n");
112 fprintf(stderr," -ifile1;file2;... - imbed files into output\n");
113 fprintf(stderr," -kk1,k2,... - treat k1, k2 as reserved (key=c++ adds c++ keywords)\n");
114 fprintf(stderr," -n# - separate line numbers from lines with # spaces\n");
115 fprintf(stderr," -n0 - do not generate line numbers\n");
116 fprintf(stderr," -ofile - output written to file (instead of stdout)\n");
117 fprintf(stderr," -p[+|-] - enable/disable page break at functions\n");
118 fprintf(stderr," -rfile1;file2,... - replace default PS procs with contents of files\n");
119 fprintf(stderr," -snt or -stn - sort files by name/type or type/name\n");
120 fprintf(stderr," -t# - expand tabs to # columns\n");
121 fprintf(stderr," -wf1,f2;f3,f4 - prepend files f1, f2 to output, append files f3, f4\n");
122 fprintf(stderr," -xx,y - coordinates for page adjustment\n");
123 fprintf(stderr," -ypath - path to use for temporary files\n");
124 fprintf(stderr," -? - display this help\n\n");
125 fprintf(stderr,"Default options are:\n");
126 fprintf(stderr," -b+ -d- -cc -hh -n2 -p+ -stn -t4 -x0,0\n");
127 fprintf(stderr,"Options may also be set in the environment variable %s.\n",PROGRAM_ENVV);
128
129 exit(1);
130 }
131
132 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
133 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
134
135 /*------------------------------------------------------------------
136 * add default key words to reserved hash
137 *------------------------------------------------------------------*/
138 void InitializeReservedHash(
139 Info *info,
140 char *keyList
141 )
142 {
143 int i;
144 char *part;
145
146 /*---------------------------------------------------------------
147 * create hash table
148 *---------------------------------------------------------------*/
149 info->reservedHash = HashCreate(sizeof(char *),
150 30,
151 (HashFunc *)IdentHash,
152 (ListCompareFunc *)IdentCompare,
153 cPostNoMem);
154
155 if (!info->reservedHash)
156 cPostError(1,"error creating reserved word hash table");
157
158 for (i=0; i<sizeof(ReservedTokens)/sizeof(char *); i++)
159 if (!HashAdd(info->reservedHash,&(ReservedTokens[i])))
160 cPostError(1,"error adding reserved word '%s' to hash table",
161 ReservedTokens[i]);
162
163 /*---------------------------------------------------------------
164 * loop through the comma separated keys ...
165 *---------------------------------------------------------------*/
166 part = strtok(keyList,",");
167 while (part)
168 {
169 /*------------------------------------------------------------
170 * special c++ token
171 *------------------------------------------------------------*/
172 if (!Stricmp("c++",part))
173 {
174 for (i=0; i<sizeof(CppReservedTokens)/sizeof(char *); i++)
175 if (!HashAdd(info->reservedHash,&(CppReservedTokens[i])))
176 cPostError(1,"error adding reserved word '%s' to hash table",
177 CppReservedTokens[i]);
178
179 }
180
181 /*------------------------------------------------------------
182 * file name
183 *------------------------------------------------------------*/
184 else if (('@' == part[0]) && (1 != strlen(part)))
185 {
186 TokFileInfo tfi;
187 char *key;
188
189 part++;
190
191 tfi = TokFileOpen(part);
192
193 if (!tfi)
194 cPostError(0,"error opening file '%s' for reading",part);
195
196 else
197 {
198 while (NULL != (part = TokFileNext(tfi)))
199 {
200 key = malloc(1 + strlen(part));
201 if (!key)
202 cPostError(1,"out of memory!!");
203
204 strcpy(key,part);
205
206 if (!HashAdd(info->reservedHash,&key))
207 cPostError(0,"error adding reserved word '%s' to hash table; word ignored",
208 key);
209 }
210 }
211 }
212
213 /*------------------------------------------------------------
214 * plain old token
215 *------------------------------------------------------------*/
216 else if (!HashAdd(info->reservedHash,&part))
217 {
218 cPostError(0,"error adding reserved word '%s' to hash table; word ignored",part);
219 }
220
221 part = strtok(NULL,",");
222 }
223 }
224
225 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
226 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
227
228 /*------------------------------------------------------------------
229 * clean up file list
230 *------------------------------------------------------------------*/
231 static int CleanUpFileList(
232 File *file,
233 Info *info
234 )
235 {
236 PageEject *pe;
237
238 if (!(info->oDebug & 1) && (file->tempName))
239 remove(file->tempName);
240
241 /*---------------------------------------------------------------
242 * free up file fields
243 *---------------------------------------------------------------*/
244 free(file->name);
245 free(file->pathName);
246
247 if (*(file->ext))
248 free(file->ext);
249
250 if (file->tempName)
251 free(file->tempName);
252
253 /*---------------------------------------------------------------
254 * free function lists
255 *---------------------------------------------------------------*/
256 ListDestroy(file->funcDefList);
257 ListDestroy(file->funcProList);
258
259 /*---------------------------------------------------------------
260 * free page eject list
261 *---------------------------------------------------------------*/
262 pe = file->breakList;
263 while (pe)
264 {
265 PageEject *next;
266
267 next = pe->next;
268 free(pe);
269 pe = next;
270 }
271
272 return 0;
273 }
274
275 /*------------------------------------------------------------------
276 * clean up function list
277 *------------------------------------------------------------------*/
278 static int CleanUpFuncList(
279 Function *func,
280 Info *info
281 )
282 {
283 ListDestroy(func->callsList);
284 ListDestroy(func->calledByList);
285
286 free(func->name);
287
288 return 0;
289 }
290
291 /*------------------------------------------------------------------
292 * atexit processing
293 *------------------------------------------------------------------*/
294 static void RunAtExit(void)
295 {
296
297 if (!AllDone)
298 fprintf(stderr,"%s : Program terminated.\n",PROGRAM_NAME);
299
300 /*---------------------------------------------------------------
301 * erase any temporary files we might have open
302 *---------------------------------------------------------------*/
303 if (!AllDone)
304 fprintf(stderr,"%s : Cleaning up temporary files.\n",PROGRAM_NAME);
305
306 ListIterate(info.fileList,(ListIterateFunc *)CleanUpFileList,&info);
307
308 /*---------------------------------------------------------------
309 * destroy file list
310 *---------------------------------------------------------------*/
311 ListDestroy(info.fileList);
312
313 /*---------------------------------------------------------------
314 * destroy hash tables
315 *---------------------------------------------------------------*/
316 HashDestroy(info.identHash);
317 HashDestroy(info.reservedHash);
318
319 /*---------------------------------------------------------------
320 * destroy function list
321 *---------------------------------------------------------------*/
322 ListIterate(info.funcTree,(ListIterateFunc *)CleanUpFuncList,&info);
323 ListDestroy(info.funcTree);
324
325 /*---------------------------------------------------------------
326 * dump memory (if debug enabled
327 *---------------------------------------------------------------*/
328 #if defined(__DEBUG_ALLOC__)
329 _dump_allocated(0);
330 #endif
331 }
332
333 /*------------------------------------------------------------------
334 * signal handler for program interruption
335 *------------------------------------------------------------------*/
336 #if defined(OPSYS_LINUX)
337 void SigHandler(int sig)
338 #else
339 void SignalHandler(int sig)
340 #endif
341 {
342 exit(1);
343 }
344
345 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
346 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
347
348 /*------------------------------------------------------------------
349 * print function name symbol defintions
350 *------------------------------------------------------------------*/
351 static int PrintFunctionDefinition(
352 Function *func,
353 Info *info
354 )
355 {
356 fprintf(info->oFile,
357 ".nameit symbol=fn%4.4d gmltype=hp%c size='+%d' text='%s'\n",
358 func->id, '2', 3, func->name);
359
360 return 0;
361 }
362
363 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
364 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
365
366 /*------------------------------------------------------------------
367 * compute calls and called bys, replace if > than max
368 *------------------------------------------------------------------*/
369 static int CountFunctionRefs(
370 Function *func,
371 Info *info
372 )
373 {
374 int count;
375
376 count = ListCount(func->callsList);
377 count += ListCount(func->calledByList);
378
379 if (count > info->count1)
380 info->count1 = count;
381
382 return 0;
383 }
384
385 /*------------------------------------------------------------------
386 * get maximum number of calls and called bys for all the functions
387 * so figure out which table to use
388 *------------------------------------------------------------------*/
389 int GetMaxFuncTableEntries(
390 Info *info
391 )
392 {
393
394 info->count1 = 0;
395
396 ListIterate(info->funcTree,
397 (ListIterateFunc *)CountFunctionRefs,
398 info);
399
400 return info->count1;
401 }
402
403 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
404 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
405
406 /*------------------------------------------------------------------
407 * parse command line for options
408 *------------------------------------------------------------------*/
409 static void GetOptions(
410 int *argc,
411 char *argv[],
412 Info *info
413 )
414 {
415 int oHelp;
416 char *oBrack;
417 char *oTabs;
418 char *oCtype;
419 char *oHtype;
420 #if defined(OPSYS_LINUX)
421 char oSort[10];
422 #else
423 char *oSort;
424 #endif
425 char *oFile;
426 char *oSpace;
427 char *oKeys;
428 char *oBreak;
429 char *oTemp;
430 char *oImbed;
431 char *oDuplex;
432 #if defined(OPSYS_LINUX)
433 char oXlate[80];
434 #else
435 char *oXlate;
436 #endif
437 char *numLeft;
438 char *s1;
439 char *s2;
440 char *oWrap;
441 char *oRepHdr;
442
443 /*---------------------------------------------------------------
444 * parse arguments
445 *---------------------------------------------------------------*/
446 parsearg(argc,argv,0,PROGRAM_ENVV,"-",
447 "? b@ c@ d@ h@ k@ i@ n@ o@ p@ r@ s@ t@ w@ x@ y@",
448 &oHelp,&oBrack,&oCtype,&oDuplex,&oHtype,&oKeys,&oImbed,
449 &oSpace,&oFile,&oBreak,&oRepHdr,&oSort,&oTabs,&oWrap,
450 &oXlate,&oTemp);
451
452 /*---------------------------------------------------------------
453 * check parms
454 *---------------------------------------------------------------*/
455 if (oHelp || (*argc < 2))
456 Usage();
457
458 if ('?' == *argv[1])
459 Usage();
460
461 /*---------------------------------------------------------------
462 * apply option defaults
463 *---------------------------------------------------------------*/
464 if ((NULL == oBrack ) || ('\0' == *oBrack )) oBrack = "+";
465 if ((NULL == oCtype ) || ('\0' == *oCtype )) oCtype = "c";
466 if ((NULL == oDuplex) || ('\0' == *oDuplex)) oDuplex = "-";
467 if ((NULL == oHtype ) || ('\0' == *oHtype )) oHtype = "h";
468 if ((NULL == oKeys ) || ('\0' == *oKeys )) oKeys = "";
469 if ((NULL == oImbed ) || ('\0' == *oImbed )) oImbed = "";
470 if ((NULL == oSpace ) || ('\0' == *oSpace )) oSpace = "2";
471 if ((NULL == oFile ) || ('\0' == *oFile )) oFile = NULL;
472 if ((NULL == oBreak ) || ('\0' == *oBreak )) oBreak = "+";
473 if ((NULL == oRepHdr) || ('\0' == *oRepHdr)) oRepHdr = "";
474 #if defined(OPSYS_LINUX)
475 if ((NULL == oSort ) || ('\0' == *oSort )) strcpy(oSort,"tn");
476 #else
477 if ((NULL == oSort ) || ('\0' == *oSort )) oSort = "tn";
478 #endif
479 if ((NULL == oTabs ) || ('\0' == *oTabs )) oTabs = "4";
480 if ((NULL == oWrap ) || ('\0' == *oWrap )) oWrap = "";
481 #if defined(OPSYS_LINUX)
482 if ((NULL == oXlate ) || ('\0' == *oXlate )) strcpy(oXlate, "0,0");
483 #else
484 if ((NULL == oXlate ) || ('\0' == *oXlate )) oXlate = "0,0";
485 #endif
486 if ((NULL == oTemp ) || ('\0' == *oTemp )) oTemp = "";
487
488 /*---------------------------------------------------------------
489 * bracketing option
490 *---------------------------------------------------------------*/
491 info->oBrack = (int) strtol(oBrack,NULL,10);
492 if (0 == info->oBrack)
493 {
494 if ((1 != strlen(oBrack)) || (NULL == strchr("-+",*oBrack)))
495 cPostError(1,"invalid value on -b option");
496
497 if ('+' == *oBrack)
498 info->oBrack = 1000;
499 else
500 info->oBrack = 0;
501 }
502
503 /*---------------------------------------------------------------
504 * extensions for C files
505 *---------------------------------------------------------------*/
506 info->oCtype = oCtype;
507
508 /*---------------------------------------------------------------
509 * duplex
510 *---------------------------------------------------------------*/
511 if ((1 != strlen(oDuplex)) || (NULL == strchr("-+",*oDuplex)))
512 cPostError(1,"invalid value on -d option");
513
514 info->oDuplex = ('+' == *oDuplex);
515
516 /*---------------------------------------------------------------
517 * extensions for H files
518 *---------------------------------------------------------------*/
519 info->oHtype = oHtype;
520
521 /*---------------------------------------------------------------
522 * reserved words
523 *---------------------------------------------------------------*/
524 InitializeReservedHash(info,oKeys);
525
526 /*---------------------------------------------------------------
527 * imbed option
528 *---------------------------------------------------------------*/
529 info->oImbed = oImbed;
530
531 /*---------------------------------------------------------------
532 * space option
533 *---------------------------------------------------------------*/
534 info->oSpace = (int) strtol(oSpace,&numLeft,10);
535 if (*numLeft || (info->oSpace < 0))
536 cPostError(1,"invalid value on -n option");
537
538 /*---------------------------------------------------------------
539 * output file option
540 *---------------------------------------------------------------*/
541 if (NULL == oFile)
542 info->oFile = stdout;
543 else
544 {
545 info->oFile = fopen(oFile,"w");
546 if (NULL == info->oFile)
547 cPostError(1,"error opening output file %s for writing",oFile);
548 }
549
550 /*---------------------------------------------------------------
551 * page break option
552 *---------------------------------------------------------------*/
553 if ((1 != strlen(oBreak)) || (NULL == strchr("-+",*oBreak)))
554 cPostError(1,"invalid value on -p option");
555
556 info->oBreak = ('+' == *oBreak);
557
558 /*---------------------------------------------------------------
559 * replace PS header
560 *---------------------------------------------------------------*/
561 info->oRepHdr = oRepHdr;
562
563 /*---------------------------------------------------------------
564 * sort option
565 *---------------------------------------------------------------*/
566 if ((0 != Stricmp("nt",oSort)) && (0 != Stricmp("tn",oSort)))
567 cPostError(1,"invalid value on -s option");
568
569 info->oSort = Strupr(oSort);
570
571
572 /*---------------------------------------------------------------
573 * tabs option
574 *---------------------------------------------------------------*/
575 info->oTabs = (int) strtol(oTabs,NULL,10);
576 if (0 == info->oTabs)
577 cPostError(1,"invalid value on -t option");
578
579 /*---------------------------------------------------------------
580 * wrap PS around output
581 *---------------------------------------------------------------*/
582 info->oWrapB = strtok(oWrap,";");
583 info->oWrapA = strtok(NULL,"");
584
585 /*---------------------------------------------------------------
586 * translate option
587 *---------------------------------------------------------------*/
588 s1 = strtok(oXlate,",");
589 s2 = strtok(NULL,"");
590
591 if (!s1 || !s2)
592 cPostError(1,"invalid value on -x option");
593
594 info->oXlateX = (int) strtol(s1,NULL,10);
595 info->oXlateY = (int) strtol(s2,NULL,10);
596
597
598 /*---------------------------------------------------------------
599 * temp path
600 *---------------------------------------------------------------*/
601 if (!strlen(oTemp))
602 info->oTemp = "";
603
604 else
605 {
606 char c;
607
608 c = oTemp[strlen(oTemp) - 1];
609 if (('\\' == c) || ('/' == c))
610 info->oTemp = oTemp;
611 else
612 {
613 info->oTemp = malloc(2+strlen(oTemp));
614 strcpy(info->oTemp,oTemp);
615 strcat(info->oTemp,"/");
616 }
617 }
618
619 }
620
621 /*------------------------------------------------------------------
622 * copy one file stream to another
623 *------------------------------------------------------------------*/
624 void copyFile(
625 FILE *fileFrom,
626 FILE *fileTo
627 )
628 {
629 #define BUFFER_SIZE 8192
630 char *buffer;
631
632 /*---------------------------------------------------------------
633 * allocate buffer
634 *---------------------------------------------------------------*/
635 buffer = malloc(BUFFER_SIZE);
636 if (!buffer)
637 cPostError(1,"out of memory!!");
638
639 /*---------------------------------------------------------------
640 * copy file buffer at a time
641 *---------------------------------------------------------------*/
642 while (!feof(fileFrom))
643 {
644 int count;
645 count = fread(buffer,1,BUFFER_SIZE,fileFrom);
646 fwrite(buffer,1,count,fileTo);
647 }
648
649 /*---------------------------------------------------------------
650 * free the buffer
651 *---------------------------------------------------------------*/
652 free(buffer);
653 }
654
655 /*------------------------------------------------------------------
656 * process the imbed file option
657 *------------------------------------------------------------------*/
658 void processImbedFile(
659 char *imbedFileName
660 )
661 {
662 FILE *file;
663
664 /*---------------------------------------------------------------
665 * while we have imbedFileNames
666 *---------------------------------------------------------------*/
667 imbedFileName = strtok(imbedFileName,";,");
668 while (imbedFileName)
669 {
670 /*------------------------------------------------------------
671 * open the imbed file
672 *------------------------------------------------------------*/
673 file = fopen(imbedFileName,"r");
674
675 /*------------------------------------------------------------
676 * print error if not found, or copy it in if found
677 *------------------------------------------------------------*/
678 if (!file)
679 cPostError(0,"unable to open file '%s' for reading",imbedFileName);
680 else
681 {
682 copyFile(file,info.oFile);
683 fclose(file);
684 }
685
686 /*------------------------------------------------------------
687 * get next imbed file name
688 *------------------------------------------------------------*/
689 imbedFileName = strtok(NULL,";,");
690 }
691 }
692
693 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
694 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
695
696 /*------------------------------------------------------------------
697 * main program
698 *------------------------------------------------------------------*/
699 int main(
700 int argc,
701 char *argv[]
702 )
703 {
704 int i;
705 char dateStr[30];
706 struct tm *tm;
707 time_t t;
708 char *origParms;
709
710 /*---------------------------------------------------------------
711 * check for help
712 *---------------------------------------------------------------*/
713 if ((1 == argc) || ('?' == *(argv[1])))
714 Usage();
715
716 /*---------------------------------------------------------------
717 * get original parms
718 *---------------------------------------------------------------*/
719 origParms = malloc(1);
720 *origParms = 0;
721
722 for (i=0; i<argc; i++)
723 {
724 origParms = realloc(origParms,2 + strlen(origParms) + strlen(argv[i]));
725 strcat(origParms," ");
726 strcat(origParms,argv[i]);
727 }
728 /*---------------------------------------------------------------
729 * zero out info
730 *---------------------------------------------------------------*/
731 memset(&info,0,sizeof(info));
732
733 /*---------------------------------------------------------------
734 * get options
735 *---------------------------------------------------------------*/
736 GetOptions(&argc,argv,&info);
737 /*---------------------------------------------------------------
738 * buffer output
739 *---------------------------------------------------------------*/
740 /* setvbuf(info.oFile,NULL,_IOFBF,32000); */
741
742 /*---------------------------------------------------------------
743 * put filenames in a list
744 *---------------------------------------------------------------*/
745 info.fileList = ListCreate(sizeof(File),
746 (ListCompareFunc *)FileNameCompare,
747 cPostNoMem);
748 if (!info.fileList)
749 cPostError(1,"error creating list of files");
750
751 for (i=1; i<argc; i++)
752 FileSpecAdd(&info,info.fileList,argv[i]);
753
754 /*---------------------------------------------------------------
755 * check for no files to process
756 *---------------------------------------------------------------*/
757 if (!ListCount(info.fileList))
758 cPostError(1,"no files to process");
759
760 /*---------------------------------------------------------------
761 * intialize rest of info structure
762 *---------------------------------------------------------------*/
763 info.funcTree = ListCreate(sizeof(Function),
764 (ListCompareFunc *)FunctionNameCompare,
765 cPostNoMem);
766 if (!info.fileList)
767 cPostError(1,"error creating list of functions");
768
769 info.identHash = HashCreate(sizeof(char *),
770 1000,
771 (HashFunc *)IdentHash,
772 (ListCompareFunc *)IdentCompare,
773 cPostNoMem);
774
775
776 if (!info.identHash)
777 cPostError(1,"error creating global hash table");
778
779 /*---------------------------------------------------------------
780 * setup error termination processing
781 *---------------------------------------------------------------*/
782 atexit(RunAtExit);
783 #if defined(OPSYS_LINUX)
784 signal(SIGINT, SigHandler);
785 signal(SIGTERM, SigHandler);
786 #else
787 signal(SIGINT, SignalHandler);
788 signal(SIGTERM, SignalHandler);
789 #endif
790
791 #if defined(OPSYS_OS2) || defined(OPSYS_OS2V2)
792 signal(SIGBREAK,SignalHandler);
793 #endif
794
795 /*---------------------------------------------------------------
796 * print header
797 *---------------------------------------------------------------*/
798 fprintf(info.oFile,"%%! PostScript file generated by %s %s\n\n",
799 PROGRAM_NAME,PROGRAM_VERS);
800
801 /*------------------------------------------------------------------
802 * a macro to write a line to the output file
803 *------------------------------------------------------------------*/
804 #define p(x) fprintf(info.oFile,"%s\n",x);
805
806
807 /*---------------------------------------------------------------
808 * write command line and environment variable setting
809 *---------------------------------------------------------------*/
810 #if defined(ECHO_COMMAND_LINE)
811 {
812 p("%%-----------------------------------------------------------------")
813
814 fprintf(info.oFile,"%%%% this file created with the command:\n");
815 fprintf(info.oFile,"%%%% %s\n",origParms);
816 fprintf(info.oFile,"%%%% the CPOST environment variable ");
817 if (!getenv(PROGRAM_ENVV))
818 fprintf(info.oFile,"is not set.\n");
819 else
820 {
821 fprintf(info.oFile,"is set to:\n");
822 fprintf(info.oFile,"%%%% %s\n",getenv(PROGRAM_ENVV));
823 }
824
825 p("%%-----------------------------------------------------------------")
826 p("");
827 }
828 #endif
829
830 /*---------------------------------------------------------------
831 * write wrapper prefix
832 *---------------------------------------------------------------*/
833 if (info.oWrapB && strlen(info.oWrapB))
834 processImbedFile(info.oWrapB);
835
836 /*---------------------------------------------------------------
837 * get the time
838 *---------------------------------------------------------------*/
839 t = time(NULL);
840 tm = localtime(&t);
841 strftime(dateStr,sizeof(dateStr)-1,"%m/%d/%y %H:%M:%S",tm);
842
843 p("%%-----------------------------------------------------------------")
844 p("%% runtime options and values")
845 p("%%-----------------------------------------------------------------")
846 p("")
847 fprintf(info.oFile,"/printDate (%s) def\n",dateStr);
848 fprintf(info.oFile,"/oSpace %d def\n",info.oSpace);
849 fprintf(info.oFile,"/oXlate { %d %d translate } def\n",info.oXlateX,info.oXlateY);
850 fprintf(info.oFile,"/oDuplex 1 %d eq def\n",info.oDuplex);
851 fprintf(info.oFile,"/oNumber 0 %d ne def\n",info.oSpace);
852 p("")
853
854 /*---------------------------------------------------------------
855 * write replaced header ...
856 *---------------------------------------------------------------*/
857 if (info.oRepHdr && strlen(info.oRepHdr))
858 {
859 processImbedFile(info.oImbed);
860 p("");
861 processImbedFile(info.oRepHdr);
862 p("");
863 }
864
865 /*---------------------------------------------------------------
866 * or default stuff
867 *---------------------------------------------------------------*/
868 else
869 {
870 for (i=0; i< sizeof(Header_1)/sizeof(char *); i++)
871 p(Header_1[i]);
872
873 p("");
874 processImbedFile(info.oImbed);
875 p("");
876
877 for (i=0; i< sizeof(Header_2)/sizeof(char *); i++)
878 p(Header_2[i]);
879
880 p("");
881 }
882
883 /*---------------------------------------------------------------
884 * read the files. make copies
885 *---------------------------------------------------------------*/
886 fprintf(stderr,"Pass 1\n");
887 ListIterate(info.fileList,(ListIterateFunc *)Pass1,&info);
888
889 /*---------------------------------------------------------------
890 * read the copies. write the output file
891 *---------------------------------------------------------------*/
892 fprintf(stderr,"Pass 2\n");
893 ListIterate(info.fileList,(ListIterateFunc *)Pass2,&info);
894
895 /*---------------------------------------------------------------*
896 * print trailing line feed
897 *---------------------------------------------------------------*/
898 fprintf(info.oFile,"\n");
899
900 /*---------------------------------------------------------------
901 * write wrapper suffix
902 *---------------------------------------------------------------*/
903 if (info.oWrapA && strlen(info.oWrapA))
904 processImbedFile(info.oWrapA);
905
906 /*---------------------------------------------------------------
907 * close file (another line feed for luck!)
908 *---------------------------------------------------------------*/
909 fprintf(info.oFile,"\n");
910 fclose(info.oFile);
911
912 AllDone = 1;
913 return 0;
914 }