summary.c

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /* summary.c © Copyright 2004 by Raosoft Inc. All Rights Reserved.            */
00003 /*                                                                            */
00004 /* You may use and modify this file for your own use, but may not distribute  */
00005 /* it or derivative works without the prior written consent of Raosoft, Inc.  */
00006 /*                                                                            */
00007 /* If you choose to share your modifications with Raosoft, Inc. the company   */
00008 /* will attempt to incorporate them into future versions of this file.        */
00009 /*                                                                            */
00010 /* This software is provided "as is," and Raosoft makes no warranty, express  */
00011 /* or implied, of fitness for a particular application. Every measure has been*/
00012 /* taken to anticipate risks inherent to computer networks, but we cannot     */
00013 /* guarantee safety or reliability of this program in every situation.        */
00014 /*                                                                            */
00015 /******************************************************************************/
00016 
00017 /* build instructions:
00018   gcc -o summary summary.c cgi_console.c cgi_util.c cgi_data.c -lm
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 }


Raosoft, Inc.
Raosoft EZReport, EZSurvey, InterForm, RapidReport, Raosoft, and SurveyWin are registered trademarks of Raosoft, Inc. Page contents © 1996-2007 by Raosoft, Inc. You may use and modify this file for your own use, but may not distribute it or derivative works without the prior written consent of Raosoft, Inc. This software is provided "as is," and Raosoft makes no warranty, express or implied, of fitness for a particular application. Every measure has been taken to anticipate risks inherent to computer networks, but we cannot guarantee safety or reliability of this program in every situation.
Tel: 206-525-4025 (US) Email: raosoft@raosoft.com
http://www.raosoft.com/