1 /*** analog 6.0 http://www.analog.cx/ ***/
2 /*** This program is copyright (c) Stephen R. E. Turner 1995 - 2004 except as
3 *** stated otherwise.
4 ***
5 *** This program is free software. You can redistribute it and/or modify it
6 *** under the terms of version 2 of the GNU General Public License, which you
7 *** should have received with it.
8 ***
9 *** This program is distributed in the hope that it will be useful, but
10 *** without any warranty, expressed or implied. ***/
11
12 /*** outcro.c; computer-readable output ***/
13
14 #include "anlghea3.h"
15
16 /* Page width -- unused in this output style */
cro_pagewidth(Outchoices * od)17 unsigned int cro_pagewidth(Outchoices *od) {
18 return 0;
19 }
20
21 /* The top of the output if we are in CGI mode */
cro_cgihead(FILE * outf,Outchoices * od)22 void cro_cgihead(FILE *outf, Outchoices *od) {
23 fprintf(outf, "Content-Type: text/plain\n\n");
24 }
25
26 /* Stuff this output style needs in the page header */
cro_stylehead(FILE * outf,Outchoices * od)27 void cro_stylehead(FILE *outf, Outchoices *od) {
28 }
29
30 /* The title of the page, plus the user's HEADERFILE */
cro_pagetitle(FILE * outf,Outchoices * od)31 void cro_pagetitle(FILE *outf, Outchoices *od) {
32 if (!strcaseeq(od->headerfile, "none"))
33 cro_includefile(outf, od, od->headerfile, 'h');
34
35 fprintf(outf, "x%sVE%sanalog %s\n", od->compsep, od->compsep, VNUMBER);
36 fprintf(outf, "x%sHN%s%s\n", od->compsep, od->compsep, od->hostname);
37 if (!strcaseeq(od->hosturl, "none"))
38 fprintf(outf, "x%sHU%s%s\n", od->compsep, od->compsep, od->hosturl);
39 }
40
41 /* Program start time, and logfile start and end times */
cro_timings(FILE * outf,Outchoices * od,Dateman * dman)42 void cro_timings(FILE *outf, Outchoices *od, Dateman *dman) {
43 extern timecode_t starttimec;
44 char *compsep = od->compsep;
45
46 if (od->runtime)
47 fprintf(outf, "x%sPS%s%s\n", compsep, compsep,
48 timesprintf(od, od->lngstr[datefmt2_], starttimec, UNSET));
49
50 if (dman->firsttime <= dman->lasttime) {
51 fprintf(outf, "x%sFR%s%s\n", compsep, compsep,
52 timesprintf(od, od->lngstr[datefmt2_], dman->firsttime, UNSET));
53 fprintf(outf, "x%sLR%s%s\n", compsep, compsep,
54 timesprintf(od, od->lngstr[datefmt2_], dman->lasttime, UNSET));
55 }
56 }
57
58 /* Finishing the top of the page */
cro_closehead(FILE * outf,Outchoices * od)59 void cro_closehead(FILE *outf, Outchoices *od) {
60 }
61
62 /* Starting the bottom of the page */
cro_pagebotstart(FILE * outf,Outchoices * od)63 void cro_pagebotstart(FILE *outf, Outchoices *od) {
64 }
65
66 /* The credit line at the bottom of the page */
cro_credit(FILE * outf,Outchoices * od)67 void cro_credit(FILE *outf, Outchoices *od) {
68 /* Already printed at the top of the page in cro_pagehead() */
69 }
70
71 /* The program run time */
cro_runtime(FILE * outf,Outchoices * od,long secs)72 void cro_runtime(FILE *outf, Outchoices *od, long secs) {
73 }
74
75 /* The page footer, including the user's FOOTERFILE */
cro_pagefoot(FILE * outf,Outchoices * od)76 void cro_pagefoot(FILE *outf, Outchoices *od) {
77 if (!strcaseeq(od->footerfile, "none"))
78 cro_includefile(outf, od, od->footerfile, 'f');
79 }
80
81 /* Footer material for this output style */
cro_stylefoot(FILE * outf,Outchoices * od)82 void cro_stylefoot(FILE *outf, Outchoices *od) {
83 }
84
85 /* Report title */
cro_reporttitle(FILE * outf,Outchoices * od,choice rep)86 void cro_reporttitle(FILE *outf, Outchoices *od, choice rep) {
87 }
88
89 /* Report footer */
cro_reportfooter(FILE * outf,Outchoices * od,choice rep)90 void cro_reportfooter(FILE *outf, Outchoices *od, choice rep) {
91 }
92
93 /* Report description */
cro_reportdesc(FILE * outf,Outchoices * od,choice rep)94 void cro_reportdesc(FILE *outf, Outchoices *od, choice rep) {
95 }
96
97 /* The time period spanned by the report */
cro_reportspan(FILE * outf,Outchoices * od,choice rep,timecode_t maxd,timecode_t mind)98 void cro_reportspan(FILE *outf, Outchoices *od, choice rep, timecode_t maxd,
99 timecode_t mind) {
100 extern char repcodes[];
101
102 fprintf(outf, "%c%s*FR%s%s\n", repcodes[rep], od->compsep, od->compsep,
103 timesprintf(od, od->lngstr[datefmt2_], mind, UNSET));
104 fprintf(outf, "%c%s*LR%s%s\n", repcodes[rep], od->compsep, od->compsep,
105 timesprintf(od, od->lngstr[datefmt2_], maxd, UNSET));
106 }
107
108 /* General Summary header */
cro_gensumhead(FILE * outf,Outchoices * od)109 void cro_gensumhead(FILE *outf, Outchoices *od) {
110 }
111
112 /* General Summary footer */
cro_gensumfoot(FILE * outf,Outchoices * od)113 void cro_gensumfoot(FILE *outf, Outchoices *od) {
114 }
115
116 /* Single General Summary line, long data */
cro_gensumline(FILE * outf,Outchoices * od,int namecode,unsigned long x,unsigned long x7,logical isaverage)117 void cro_gensumline(FILE *outf, Outchoices *od, int namecode,
118 unsigned long x, unsigned long x7, logical isaverage) {
119 char *compsep = od->compsep;
120 char *name = od->lngstr[namecode];
121
122 if (isaverage)
123 return; /* CRO doesn't display averages */
124
125 fprintf(outf, "x%s%c%c%s%lu", compsep, name[0], name[1], compsep, x);
126 if (x7 != (unsigned long)UNSET)
127 fprintf(outf, "\nx%s%c%c%s%lu", compsep, name[2], name[3], compsep, x7);
128
129 putc('\n', outf);
130 }
131
132 /* Single General Summary line, bytes data */
cro_gensumlineb(FILE * outf,Outchoices * od,int namecode,double x,double x7,logical isaverage)133 void cro_gensumlineb(FILE *outf, Outchoices *od, int namecode, double x,
134 double x7, logical isaverage) {
135 char *compsep = od->compsep;
136 char *name = od->lngstr[namecode];
137
138 if (isaverage)
139 return; /* CRO doesn't display averages */
140
141 fprintf(outf, "x%s%c%c%s%.0f", compsep, name[0], name[1], compsep, x);
142
143 if (x7 != UNSET)
144 fprintf(outf, "\nx%s%c%c%s%.0f", compsep, name[2], name[3], compsep, x7);
145
146 putc('\n', outf);
147 }
148
149 /* "Last seven" explanation line */
cro_lastseven(FILE * outf,Outchoices * od,timecode_t last7to)150 void cro_lastseven(FILE *outf, Outchoices *od, timecode_t last7to) {
151 fprintf(outf, "x%sE7%s%s\n", od->compsep, od->compsep,
152 timesprintf(od, od->lngstr[datefmt1_], last7to, UNSET));
153 }
154
155 /* Start of a <pre> section */
cro_prestart(FILE * outf,Outchoices * od)156 void cro_prestart(FILE *outf, Outchoices *od) {
157 }
158
159 /* End of a <pre> section */
cro_preend(FILE * outf,Outchoices * od)160 void cro_preend(FILE *outf, Outchoices *od) {
161 }
162
163 /* A horizontal rule */
cro_hrule(FILE * outf,Outchoices * od)164 void cro_hrule(FILE *outf, Outchoices *od) {
165 }
166
167 /* An en dash */
cro_endash(void)168 char *cro_endash(void) {
169 return "-";
170 }
171
172 /* putc with special characters escaped */
cro_putch(FILE * outf,char c)173 void cro_putch(FILE *outf, char c) {
174 putc(c, outf);
175 }
176
177 /* strlen */
cro_strlength(const char * s)178 size_t cro_strlength(const char *s) {
179 return strlen(s);
180 }
181
182 /* Allow month in dates? DO NOT enable for human-readable text because of
183 i18n problems. */
cro_allowmonth(void)184 logical cro_allowmonth(void) {
185 return TRUE;
186 }
187
188 /* Calculate column widths */
cro_calcwidths(Outchoices * od,choice rep,unsigned int width[],unsigned int * bmult,unsigned int * bmult7,double * unit,unsigned long maxr,unsigned long maxr7,unsigned long maxp,unsigned long maxp7,double maxb,double maxb7,unsigned long howmany)189 void cro_calcwidths(Outchoices *od, choice rep, unsigned int width[],
190 unsigned int *bmult, unsigned int *bmult7, double *unit,
191 unsigned long maxr, unsigned long maxr7,
192 unsigned long maxp, unsigned long maxp7, double maxb,
193 double maxb7, unsigned long howmany) {
194 unsigned int i;
195
196 for (i = 0; i < COL_NUMBER; i++)
197 width[i] = 0;
198
199 *bmult = 0;
200 *bmult7 = 0;
201 }
202
203 /* "Each unit represents" line */
cro_declareunit(FILE * outf,Outchoices * od,char graphby,double unit,unsigned int bmult)204 void cro_declareunit(FILE *outf, Outchoices *od, char graphby, double unit,
205 unsigned int bmult) {
206 }
207
208 /* Start of column header line */
cro_colheadstart(FILE * outf,Outchoices * od,choice rep)209 void cro_colheadstart(FILE *outf, Outchoices *od, choice rep) {
210 }
211
212 /* Column header line: individual column */
cro_colheadcol(FILE * outf,Outchoices * od,choice rep,choice col,unsigned int width,char * colname,logical unterminated)213 void cro_colheadcol(FILE *outf, Outchoices *od, choice rep, choice col,
214 unsigned int width, char *colname, logical unterminated) {
215 }
216
217 /* End of column header line */
cro_colheadend(FILE * outf,Outchoices * od,choice rep)218 void cro_colheadend(FILE *outf, Outchoices *od, choice rep) {
219 }
220
221 /* Start of column header underlining line */
cro_colheadustart(FILE * outf,Outchoices * od,choice rep)222 void cro_colheadustart(FILE *outf, Outchoices *od, choice rep) {
223 }
224
225 /* Underlining of one column header */
cro_colheadunderline(FILE * ouf,Outchoices * od,choice rep,choice col,unsigned int width,char * name)226 void cro_colheadunderline(FILE *ouf, Outchoices *od, choice rep, choice col,
227 unsigned int width, char *name) {
228 }
229
230 /* End of column header underlining line */
cro_colheaduend(FILE * outf,Outchoices * od,choice rep)231 void cro_colheaduend(FILE *outf, Outchoices *od, choice rep) {
232 }
233
234 /* Start of a table row */
cro_rowstart(FILE * outf,Outchoices * od,choice rep,choice * cols,int level,char * name,char * datefmt,char * timefmt)235 void cro_rowstart(FILE *outf, Outchoices *od, choice rep, choice *cols,
236 int level, char *name, char *datefmt, char *timefmt) {
237 extern char repcodes[];
238 extern char colcodes[];
239
240 unsigned int c;
241
242 fprintf(outf, "%c%s", repcodes[rep], od->compsep);
243 if (level >= 1)
244 putc('l', outf);
245 for (c = 0; cols[c] != COL_NUMBER; c++)
246 putc(colcodes[cols[c]], outf);
247 fputs(od->compsep, outf);
248 }
249
250 /* Print level in hierarchy represented by this row */
cro_levelcell(FILE * outf,Outchoices * od,choice rep,int level)251 void cro_levelcell(FILE *outf, Outchoices *od, choice rep, int level) {
252 if (level >= 1)
253 fprintf(outf, "%d%s", level, od->compsep);
254 }
255
256 /* Name column */
cro_namecell(FILE * outf,Outchoices * od,choice rep,char * name,choice source,unsigned int width,logical name1st,logical isfirst,logical rightalign,Alias * aliashead,Include * linkhead,logical ispage,unsigned int spaces,char * baseurl)257 void cro_namecell(FILE *outf, Outchoices *od, choice rep, char *name,
258 choice source, unsigned int width, logical name1st,
259 logical isfirst, logical rightalign, Alias *aliashead,
260 Include *linkhead, logical ispage, unsigned int spaces,
261 char *baseurl) {
262 extern char *workspace;
263
264 if (isfirst)
265 return;
266
267 strcpy(workspace, name);
268 do_aliasx(workspace, aliashead);
269 fputs(workspace, outf);
270 }
271
272 /* Single cell, unsigned long argument */
cro_ulcell(FILE * outf,Outchoices * od,choice rep,choice col,unsigned long x,unsigned int width)273 void cro_ulcell(FILE *outf, Outchoices *od, choice rep, choice col,
274 unsigned long x, unsigned int width) {
275 fprintf(outf, "%lu%s", x, od->compsep);
276 }
277
278 /* Single cell, TRUSTED string argument */
cro_strcell(FILE * outf,Outchoices * od,choice rep,choice col,char * s,unsigned int width)279 void cro_strcell(FILE *outf, Outchoices *od, choice rep, choice col,
280 char *s, unsigned int width) {
281 fprintf(outf, "%s%s", s, od->compsep);
282 }
283
284 /* Single cell, listing bytes */
cro_bytescell(FILE * outf,Outchoices * od,choice rep,choice col,double b,double bmult,unsigned int width)285 void cro_bytescell(FILE *outf, Outchoices *od, choice rep, choice col,
286 double b, double bmult, unsigned int width) {
287 fprintf(outf, "%.0f%s", b, od->compsep);
288 }
289
290 /* Single cell, listing percentage */
cro_pccell(FILE * outf,Outchoices * od,choice rep,choice col,double n,double tot,unsigned int width)291 void cro_pccell(FILE *outf, Outchoices *od, choice rep, choice col, double n,
292 double tot, unsigned int width) {
293 fprintf(outf, "%.3f", (tot == 0)?0.0:(n * 100.0 / tot));
294 fputs(od->compsep, outf);
295 }
296
297 /* Single cell, index */
cro_indexcell(FILE * outf,Outchoices * od,choice rep,choice col,long index,unsigned int width)298 void cro_indexcell(FILE *outf, Outchoices *od, choice rep, choice col,
299 long index, unsigned int width) {
300 /* If index is 0 (i.e. sub-item), don't print anything */
301 if (index > 0)
302 fprintf(outf, "%ld", index);
303 fputs(od->compsep, outf);
304 }
305
306 /* End of a table row */
cro_rowend(FILE * outf,Outchoices * od,choice rep)307 void cro_rowend(FILE *outf, Outchoices *od, choice rep) {
308 putc('\n', outf);
309 }
310
311 /* Blank line in time reports */
cro_blankline(FILE * outf,Outchoices * od,choice * cols)312 void cro_blankline(FILE *outf, Outchoices *od, choice *cols) {
313 }
314
315 /* Barchart in time reports */
cro_barchart(FILE * outf,Outchoices * od,int y,char graphby)316 void cro_barchart(FILE *outf, Outchoices *od, int y, char graphby) {
317 }
318
319 /* "Busiest time period" line */
cro_busyprintf(FILE * outf,Outchoices * od,choice rep,char * datefmt,unsigned long reqs,unsigned long pages,double bys,datecode_t date,unsigned int hr,unsigned int min,datecode_t newdate,unsigned int newhr,unsigned int newmin,char graphby)320 void cro_busyprintf(FILE *outf, Outchoices *od, choice rep, char *datefmt,
321 unsigned long reqs, unsigned long pages, double bys,
322 datecode_t date, unsigned int hr, unsigned int min,
323 datecode_t newdate, unsigned int newhr,
324 unsigned int newmin, char graphby) {
325 extern char repcodes[];
326
327 char *compsep = od->compsep;
328
329 putc(repcodes[rep], outf);
330 if (TOLOWER(graphby) == 'r')
331 fprintf(outf, "%s*BT%sR%s%lu", compsep, compsep, compsep, reqs);
332 else if (TOLOWER(graphby) == 'p')
333 fprintf(outf, "%s*BT%sP%s%lu", compsep, compsep, compsep, pages);
334 else /* TOLOWER(graphby) == 'b' */
335 fprintf(outf, "%.0f", bys);
336 fprintf(outf, "%s%s\n", compsep,
337 datesprintf(od, datefmt, date, hr, min, newdate, newhr, newmin,
338 TRUE, UNSET));
339 }
340
341 /* End of "Not listed" line. */
cro_notlistedstr(FILE * outf,Outchoices * od,choice rep,unsigned long badn)342 void cro_notlistedstr(FILE *outf, Outchoices *od, choice rep,
343 unsigned long badn) {
344 extern unsigned int *rep2lng;
345
346 char **lngstr = od->lngstr;
347 char gender = lngstr[rep2lng[rep] + 3][0];
348
349 char *notlistedstr;
350
351 if (gender == 'm')
352 notlistedstr = lngstr[notlistedm_];
353 else if (gender == 'f')
354 notlistedstr = lngstr[notlistedf_];
355 else
356 notlistedstr = lngstr[notlistedn_];
357
358 fprintf(outf, "[%s: %lu]", notlistedstr, badn);
359 }
360
361 /* The line declaring the floor and sort for a report */
cro_whatincluded(FILE * outf,Outchoices * od,choice rep,unsigned long n,Dateman * dman)362 void cro_whatincluded(FILE *outf, Outchoices *od, choice rep,
363 unsigned long n, Dateman *dman) {
364 extern char repcodes[];
365
366 choice sortby = od->sortby[G(rep)];
367 double floormin = od->floor[G(rep)].min;
368 char floorqual = od->floor[G(rep)].qual;
369 choice floorby = od->floor[G(rep)].floorby;
370
371 timecode_t tempd;
372
373 fprintf(outf, "%c%s*f%s", repcodes[rep], od->compsep, od->compsep);
374 if (floormin < 0)
375 fprintf(outf, "-%lu", (unsigned long)(-floormin + EPSILON));
376 else if (floorby == DATESORT || floorby == FIRSTDATE) {
377 tempd = (timecode_t)(floormin + EPSILON);
378 fputs(timesprintf(od, "%Y%M%D:%H%n", tempd, UNSET), outf);
379 }
380 else if (floorqual == '\0')
381 fprintf(outf, "%lu", (unsigned long)(floormin + EPSILON));
382 else
383 fprintf(outf, "%f", floormin);
384 if (floorqual != '\0')
385 putc(floorqual, outf);
386 if (floorby == REQUESTS)
387 putc('R', outf);
388 else if (floorby == REQUESTS7)
389 putc('S', outf);
390 else if (floorby == PAGES)
391 putc('P', outf);
392 else if (floorby == PAGES7)
393 putc('Q', outf);
394 else if (floorby == BYTES)
395 putc('B', outf);
396 else if (floorby == BYTES7)
397 putc('C', outf);
398 else if (floorby == DATESORT)
399 putc('D', outf);
400 else /* floorby == FIRSTDATE */
401 putc('E', outf);
402
403 /* now the sortby */
404 if (floormin < 0 && sortby == RANDOM)
405 sortby = floorby;
406 fprintf(outf, "%s", od->compsep);
407 if (sortby == ALPHABETICAL)
408 putc('a', outf);
409 else if (sortby == BYTES)
410 putc('b', outf);
411 else if (sortby == BYTES7)
412 putc('c', outf);
413 else if (sortby == DATESORT)
414 putc('d', outf);
415 else if (sortby == FIRSTDATE)
416 putc('e', outf);
417 else if (sortby == PAGES)
418 putc('p', outf);
419 else if (sortby == PAGES7)
420 putc('q', outf);
421 else if (sortby == REQUESTS)
422 putc('r', outf);
423 else if (sortby == REQUESTS7)
424 putc('s', outf);
425 else /* sortby == RANDOM */
426 putc('x', outf);
427 putc('\n', outf);
428 }
429
430 /* Include a header file or footer file */
cro_includefile(FILE * outf,Outchoices * od,char * name,char type)431 void cro_includefile(FILE *outf, Outchoices *od, char *name, char type) {
432 FILE *inf;
433 char buffer[BLOCKSIZE];
434 size_t n;
435
436 if ((inf = my_fopen(name, (type == 'h')?"header file":"footer file")) !=
437 NULL) {
438 while ((n = fread(buffer, 1, BLOCKSIZE, inf))) /* single equals */
439 fwrite((void *)buffer, 1, n, outf);
440 (void)my_fclose(inf, name, (type == 'h')?"header file":"footer file");
441 }
442 }
443
444 /* Filetype for RISC OS */
cro_riscosfiletype(void)445 unsigned int cro_riscosfiletype(void) {
446 return 0xfff;
447 }
448