coan 4.2.4
report.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004, 2006 Symbian Software Ltd.                        *
00003  *   All rights reserved.                                                  *
00004  *   Copyright (C) 2007-2011 Mike Kinghan, imk@strudl.org                  *
00005  *   All rights reserved.                                                  *
00006  *                                                                         *
00007  *   Contributed originally by Mike Kinghan, imk@strudl.org                *
00008  *                                                                         *
00009  *   Redistribution and use in source and binary forms, with or without    *
00010  *   modification, are permitted provided that the following conditions    *
00011  *   are met:                                                              *
00012  *                                                                         *
00013  *   Redistributions of source code must retain the above copyright        *
00014  *   notice, this list of conditions and the following disclaimer.         *
00015  *                                                                         *
00016  *   Redistributions in binary form must reproduce the above copyright     *
00017  *   notice, this list of conditions and the following disclaimer in the   *
00018  *   documentation and/or other materials provided with the distribution.  *
00019  *                                                                         *
00020  *   Neither the name of Symbian Software Ltd. nor the names of its        *
00021  *   contributors may be used to endorse or promote products derived from  *
00022  *   this software without specific prior written permission.              *
00023  *                                                                         *
00024  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   *
00025  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     *
00026  *   LIMITED TO, THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS    *
00027  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE        *
00028  *   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,   *
00029  *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  *
00030  *   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
00031  *   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    *
00032  *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,*
00033  *   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF *
00034  *   THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH  *
00035  *   DAMAGE.                                                               *
00036  *                                                                         *
00037  **************************************************************************/
00038 
00039 #include "platform.h"
00040 #include "report.h"
00041 #include "io.h"
00042 #include "args.h"
00043 #include "chew.h"
00044 #include "if_control.h"
00045 #include "line_despatch.h"
00046 #include "exception.h"
00047 #include "dataset.h"
00048 
00056 
00058 static char const * const comment_name[] = {
00059     "NO","C","CXX",     "STARTING",     "FINISHING","PSEUDO"
00060 };
00061 
00063 static char const * const linestate_name[] = {
00064     "VACANT","DIRECTIVE","CODE"
00065 };
00066 
00068 static char const * const ifstate_name[] = {
00069     "OUTSIDE", "FALSE_PREFIX", "TRUE_PREFIX",
00070     "PASS_MIDDLE", "FALSE_MIDDLE", "TRUE_MIDDLE",
00071     "PASS_ELSE", "FALSE_ELSE", "TRUE_ELSE",
00072     "FALSE_TRAILER"
00073 };
00074 
00076 static char const * const linetype_name[] = {
00077     "TRUEI", "FALSEI", "IF", "TRUE", "FALSE",
00078     "ELIF", "ELTRUE", "ELFALSE", "ELSE", "ENDIF",
00079     "DODGY TRUEI", "DODGY FALSEI",
00080     "DODGY IF", "DODGY TRUE", "DODGY FALSE",
00081     "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE",
00082     "DODGY ELSE", "DODGY ENDIF",
00083     "PLAIN", "EOF",
00084     "CONSISTENT DEFINE KEEP","CONSISTENT DEFINE DROP",
00085     "CONTRADICTORY DEFINE","DIFFERING DEFINE",
00086     "CONSISTENT UNDEF KEEP", "CONSISTENT UNDEF DROP",
00087     "CONTRADICTORY UNDEF"
00088 };
00089 
00090 
00094 static char const *
00095 get_comment_type_name(void)
00096 {
00097     return comment_name[GET_PUBLIC(chew,comment_state)];
00098 }
00099 
00103 static char const *
00104 get_linestate_name(void)
00105 {
00106     return linestate_name[GET_PUBLIC(chew,line_state)];
00107 }
00108 
00112 static char const *
00113 if_state_name(void)
00114 {
00115     return ifstate_name[if_state()];
00116 }
00117 
00123 static char const *
00124 get_linetype_name(line_type_t type)
00125 {
00126     return linetype_name[type];
00127 }
00128 
00129 
00138 static size_t
00139 vformat_output( void *dest,
00140                 int *buflen,
00141                 int *startoff,
00142                 char const *format,
00143                 va_list argp)
00144 {
00145     size_t written;
00146     if (*buflen >= 0) {
00147         char *buf = *(heap_str *)dest;
00148         size_t spare;
00149         if (*buflen == 0) {
00150             *buflen = 1024;
00151             *startoff = 0;
00152             release(dest);
00153             buf = zallocate(*buflen);
00154         }
00155         spare = *buflen - *startoff;
00156         written = vsnprintf(buf + *startoff,spare,format,argp);
00157         while(written >= spare) {
00158             spare += *buflen;
00159             buf = reallocate(buf,*buflen >>= 1);
00160             written = vsnprintf(buf + *startoff,spare,format,argp);
00161         }
00162         *(heap_str *)dest = buf;
00163         *startoff += (int)written;
00164     } else {
00165         FILE * out = dest;
00166         written = vfprintf(out,format,argp);
00167     }
00168     return written;
00169 }
00170 
00180 static void
00181 vreport(reason_code_t reason, heap_str *buf, const char *format, va_list argp);
00182 
00188 
00190 STATE_DEF(report)
00191 {
00192     bool                dbg; 
00193     unsigned int        exitstat; 
00194     char const * hash_keywords[HASH_COUNT];
00196 }
00197 STATE_T(report);
00202 NO_PUBLIC_STATE(report);
00203 
00204 IMPLEMENT(report,ZERO_INITABLE);
00208 static void
00209 vreport(reason_code_t reason, heap_str *bufp, const char *format, va_list argp)
00210 {
00211     if (GET_PUBLIC(args,got_opts) && reason != MSGCLASS_NONE) {
00212         int mask = GET_PUBLIC(args,diagnostic_filter);
00213         if (mask && ((reason & mask) != 0)) {
00214             /* This message is filtered out. Don't output*/
00215             SET_STATE(report,exitstat) |= reason & MSGEVENT_MASK;
00216             if (bufp) {
00217                 *bufp = NULL;
00218             }
00219             return;
00220         }
00221     }
00222     if (!format) {
00223         assert(bufp);
00224         if (*bufp) {
00225             char *mess = *bufp;
00226             fputs(mess,stderr);
00227             release((void **)bufp);
00228         }
00229     } else {
00230         void *dest;
00231         int buflen;
00232         int startoff = 0;
00233         size_t depth = if_depth();
00234         if (!bufp) {
00235             dest = stderr;
00236             buflen = -1;
00237         } else {
00238             dest = bufp;
00239             buflen = 0;
00240         }
00241         format_output(dest,&buflen,&startoff,"%s: ",GET_PUBLIC(args,prog_name));
00242         if (!GET_PUBLIC(args,got_opts)) {
00243             format_output(dest,&buflen,&startoff,"while parsing options: ");
00244         }
00245         if (GET_PUBLIC(io,filename)) {
00246             format_output(dest,&buflen,&startoff,
00247                           "%s: ",GET_PUBLIC(io,filename));
00248         }
00249         if (GET_PUBLIC(io,line_num)) {
00250             format_output(dest,&buflen,&startoff,"line %d: ",
00251                           GET_PUBLIC(io,line_num));
00252         }
00253         if (reason & ISSUE_MASK) {
00254             char * category = NULL;
00255             switch(reason & MSGSEVERITY_MASK) {
00256             case MSGCLASS_PROGRESS:
00257                 category = "progress";
00258                 break;
00259             case MSGCLASS_INFO:
00260                 category = "info";
00261                 break;
00262             case MSGCLASS_WARNING:
00263                 category = "warning";
00264                 break;
00265             case MSGCLASS_ERROR:
00266                 category = "error";
00267                 break;
00268             case MSGCLASS_ABEND:
00269                 category = "abend";
00270                 break;
00271             default:
00272                 assert(false);
00273             }
00274             format_output(dest,&buflen,&startoff,"%s 0x%05x: ",category,reason);
00275             SET_STATE(report,exitstat) |= reason & MSGEVENT_MASK;
00276         }
00277         vformat_output(dest,&buflen,&startoff,format,argp);
00278         if (depth > 0) {
00279             format_output(dest,&buflen,&startoff," (#if line %d depth %d)",
00280                           (int)if_start_line(),(int)depth);
00281         }
00282         format_output(dest,&buflen,&startoff,"\n");
00283     }
00284 }
00285 
00286 
00287 /* API **************************************************************/
00288 
00289 void
00290 flatten_line(char * line)
00291 {
00292     size_t len = line_len(line);
00293     for (       ; len && *line; ++line,--len) {
00294         if (*line == '\\' && line[1] == '\n') {
00295             *line = line[1] = ' ';
00296         }
00297         else if (*line == '\n' || *line == '\r' || *line == '\t') {
00298             *line = ' ';
00299         }
00300     }
00301 }
00302 
00303 
00304 size_t
00305 line_len(char const *str)
00306 {
00307     /* Some rigmarole here to maintain line-end agnosticism*/
00308     size_t len = strlen(str);
00309     char const *last_ch = str + len - 1;
00310     char const *last_but_1_ch = last_ch - 1;
00311     if (eol(last_but_1_ch)) {
00312         /* This will be a Windows line-end when we're a Unixoid build.
00313                 Need to test this first*/
00314         len -= 2;
00315     } else if (eol(last_ch)) {
00316         /* This will be the usual case Unix or Windows*/
00317         --len;
00318     }
00319     return len;
00320 }
00321 
00322 int
00323 exitcode(void)
00324 {
00325     unsigned severities;
00326     unsigned summaries;
00327     unsigned ret = GET_STATE(report,exitstat);
00328     if (GET_PUBLIC(line_despatch,lines_inactive)) {
00329         ret |= EVENT_SUMMARY_DROPPED_LINES & ~MSGCLASS_SUMMARY;
00330     }
00331     if (GET_PUBLIC(line_despatch,lines_changed)) {
00332         ret |= EVENT_SUMMARY_CHANGED_LINES & ~MSGCLASS_SUMMARY;
00333     }
00334     SET_STATE(report,exitstat) = ret;
00335     /* Drop the progress flag off the severities*/
00336     severities = ret >> (MSGCLASS_SHIFT + 1);
00337     summaries = (ret & EVENT_SUMMARY_MASK) << GRIPE_SHIFT;
00338     return severities | summaries;
00339 }
00340 
00341 int
00342 get_exit_flags(int bits)
00343 {
00344     return bits &
00345            (EVENT_SUMMARY_MASK | MSGSEVERITY_MASK) & GET_STATE(report,exitstat);
00346 }
00347 
00348 void
00349 set_exit_flags(int bits, bool set)
00350 {
00351     bits &= (EVENT_SUMMARY_MASK | MSGSEVERITY_MASK);
00352     if (set) {
00353         SET_STATE(report,exitstat) |= bits;
00354     } else {
00355         SET_STATE(report,exitstat) &= ~bits;
00356     }
00357 }
00358 
00359 size_t
00360 format_output(void *dest, int *buflen,  int *startoff, char const *format,...)
00361 {
00362     size_t written;
00363     va_list argp;
00364     va_start(argp,format);
00365     written = vformat_output(dest,buflen,startoff,format,argp);
00366     va_end(argp);
00367     return written;
00368 }
00369 
00370 
00371 void
00372 report(reason_code_t reason, heap_str *buf, const char *format,...)
00373 {
00374     va_list argp;
00375     va_start(argp,format);
00376     vreport(reason,buf,format,argp);
00377     va_end(argp);
00378 }
00379 
00380 void
00381 parse_error(int reason, const char *format,...)
00382 {
00383     va_list argp;
00384     va_start(argp,format);
00385     vbail(reason,format,argp);
00386     va_end(argp);
00387 }
00388 
00389 void
00390 give_up_confused(void)
00391 {
00392     bail(GRIPE_CONFUSED,"Bailing out in confusion");
00393 }
00394 
00395 void
00396 vbail(int reason, const char *msg, va_list argp)
00397 {
00398     if (msg) {
00399         vreport(reason,NULL,msg,argp);
00400     } else {
00401         SET_STATE(report,exitstat) |= reason & MSGEVENT_MASK;
00402     }
00403     if (exceptions_enabled &&
00404             ((reason & MSGEVENT_MASK) != MSGCLASS_ABEND)) {
00405         throw(reason);
00406     }
00407     exit(exitcode());
00408 }
00409 
00410 
00411 void
00412 bail(int reason, const char *format,...)
00413 {
00414     va_list argp;
00415     va_start(argp,format);
00416     vbail(reason,format,argp);
00417     va_end(argp);
00418 }
00419 
00420 void
00421 debugging(bool on)
00422 {
00423     SET_STATE(report,dbg) = on;
00424 }
00425 
00426 void
00427 debug(dbg_code_t how,...)
00428 {
00429     if (GET_STATE(report,dbg)) {
00430         va_list ap;
00431         va_start(ap, how);
00432         switch(how) {
00433         case DBG_1:
00434             vreport(MSGCLASS_NONE,NULL,"eval%d !",ap);
00435             break;
00436         case DBG_2:
00437             vreport(MSGCLASS_NONE,NULL,"eval%d (",ap);
00438             break;
00439         case DBG_3:
00440             vreport(MSGCLASS_NONE,NULL,"eval%d number",ap);
00441             break;
00442         case DBG_4:
00443             vreport(MSGCLASS_NONE,NULL,"eval%d defined",ap);
00444             break;
00445         case DBG_5:
00446             vreport(MSGCLASS_NONE,NULL,"eval%d symbol",ap);
00447             break;
00448         case DBG_6:
00449             vreport(MSGCLASS_NONE,NULL,"eval%d bad expr",ap);
00450             break;
00451         case DBG_7:
00452             vreport(MSGCLASS_NONE,NULL,"eval%d = %d",ap);
00453             break;
00454         case DBG_8:
00455             vreport(MSGCLASS_NONE,NULL,"eval%d",ap);
00456             break;
00457         case DBG_9:
00458             vreport(MSGCLASS_NONE,NULL,"eval%d %s",ap);
00459             break;
00460         case DBG_10:
00461             vreport(MSGCLASS_NONE,NULL,"eval%d = %d",ap);
00462             break;
00463         case DBG_11:
00464             vreport(MSGCLASS_NONE,NULL,"eval %s",ap);
00465             break;
00466         case DBG_12:
00467             vreport(MSGCLASS_NONE,NULL,"eval = %d",ap);
00468             break;
00469         case DBG_13:
00470             vreport(MSGCLASS_NONE,NULL,"eval #define %.*s",ap);
00471             break;
00472         case DBG_14: {
00473             size_t safelen = va_arg(ap,size_t);
00474             char const * define = va_arg(ap,char const *);
00475             int linetype = va_arg(ap,int);
00476             char const * const linetype_name = get_linetype_name(linetype);
00477             report(MSGCLASS_NONE,NULL,"eval #define %.*s = %s",
00478                    safelen,define,linetype_name);
00479             break;
00480         }
00481         case DBG_15:
00482             vreport(MSGCLASS_NONE,NULL,"eval #undef %.*s",ap);
00483             break;
00484         case DBG_16: {
00485             size_t safelen = va_arg(ap,size_t);
00486             char const * define = va_arg(ap,char const *);
00487             int linetype = va_arg(ap,int);
00488             char const * const linetype_name = get_linetype_name(linetype);
00489             report(MSGCLASS_NONE,NULL,"eval #undef %.*s = %s",
00490                    safelen,define,linetype_name);
00491             break;
00492         }
00493         case DBG_17:
00494             report(MSGCLASS_NONE,NULL,"parser %s comment %s line",
00495                    get_comment_type_name(), get_linestate_name());
00496             break;
00497         case DBG_18:
00498             vreport(MSGCLASS_NONE,NULL,"symbol_table_seek %s %s",ap);
00499             break;
00500         case DBG_19: {
00501             int linetype = va_arg(ap,int);
00502             report(MSGCLASS_NONE,NULL,"process %s -> %s depth %d",
00503                    get_linetype_name(linetype),
00504                    if_state_name(),
00505                    if_depth());
00506             break;
00507         }
00508         case DBG_20:
00509             vreport(MSGCLASS_NONE,NULL,"eval%d +",ap);
00510             break;
00511         case DBG_21:
00512             vreport(MSGCLASS_NONE,NULL,"eval%d -",ap);
00513             break;
00514         case DBG_22:
00515             vreport(MSGCLASS_NONE,NULL,"eval%d ~",ap);
00516             break;
00517         default:
00518             assert(false);
00519         }
00520         va_end(ap);
00521     }
00522 }
00523 
00524 void
00525 exit_diagnostics(void)
00526 {
00527     size_t infiles =
00528         file_tree_count(GET_PUBLIC(dataset,file_tree),FT_COUNT_FILES,NULL);
00529     unsigned donefiles = GET_PUBLIC(dataset,donefiles);
00530     unsigned errorfiles = GET_PUBLIC(dataset,errorfiles);
00531     char * diagnostic_status = "";
00532 
00533     int ret = exitcode();
00534     if_control_toplevel();
00535     io_toplevel();
00536 
00537     if (GET_STATE(report,exitstat) & MSGCLASS_ABEND) {
00538         diagnostic_status = " ABNORMALLY";
00539     } else if (GET_STATE(report,exitstat) & MSGCLASS_ERROR) {
00540         diagnostic_status = " with errors";
00541     } else if (GET_STATE(report,exitstat) & MSGCLASS_WARNING) {
00542         diagnostic_status = " with warnings";
00543     } else if (GET_STATE(report,exitstat) & MSGCLASS_INFO) {
00544         diagnostic_status = " with remarks";
00545     }
00546     report(PROGRESS_SUMMARY_ALL_DONE,NULL,
00547            "Completed%s, exit code 0x%02x",diagnostic_status,ret);
00548     if (infiles) {
00549         report(PROGRESS_SUMMARY_FILES_REACHED,NULL,
00550                "%d out of %d input files were reached; %d files were not reached",
00551                donefiles,infiles,infiles - donefiles);
00552         report(PROGRESS_SUMMARY_FILES_DROPPED,NULL,
00553                "%d out %d files reached were valid; "
00554                "%d were abandoned due to parse errors",
00555                donefiles - errorfiles,donefiles,errorfiles);
00556         if (infiles == donefiles && errorfiles == 0) {
00557             if (GET_STATE(report,exitstat) &
00558                     EVENT_SUMMARY_DROPPED_LINES & ISSUE_MASK) {
00559                 report(EVENT_SUMMARY_DROPPED_LINES,NULL,
00560                        "Input lines were dropped");
00561             }
00562             if (GET_STATE(report,exitstat) &
00563                     EVENT_SUMMARY_CHANGED_LINES & ISSUE_MASK) {
00564                 report(EVENT_SUMMARY_CHANGED_LINES,NULL,
00565                        "Input lines were changed");
00566             }
00567             if (GET_STATE(report,exitstat) &
00568                     EVENT_SUMMARY_ERRORED_LINES & ISSUE_MASK) {
00569                 report( EVENT_SUMMARY_ERRORED_LINES,
00570                         NULL,
00571                         "Input lines were changed to #error directives");
00572             }
00573             if (GET_STATE(report,exitstat) &
00574                     EVENT_SUMMARY_ERROR_OUTPUT & ISSUE_MASK) {
00575                 report( EVENT_SUMMARY_ERRORED_LINES,
00576                         NULL,
00577                         "Unconditional #error directives are operative");
00578             }
00579         }
00580     }
00581 }
00582 
00583 void
00584 orphan_elif(void)
00585 {
00586     parse_error(GRIPE_ORPHAN_ELIF,"Orphan #elif");
00587 }
00588 
00589 void
00590 orphan_else(void)
00591 {
00592     parse_error(GRIPE_ORPHAN_ELSE,"Orphan #else");
00593 }
00594 
00595 void
00596 orphan_endif(void)
00597 {
00598     parse_error(GRIPE_ORPHAN_ENDIF,"Orphan #endif");
00599 }
00600 
00601 void
00602 early_eof(void)
00603 {
00604     parse_error(GRIPE_EOF_TOO_SOON,"Unexpected EOF");
00605 }
00606 
00607 void
00608 processing_file(char const *filename)
00609 {
00610     report(PROGRESS_PROCESSING_FILE,NULL,"Processing file \"%s\"",filename);
00611 }
00612 
00613 void
00614 entering_dir(char const *dirname)
00615 {
00616     report(PROGRESS_ENTERING_DIR,NULL,"Entering directory \"%s\"",dirname);
00617 }
00618 
00619 void
00620 leaving_dir(char const *dirname)
00621 {
00622     report(PROGRESS_LEAVING_DIR,NULL,"Leaving directory \"%s\"",dirname);
00623 }
00624 
00625 heap_str
00626 concatenate(size_t count, char *strs[], int punctch)
00627 {
00628     heap_str concat;
00629     char *posn;
00630     size_t *lengths = callocate(count,sizeof(size_t));
00631     size_t buflen = 0;
00632     size_t punctsz = punctch == -1 ? 0 : count - 1;
00633     size_t i = 0;
00634     for (       ; i < count; ++i) {
00635         buflen += lengths[i] = strlen(strs[i]);
00636     }
00637     buflen += punctsz + 2;
00638     concat = zallocate(buflen);
00639     posn = concat;
00640     for (i = 0; i < count; ++i) {
00641         strcpy(posn,strs[i]);
00642         posn += lengths[i];
00643         if (punctch != -1) {
00644             *posn++ = (char)punctch;
00645         }
00646     }
00647     if (punctch != -1) {
00648         posn[-1] = '\0';
00649     }
00650     free(lengths);
00651     return concat;
00652 }
00653 
00654 void
00655 report_symbol(symbol_h sym)
00656 {
00657     if (!symbol_reported(sym) || !GET_PUBLIC(args,list_only_once)) {
00658         printf("%s",symbol_name(sym));
00659         if (GET_PUBLIC(args,resolve_symbols)) {
00660             canonical_string_const_h resolved = symbol_resolve(sym,NULL);
00661             if (strcmp(symbol_name(sym),canonical_string_text(resolved))) {
00662                 printf(": resolves as <|%s|>",canonical_string_text(resolved));
00663             }
00664             else {
00665                 fputs(": insoluble",stdout);
00666             }
00667         }
00668         if (GET_PUBLIC(args,list_locate)) {
00669             printf(": %s(%d)",GET_PUBLIC(io,filename),GET_PUBLIC(io,line_num));
00670         }
00671         putchar('\n');
00672         SET_REPORTED(*sym);
00673     }
00674 }
00675 
00676 
00677 void
00678 report_include(hash_include_const_h inc_arg)
00679 {
00680     canonical_string_const_h sym_def = hash_include_definition(inc_arg);
00681     printf("#include %s",hash_include_str(inc_arg));
00682     if (sym_def) {
00683         char const *def_text = canonical_string_text(sym_def);
00684         printf(": defined symbol, resolves as \"%s\"",def_text);
00685     }
00686     if (GET_PUBLIC(args,list_locate)) {
00687         printf(": %s(%d)",GET_PUBLIC(io,filename),GET_PUBLIC(io,line_num));
00688     }
00689     putchar('\n');
00690 }
00691 
00692 void
00693 report_directive(canonical_string_const_h cl, directive_type_t directive_type)
00694 {
00695     char const ** hash_keywords = GET_STATE(report,hash_keywords);
00696     if (!hash_keywords[HASH_IF]) { /* First time only */
00697         int ind = HASH_UNKNOWN;
00698         for (++ind; ind < HASH_COUNT; ++ind) {
00699             hash_keywords[ind] = get_directive_keyword(ind);
00700         }
00701     }
00702     printf("#%s %s",hash_keywords[directive_type],canonical_string_text(cl));
00703     if (GET_PUBLIC(args,list_locate)) {
00704         printf(": %s(%d)",GET_PUBLIC(io,filename),GET_PUBLIC(io,line_num));
00705     }
00706     putchar('\n');
00707 }
00708 
00709 char *
00710 format_int(int_spec_t const *int_spec)
00711 {
00712     static char numeral[48];
00713     switch(int_spec->type) {
00714     case INT_CHAR:
00715     case INT_UCHAR:
00716         sprintf(numeral,"%d ('%c')",int_spec->val.i,(char)int_spec->val.i);
00717         break;
00718     case INT_SHORT:
00719         sprintf(numeral,"%hd",(short)int_spec->val.i);
00720         break;
00721     case INT_USHORT:
00722         sprintf(numeral,"%hu",(unsigned short)int_spec->val.i);
00723         break;
00724     case INT_INT:
00725         sprintf(numeral,"%d",int_spec->val.i);
00726         break;
00727     case INT_UINT:
00728         sprintf(numeral,"%u",int_spec->val.ui);
00729         break;
00730     case INT_LONG:
00731         sprintf(numeral,"%ld",int_spec->val.l);
00732         break;
00733     case INT_ULONG:
00734         sprintf(numeral,"%lu",int_spec->val.ul);
00735         break;
00736     case INT_LLONG:
00737 #ifdef GNUWIN
00738         sprintf(numeral,"%I64d",int_spec->val.ll);
00739 #else
00740         sprintf(numeral,"%lld",int_spec->val.ll);
00741 #endif
00742         break;
00743     case INT_ULLONG:
00744 #ifdef GNUWIN
00745         sprintf(numeral,"%I64u",int_spec->val.ull);
00746 #else
00747         sprintf(numeral,"%llu",int_spec->val.ull);
00748 #endif
00749         break;
00750     default:
00751         assert(false);
00752         break;
00753     }
00754     return clone(numeral,0);
00755 }
00756 
00757 
00758 /* EOF*/
00759 
00760 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines