/*** analog 4.13 http://www.analog.cx/ ***/ /*** This program is copyright (c) Stephen R. E. Turner 1995 - 2000 except as *** stated otherwise. Distribution, usage and modification of this program is *** subject to the conditions of the Licence which you should have received *** with it. This program comes with no warranty, expressed or implied. ***/ /*** output2.c; subsiduary output functions ***/ #include "anlghea3.h" extern unsigned int *rep2lng; void pagetop(FILE *outf, Outchoices *od, Dateman *dman) { extern timecode_t starttimec; char *datestr; double t0; int t1, t2; if (od->cgi) { if (od->outstyle == HTML) fprintf(outf, "Content-Type: text/html; charset=%s\n\n", od->lngstr[charset_]); else fprintf(outf, "Content-Type: text/plain\n\n"); } if (od->outstyle == HTML) { fputs("\n", outf); fputs("\n \n", outf); fprintf(outf, "\n", od->lngstr[charset_]); if (od->norobots) fputs("\n", outf); fprintf(outf, "\n", VERSION); fprintf(outf, "%s ", od->lngstr[webstatsfor_]); htmlfprintf(outf, od->outstyle, od->multibyte, od->hostname, &(od->html), TRUE); fputs(" \n", outf); if (!strcaseeq(od->stylesheet, "none")) { fputs("outstyle, FALSE, od->stylesheet, &(od->html), FALSE); fputs("\" rel=\"stylesheet\">\n", outf); } fputs("\n", outf); fputs("\n

