00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #include "cgi.h"
00023 
00024 #include "math.h"
00025 
00026 typedef struct {int count; double sum, sum2; char* field; char* query;} counter;
00027 
00028 void UpdateCounts(CGINameValue* record,counter* counts,int length)
00029 {
00030  size_t j;
00031  for(j=0; j< length; j++)
00032     {
00033         if (counts[j].query == 0 || EvaluateLogic(counts[j].query,record,0))
00034         {
00035             counts[j].count ++;
00036             if (counts[j].field)
00037             {
00038                 double d = strtod(GetFieldValue(record,counts[j].field),0);
00039                 if (d < 10E16 && d > -10E16)
00040                 {
00041                     counts[j].sum += d;
00042                     counts[j].sum2 += d * d;
00043                 }
00044             }
00045         }
00046     }
00047 }
00048 
00049 counter* SetupList(CGINameValue*x,int field, int* length)
00050 {
00051     int i = 0;
00052    counter* list;
00053     while (x[i].name) i++;
00054     if (!i) return 0;
00055     list = malloc(i * sizeof(counter));
00056     for (i=0; x[i].name; i++)
00057     {
00058         if (field)
00059         {
00060             char* c = strchr(x[i].value,',');
00061             if (c) *c++ = 0;
00062             list[i].query = c;
00063             list[i].field = x[i].value;
00064         }
00065         else
00066         {
00067             list[i].field = 0;
00068             list[i].query = x[i].value;
00069         }
00070         list[i].sum = list[i].sum2 = 0;
00071         list[i].count = 0;
00072     }
00073     if (length) *length = i;
00074     return list;
00075 }
00076 
00077 CGINameValue* GetTotal(CGINameValue* count,CGINameValue* sum,
00078     counter* countList,
00079     counter* sumList,
00080     int countLength,
00081     int sumLength)
00082 {
00083     CGINameValue* result = NewNVP(countLength + (sumLength * 6));
00084     int i;
00085     int j=0;
00086     char temp[32];
00087 
00088     if (count && countList)
00089     for (i=0; count[i].name; i++)
00090     {
00091         result[j].name = strdup(count[i].name);
00092         sprintf(temp,"%d",countList[i].count);
00093         result[j++].value = strdup(temp);
00094     }
00095 
00096     if (sum && sumList)
00097     for (i=0; sum[i].name; i++)
00098     {
00099         double Average = 0;
00100         double StdDev = 0;
00101         double StdError = 0;
00102 
00103         result[j].name = strdup(sum[i].name);
00104         sprintf(temp,"%d",sumList[i].sum);
00105         result[j++].value = strdup(temp);
00106 
00107         result[j].name = strdup3(sum[i].name,".sum","");
00108         sprintf(temp,"%f",sumList[i].sum);
00109         result[j++].value = strdup(temp);
00110 
00111         result[j].name = strdup3(sum[i].name,".sum2","");
00112         sprintf(temp,"%f",sumList[i].sum2);
00113         result[j++].value = strdup(temp);
00114 
00115         if (sumList[i].count > 0)
00116         {
00117             Average = sumList[i].sum/sumList[i].count;
00118             StdDev = sqrt((sumList[i].sum2 - Average * sumList[i].sum)/sumList[i].count);
00119             StdError = StdDev/sqrt(sumList[i].count);
00120         }
00121         result[j].name = strdup3(sum[i].name,".average","");
00122         sprintf(temp,"%f",Average);
00123         result[j++].value = strdup(temp);
00124         result[j].name = strdup3(sum[i].name,".stddev","");
00125         sprintf(temp,"%f",StdDev);
00126         result[j++].value = strdup(temp);
00127         result[j].name = strdup3(sum[i].name,".stderr","");
00128         sprintf(temp,"%f",StdError);
00129         result[j++].value = strdup(temp);
00130     }
00131     return result;
00132 }
00133 
00134 int CGImain(char * argv0,CGINameValue* Params,STREAM htmlout)
00135 {
00136     CGINameValue* count = 0;
00137     CGINameValue* sum = 0;
00138     counter* countList=0;
00139     counter* sumList= 0;
00140     char FileName[MAXPATH];
00141     int i, countLength=0, sumLength=0, printSummary = 1;
00142 
00143     if (Params == 0)
00144     {
00145       HTMLWrite(htmlout,"Usage: summary setup_file data_file1 data_file2 ...\n");
00146       HTMLWrite(htmlout,"Usage: summary setup_file load=calc_file report=report_file...\n");
00147       return 1;
00148     }
00149 
00150     ExpandLocalPath(argv0,FileName,Params[0].name,0);
00151     count = ReadINIFileSection(FileName,"COUNT",0);
00152     sum = ReadINIFileSection(FileName,"SUM",0);
00153 
00154     if (count) countList = SetupList(count,0,&countLength);
00155 
00156     if (sum) sumList = SetupList(sum,1,&sumLength);
00157 
00158     for (i=1; Params[i].name; i++)
00159     {
00160         CGINameValue* data;
00161         FILE * db;
00162         int skip = 0;
00163         if (!stricmp(Params[i].name,"load") && *Params[i].value)
00164         {
00165             int j;
00166             FILE* report;
00167             ExpandLocalPath(argv0,FileName,Params[i].value,0);
00168             report = fopen(FileName,"rt");
00169             if (report)
00170             {
00171                 char str[32768];
00172                 str[fread(str,1,32767,report)]=0;
00173                 data = ReadPairedString(str,'\n',0);
00174 
00175                 if (data && count) for (j=0; count[j].name; j++)
00176                 {
00177                     countList[j].count += atoi(GetFieldValue(data,count[j].name));
00178                 }
00179                 if (data && sum) for (j=0; sum[j].name; j++)
00180                 {
00181                char * name = strdup3(sum[j].name,".sum","");
00182                     sumList[j].count += atoi(GetFieldValue(data,count[j].name));
00183                     sumList[j].sum += strtod(GetFieldValue(data,name),0);
00184                     free(name);
00185                     name = strdup3(sum[j].name,".sum2","");
00186                     sumList[j].sum2 += strtod(GetFieldValue(data,name),0);
00187                     free(name);
00188                 }
00189                 DeleteNVP(data);
00190             }
00191         }
00192         if (!stricmp(Params[i].name,"report") && *Params[i].value)
00193         {
00194             CGINameValue* total = GetTotal(count,sum,countList,sumList,countLength,sumLength);
00195             FILE* report;
00196             ExpandLocalPath(argv0,FileName,Params[i].value,0);
00197             report = fopen(FileName,"rt");
00198             if (report)
00199             {
00200                 printSummary = 0;
00201                 RunReport(argv0,htmlout,report,total,total,0,0,0);
00202                 fclose(report);
00203             }
00204 
00205             DeleteNVP(total);
00206         }
00207         else
00208         {
00209             ExpandLocalPath(argv0,FileName,Params[i].name,0);
00210             if (!DatabaseOpen(FileName,&db,&data,0))
00211                continue;
00212 
00213             while (DatabaseReadRecord(db, data,&skip))
00214             {
00215                 if (skip) continue;
00216              if (countList)
00217                 UpdateCounts(data,countList,countLength);
00218              if (sumList)
00219                 UpdateCounts(data,sumList,sumLength);
00220             }
00221 
00222             DatabaseClose(db,data);
00223         }
00224     }
00225 
00226     if (printSummary)
00227     {
00228         CGINameValue* total = GetTotal(count,sum,countList,sumList,countLength,sumLength);
00229         for (i=0; total[i].name; i++)
00230         {
00231             HTMLWrite(htmlout,total[i].name);
00232             HTMLWrite(htmlout,"=");
00233             HTMLWrite(htmlout,total[i].value);
00234             HTMLWrite(htmlout,"\n");
00235         }
00236     }
00237     return 0;
00238 }