FIX #1955: confusion between .exe.hp and .hp suffixes for heap profiles
[ghc-hetmet.git] / utils / hp2ps / Main.c
1 #include "Main.h"
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include "Defines.h"
6 #include "AuxFile.h"
7 #include "AreaBelow.h"
8 #include "Dimensions.h"
9 #include "HpFile.h"
10 #include "PsFile.h"
11 #include "Reorder.h"
12 #include "Scale.h"
13 #include "TopTwenty.h"
14 #include "TraceElement.h"
15 #include "Deviation.h"
16 #include "Error.h"
17 #include "Utilities.h"
18
19 boolish pflag = 0;      /* read auxiliary file                  */
20 boolish eflag = 0;      /* scaled EPSF                          */
21 boolish dflag = 0;      /* sort by standard deviation           */
22 int     iflag = 0;      /* sort by identifier (3-way flag)      */
23 boolish gflag = 0;      /* output suitable for previewer        */
24 boolish yflag = 0;      /* ignore marks                         */
25 boolish bflag = 0;      /* use a big title box                  */
26 boolish sflag = 0;      /* use a small title box                */
27 int     mflag = 0;      /* max no. of bands displayed (default 20) */
28 boolish tflag = 0;      /* ignored threshold specified          */
29 boolish cflag = 0;      /* colour output                        */
30
31 boolish filter;         /* true when running as a filter        */
32 boolish multipageflag = 0;  /* true when the output should be 2 pages - key and profile */ 
33
34 static floatish WidthInPoints PROTO((char *));            /* forward */
35 static FILE *Fp PROTO((char *, char **, char *, char *)); /* forward */
36
37 char *hpfile;
38 char *psfile;
39 char *auxfile;
40
41 char *programname;
42
43 static char *pathName;
44 static char *baseName; /* "basename" is a std C library name (sigh) */
45
46 FILE* hpfp;
47 FILE* psfp;
48 FILE* auxfp;
49
50 floatish xrange = 0.0;
51 floatish yrange = 0.0;
52
53 floatish auxxrange = 0.0;
54 floatish auxyrange = 0.0;
55
56 floatish epsfwidth;
57 floatish areabelow;
58
59 intish nsamples;
60 intish nmarks;
61 intish nidents;
62
63 floatish THRESHOLD_PERCENT = DEFAULT_THRESHOLD;
64 int TWENTY = DEFAULT_TWENTY;
65
66 int main(argc, argv)
67 int argc;
68 char* argv[];
69 {
70
71     programname = copystring(Basename(argv[0]));
72
73     argc--, argv++;
74     while (argc && argv[0][0] == '-') {
75         while (*++*argv)
76             switch(**argv) {
77             case 'p':
78                 pflag++;
79                 break;
80             case 'e':
81                 eflag++;
82                 epsfwidth = WidthInPoints(*argv + 1);
83                 goto nextarg;
84             case 'd':
85                 dflag++;
86                 goto nextarg;
87             case 'i':
88                 switch( *(*argv + 1) ) {
89                   case '-':
90                     iflag = -1;
91                   case '+':
92                   default:
93                     iflag = 1;
94                 }
95                 goto nextarg;
96             case 'g':
97                 gflag++;
98                 goto nextarg;
99             case 'y':
100                 yflag++;
101                 goto nextarg;
102             case 'b':
103                 bflag++;
104                 goto nextarg;
105             case 's':
106                 sflag++;
107                 goto nextarg;
108             case 'm':
109                 mflag++;
110                 TWENTY = atoi(*argv + 1);
111                 // only 20 keys fit on a page
112                 if (TWENTY > DEFAULT_TWENTY) 
113                    multipageflag++;
114                 goto nextarg;
115             case 'M':
116                 multipageflag++;
117                 goto nextarg;
118             case 't':
119                 tflag++;
120                 THRESHOLD_PERCENT = (floatish) atof(*argv + 1);
121                 if (THRESHOLD_PERCENT < 0 || THRESHOLD_PERCENT > 5)
122                     Usage(*argv-1);
123                 goto nextarg;
124             case 'c':
125                 cflag++;
126                 goto nextarg;
127             case '?':
128             default:
129                 Usage(*argv-1);
130             }
131 nextarg: ;
132         argc--, argv++;
133     }
134
135     hpfile = "stdin";
136     psfile = "stdout";
137
138     hpfp = stdin;
139     psfp = stdout;
140
141     filter = argc < 1;
142
143
144
145     if (!filter) {
146         pathName = copystring(argv[0]);
147         DropSuffix(pathName, ".hp");
148 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
149         DropSuffix(pathName, ".exe");
150 #endif
151         baseName = copystring(Basename(pathName));
152         
153         hpfp  = Fp(pathName, &hpfile, ".hp", "r"); 
154         psfp  = Fp(baseName, &psfile, ".ps", "w"); 
155
156         if (pflag) auxfp = Fp(baseName, &auxfile, ".aux", "r");
157     }
158
159     GetHpFile(hpfp);
160
161     if (!filter && pflag) GetAuxFile(auxfp);
162
163
164     TraceElement();          /* Orders on total, Removes trace elements (tflag) */
165
166     if (dflag) Deviation();  /* ReOrders on deviation */
167
168     if (iflag) Identorder(iflag); /* ReOrders on identifier */
169
170     if (pflag) Reorder();    /* ReOrders on aux file */
171
172     /* Selects top bands (mflag) - can be more than 20 now */
173     if (TWENTY != 0) TopTwenty(); 
174
175     Dimensions();
176
177     areabelow = AreaBelow();
178
179     Scale();
180
181     PutPsFile();
182
183     if (!filter) {
184         auxfp = Fp(baseName, &auxfile, ".aux", "w");
185         PutAuxFile(auxfp);
186     } 
187
188     return(0);
189 }
190
191
192
193 typedef enum {POINTS, INCHES, MILLIMETRES} pim;
194
195 static pim Units PROTO((char *));   /* forward */
196
197 static floatish
198 WidthInPoints(wstr)
199   char *wstr;
200 {
201     floatish result;
202
203     result = (floatish) atof(wstr);
204
205     switch (Units(wstr)) {
206         case INCHES:            
207             result *= 72.0;
208             break;
209         case MILLIMETRES:       
210             result *= 2.834646;
211             break;
212         case POINTS:
213         default: ;
214     }
215
216     if (result <= 144)   /* Minimum of 2in wide ! */
217         Usage(wstr);
218
219     return result;
220 }
221
222         
223 static pim
224 Units(wstr)
225   char* wstr;
226 {
227 int i;
228
229     i = strlen(wstr) - 2;
230
231     if (wstr[i] == 'p' && wstr[i+1] == 't') {
232         return POINTS;
233     } else if (wstr[i] == 'i' && wstr[i+1] == 'n') {
234         return INCHES;  
235     } else if (wstr[i] == 'm' && wstr[i+1] == 'm') {
236         return MILLIMETRES;
237     } else {
238         return POINTS;
239     }
240 }
241
242 static FILE *
243 Fp(rootname, filename, suffix, mode)
244   char* rootname; char** filename; char* suffix; char* mode;
245 {
246     *filename = copystring2(rootname, suffix);
247
248     return(OpenFile(*filename, mode));
249 }
250
251 #ifdef DEBUG
252 void
253 _stgAssert (filename, linenum)
254   char          *filename;
255   unsigned int  linenum;
256 {
257     fflush(stdout);
258     fprintf(stderr, "ASSERTION FAILED: file %s, line %u\n", filename, linenum);
259     fflush(stderr);
260     abort();
261 }
262 #endif