", outf); if (!strcaseeq(od->logo, "none")) { fputs("logo[0] != '/' && strstr(od->logo, "://") == NULL) htmlfprintf(outf, od->outstyle, FALSE, od->imagedir, &(od->html), FALSE); htmlfprintf(outf, od->outstyle, FALSE, od->logo, &(od->html), FALSE); fputs("\" alt=\"\"> ", outf); } if (strcaseeq(od->hosturl, "none")) { fprintf(outf, "%s ", od->lngstr[webstatsfor_]); htmlfprintf(outf, od->outstyle, od->multibyte, od->hostname, &(od->html), TRUE); } else { fprintf(outf, "%s lngstr[webstatsfor_]); htmlfprintf(outf, od->outstyle, FALSE, od->hosturl, &(od->html), FALSE); fputs("\">", outf); htmlfprintf(outf, od->outstyle, od->multibyte, od->hostname, &(od->html), TRUE); fputs("", outf); } fputs("

\n\n", outf); } else if (od->outstyle == ASCII) { fprintf(outf, "%s %s\n", od->lngstr[webstatsfor_], od->hostname); matchlength(outf, od->outstyle, od->hostname, '='); matchlength(outf, od->outstyle, od->lngstr[webstatsfor_], '='); fputs("=\n\n", outf); } if (!strcaseeq(od->headerfile, "none")) include_file(outf, od->outstyle, od->headerfile, 'h', od->pagewidth, &(od->html)); if (od->outstyle == COMPUTER) { fprintf(outf, "x%sVE%sanalog %s\n", od->compsep, od->compsep, VNUMBER); fprintf(outf, "x%sHN%s%s\n", od->compsep, od->compsep, od->hostname); if (!strcaseeq(od->hosturl, "none")) fprintf(outf, "x%sHU%s%s\n", od->compsep, od->compsep, od->hosturl); } datestr = (char *)xmalloc((size_t)datefmtlen(od->lngstr[datefmt2_], od->plainmonthlen, od->plaindaylen, od->compsep, (logical)(od->outstyle == COMPUTER)) + 1); if (od->runtime) { if (od->outstyle == COMPUTER) fprintf(outf, "x%sPS%s%s\n", od->compsep, od->compsep, datesprintf(datestr, od->lngstr[datefmt2_], od->outstyle, starttimec / 1440, (starttimec % 1440) / 60, starttimec % 60, 0, 0, NULL, NULL, 0, 0, od->compsep, TRUE)); else fprintf(outf, "%s %s.\n", od->lngstr[progstart_], datesprintf(datestr, od->lngstr[datefmt2_], od->outstyle, starttimec / 1440, (starttimec % 1440) / 60, starttimec % 60, 0, 0, od->monthname, od->dayname, 0, 0, NULL, FALSE)); if (od->outstyle == HTML) fputs("
", outf); } if (dman->firsttime <= dman->lasttime) { if (od->outstyle == COMPUTER) { fprintf(outf, "x%sFR%s%s\n", od->compsep, od->compsep, datesprintf(datestr, od->lngstr[datefmt2_], od->outstyle, dman->firsttime / 1440, (dman->firsttime % 1440) / 60, dman->firsttime % 60, 0, 0, NULL, NULL, 0, 0, od->compsep, TRUE)); fprintf(outf, "x%sLR%s%s\n", od->compsep, od->compsep, datesprintf(datestr, od->lngstr[datefmt2_], od->outstyle, dman->lasttime / 1440, (dman->lasttime % 1440) / 60, dman->lasttime % 60, 0, 0, NULL, NULL, 0, 0, od->compsep, TRUE)); } else { mprintf(outf, od->pagewidth, "%s %s ", od->lngstr[reqstart_], datesprintf(datestr, od->lngstr[datefmt2_], od->outstyle, dman->firsttime / 1440, (dman->firsttime % 1440) / 60, dman->firsttime % 60, 0, 0, od->monthname, od->dayname, 0, 0, NULL, FALSE)); mprintf(outf, od->pagewidth, "%s %s", od->lngstr[to_], datesprintf(datestr, od->lngstr[datefmt2_], od->outstyle, dman->lasttime / 1440, (dman->lasttime % 1440) / 60, dman->lasttime % 60, 0, 0, od->monthname, od->dayname, 0, 0, NULL, FALSE)); t0 = (dman->lasttime - dman->firsttime) / 1440.0 + 0.005; t1 = (int)t0; t2 = (int)(100 * (t0 - (double)t1)); mprintf(outf, od->pagewidth, " (%d%c%02d %s).", t1, od->decpt, t2, od->lngstr[days_]); mprintf(outf, 0, NULL); } } if (od->outstyle == HTML && od->gotos == FEW) gotos(outf, INT_MAX, od->repq, od->lngstr, od->reporder); hrule(outf, od->outstyle, od->pagewidth); } void pagebot(FILE *outf, Outchoices *od) { extern time_t origstarttime; time_t stoptime; long secs; if (od->outstyle == HTML) fprintf(outf, "%s analog %s.\n", od->lngstr[credit_], ANALOGURL, VNUMBER); else if (od->outstyle == ASCII) fprintf(outf, "%s analog %s.\n", od->lngstr[credit_], VNUMBER); if (od->runtime && (od->outstyle == HTML || od->outstyle == ASCII)) { if (od->outstyle == HTML) fprintf(outf, "
%s: ", od->lngstr[runtime_]); else fprintf(outf, "%s: ", od->lngstr[runtime_]); time(&stoptime); secs = (long)difftime(time((time_t *)NULL), origstarttime); if (secs == 0) fprintf(outf, "%s %s.\n", od->lngstr[lessone_], od->lngstr[second_]); else if (secs < 60) fprintf(outf, "%ld %s.\n", secs, (secs == 1)?(od->lngstr[second_]):(od->lngstr[seconds_])); else fprintf(outf, "%ld %s, %ld %s.\n", secs / 60, (secs < 120)?(od->lngstr[minute_]):(od->lngstr[minutes_]), secs % 60, (secs % 60 == 1)?(od->lngstr[second_]):(od->lngstr[seconds_])); } if (od->outstyle == HTML) { fputs("
\n", outf); if (od->gotos != FALSE) gotos(outf, INT_MAX, od->repq, od->lngstr, od->reporder); } if (!strcaseeq(od->footerfile, "none")) include_file(outf, od->outstyle, od->footerfile, 'f', od->pagewidth, &(od->html)); if (od->outstyle == HTML && od->html) { fputs("

\n", outf); fputs("outstyle, FALSE, od->imagedir, &(od->html), FALSE); fputs("html2.gif\"\n", outf); fputs("alt=\"HTML 2.0 Conformant!\">\n", outf); } if (od->outstyle == HTML) fputs("\n\n", outf); } /* Print "goto"s. Assume outstyle == HTML and want-gotos already tested. */ void gotos(FILE *outf, int code, logical *repq, char **lngstr, choice *reporder) { extern char *anchorname[]; int i; fprintf(outf, "

(%s", lngstr[goto_]); fprintf(outf, ": %s", lngstr[top_]); for (i = 0; reporder[i] != -1; i++) { if (reporder[i] == code) fprintf(outf, "%s %s", lngstr[colon_], lngstr[rep2lng[reporder[i]]]); else if (repq[reporder[i]]) fprintf(outf, "%s %s", lngstr[colon_], anchorname[reporder[i]], lngstr[rep2lng[reporder[i]]]); } fputs(")\n", outf); } void report_title(FILE *outf, char *name, int code, choice gotoq, logical *repq, char **lngstr, choice *reporder, choice outstyle) { extern char *anchorname[]; if (outstyle == HTML) { fprintf(outf, "

%s

\n", anchorname[code], name); if (gotoq == TRUE) gotos(outf, code, repq, lngstr, reporder); } else if (outstyle == ASCII) { fprintf(outf, "%s\n", name); matchlength(outf, outstyle, name, '-'); fputc('\n', outf); } } size_t htmlstrlen(char *s, choice outstyle) { /* Assume string contains no &'s except as markup */ /* NB This may not work well for multibyte character sets? */ logical f; size_t i; if (outstyle != HTML) return(strlen(s)); for (f = TRUE, i = 0; *s != '\0'; s++) { if (*s == '&') f = FALSE; else if (*s == ';') f = TRUE; if (f) i++; } return(i); } void matchlength(FILE *outf, choice outstyle, char *s, char c) { size_t i; for (i = htmlstrlen(s, outstyle); i > 0; i--) myputc(outf, c, outstyle); } void myputc(FILE *outf, char c, choice outstyle) { if (outstyle != HTML) putc(c, outf); else if (c == '<') fputs("<", outf); else if (c == '>') fputs(">", outf); else if (c == '&') fputs("&", outf); else if (c == '"') fputs(""", outf); else putc(c, outf); } /* quicker than using myputc() */ void htmlfprintf(FILE *outf, choice outstyle, logical multibyte, char *s, logical *html, logical userinput) { char w1[64]; char *c; char *w = w1; int len = 0; if (outstyle != HTML || multibyte) fputs(s, outf); else { for (c = s; *c != '\0'; c++) { if (*c == '<') { PUTs(w, "<", 0); len += 4; } else if (*c == '>') { PUTs(w, ">", 0); len += 4; } else if (*c == '&') { PUTs(w, "&", 0); len += 5; } else if (*c == '"') { PUTs(w, """, 0); len += 6; } else if (userinput && *c == '\\' && *(c + 1) != '\0') { *html = FALSE; PUTc(w, *(++c)); len += 1; } else { PUTc(w, *c); len += 1; } if (len > 57) { *w = '\0'; fputs(w1, outf); w = w1; len = 0; } } } *w = '\0'; fputs(w1, outf); } void escfprintf(FILE *outf, char *name) { /* Escape names for use in hyperlinks. As with htmlfprintf(), don't try and print character by character. Assume outstyle == HTML already tested. */ #ifdef EBCDIC extern unsigned char os_toascii_strictly[]; #endif char w1[64]; char *w = w1; int len = 0; for ( ; *name != '\0'; name++) { if (ISALNUM(*name) || *name == '/' || *name == '.' || *name == ':' || *name == '-' || *name == '~' || *name == '_' || *name == '?' || *name == '&' || *name == '%' || *name == '=' || *name == '+' || *name == ';' || *name == '@' || *name == '$' || *name == ',') { /* All reserved and some unreserved chars from RFC 2396 Sec 2. */ /* Reserved chars are not escaped because if they are in the logfile they must have their special meanings (path delimiters etc.), and escaping them would change the semantics of the URL. */ PUTc(w, *name); len += 1; } else { #ifdef EBCDIC sprintf(w, "%%%.2X", os_toascii_strictly[*name]); #else sprintf(w, "%%%.2X", (unsigned char)(*name)); #endif w += 3; len += 3; } if (len > 60) { *w = '\0'; fputs(w1, outf); w = w1; len = 0; } } *w = '\0'; fputs(w1, outf); } void hrule(FILE *outf, choice outstyle, unsigned int pagewidth) { unsigned int i; if (outstyle == HTML) fputs("
\n", outf); else if (outstyle == ASCII) { for (i = 0; i < pagewidth; i++) putc('-', outf); fputs("\n\n", outf); } } void include_file(FILE *outf, choice outstyle, char *name, char type, unsigned int pagewidth, logical *html) { extern char *block_start, *block_end; FILE *inf; if ((inf = my_fopen(name, (type == 'h')?"header file":"footer file")) != NULL) { *html = FALSE; if (type == 'f' || outstyle == HTML) hrule(outf, outstyle, pagewidth); while (getmoredata(inf, block_start, BLOCKSIZE) != EOF) fwrite((void *)block_start, 1, (size_t)((char *)block_end - (char *)block_start), outf); if (type == 'h') hrule(outf, outstyle, pagewidth); (void)my_fclose(inf, name, (type == 'h')?"header file":"footer file"); } } /*** Date printing routine ***/ unsigned int datefmtlen(char *fmt, unsigned int monthlen, unsigned int daylen, char *compsep, logical allowmonth) { /* Assume no HTML accents in fmt. */ unsigned int i = 0; char *c; for (c = fmt; *c != '\0'; c++) { if (*c == '%' && *(c + 1) != '\0') { c++; if (*c == '%') i += 1; else if (*c == 'd' || *c == 'D' || *c == 'y' || *c == 'h' || *c == 'H' || *c == 'i' || *c == 'I' || *c == 'n' || *c == 'o') i += 2; else if (*c == 'Y') i += 4; else if (*c == 'm') i += monthlen; else if (*c == 'w') i += daylen; else if (*c == '\b') i += (compsep == NULL)?0:strlen(compsep); else if (*c == 'M' && allowmonth) i += 2; } else i += 1; } return(i); } char *datesprintf(char *ans, char *fmt, choice outstyle, datecode_t date, unsigned int hr, unsigned int min, unsigned int newhr, unsigned int newmin, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, char *compsep, logical allowmonth) { /* Puts date into ans. Calling fn. must ensure enough space in ans. */ /* monthlen & daylen should be set to 0 in running (not formatted) text. */ /* outstyle == OUT_NONE is used when a non-output function calls this one. */ unsigned int d, m, y, i; char *s, *c; s = ans; if (date == 0) { if (outstyle == COMPUTER && compsep != NULL) { for (i = chrn(fmt, '\b'); i > 0; i--) PUTs(s, compsep, 0); } *s = '\0'; return(ans); } code2date(date, &d, &m, &y); for (c = fmt; *c != '\0'; c++) { if (*c == '%' && *(c + 1) != '\0') { c++; switch (*c) { case '%': PUTc(s, '%'); break; case 'd': PUT2d(s, d); break; case 'D': PUT02d(s, d); break; case 'm': if (monthname != NULL) PUTs(s, monthname[m], /* assume contains no &'s in not HTML */ (int)monthlen - (int)htmlstrlen(monthname[m], HTML)); break; case 'M': if (allowmonth) PUT02d(s, m + 1); break; case '\b': /* \b only used internally */ if (compsep != NULL) PUTs(s, compsep, 0); break; case 'y': PUT02d(s, y % 100); break; case 'Y': PUT04d(s, y); break; case 'h': PUT2d(s, hr); break; case 'H': PUT02d(s, hr); break; case 'i': PUT2d(s, newhr); break; case 'I': PUT02d(s, newhr); break; case 'n': PUT02d(s, min); break; case 'o': PUT02d(s, newmin); break; case 'w': if (dayname != NULL) PUTs(s, dayname[DAYOFWEEK(date)], (int)daylen - (int)htmlstrlen(dayname[DAYOFWEEK(date)], HTML)); break; } } else PUTc(s, *c); } *s = '\0'; return(ans); } int f3printf(FILE *outf, choice outstyle, double x, unsigned int width, char sepchar) { /* return number of characters printed, but counting e.g. & as one */ int ans, i; x += EPSILON; /* just to make sure rounding down works OK */ if (sepchar == '\0') return(fprintf(outf, "%*.0f", width, x)); for (i = 0; x >= 1000; i++) x /= 1000; /* find out how big x is to get number of leading spaces */ ans = fprintf(outf, "%*d", MAX((int)width - 4 * i, 0), (int)x); ans += 4 * i; /* now run down again, printing each clump */ for ( ; i > 0; i--) { myputc(outf, sepchar, outstyle); x -= (int)x; x *= 1000; fprintf(outf, "%03d", (int)x); } return(ans); } void printbytes(FILE *outf, choice outstyle, double bytes, unsigned int bmult, unsigned int width, char sepchar, char decpt) { int by1, by2; unsigned int j; if (bmult == 0) (void)f3printf(outf, outstyle, bytes, width, sepchar); else { for (j = 0; j < bmult; j++) bytes /= 1024; by1 = (int)bytes; by2 = (int)(1000 * (bytes - (double)by1)); width = MAX(width, 3); fprintf(outf, "%*d", width - 4, by1); myputc(outf, decpt, outstyle); fprintf(outf, "%03d", by2); } } void doublemprintf(FILE *outf, choice outstyle, unsigned int pagewidth, double x, char decpt) { unsigned int prec; double d; /* first calculate how many decimal places we need */ for (prec = 0, d = x - (double)((int)(x)); d - (double)((int)(d + 0.000005)) > 0.00001; d *= 10) prec++; /* now print it */ if (pagewidth == 0 || outstyle == HTML) { /* just fprintf not mprintf */ if (prec > 0) { fprintf(outf, "%d", (int)x); myputc(outf, decpt, outstyle); fprintf(outf, "%0*d", prec, (int)(d + EPSILON)); } else fprintf(outf, "%d", (int)(x + EPSILON)); } else if (prec > 0) mprintf(outf, pagewidth, "%d%c%0*d", (int)x, decpt, prec, (int)(d + EPSILON)); else mprintf(outf, pagewidth, "%d", (int)(x + EPSILON)); } double findunit(double n, unsigned int pagewidth, unsigned int width[], unsigned int mingraphwidth, choice *cols) { int w; double unit; int c; int i, j; w = (int)pagewidth - (int)width[COL_TITLE] - 2; for (c = 0; cols[c] != COL_NUMBER; c++) w -= (int)width[cols[c]] + 2; w = MAX(w, (int)mingraphwidth); /* unit must be nice amount: i.e., {1, 1.5, 2, 2.5, 3, 4, 5, 6, 8} * 10^n */ unit = ((n - 1) / (double)w); j = 0; while (unit > 24.) { unit /= 10.; j++; } unit = (double)((int)unit); if (unit == 6.) unit = 7.; else if (unit == 8.) unit = 9.; else if (unit >= 20.) unit = 24.; else if (unit >= 15.) unit = 19.; else if (unit >= 10.) unit = 14.; unit += 1.; for (i = 0; i < j; i++) { unit *= 10.; } return(unit); } void calcsizes(choice outstyle, unsigned int width[], unsigned int *bmult, double *unit, unsigned long maxr, unsigned long maxp, double maxb, unsigned long howmany, unsigned int pagewidth, unsigned int mingraphwidth, char graphby, char repsepchar, logical rawbytes, choice *cols, unsigned int monthlen, unsigned int daylen, char **lngstr) { /* width[COL_TITLE] should be set before calling this function */ extern unsigned int *col2colhead; int w; unsigned int i; if (outstyle == COMPUTER) { width[COL_REQS] = 0; width[COL_PAGES] = 0; width[COL_BYTES] = 0; width[COL_PREQS] = 0; width[COL_PPAGES] = 0; width[COL_PBYTES] = 0; width[COL_DATE] = 0; width[COL_TIME] = 0; width[COL_INDEX] = 0; width[COL_TITLE] = 0; *bmult = 0; } else { width[COL_REQS] = MAX(LEN3(log10i(maxr) + 1, repsepchar), htmlstrlen(lngstr[col2colhead[COL_REQS]], outstyle)); width[COL_PAGES] = MAX(LEN3(log10i(maxp) + 1, repsepchar), htmlstrlen(lngstr[col2colhead[COL_PAGES]], outstyle)); if (rawbytes || maxb < 1024.0) { width[COL_BYTES] = MAX(LEN3(log10x(maxb) + 1, repsepchar), htmlstrlen(lngstr[col2colhead[COL_BYTES]], outstyle)); *bmult = 0; } else { width[COL_BYTES] = MAX(7, htmlstrlen(lngstr[col2colhead[COL_BYTES]], outstyle) + 1); *bmult = findbmult(maxb); /* +1 for k, M etc. prefix */ } width[COL_PREQS] = MAX(6, htmlstrlen(lngstr[col2colhead[COL_PREQS]], outstyle)); width[COL_PPAGES] = MAX(6, htmlstrlen(lngstr[col2colhead[COL_PPAGES]], outstyle)); width[COL_PBYTES] = MAX(6, htmlstrlen(lngstr[col2colhead[COL_PBYTES]], outstyle)); width[COL_DATE] = MAX(datefmtlen(lngstr[genrepdate_], monthlen, daylen, NULL, FALSE), htmlstrlen(lngstr[col2colhead[COL_DATE]], outstyle)); width[COL_TIME] = MAX(datefmtlen(lngstr[genreptime_], monthlen, daylen, NULL, FALSE), htmlstrlen(lngstr[col2colhead[COL_TIME]], outstyle)); width[COL_INDEX] = MAX(LEN3(log10i(howmany) + 1, repsepchar), htmlstrlen(lngstr[col2colhead[COL_INDEX]], outstyle)); if (*unit == 0) { /* unit != 0 is used as a marker for not a timegraph */ if (graphby == 'R' || graphby == 'r') *unit = findunit((double)maxr, pagewidth, width, mingraphwidth, cols); else if (graphby == 'P' || graphby == 'p') *unit = findunit((double)maxp, pagewidth, width, mingraphwidth, cols); else { for (i = 0; i < *bmult; i++) maxb /= 1024; if (*bmult > 0) maxb *= 1000; *unit = findunit(maxb, pagewidth, width, mingraphwidth, cols); if (*bmult > 0) *unit /= 1000; } } if (width[COL_TITLE] == 0) { w = (int)pagewidth; for (i = 0; cols[i] != COL_NUMBER; i++) w -= (int)width[cols[i]] + 2; width[COL_TITLE] = (unsigned int)MAX(0, w); } } } unsigned int alphatreewidth(Hashtable *tree, choice outstyle) { Hashindex *p; /* width needed for Organisation Report */ unsigned int tw = 0, tmp1, tmp2; if (tree == NULL) return(0); for (p = tree->head[0]; p != NULL; TO_NEXT(p)) { tmp1 = htmlstrlen(p->name, outstyle); tmp2 = alphatreewidth((Hashtable *)(p->other), outstyle); if (tmp2 > 0) /* there are some children... */ tmp1 += tmp2 + 3; /* self name + longest child name + 1 delimiting '.' + 2 trailing spaces */ tw = MAX(tw, tmp1); } return(tw); } void declareunit(FILE *outf, choice outstyle, unsigned int pagewidth, char graphby, double unit, unsigned int bmult, char barstyle, char markchar, char sepchar, char decpt, char *imagedir, char **lngstr) { /* NB Number, or string kbytes, can still overflow PAGEWIDTH, but only if PAGEWIDTH is small, and will wrap straight after. PAGEWIDTH is never guaranteed anyway. */ extern char byteprefix[]; extern unsigned int ppcol; if (outstyle == HTML || outstyle == ASCII) { if (outstyle == HTML) fputs("

\n", outf); mprintf(outf, pagewidth, "%s (", lngstr[eachunit_]); if (ISLOWER(graphby) || outstyle != HTML) mprintf(outf, pagewidth, "%c", markchar); else mprintf(outf, pagewidth, "", imagedir, barstyle, markchar); mprintf(outf, pagewidth, ") %s ", lngstr[represents_]); if (graphby == 'R' || graphby == 'r') { ppcol += f3printf(outf, outstyle, unit, 0, sepchar); mprintf(outf, pagewidth, " "); if (unit == 1.) mprintf(outf, pagewidth, "%s.", lngstr[request_]); else mprintf(outf, pagewidth, "%s %s.", lngstr[requests_], lngstr[partof_]); } else if (graphby == 'P' || graphby == 'p') { ppcol += f3printf(outf, outstyle, unit, 0, sepchar); mprintf(outf, pagewidth, " "); if (unit == 1.) mprintf(outf, pagewidth, "%s.", lngstr[pagereq_]); else mprintf(outf, pagewidth, "%s %s.", lngstr[pagereqs_], lngstr[partof_]); } else { if (bmult > 0) { doublemprintf(outf, outstyle, pagewidth, unit, decpt); mprintf(outf, pagewidth, " "); mprintf(outf, pagewidth, "%c", byteprefix[bmult]); } else { ppcol += f3printf(outf, outstyle, unit, 0, sepchar); mprintf(outf, pagewidth, " "); } mprintf(outf, pagewidth, "%s %s.", lngstr[bytes_], lngstr[partof_]); } mprintf(outf, 0, NULL); } } void whatincluded(FILE *outf, choice rep, choice outstyle, unsigned long n, unsigned int pagewidth, Floor *floor, choice sortby, char decpt, char *compsep, char *gens, char *genp, char gender, choice requests, choice date, timecode_t firsttime, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, char **lngstr) { extern unsigned int *method2sing, *method2pl, *method2date, *method2pc; extern unsigned int *method2relpc, *method2sort; extern char repcodes[]; int firsts, firstds, alls, sorted, alphsort, unsort; char *datestr; unsigned long temp = 0; timecode_t tempd; if (outstyle == HTML || outstyle == ASCII) { if (gender == 'm') { firsts = firstsm_; firstds = firstdsm_; alls = allsm_; sorted = sortedm_; alphsort = STREQ(gens, lngstr[codegs_])?numsortm_:alphasortm_; unsort = unsortedm_; /* quickest kludge for only one report */ } else if (gender == 'f') { firsts = firstsf_; firstds = firstdsf_; alls = allsf_; sorted = sortedf_; alphsort = STREQ(gens, lngstr[codegs_])?numsortf_:alphasortf_; unsort = unsortedf_; } else { /* gender == 'n' */ firsts = firstsn_; firstds = firstdsn_; alls = allsn_; sorted = sortedn_; alphsort = STREQ(gens, lngstr[codegs_])?numsortn_:alphasortn_; unsort = unsortedn_; } /* see also report_floor() in settings.c */ if (outstyle == HTML) fputs("

\n", outf); if (floor->min < 0 && n < (unsigned long)(-floor->min + EPSILON)) floor->min = 0; /* not enough items for requested -ve floor */ if (floor->min < 0) { temp = (unsigned long)(-floor->min + EPSILON); if (temp == 1) mprintf(outf, pagewidth, lngstr[firsts], gens); else mprintf(outf, pagewidth, lngstr[firstds], temp, genp); mprintf(outf, pagewidth, " %s ", lngstr[floorby_]); if (floor->floorby == REQUESTS) mprintf(outf, pagewidth, lngstr[method2sort[requests]]); else if (floor->floorby == DATESORT) mprintf(outf, pagewidth, lngstr[method2sort[date]]); else mprintf(outf, pagewidth, lngstr[method2sort[floor->floorby]]); } else { /* floor->min >= 0 */ mprintf(outf, pagewidth, lngstr[alls], genp); if (floor->floorby == DATESORT) { tempd = (timecode_t)(floor->min + EPSILON); if (tempd > firsttime) { mprintf(outf, pagewidth, " %s ", lngstr[method2date[date]]); datestr = (char *)xmalloc((size_t)datefmtlen(lngstr[whatincfmt_], monthlen, daylen, NULL, FALSE) + 1); mprintf(outf, pagewidth, datesprintf(datestr, lngstr[whatincfmt_], outstyle, tempd / 1440, (tempd % 1440) / 60, tempd % 60, 0, 0, monthname, dayname, 0, 0, NULL, FALSE)); free((void *)datestr); } } else if (floor->min > EPSILON) { mprintf(outf, pagewidth, " %s ", lngstr[atleast_]); if (floor->qual == '\0') { temp = (unsigned long)(floor->min + EPSILON); mprintf(outf, pagewidth, "%lu ", temp); if (floor->floorby == REQUESTS) mprintf(outf, pagewidth, (temp == 1)?lngstr[method2sing[requests]]: lngstr[method2pl[requests]]); else mprintf(outf, pagewidth, (temp == 1)? lngstr[method2sing[floor->floorby]]: lngstr[method2pl[floor->floorby]]); } else { /* floor->qual != '\0' */ doublemprintf(outf, outstyle, pagewidth, floor->min, decpt); if (floor->qual == '%') { if (floor->floorby == REQUESTS) mprintf(outf, pagewidth, lngstr[method2pc[requests]]); else mprintf(outf, pagewidth, lngstr[method2pc[floor->floorby]]); } else if (floor->qual == ':') { if (floor->floorby == REQUESTS) mprintf(outf, pagewidth, lngstr[method2relpc[requests]]); else mprintf(outf, pagewidth, lngstr[method2relpc[floor->floorby]]); } else { /* if qual is anything else, must be (k|M|G|T)bytes */ mprintf(outf, pagewidth, " "); mprintf(outf, pagewidth, "%c%s", floor->qual, lngstr[bytes_]); } } /* end floor->qual != '\0' */ } /* end floor->min > EPSILON */ } /* end floor->min > 0 */ /* That completes the floor; now we are just left with the sortby */ if (floor->min >= 0 || temp != 1) { /* else only one item, so no sort */ if (floor->min < 0 && sortby == RANDOM) sortby = floor->floorby; mprintf(outf, pagewidth, ", "); if (sortby == ALPHABETICAL) mprintf(outf, pagewidth, lngstr[alphsort]); else if (sortby == RANDOM) mprintf(outf, pagewidth, lngstr[unsort]); else { mprintf(outf, pagewidth, lngstr[sorted]); mprintf(outf, pagewidth, " "); if (sortby == REQUESTS) mprintf(outf, pagewidth, lngstr[method2sort[requests]]); else if (sortby == DATESORT) mprintf(outf, pagewidth, lngstr[method2sort[date]]); else mprintf(outf, pagewidth, lngstr[method2sort[sortby]]); } } mprintf(outf, pagewidth, "."); mprintf(outf, 0, NULL); } else { /* outstyle == COMPUTER */ fprintf(outf, "%c%sf%s", repcodes[rep], compsep, compsep); if (floor->min < 0) fprintf(outf, "-%lu", (unsigned long)(-floor->min + EPSILON)); else if (floor->floorby == DATESORT) { datestr = (char *)xmalloc((size_t)datefmtlen("%Y%M%D:%H%n", monthlen, daylen, NULL, TRUE) + 1); tempd = (timecode_t)(floor->min + EPSILON); fputs(datesprintf(datestr, "%Y%M%D:%H%n", outstyle, tempd / 1440, (tempd % 1440) / 60, tempd % 60, 0, 0, monthname, dayname, 0, 0, NULL, TRUE), outf); free((void *)datestr); } else if (floor->qual == '\0') fprintf(outf, "%lu", (unsigned long)(floor->min + EPSILON)); else fprintf(outf, "%f", floor->min); if (floor->qual != '\0') putc(floor->qual, outf); if (floor->floorby == REQUESTS) putc('R', outf); else if (floor->floorby == PAGES) putc('P', outf); else if (floor->floorby == BYTES) putc('B', outf); else /* floor->floorby == DATESORT */ putc('D', outf); /* now the sortby */ if (floor->min < 0 && sortby == RANDOM) sortby = floor->floorby; fprintf(outf, "%s", compsep); if (sortby == ALPHABETICAL) putc('a', outf); else if (sortby == BYTES) putc('b', outf); else if (sortby == DATESORT) putc('d', outf); else if (sortby == PAGES) putc('p', outf); else if (sortby == REQUESTS) putc('r', outf); else if (sortby == RANDOM) putc('x', outf); putc('\n', outf); } } void busyprintf(FILE *outf, choice outstyle, char *datefmt, unsigned long reqs, unsigned long pages, double bys, datecode_t date, unsigned int hr, unsigned int min, unsigned int newhr, unsigned int newmin, char graphby, char sepchar, char decpt, logical rawbytes, char **lngstr, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, char *busystr) { extern char byteprefix[]; char *datestr; unsigned int bmult; if (outstyle == ASCII || outstyle == HTML) { if (outstyle == ASCII) putc('\n', outf); datestr = (char *)xmalloc((size_t)datefmtlen(datefmt, monthlen, daylen, NULL, FALSE) + 1); fprintf(outf, "%s %s (", busystr, datesprintf(datestr, datefmt, outstyle, date, hr, min, (newmin == 0)?(hr + 1):hr, (unsigned int)newmin, monthname, dayname, 0, 0, NULL, FALSE)); free((void *)datestr); if (graphby == 'R' || graphby == 'r') { f3printf(outf, outstyle, (double)reqs, 0, sepchar); fprintf(outf, " %s).\n", (reqs == 1)?lngstr[request_]:lngstr[requests_]); } else if (graphby == 'P' || graphby == 'p') { f3printf(outf, outstyle, (double)pages, 0, sepchar); fprintf(outf, " %s).\n", (pages == 1)?lngstr[pagereq_]:lngstr[pagereqs_]); } else /* graphby == 'B' or 'b' */ { if (rawbytes) bmult = 0; else bmult = findbmult(bys); printbytes(outf, outstyle, bys, bmult, 0, sepchar, decpt); putc(' ', outf); if (bmult >= 1) putc(byteprefix[bmult], outf); fprintf(outf, "%s).\n", lngstr[bytes_]); } } } void pccol(FILE *outf, choice outstyle, double n, double tot, unsigned int width, char decpt) { double pc; unsigned int pc1, pc2; int i; if (outstyle == COMPUTER) fprintf(outf, "%.3f", (tot == 0)?0.0:(n * 100.0 / tot)); else { for (i = 0; i < (int)width - 6; i++) putc(' ', outf); if (tot == 0) pc = 0.0; else pc = n * 10000.0 / tot; if (pc >= 9999.5) fputs(" 100%", outf); else if (pc < 0.5) fputs(" ", outf); else { pc1 = ((int)(pc + 0.5)) / 100; pc2 = ((int)(pc + 0.5)) % 100; fprintf(outf, "%2d", pc1); myputc(outf, decpt, outstyle); fprintf(outf, "%02d%%", pc2); } } } void barchart(FILE *outf, choice outstyle, char graphby, unsigned long reqs, unsigned long pages, double bys, double unit, char barstyle, char markchar, char *imagedir) { int i, j; double x; int y; logical first = TRUE; if (graphby == 'P' || graphby == 'p') x = (double)pages - 0.5; else if (graphby == 'R' || graphby == 'r') x = (double)reqs - 0.5; else x = bys; x /= unit; x += 1; y = (int)x; if (ISLOWER(graphby) || outstyle != HTML) { for (i = 0; i < y; i++) myputc(outf, markchar, outstyle); } else { for (j = 32; j >= 1; j /= 2) { while (y >= j) { fprintf(outf, "\"",", outf); y -= j; } } } } void colheads(FILE *outf, choice *cols, choice outstyle, unsigned int width[], unsigned int bmult, char *name, logical name1st, char **lngstr) { extern unsigned int *col2colhead; extern char byteprefix[]; int len; unsigned int c, i; if (outstyle == HTML || outstyle == ASCII) { if (name1st) fprintf(outf, "%*s: ", width[COL_TITLE] + strlen(name) - htmlstrlen(name, outstyle), name); for (c = 0; cols[c] != COL_NUMBER; c++) { if (cols[c] == COL_BYTES) { len = (int)htmlstrlen(lngstr[col2colhead[cols[c]]], outstyle) + (int)(bmult != 0); for (i = width[cols[c]] - len; i > 0; i--) putc(' ', outf); if (bmult != 0) putc(byteprefix[bmult], outf); fprintf(outf, "%s: ", lngstr[col2colhead[cols[c]]]); } else fprintf(outf, "%*s: ", width[cols[c]] + strlen(lngstr[col2colhead[cols[c]]]) - htmlstrlen(lngstr[col2colhead[cols[c]]], outstyle), lngstr[col2colhead[cols[c]]]); } if (!name1st) fputs(name, outf); putc('\n', outf); if (name1st) { for (i = 0; i < width[COL_TITLE]; i++) putc('-', outf); fputs(": ", outf); } for (c = 0; cols[c] != COL_NUMBER; c++) { for (i = width[cols[c]] ; i > 0; i--) putc('-', outf); fputs(": ", outf); } if (!name1st) matchlength(outf, outstyle, name, '-'); fputc('\n', outf); } } void printcols(FILE *outf, choice rep, choice *cols, choice outstyle, logical multibyte, unsigned long reqs, unsigned long pages, double bys, long index, int level, unsigned long totr, unsigned long totp, double totb, unsigned int width[], unsigned int bmult, char graphby, double unit, char barstyle, char markchar, char repsepchar, char decpt, char *compsep, logical name1st, logical timegraph, char *imagedir, logical *html, char *name, logical ispage, unsigned int spaces, Alias *aliashead, Include *linkhead, char *baseurl, char *datefmt, char *timefmt, datecode_t date, unsigned int hr, unsigned int min, unsigned int newhr, unsigned int newmin, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, unsigned int plainmonthlen, unsigned int plaindaylen) { /* NB multibyte only used if name1st == FALSE; so not needed for time reps */ /* 'level' is -1 for time reports, 0 for other non-hierarchical reports (although both are currently ignored). */ extern char *workspace; /* see top of alias.c */ extern char repcodes[]; static char *datestr = NULL; static size_t len = 0, need; int c, i; if (outstyle == COMPUTER) { fprintf(outf, "%c%s", repcodes[rep], compsep); if (level >= 1) putc('l', outf); for (c = 0; cols[c] != COL_NUMBER; c++) { switch(cols[c]) { case COL_REQS: putc('R', outf); break; case COL_PREQS: putc('r', outf); break; case COL_PAGES: putc('P', outf); break; case COL_PPAGES: putc('p', outf); break; case COL_BYTES: putc('B', outf); break; case COL_PBYTES: putc('b', outf); break; case COL_DATE: putc('d', outf); break; case COL_TIME: putc('D', outf); break; case COL_INDEX: putc('N', outf); break; } } fputs(compsep, outf); } else if (name1st) { if (IS_EMPTY_STRING(name)) { need = datefmtlen(datefmt, plainmonthlen, plaindaylen, NULL, FALSE) + 1; ENSURE_LEN(datestr, len, need); name = datesprintf(datestr, datefmt, outstyle, date, hr, min, newhr, newmin, monthname, dayname, monthlen, daylen, NULL, FALSE); } for (i = (int)width[COL_TITLE] - (int)htmlstrlen(name, outstyle); i > 0; i--) putc(' ', outf); fprintf(outf, "%s: ", name); } if (outstyle == COMPUTER && level >= 1) fprintf(outf, "%d%s", level, compsep); for (c = 0; cols[c] != COL_NUMBER; c++) { switch(cols[c]) { case COL_REQS: f3printf(outf, outstyle, (double)reqs, width[cols[c]], repsepchar); break; case COL_PREQS: pccol(outf, outstyle, (double)reqs, (double)totr, width[cols[c]], decpt); break; case COL_PAGES: f3printf(outf, outstyle, (double)pages, width[cols[c]], repsepchar); break; case COL_PPAGES: pccol(outf, outstyle, (double)pages, (double)totp, width[cols[c]], decpt); break; case COL_BYTES: printbytes(outf, outstyle, bys, bmult, width[cols[c]], repsepchar, decpt); break; case COL_PBYTES: pccol(outf, outstyle, bys, totb, width[cols[c]], decpt); break; case COL_DATE: case COL_TIME: need = datefmtlen((cols[c] == COL_DATE)?datefmt:timefmt, plainmonthlen, plaindaylen, compsep, (logical)(outstyle == COMPUTER)) + 1; ENSURE_LEN(datestr, len, need); (void)datesprintf(datestr, (cols[c] == COL_DATE)?datefmt:timefmt, outstyle, date, hr, min, newhr, newmin, monthname, dayname, monthlen, daylen, compsep, (logical)(outstyle == COMPUTER)); for (i = (int)width[cols[c]] - (int)htmlstrlen(datestr, outstyle); i > 0; i--) putc(' ', outf); fprintf(outf, "%s", datestr); break; case COL_INDEX: if (index > 0) f3printf(outf, outstyle, (double)index, width[cols[c]], repsepchar); else for (i = (int)width[cols[c]]; i > 0; i--) putc(' ', outf); break; } if (outstyle == HTML || outstyle == ASCII) fputs(": ", outf); else fputs(compsep, outf); } if (timegraph && (outstyle == HTML || outstyle == ASCII)) { for (i = 0; i < (int)bmult; i++) bys /= 1024; barchart(outf, outstyle, graphby, reqs, pages, bys, unit, barstyle, markchar, imagedir); } else if (!name1st) { if (name == NULL) return; /* calling function supplies name and newline */ if (outstyle != COMPUTER) { if (width[COL_TITLE] == 0) { for (i = 0; i < (int)spaces; i++) putc(' ', outf); } else { for (i = (int)width[COL_TITLE] - (int)htmlstrlen(name, outstyle) - (int)spaces; i > 0; i--) putc(' ', outf); } } strcpy(workspace, name); do_aliasx(workspace, aliashead); if (linkhead != NULL && outstyle == HTML && included(name, ispage, linkhead)) { fputs("", outf); htmlfprintf(outf, outstyle, multibyte, workspace, html, TRUE); fputs("", outf); } else htmlfprintf(outf, outstyle, multibyte, workspace, html, TRUE); } /* The previous htmlfprintf's have userinput = TRUE because of aliases, particularly accents in domains: cf do_aliasr(). Note also that for multibyte charsets, some necessary conversions may not take place. There's not much we can do about this because the source of the name may be a URL etc. which we should convert, but may be a lngstr, OUTPUTALIAS etc. which we shouldn't. We play conservative, not converting entities, and setting html == FALSE (in finalinit(), init.c). */ else if (outstyle == COMPUTER) { if (IS_EMPTY_STRING(name)) { need = datefmtlen(datefmt, plainmonthlen, plaindaylen, compsep, TRUE) + 1; ENSURE_LEN(datestr, len, need); name = datesprintf(datestr, datefmt, outstyle, date, hr, min, newhr, newmin, monthname, dayname, monthlen, daylen, compsep, TRUE); } fprintf(outf, "%s", name); } fputc('\n', outf); } void lastseven(FILE *outf, choice outstyle, timecode_t last7to, char *compsep, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, char **lngstr) { char *datestr; datestr = (char *)xmalloc((size_t)datefmtlen(lngstr[datefmt1_], monthlen, daylen, compsep, (logical)(outstyle == COMPUTER)) + 1); if (outstyle == HTML) fputs("

