System Preprocessors
reporting.c
Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include "syspro.h"
00005 #include "sysprotransform.h"
00006 #include "syspro_impl.h"
00007 
00008 /*! \page reporting Preprocessor reporting
00009   For purposes of reporting, there are routines for retrieving the names
00010   of all preprocessors in sequence. This is the general idea:
00011 \verbatim
00012   ierr = GetFirstPreprocessor(&name); CHKERRQ(ierr);
00013   while (name) {
00014    .....
00015    ierr = GetNextPreprocessor(&name); CHKERRQ(ierr);
00016   }
00017 \endverbatim
00018   Similarly, StartRetrievingCurrentPreprocessors() and
00019   ContinueRetrievingCurrentPreprocessors() get the class and specific
00020   choice of the currently active preprocessors.
00021 
00022   With StartRetrievingAllPreprocessors() and
00023   ContinueRetrievingAllPreprocessors() one can the classes, and
00024   in each class all defined choices.
00025 
00026   The specific reporting funtions are:
00027   - TabReportPreprocessors() : report on currently active preprocessors; 
00028   suitable for database file output
00029   - ReportEnabledPreprocessors() : report on non-disabled choices for
00030   a given preprocessor
00031   - ReportSysProCallStackState() : report currently active preprocessors
00032 */
00033 extern int npreprocess,preprocesslevel;
00034 static int preprocessreadout;
00035 extern SystemPreprocessor *preprocessors;
00036 
00037 #undef __FUNCT__
00038 #define __FUNCT__ "GetFirstPreprocessor"
00039 /*!
00040   Get the name of the first declared preprocessor (in order of declaration)
00041   or null if none have been declared.
00042   Subsequent preprocessors can be retrieved with
00043   GetNextPreprocessor() or SuccessorPreprocessor().
00044 */
00045 PetscErrorCode GetFirstPreprocessor(const char **preprocess)
00046 {
00047   PetscErrorCode ierr;
00048   PetscFunctionBegin;
00049   preprocessreadout = 0;
00050   ierr = GetNextPreprocessor(preprocess); CHKERRQ(ierr);
00051   PetscFunctionReturn(0);
00052 }
00053 
00054 #undef __FUNCT__
00055 #define __FUNCT__ "GetNextPreprocessor"
00056 /*! 
00057   Get the next preprocessor according to the variable preprocessreadout.
00058 
00059   The result is null if there are no further preprocessors.
00060 */
00061 PetscErrorCode GetNextPreprocessor(const char **next_one)
00062 {
00063   PetscFunctionBegin;
00064   if (preprocessreadout>=npreprocess)
00065     *next_one = NULL;
00066   else
00067     *next_one = preprocessors[preprocessreadout++]->name;
00068   PetscFunctionReturn(0);
00069 }
00070 
00071 #undef __FUNCT__
00072 #define __FUNCT__ "SuccessorPreprocessor"
00073 /*! Given a preprocessor, get the name of the next one
00074   (in order of declaration) or null if there are no further ones.
00075 
00076   The arguments are allowed to be the same.
00077 */
00078 PetscErrorCode SuccessorPreprocessor(const char *this_one,const char **next_one)
00079 {
00080   int ipre; PetscBool flg; PetscErrorCode ierr;
00081   PetscFunctionBegin;
00082   for (ipre=0; ipre<npreprocess; ipre++) {
00083     ierr = PetscStrcmp(this_one,preprocessors[ipre]->name,&flg); CHKERRQ(ierr);
00084     if (flg) {
00085       if (ipre<npreprocess-1)
00086         *next_one = preprocessors[ipre+1]->name;
00087       else
00088         *next_one = 0;
00089       goto found;
00090     }
00091   }
00092   SETERRQ1(PETSC_COMM_SELF,1,"Could not find preprocessor <%s>",this_one);
00093  found:
00094   PetscFunctionReturn(0);
00095 }
00096 
00097 #undef __FUNCT__
00098 #define __FUNCT__ "StartRetrievingCurrentPreprocessors"
00099 /*!
00100   This routine gives the class and current value of the first
00101   declared preprocessor.
00102   To get the next preprocessor, call 
00103   ContinueRetrievingAllPreprocessors().
00104 
00105   The class, types, and ntypes arguments can all be null.
00106 */
00107 PetscErrorCode StartRetrievingCurrentPreprocessors
00108 (const char **cclass,const char **type,int *opt,PetscBool *success)
00109 {
00110   PetscErrorCode ierr;
00111   PetscFunctionBegin;
00112   preprocessreadout = 0;
00113   ierr = ContinueRetrievingCurrentPreprocessors
00114     (cclass,type,opt,success); CHKERRQ(ierr);
00115   PetscFunctionReturn(0);
00116 }
00117 
00118 #undef __FUNCT__
00119 #define __FUNCT__ "ContinueRetrievingCurrentPreprocessors"
00120 /*!
00121   This routine is to be used repeatedly after an initial call
00122   to StartRetrievingCurrentPreprocessors().
00123 */
00124 PetscErrorCode ContinueRetrievingCurrentPreprocessors
00125 (const char **cclass,const char **atype,int *opt,PetscBool *success)
00126 {
00127   PetscFunctionBegin;
00128   if (preprocessreadout>=preprocesslevel) 
00129     *success = PETSC_FALSE;
00130   else {
00131     const char *curtype; int curopt; PetscErrorCode ierr;
00132     ierr = RetrievePreprocessorChoice
00133       (preprocessreadout,&curtype,&curopt); CHKERRQ(ierr);
00134     *success = PETSC_TRUE;
00135     if (cclass) *cclass = preprocessors[preprocessreadout]->name;
00136     if (atype)  *atype = curtype;
00137     if (opt)   *opt = curopt;
00138     preprocessreadout++;
00139   }
00140   PetscFunctionReturn(0);
00141 }
00142 
00143 #undef __FUNCT__
00144 #define __FUNCT__ "StartRetrievingAllPreprocessors"
00145 /*!
00146   This routine gives the class of the first
00147   declared preprocessor, and all possible values.
00148   To get the next preprocessor, call 
00149   ContinueRetrievingAllPreprocessors().
00150 
00151   The class, types, and ntypes arguments can all be null.
00152 
00153   The \c types argument is allocated internally and should be deallocated
00154   by the user.
00155 */
00156 PetscErrorCode StartRetrievingAllPreprocessors
00157 (const char **cclass,const char ***types,int *ntypes,PetscBool *success)
00158 {
00159   PetscErrorCode ierr;
00160   PetscFunctionBegin;
00161   preprocessreadout = 0;
00162   ierr = ContinueRetrievingAllPreprocessors
00163     (cclass,types,ntypes,success); CHKERRQ(ierr);
00164   PetscFunctionReturn(0);
00165 }
00166 
00167 #undef __FUNCT__
00168 #define __FUNCT__ "InitRetrievingPreprocessors"
00169 PetscErrorCode InitRetrievingPreprocessors()
00170 {
00171   PetscFunctionBegin;
00172   preprocessreadout = 0;
00173   PetscFunctionReturn(0);
00174 }
00175 
00176 #undef __FUNCT__
00177 #define __FUNCT__ "ContinueRetrievingAllPreprocessors"
00178 /*!
00179   This routine is to be used repeatedly after an initial call
00180   to StartRetrievingAllPreprocessors().
00181   
00182   The \c types argument is allocated internally and should be deallocated
00183   by the user.
00184 */
00185 PetscErrorCode ContinueRetrievingAllPreprocessors
00186 (const char **cclass,const char ***types,int *ntypes,PetscBool *success)
00187 {
00188   PetscErrorCode ierr;
00189   PetscFunctionBegin;
00190   if (preprocessreadout>=npreprocess) 
00191     *success = PETSC_FALSE;
00192   else {
00193     *success = PETSC_TRUE;
00194     if (cclass)
00195       *cclass = preprocessors[preprocessreadout]->name;
00196     if (ntypes)
00197       *ntypes = preprocessors[preprocessreadout]->transform->n_objects;
00198     if (types) {
00199       ierr = TransformObjectsGetNames
00200         (preprocessors[preprocessreadout]->transform,types); CHKERRQ(ierr);
00201     }
00202     preprocessreadout++;
00203   }
00204   PetscFunctionReturn(0);
00205 }
00206 
00207 #undef __FUNCT__ 
00208 #define __FUNCT__ "RetrieveAllPreprocessorValues"
00209 PetscErrorCode RetrieveAllPreprocessorValues
00210 (const char *cclass,const char ***types,int *ntypes)
00211 {
00212   int idx; PetscBool flg; PetscErrorCode ierr;
00213   PetscFunctionBegin;
00214   for (idx=0; idx<npreprocess; idx++) {
00215     ierr = PetscStrcmp(cclass,preprocessors[idx]->name,&flg); CHKERRQ(ierr);
00216     if (flg) {preprocessreadout=idx; goto retrieve;}
00217   }
00218   SETERRQ1(PETSC_COMM_SELF,1,"Preprocessor unknown: <%s>",cclass);
00219  retrieve:
00220   ierr = ContinueRetrievingAllPreprocessors
00221     (PETSC_NULL,types,ntypes,&flg); CHKERRQ(ierr);
00222   if (!flg) SETERRQ(PETSC_COMM_SELF,1,"This can not happen");
00223   PetscFunctionReturn(0);
00224 }
00225 
00226 #define LINELEN 1500
00227 #define REPOSITION(a,b) \
00228   ierr = PetscStrlen(a,&b); CHKERRQ(ierr); \
00229   if (b>LINELEN) SETERRQ(PETSC_COMM_SELF,1,"string overflow")
00230 #undef __FUNCT__
00231 #define __FUNCT__ "TabReportPreprocessors"
00232 /*! Report all defined preprocessors. Either key and val argument can 
00233    be NULL. The string arguments returned need to be deallocated
00234    in the calling environment.
00235 */
00236 static PetscErrorCode TabReportPreprocessors
00237 (PetscBool active,const char **key,const char **val,int separator)
00238 {
00239   PetscBool has_preprocessor; const char *cclass,*value,*sql_key,*sql_val;
00240   size_t loc_key,loc_val; int option; 
00241   PetscBool begun=PETSC_FALSE; PetscErrorCode ierr;
00242 
00243   PetscFunctionBegin;
00244   if (key) {
00245     ierr = PetscMalloc(LINELEN*sizeof(char),&sql_key); CHKERRQ(ierr);
00246     ierr = PetscMemzero((char*)sql_key,LINELEN*sizeof(char)); CHKERRQ(ierr);
00247   }
00248   if (val) {
00249     ierr = PetscMalloc(LINELEN*sizeof(char),&sql_val); CHKERRQ(ierr);
00250     ierr = PetscMemzero((char*)sql_val,LINELEN*sizeof(char)); CHKERRQ(ierr);
00251   }
00252   loc_key = loc_val = 0;
00253 
00254   ierr = InitRetrievingPreprocessors(); CHKERRQ(ierr);
00255   do {
00256     if (active) {
00257       ierr = ContinueRetrievingCurrentPreprocessors
00258         (&cclass,&value,&option,&has_preprocessor); CHKERRQ(ierr);
00259       if (has_preprocessor) {
00260       } else active = PETSC_FALSE;
00261     }
00262     if (!active) {
00263       ierr = ContinueRetrievingAllPreprocessors
00264         (&cclass,PETSC_NULL,PETSC_NULL,&has_preprocessor); CHKERRQ(ierr);
00265       value = "(inactive)"; option = 0;
00266       if (has_preprocessor) {
00267       } else break;      
00268     }
00269 
00270     if (begun) {
00271       if (key) sprintf((char*)sql_key+loc_key++,"\t");
00272       if (val) sprintf((char*)sql_val+loc_val++,"\t");
00273     } else begun=PETSC_TRUE;
00274 
00275     if (key) sprintf((char*)sql_key+loc_key,"%s\t%sv",cclass,cclass);
00276     if (val) sprintf((char*)sql_val+loc_val,"%s\t%d",value,option);
00277 
00278     if (key) REPOSITION((char*)sql_key,loc_key);
00279     if (val) REPOSITION((char*)sql_val,loc_val);
00280 
00281   } while (1);
00282   CHKMEMQ;
00283 
00284   if (key) *key = sql_key;
00285   if (val) *val = sql_val;
00286 
00287   PetscFunctionReturn(0);
00288 }
00289 
00290 #undef __FUNCT__
00291 #define __FUNCT__ "TabReportAllPreprocessors"
00292 /* Report all defined preprocessors. Either key and val argument can 
00293    be NULL.
00294 */
00295 PetscErrorCode TabReportAllPreprocessors(const char **key,int separator)
00296 {
00297   PetscErrorCode ierr;
00298   PetscFunctionBegin;
00299   ierr = TabReportPreprocessors
00300     (PETSC_FALSE,key,PETSC_NULL,separator); CHKERRQ(ierr);
00301   PetscFunctionReturn(0);
00302 }
00303 
00304 #undef __FUNCT__
00305 #define __FUNCT__ "TabReportActivePreprocessors"
00306 /* Report all defined preprocessors. Either key and val argument can 
00307    be NULL.
00308 */
00309 PetscErrorCode TabReportActivePreprocessors(const char **key,const char **val,int separator)
00310 {
00311   PetscErrorCode ierr;
00312   PetscFunctionBegin;
00313   ierr = TabReportPreprocessors(PETSC_TRUE,key,val,separator); CHKERRQ(ierr);
00314   PetscFunctionReturn(0);
00315 }
00316 
00317 
00318 #undef __FUNCT__
00319 #define __FUNCT__ "ScreenOutputTab"
00320 PetscErrorCode ScreenOutputTab(const char *key,const char *val)
00321 {
00322   PetscBool flg;
00323   char *ck,*cv; PetscErrorCode ierr;
00324   PetscFunctionBegin;
00325 
00326   ierr = SysProHasTrace(&flg); CHKERRQ(ierr);
00327   if (flg) {
00328     ck = (char*)key; cv = (char*)val;
00329     while (1) {
00330       size_t ik=0, iv=0, lk,lv;
00331       lk = strlen(ck); while (ik<lk && ck[ik]!='\t') ik++; if (ik<lk) ck[ik] = 0;
00332       lv = strlen(cv); while (iv<lv && cv[iv]!='\t') iv++; if (iv<lv) cv[iv] = 0;
00333       ierr = SysProTraceMessage("%s: %s\n",ck,cv); CHKERRQ(ierr);
00334       if (iv<lv) {
00335         ck[ik] = '\t'; cv[iv] = '\t';
00336         ck = ck+ik+1; cv = cv+iv+1;
00337       } else break;
00338     }
00339   }
00340   CHKMEMQ;
00341 
00342   PetscFunctionReturn(0);
00343 }
00344 
00345 #undef __FUNCT__
00346 #define __FUNCT__ "ScreenOutputTabLine"
00347 PetscErrorCode ScreenOutputTabLine(const char *key,const char *val)
00348 {
00349   PetscBool flg;
00350   char *ck,*cv,*message; PetscErrorCode ierr;
00351   PetscFunctionBegin;
00352 
00353   ierr = SysProHasTrace(&flg); CHKERRQ(ierr);
00354   if (flg) {
00355 #define MAXLEN 500
00356     ierr = PetscMalloc(MAXLEN*sizeof(char),&message); CHKERRQ(ierr);
00357     ierr = PetscMemzero(message,MAXLEN*sizeof(char)); CHKERRQ(ierr);
00358     ck = (char*)key; cv = (char*)val;
00359     while (1) {
00360       int l = strlen(message);
00361       size_t ik=0, iv=0, lk,lv;
00362 
00363       lk = strlen(ck);
00364       while (ik<lk && ck[ik]!='\t') ik++;
00365       if (ik<lk) ck[ik] = 0;
00366 
00367       lv = strlen(cv);
00368       while (iv<lv && cv[iv]!='\t') iv++;
00369       if (iv<lv) cv[iv] = 0;
00370 
00371       if (l+strlen(ck)+strlen(cv)+6<MAXLEN) {
00372         sprintf((char*)message+l,"%s: %s || ",ck,cv);
00373       }
00374       if (iv<lv) {
00375         ck[ik] = '\t'; cv[iv] = '\t';
00376         ck = ck+ik+1; cv = cv+iv+1;
00377       } else break;
00378     }
00379     ierr = SysProTraceMessage("%s\n",message); CHKERRQ(ierr);
00380     ierr = PetscFree(message); CHKERRQ(ierr);
00381   }
00382   CHKMEMQ;
00383 
00384   PetscFunctionReturn(0);
00385 }
00386 
00387 #undef __FUNCT__
00388 #define __FUNCT__ "ReportEnabledPreprocessors"
00389 /*! Report preprocessor choices that are available after the 
00390   specific setup has possible disabled some of the registered ones.
00391   This function uses the \c sysprotrace function, so this has to have
00392   been declared.
00393 */
00394 PetscErrorCode ReportEnabledPreprocessors(const char *name)
00395 {
00396   PetscBool flg;
00397   SalsaTransform tf; const char *s; PetscErrorCode ierr;
00398   PetscFunctionBegin;
00399   ierr = SysProHasTrace(&flg); CHKERRQ(ierr);
00400   if (flg) {
00401     ierr = TransformGetByName(name,&tf); CHKERRQ(ierr);
00402     ierr = TransformReportEnabled(tf,&s); CHKERRQ(ierr);
00403     ierr = SysProTraceMessage
00404       ("Enabled <%s> preprocessors: %s\n",name,s); CHKERRQ(ierr);
00405     ierr = PetscFree(s); CHKERRQ(ierr);
00406   }
00407   CHKMEMQ;
00408   PetscFunctionReturn(0);
00409 }
00410 
00411 #undef __FUNCT__
00412 #define __FUNCT__ "ReportSysProCallStackState"
00413 /*! Report preprocessor choices that are available after the 
00414   specific setup has possible disabled some of the registered ones.
00415   This function uses the \c sysprotrace function, so this has to have
00416   been declared.
00417 */
00418 PetscErrorCode ReportSysProCallStackState(const char *name)
00419 {
00420   PetscBool flg;
00421   PetscErrorCode ierr;
00422   PetscFunctionBegin;
00423   ierr = SysProHasTrace(&flg); CHKERRQ(ierr);
00424   if (flg) {
00425     const char *key,*val;
00426     ierr = SysProTraceMessage
00427       ("Entering preprocessor: <%s>\n",name); CHKERRQ(ierr);
00428     ierr = SysProTraceMessage("Currently active:\n"); CHKERRQ(ierr);
00429     ierr = TabReportPreprocessors(PETSC_TRUE,&key,&val,','); CHKERRQ(ierr);
00430     ierr = ScreenOutputTabLine(key,val); CHKERRQ(ierr);
00431     ierr = PetscFree(key); CHKERRQ(ierr);
00432     ierr = PetscFree(val); CHKERRQ(ierr);
00433   }
00434   CHKMEMQ;
00435   PetscFunctionReturn(0);
00436 }