", outf); if (outstyle == COMPUTER) fprintf(outf, "x%sE7%s%s\n", compsep, compsep, datesprintf(datestr, lngstr[datefmt1_], outstyle, last7to / 1440, (last7to % 1440) / 60, last7to % 60, 0, 0, NULL, NULL, 0, 0, compsep, TRUE)); else fprintf(outf, "(%s %s %s).\n", lngstr[brackets_], lngstr[sevendaysto_], datesprintf(datestr, lngstr[datefmt1_], outstyle, last7to / 1440, (last7to % 1440) / 60, last7to % 60, 0, 0, monthname, dayname, 0, 0, NULL, FALSE)); free((void *)datestr); } /*** Now some stuff for the general summary ***/ void distcount(Hashindex *gooditems, Hashindex *baditems, unsigned long *tot, unsigned long *tot7) { Hashindex *p; for (p = gooditems, *tot = 0, *tot7 = 0; p != NULL; TO_NEXT(p)) { if (p->own != NULL && p->own->data[REQUESTS] > 0) { (*tot)++; *tot7 += (unsigned long)(p->own->last7); } } for (p = baditems; p != NULL; TO_NEXT(p)) { if (p->own != NULL && p->own->data[REQUESTS] > 0) { (*tot)++; *tot7 += (unsigned long)(p->own->last7); } } } void gensumline(FILE *outf, choice outstyle, int namecode, unsigned long x, unsigned long x7, char sepchar, char *compsep, logical p, char **lngstr) { if ((x > 0 || namecode == succreqs_) && x != (unsigned long)UNSET) { if (outstyle == HTML) { if (p) fprintf(outf, "

%s%s ", lngstr[namecode], lngstr[colon_]); else fprintf(outf, "
%s%s ", lngstr[namecode], lngstr[colon_]); } else if (outstyle == ASCII) fprintf(outf, "%s%s ", lngstr[namecode], lngstr[colon_]); else fprintf(outf, "x%s%c%c%s", compsep, lngstr[namecode][0], lngstr[namecode][1], compsep); f3printf(outf, outstyle, (double)x, 0, sepchar); if (x7 != (unsigned long)(-1)) { if (outstyle == COMPUTER) { fprintf(outf, "\nx%s%c%c%s", compsep, lngstr[namecode][2], lngstr[namecode][3], compsep); f3printf(outf, outstyle, (double)x7, 0, sepchar); } else { fputs(" (", outf); f3printf(outf, outstyle, (double)x7, 0, sepchar); putc(')', outf); } } putc('\n', outf); } } void gensumlineb(FILE *outf, choice outstyle, int namecode, double x, double x7, logical rawbytes, char sepchar, char decpt, char *compsep, char **lngstr) { /* same as gensumline() but for bytes */ extern char byteprefix[]; unsigned int j; if (x > 0) { if (outstyle == HTML) fprintf(outf, "
%s%s ", lngstr[namecode], lngstr[colon_]); else if (outstyle == ASCII) fprintf(outf, "%s%s ", lngstr[namecode], lngstr[colon_]); else fprintf(outf, "x%s%c%c%s", compsep, lngstr[namecode][0], lngstr[namecode][1], compsep); j = rawbytes?0:findbmult(x); printbytes(outf, outstyle, x, j, 0, sepchar, decpt); if (outstyle == HTML || outstyle == ASCII) { if (j > 0) fprintf(outf, " %c%s", byteprefix[j], lngstr[bytes_]); else fprintf(outf, " %s", lngstr[bytes_]); } if (x7 != UNSET) { if (outstyle == COMPUTER) { fprintf(outf, "\nx%s%c%c%s", compsep, lngstr[namecode][2], lngstr[namecode][3], compsep); f3printf(outf, outstyle, (double)x7, 0, sepchar); } else { fputs(" (", outf); j = rawbytes?0:findbmult(x7); printbytes(outf, outstyle, x7, j, 0, sepchar, decpt); if (j > 0) fprintf(outf, " %c%s)", byteprefix[j], lngstr[bytes_]); else fprintf(outf, " %s)", lngstr[bytes_]); } } putc('\n', outf); } } logical checkonerep(Hashindex *gp, choice requests) { for ( ; gp != NULL; TO_NEXT(gp)) { if (gp->own != NULL && gp->own->data[requests] > 0) return(TRUE); } return(FALSE); } logical checksearchrep(Hashindex *gp, choice requests, Strpair *list) { /* it's a bit complicated whether the Search Reports have anything in them, so the easiest thing is to let their routines check */ char *name, *nameend; for ( ; gp != NULL; TO_NEXT(gp)) { if (gp->own != NULL && gp->own->data[requests] > 0) { name = NULL; nnextname(&name, &nameend, gp->name, list); if (name != NULL) return(TRUE); } } return(FALSE); } logical checktreerep(Hashtable *tp, choice requests) { unsigned long i; for (i = 0; i < tp->size; i++) { if (checkonerep(tp->head[i], requests)) return(TRUE); } return(FALSE); } logical checkarrayrep(Arraydata *array) { choice i; for (i = 0; ; i++) { if (array[i].reqs > 0) return(TRUE); if (array[i].threshold < -0.5) return(FALSE); } } void checkreps(Outchoices *od, logical *repq, Dateman *dman, choice *alltrees, choice *alldervs, Hashindex **gooditems, Tree **trees, Derv **dervs, Arraydata **arraydata) { extern choice *rep2type, *rep2reqs; extern char *repname[]; int i, j; choice ok; if (dman->currdp == NULL) { for (i = 0; i < DATEREP_NUMBER; i++) { if (repq[i]) { warn('R', TRUE, "Turning off empty time reports"); for ( ; i < DATEREP_NUMBER; i++) repq[i] = FALSE; } } } for (i = FIRST_GENREP; i <= LAST_NORMALREP; i++) { for (ok = 0, j = 0; alltrees[j] != REP_NUMBER; j++) { if (i == alltrees[j]) ok = 1; } for (j = 0; alldervs[j] != REP_NUMBER; j++) { if (i == alldervs[j]) ok = 2; } if (ok == 1) { if (!checktreerep(trees[G(i)]->tree, rep2reqs[G(i)])) { /* alltrees implies repq so don't have to check that */ warn('R', TRUE, "Turning off empty %s", repname[i]); repq[i] = FALSE; } } else if (ok == 2) { if (!checktreerep(dervs[i - FIRST_DERVREP]->table, rep2reqs[G(i)])) { /* again, alldervs implies repq */ warn('R', TRUE, "Turning off empty %s", repname[i]); repq[i] = FALSE; } } else if (i == REP_SEARCHREP || i == REP_SEARCHSUM) { if (repq[i] && !checksearchrep(gooditems[rep2type[i]], rep2reqs[G(i)], *(od->derv[REP_SEARCHSUM - FIRST_DERVREP]->list))) { warn('R', TRUE, "Turning off empty %s", repname[i]); repq[i] = FALSE; } } else if (repq[i] && !checkonerep(gooditems[rep2type[i]], rep2reqs[G(i)])) { warn('R', TRUE, "Turning off empty %s", repname[i]); repq[i] = FALSE; } } for ( ; i < REP_NUMBER; i++) { if (repq[i] && !checkarrayrep(arraydata[i - FIRST_ARRAYREP])) { warn('R', TRUE, "Turning off empty %s", repname[i]); repq[i] = FALSE; } } }