"Fossies" - the Fresh Open Source Software Archive

Member "statist-1.4.2/src/statist.c" (21 Dec 2009, 31174 Bytes) of package /linux/privat/old/statist-1.4.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "statist.c" see the Fossies "Dox" file reference documentation.

    1 /* This file is part of statist
    2 **
    3 ** It is distributed under the GNU General Public License.
    4 ** See the file COPYING for details.
    5 **
    6 ** (c) 1997 Dirk Melcher
    7 **  Doerper Damm 4
    8 **  49134 Wallenhorst
    9 **  GERMANY
   10 **  Tel. 05407/7636
   11 **  email: Dirk.Melcher@usf.Uni-Osnabrueck.DE
   12 **
   13 **  some changes by Bernhard Reiter  http://www.usf.Uni-Osnabrueck.DE/~breiter
   14 **  $Id: statist.c,v 1.41 2009/12/21 17:08:51 jakson Exp $
   15 ***************************************************************/
   16 
   17 /* statist.c */
   18 
   19 #include <stdio.h>
   20 #include <stdlib.h>
   21 #include <stdarg.h>
   22 #include <string.h>
   23 #include <signal.h>
   24 #include <dirent.h>
   25 #ifndef NO_VALUES_H
   26 #include <values.h>
   27 #endif
   28 #ifndef NO_IOCTIL_H
   29 #include <sys/ioctl.h> /* terminal number of columns and lines */
   30 #endif
   31 #ifndef MSDOS
   32 #include <unistd.h> /* getlogin */
   33 #include <pwd.h> /* getpwnam */
   34 #endif
   35 
   36 #include "statist.h"
   37 #include "menue.h"
   38 #include "data.h"
   39 #include "funcs.h"
   40 #include "plot.h"
   41 #include "gettext.h"
   42 
   43 typedef struct {
   44   char *optstr;
   45   BOOLEAN *optvar;
   46 } OPTREC;
   47 
   48 BOOLEAN get_options(char **args, int options[], int nopt, OPTREC optrec[]);
   49 BOOLEAN read_options();
   50 void help_msg();
   51 void set_prefs_filename();
   52 
   53 #ifndef MSDOS
   54 void handle_pipe_interrupt(int sig);
   55 char * user_dir();
   56 #endif
   57 void handle_fpe_interrupt(int sig);
   58 void handle_term_interrupt(int sig);
   59 void set_default_colors();
   60 
   61 Labels **names;
   62 Labels *first_labels, *old_first_labels;
   63 PREAL   *xx, *yy, tempcol;
   64 #ifndef NO_VALUES_H
   65 REAL SYSMIS = (-DBL_MAX);
   66 #else
   67 REAL SYSMIS = (1.79769313486231570e-308);
   68 #endif
   69 char  *sourcename;
   70 char *NODATA = NULL;
   71 char sep = 0;
   72 char dec = '.';
   73 int     *nn, *vn, *acol, *ny;
   74 int MRESULT = 200;
   75 
   76 int SCRCOLS, SCRLINES; /* terminal number of cols and lines */
   77 int rcols = 0, rlines = 0; /* values for SCRCOLS and SCRLINES read from
   78                   statistrc (or set in Preferences menu) */
   79 
   80 BOOLEAN is_utf8;
   81 int MCOL = 0;
   82 BOOLEAN *x_read, empty, gnupl_open=FALSE;
   83 int     ncol=0, status;
   84 char    line[MLINE];
   85 char    **alias; /* Column labels*/
   86 FILE    **tmpptr; /* Pointers to temporary files */
   87 FILE    *logfile;
   88 
   89 BOOLEAN silent=FALSE, noplot=FALSE, help=FALSE, log_set=FALSE, nofile=FALSE,
   90     nobell=FALSE, thist=FALSE, bernhard=FALSE, xsample=FALSE, xcols=FALSE,
   91     color=FALSE, version=FALSE, noheader=FALSE, has_header=FALSE;
   92 BOOLEAN system_ls = FALSE, verbose = TRUE, format_columns_out = TRUE,
   93     detect_header = TRUE, ask_fileformat = FALSE, int_as_int = FALSE;
   94 
   95 FILE    *pipef;
   96 
   97 char msdos_temp_dir[255];
   98 char *ls_cmd; /* Command send to system to list content of current directory */
   99 char *saved_locale, *old_locale, *prefs_filename, *gtprefix, *gplt_default_term,
  100      *gplt_png;
  101 char *clError, *clInstr, *clHeader, *clLineNum,  *clMenuSep;
  102 
  103 /* ================================================================== */
  104 
  105 #ifndef NO_GETTEXT
  106 BOOLEAN get_utf8_status(){
  107   char *s;
  108   s = setlocale(LC_CTYPE, NULL);
  109   if(strstr(s, "UTF-8") != NULL)
  110     return TRUE;
  111   else
  112     return FALSE;
  113 }
  114 
  115 size_t stringLen(char *s){
  116   wchar_t dest[256];
  117   if(is_utf8)
  118     return mbstowcs(dest, s, 255);
  119   else
  120     return strlen(s);
  121 }
  122 #else
  123 size_t stringLen(char *s){
  124   return strlen(s);
  125 }
  126 #endif
  127 
  128 
  129 int main(int argc, char *argv[]) {
  130    int   i, labelsfile = 0;
  131    BOOLEAN source_set=FALSE;
  132    BOOLEAN has_strc;
  133    int options[MOPT], nopt=0;
  134 #ifdef MSDOS
  135    char *s;
  136    s = getenv("TMP");
  137    if(strlen(s))
  138      strcpy(msdos_temp_dir, s);
  139    else
  140      strcpy(msdos_temp_dir, "C:\\tmp");
  141    set_prefs_filename(argv[0]);
  142    has_strc = FALSE;
  143 #endif
  144 
  145    NODATA = (char*)mymalloc(2 * sizeof(char));
  146    strcpy(NODATA, "M");
  147 
  148    OPTREC optrec[MOPT] = {
  149       {"-h", &help}, {"-help", &help}, {"--help", &help}, {"-?", &help},
  150       {"-silent", &silent}, {"--silent", &silent},
  151       {"-noplot", &noplot}, {"--noplot", &noplot},
  152       {"-log", &log_set}, {"--log", &log_set},
  153       {"-nofile", &nofile}, {"--nofile", &nofile},
  154       {"-nobell", &nobell}, {"--nobell", &nobell},
  155       {"-thist", &thist}, {"--thist", &thist},
  156       {"--bernhard",&bernhard},
  157       {"--header", &has_header},
  158       {"--noheader", &noheader},
  159       {"--xsample", &xsample},
  160       {"--xcols", &xcols},
  161       {"--color", &color},
  162       {"--quiet",&silent},
  163       {"--version", &version} };
  164 
  165 #ifndef MSDOS
  166    prefs_filename = (char*)mymalloc(15 * sizeof(char));
  167    strcpy(prefs_filename, "/etc/statistrc");
  168    has_strc = read_options();
  169    myfree(prefs_filename);
  170    prefs_filename = NULL;
  171    set_prefs_filename();
  172    signal(SIGPIPE, handle_pipe_interrupt);
  173 #endif
  174    signal(SIGFPE, handle_fpe_interrupt);
  175    signal(SIGINT, handle_term_interrupt);
  176    signal(SIGTERM, handle_term_interrupt);
  177 
  178 #ifndef NO_GETTEXT
  179    setlocale (LC_ALL, "");
  180 #ifdef MSDOS
  181    char locale_dir[255];
  182    strcpy(locale_dir, prefs_filename);
  183    int k = strlen(locale_dir);
  184    for(i = (k-1); i > 0; i--)
  185      if(locale_dir[i] == '/'){
  186        locale_dir[i] = 0;
  187        break;
  188      }
  189    strcat(locale_dir, "/locale");
  190    bindtextdomain (PACKAGE, locale_dir);
  191 #else
  192    bindtextdomain (PACKAGE, LOCALEDIR);
  193 #endif
  194    textdomain (PACKAGE);
  195    is_utf8 = get_utf8_status();
  196 #endif
  197 
  198    if(has_strc)
  199      read_options();
  200    else
  201      has_strc = read_options();
  202 
  203    set_default_colors();
  204    for (i=1; i<argc; i++) {
  205      if (argv[i][0]=='-') {
  206        options[nopt] = i;
  207        nopt ++;
  208        if (nopt > MOPT) {
  209      out_err(FAT, ERR_FILE, ERR_LINE, _("Too many options") );
  210        }
  211      }
  212    }
  213 
  214    if (!get_options(argv, options, nopt, optrec)) {
  215      exit(1);
  216    }
  217    out_d(_(VERSION_INFO), _STATIST_VERSION_NUMBER);
  218 #ifdef DEBUG
  219    out_d(_(" Compiled with DEBUG.\n"));
  220 #ifndef NO_GETTEXT
  221   #ifdef MSDOS
  222     out_d(" LOCALEDIR=%s\n", locale_dir);
  223   #else
  224     out_d(" LOCALEDIR=%s\n", LOCALEDIR);
  225   #endif
  226 #endif
  227 #endif
  228 
  229   if(version){
  230     exit(0);
  231   }
  232   if(silent)
  233     verbose = FALSE;
  234 
  235   if(noheader)
  236     detect_header = FALSE;
  237 
  238   if(verbose){
  239     out_d(_(" Hint: You can often answer \"%s\" for the number of columns.\n"),
  240     _(_ALL_) );
  241 #ifndef MSDOS
  242     if(has_strc == FALSE)
  243       out_d(_("\n You can create an ~/.statistrc file to increase statist "
  244         "functionality.\n There is an example of statistrc at %s.\n"),
  245       DOCDIR);
  246 #endif
  247   }
  248 
  249    out_d("\n");
  250    if (help) {
  251      help_msg();
  252      exit(0);
  253    }
  254 
  255    if(xsample){
  256      extract_sample(argc, argv);
  257      finish();
  258      exit(0);
  259    }
  260 
  261    for (i=1; i<argc; i++) {
  262      if (!(argv[i][0]=='-')){
  263        if(strcmp(argv[i-1], "--labels") == 0){
  264      labelsfile = i;
  265        } else
  266      if(strcmp(argv[i-1], "--na-string") == 0){
  267        NODATA = (char*)mymalloc((strlen(argv[i]) + 1) * sizeof(char));
  268        strcpy(NODATA, argv[i]);
  269      } else
  270        if(strcmp(argv[i-1], "--sep") == 0){
  271          if(strcmp(argv[i], "\\t") == 0)
  272            sep = '\t';
  273          else
  274            sep = argv[i][0];
  275        } else
  276          if(strcmp(argv[i-1], "--dec") == 0){
  277            dec = argv[i][0];
  278          } else
  279            if(!xcols){
  280          if (!source_set) {
  281            sourcename = (char*) mycalloc(strlen(argv[i]) + 1, sizeof(char));
  282            strcpy(sourcename, argv[i]);
  283            source_set = TRUE;
  284          }
  285          else {
  286            if(silent)
  287              out_err(FAT, ERR_FILE, ERR_LINE,
  288              _(" More than one data file given!"));
  289            else{
  290              out_err(ERR, ERR_FILE, ERR_LINE,
  291              _(" More than one data file given!\n"
  292                "   Only the first one will be read."));
  293              if(verbose)
  294                out_d(_(
  295                  "   If you really want to load more than one file, please\n"
  296                  "   choose the menu option:\n"
  297                  "   'Data management | Read another file'\n"));
  298              mywait();
  299            }
  300          }
  301            }
  302      }
  303    }
  304 
  305    if(xcols){
  306      extract_cols(argc, argv);
  307      finish();
  308      exit(0);
  309    }
  310 
  311    if ( (!source_set) && (!nofile) ) {
  312      ls();
  313      out_i(_("Name of data file: ") );
  314      GETNLINE
  315        if (empty) {
  316      out_d(_("No data file given. "));
  317      nofile = TRUE;
  318        } else {
  319      sourcename = (char*) mycalloc(strlen(line) + 1, sizeof(char));
  320      sscanf(line, "%s", sourcename);
  321      if(!(myexist(sourcename))){
  322        nofile = TRUE;
  323        out_err(ERR, ERR_FILE, ERR_LINE,
  324            _("File \"%s\" not found!"), sourcename);
  325        myfree(sourcename);
  326        sourcename = NULL;
  327      }
  328        }
  329    }
  330 
  331    if (log_set) {
  332      FOPEN("statist.log", "wt", logfile);
  333      if(!nofile)
  334        out_r(_("Source file = %s\n\n"), sourcename);
  335    }
  336 
  337    if(dec != '.' && dec != ','){
  338      if(silent){
  339        out_err(WAR, ERR_FILE, ERR_LINE,
  340        _("Invalid decimal delimiter: '%c'. Please, choose either ',' or '.'"), dec);
  341      } else{
  342        out_err(ERR, ERR_FILE, ERR_LINE,
  343        _("Invalid decimal delimiter: '%c'. Please, choose either ',' or '.'"), dec);
  344        if(!nofile)
  345      show_file_head(sourcename);
  346        set_fileformat();
  347      }
  348    }
  349 
  350    if(sep && !(sep == ' '  || sep == ',' || sep == ';' || sep == '\t')){
  351        if(silent){
  352      out_err(WAR, ERR_FILE, ERR_LINE, _("Invalid field separator: '%c'"), sep);
  353        } else{
  354      out_err(ERR, ERR_FILE, ERR_LINE, _("Invalid field separator: '%c'"), sep);
  355      if(!nofile)
  356        show_file_head(sourcename);
  357      set_fileformat();
  358        }
  359      }
  360 
  361    if(nofile){
  362      out_d(_("Load file using menu option\n"
  363        "Data management | Read another file\n"));
  364    } else{
  365      readsourcefile(sourcename);
  366      mywait();
  367    }
  368    out_d("\n");
  369 
  370    if(labelsfile){
  371      if(myexist(argv[labelsfile]))
  372        read_labels(argv[labelsfile]);
  373      else{
  374        out_err(ERR, ERR_FILE, ERR_LINE,
  375        _("File \"%s\" not found!"),
  376        argv[labelsfile]);
  377      }
  378    }
  379 
  380    main_menue();
  381    finish();
  382    return 0;
  383 }
  384 
  385 /* =================================================================== */
  386 
  387 void finish() {
  388   int i;
  389   Labels *ptr;
  390    erasetempfiles();
  391    if (log_set) {
  392      FCLOSE(logfile);
  393    }
  394 #ifndef NOPIPE
  395    if (gnupl_open == TRUE) {
  396      fprintf(pipef, "quit\n");
  397      pclose(pipef);
  398    }
  399    if (myexist(GPL_DAT)) {
  400      remove(GPL_DAT);
  401    }
  402 #endif
  403    if(prefs_filename)
  404      myfree(prefs_filename);
  405    if(sourcename)
  406      myfree(sourcename);
  407    if(ls_cmd)
  408      myfree(ls_cmd);
  409    if(gnuplot_charset)
  410      myfree(gnuplot_charset);
  411    if(old_first_labels)
  412      first_labels = old_first_labels;
  413    while(first_labels){
  414      ptr = first_labels->next;
  415      myfree(first_labels->clabel);
  416      myfree(first_labels->ctitle);
  417      for(i = 0; i < first_labels->n; i++){
  418        myfree(first_labels->l[i]);
  419      }
  420      myfree(first_labels->v);
  421      myfree(first_labels->l);
  422      myfree(first_labels);
  423      first_labels = ptr;
  424    }
  425    if(plothist){
  426      for(i = 0; i < histsize; i++)
  427        if(plothist[i])
  428      myfree(plothist[i]);
  429      myfree(plothist);
  430    }
  431    if(gplt_png)
  432      myfree(gplt_png);
  433    if(clError)
  434      myfree(clError);
  435    if(clInstr)
  436      myfree(clInstr);
  437    if(clHeader)
  438      myfree(clHeader);
  439    if(clLineNum)
  440      myfree(clLineNum);
  441    if(clMenuSep)
  442      myfree(clMenuSep);
  443    if(gtprefix)
  444      myfree(gtprefix);
  445    myfree(NODATA);
  446 }
  447 
  448 
  449 
  450 void help_msg() {
  451 out_d(_("Usage:\n"
  452       "  statist [ options ] data_file\n"));
  453 out_d(_("Options:\n"));
  454 out_d(_("--help, -h, -?  : print this help message and exit\n"));
  455 out_d(_("--silent, --quiet\n"
  456         "                : don't print menu etc. (for batch/script usage)\n"));
  457 out_d(_("--log           : write results to log file `statist.log'\n"));
  458 out_d(_("--nofile        : don't read a data file when starting the program\n"));
  459 out_d(_("--nobell        : no beep at errors and warnings\n"));
  460 out_d(_("--thist         : histogram as text graphic instead of gnuplot-graphic\n"));
  461 out_d(_("--noplot        : no gnuplot-graphic\n"));
  462 #ifndef MSDOS
  463 out_d(_("--color         : colorized output\n"));
  464 #endif
  465 out_d(_("--labels <file> : read column titles and value labels from file\n"));
  466 out_d(_("--header        : the file has column names in the first line\n"));
  467 out_d(_("--noheader      : the file does not have column names\n"));
  468 out_d(_("--sep <char>    : field separator character\n"));
  469 out_d(_("--dec <char>    : decimal delimiter character (default: '.')\n"));
  470 out_d(_("--na-string <string>\n"
  471 "                : indicator of missing values (default: \"M\")\n"));
  472 out_d(_("--xcols <conf_file> <orig_datafile> <new_data_file>\n"
  473 "                : extract columns from a fixed width data file\n"));
  474 out_d(_("--xsample <percentage> <database> <dest_file>\n"
  475 "                : extract a sample of rows from a file\n"));
  476 out_d(_("--bernhard      : special output changes from Bernhard, i.e.:\n"
  477 "                  - table output at Miscellaneous/Standard deviation\n"
  478 "                  - if --noplot defined no text histogram at\n"
  479 "                       Miscellaneous/Standard deviation\n"));
  480 out_d("\n");
  481 out_d(_("Missing values must be indicated by '%s'\n"), NODATA);
  482 #ifndef MSDOS
  483 #ifdef DOCDIR
  484 out_d("\n");
  485 out_d(_("Statist documentation can be found at: %s\n"), DOCDIR);
  486 #endif
  487 #endif
  488 }
  489 
  490 /* =================================================================== */
  491 
  492 BOOLEAN get_options(char **args, int options[], int nopt, OPTREC optrec[]) {
  493   int i, k;
  494   BOOLEAN found;
  495 
  496   for (i=0; i<nopt; i++) {
  497     found = FALSE;
  498     for (k=0; k<MOPT; k++) {
  499       if (strcmp(args[options[i]], optrec[k].optstr) == 0) {
  500     *(optrec[k].optvar) = TRUE;
  501     found = TRUE;
  502     if ((strlen(optrec[k].optstr) > 2) && optrec[k].optstr[0] == '-'
  503         && optrec[k].optstr[1] != '-')
  504       out_err(WAR, ERR_FILE, ERR_LINE,
  505           _("The option short format %s is deprecated\n"
  506         "  and might be removed some time in the future.\n"
  507         "  Use -%s instead."), optrec[k].optstr, optrec[k].optstr);
  508     break;
  509       }
  510     }
  511     if (!found && !(strcmp(args[options[i]], "--labels") == 0 || 
  512       strcmp(args[options[i]], "--na-string") == 0 || 
  513       strcmp(args[options[i]], "--dec") == 0 || 
  514       strcmp(args[options[i]], "--sep") == 0)) {
  515       out_err(ERR, ERR_FILE, ERR_LINE,
  516         _("Illegal option: '%s'. Try -h for help."), args[options[i]]);
  517       return FALSE;
  518     }
  519   }
  520   return TRUE;
  521 }
  522 
  523 /* =================================================================== */
  524 
  525 void mywait() {
  526   if (!silent) {
  527     out_i(_("  --- Please, continue with <RETURN> ... ---") );
  528     GETRLINE
  529   }
  530 }
  531 
  532 
  533 
  534 BOOLEAN myexist(char *name) {
  535   FILE *F;
  536   F = fopen(name,"r");
  537   if (F) {
  538     fclose(F);
  539     return TRUE;
  540   }
  541   else {
  542     return FALSE;
  543   }
  544 }
  545 
  546 
  547 /* This function is not very good, but it's possible to use the system "ls".
  548  * It will be used only if for some reason the user preferred it.  */
  549 BOOLEAN ls(){
  550   struct dirent* entry;
  551   DIR* dir;
  552   char s[10];
  553   int i, l = 1, nc;
  554   if(silent)
  555     return(TRUE);
  556   if(system_ls && ls_cmd != NULL){
  557     out_d("\n");
  558     out_d(_("Content of current directory:"));
  559     out_d("\n\n");
  560     i = system(ls_cmd);
  561     out_d("\n");
  562     if(i == 0)
  563       return(TRUE);
  564     else
  565       out_err(WAR, ERR_FILE, ERR_LINE,
  566       _("Error while running the command \"%s\"."), ls_cmd);
  567   }
  568   dir = opendir(".");
  569   if (!dir) {
  570     perror("opendir");
  571     return FALSE;
  572   } else{
  573     set_winsize();
  574     out_d("\n");
  575     out_d(_("Content of current directory:"));
  576     out_d("\n");
  577     if(format_columns_out){
  578       while((entry = readdir(dir)) != NULL){
  579     if(entry->d_name[0] != '.'){
  580       i = strlen(entry->d_name) + 1;
  581       if(i > l)
  582         l = i;
  583     }
  584       }
  585       sprintf(s, "%%-%is ", l); /* formatting the column width */
  586       nc = SCRCOLS / l; /* number of columns */
  587       rewinddir(dir);
  588       i = 0;
  589       while((entry = readdir(dir)) != NULL){
  590     if(entry->d_name[0] != '.'){
  591       if((i % nc) == 0)
  592         out_d("\n");
  593       out_d(s, entry->d_name);
  594       i++;
  595     }
  596       }
  597     } else{
  598       while((entry = readdir(dir)) != NULL)
  599     if(entry->d_name[0] != '.')
  600       out_d("%s  ", entry->d_name);
  601     }
  602     if (closedir(dir) == -1) {
  603       perror("closedir");
  604       return FALSE;
  605     }
  606     out_d("\n\n");
  607   }
  608   return TRUE;
  609 }
  610 
  611 void out_r(char *fmt, ...) {
  612   va_list argptr;
  613 
  614   va_start(argptr, fmt);
  615   vprintf(fmt, argptr);
  616   va_end(argptr);
  617   if (log_set) {
  618     va_start(argptr, fmt);
  619     vfprintf(logfile, fmt, argptr);
  620     va_end(argptr);
  621   }
  622 }
  623 
  624 
  625 void out_d(char *fmt, ...) {
  626   va_list argptr;
  627 
  628   if (!silent) {
  629     va_start(argptr, fmt);
  630     vprintf(fmt, argptr);
  631     va_end(argptr);
  632   }
  633 }
  634 
  635 void out_i(char *fmt, ...) {
  636   va_list argptr;
  637 
  638   if (!silent) {
  639     va_start(argptr, fmt);
  640     colorize(ClInstr);
  641     vprintf(fmt, argptr);
  642     colorize(ClDefault);
  643     va_end(argptr);
  644   }
  645 }
  646 
  647 
  648 
  649 void out_err(int errn, char *modulname, int lno, char *fmt, ...) {
  650   va_list argptr;
  651   char where[128];
  652 
  653   va_start(argptr, fmt);
  654   switch (errn) {
  655     case WAR: strcpy(line, _("> statist-warning ") );
  656       break;
  657     case ERR: strcpy(line, _("> statist-error ") );
  658       break;
  659     case FAT: strcpy(line, _("\n> statist-fatal error ") );
  660       break;
  661     case MAT: strcpy(line, _("> statist-numerical error ") );
  662       break;
  663     case MWA: strcpy(line, _("> statist-warning ") );
  664       break;
  665   }
  666 
  667   if (lno != 0) {
  668     sprintf(where, _("(Module %15s, line %i):\n  "), modulname, lno);
  669     strncat(line, where, 254-strlen(line));
  670   }
  671   else {
  672     strncat(line, ":\n  ", 254-strlen(line));
  673   }
  674   strncat(line, fmt, 254-strlen(line));
  675   strncat(line, "\n\n", 254-strlen(line));
  676 
  677   if(!nobell)
  678     fprintf(stderr, "\a");
  679 
  680   colorize(ClError);
  681   if(errn == FAT && !(silent)){
  682     strncat(line, "> ", 254-strlen(line));
  683     strncat(line, _("Please, report bugs to: statist-list@intevation.de\n\n"),
  684     254-strlen(line));
  685   }
  686   vfprintf(stderr, line, argptr);
  687   if ( ((errn==MAT) || (errn==MWA)) && (log_set) ) {
  688     vfprintf(logfile, line, argptr);
  689   }
  690   colorize(ClErrorD);
  691   va_end(argptr);
  692 
  693   fflush(stderr);
  694   if (errn == FAT) {
  695     finish();
  696     exit(1);
  697   }
  698 }
  699 
  700 
  701 
  702 /* =================================================================== */
  703 
  704 void print_histo(REAL x[], int y[], int n) {
  705   int maxclass;
  706   int   k, cols, i;
  707   char show[80];
  708 
  709   maxclass = get_maxint(y, n);
  710   for (i=0; i<n; i++) {
  711     cols = y[i]*60/maxclass;
  712     strcpy(show,"");
  713     for (k=0; k<cols; k++) {
  714       strcat(show, "*");
  715     }
  716     out_r("%9f %s %i\n", x[i], show, y[i]);
  717     if (((i+1) % (SCRLINES - 1)) == 0) {
  718       mywait();
  719     }
  720   }
  721 }
  722 
  723 
  724 /* =================================================================== */
  725 
  726 #ifndef MSDOS
  727 void handle_pipe_interrupt(int sig) {
  728   gnupl_open = FALSE;
  729   out_err(WAR, ERR_FILE, ERR_LINE,
  730     _("Broken pipe to gnuplot. Re-connecting.") );
  731   pclose(pipef);
  732 }
  733 #endif
  734 
  735 void handle_fpe_interrupt(int sig) {
  736   out_err(FAT, ERR_FILE, ERR_LINE,
  737     _("Signal from operating system: floating point exception\n\
  738         Division by zero? Terminating!") );
  739 }
  740 
  741 void handle_term_interrupt(int sig) {
  742   out_d("\n\nstatist: ");
  743   out_d(_("Received signal SIGTERM (Ctrl-C?). Terminating!") );
  744   out_d("\nstatist: ");
  745   out_d(_("Please, report bugs to: statist-list@intevation.de\n\n"));
  746   finish();
  747   exit(1);
  748 }
  749 
  750 #ifdef MSDOS
  751 void set_prefs_filename(char *p){
  752   char *s;
  753   int i, l;
  754   s = (char*)mymalloc(300 * sizeof(char));
  755    strcpy(s, p);
  756    l = strlen(s);
  757    i = 0;
  758    for(i = 0; i < l; i++)
  759      if(s[i] == '\\')
  760        s[i] = '/';
  761    for(i = (l-1); i > 0; i--)
  762      if(s[i] == '/'){
  763        s[i] = 0;
  764        break;
  765      }
  766    strcat(s, "/statistrc.txt");
  767 #else
  768 void set_prefs_filename(){
  769   char *s;
  770   struct passwd *uinf = NULL;
  771   s = getlogin();
  772   if(s == NULL)
  773     return;
  774   uinf = getpwnam(s);
  775   if(uinf == NULL)
  776     return;
  777   s = (char*)mymalloc((12 + strlen(uinf->pw_dir)) * sizeof(char));
  778   strcpy(s, uinf->pw_dir);
  779   strcat(s, "/.statistrc");
  780 #endif
  781   prefs_filename = (char*)mymalloc((strlen(s) + 1) * sizeof(char));
  782   strcpy(prefs_filename, s);
  783   myfree(s);
  784 }
  785 
  786 void set_color(char *opt, char *value){
  787   char s[20], *v, *t;
  788   s[0] = 0;
  789   
  790   if(strstr(value, "underln") == value){
  791     sprintf(s, "\033[3;");
  792     v = value + 7;
  793   } else{
  794     if(strstr(value, "bright") == value){
  795       sprintf(s, "\033[1;");
  796       v = value + 6;
  797     } else{
  798       if(strstr(value, "blink") == value){
  799     sprintf(s, "\033[5;");
  800     v = value + 5;
  801       } else{
  802     if(strstr(value, "dim") == value){
  803       sprintf(s, "\033[2;");
  804       v = value + 3;
  805     } else{
  806       sprintf(s, "\033[");
  807       v = value;
  808     }
  809       }
  810     }
  811   }
  812   if(strcmp(v, "magenta") == 0){
  813     strcat(s, "35m");
  814   } else 
  815     if(strcmp(v, "yellow") == 0){
  816       strcat(s, "33m");
  817     } else 
  818       if(strcmp(v, "green") == 0){
  819     strcat(s, "32m");
  820       } else 
  821     if(strcmp(v, "cyan") == 0){
  822       strcat(s, "36m");
  823     } else 
  824       if(strcmp(v, "blue") == 0){
  825         strcat(s, "34m");
  826       } else 
  827         if(strcmp(v, "white") == 0){
  828           strcat(s, "37m");
  829         } else 
  830           if(strcmp(v, "black") == 0){
  831         strcat(s, "30m");
  832           } else 
  833         if(strcmp(v, "red") == 0){
  834           strcat(s, "31m");
  835         }
  836 
  837   if(strlen(s) < 5){
  838     out_err(WAR, ERR_FILE, ERR_LINE,
  839     _("Unknown color name \"%s\" in file \"%s\"."), value, prefs_filename);
  840     return;
  841   }
  842   t = (char*)mymalloc((strlen(s) + 1) * sizeof(char));
  843   strcpy(t, s);
  844   if((strcmp(opt, "cl_menu_separator") == 0)){
  845     if(clMenuSep)
  846       myfree(clMenuSep);
  847     clMenuSep = t;
  848   } else
  849     if((strcmp(opt, "cl_header") == 0)){
  850       if(clHeader)
  851     myfree(clHeader);
  852       clHeader = t;
  853     } else
  854       if((strcmp(opt, "cl_line_num") == 0)){
  855     if(clLineNum)
  856       myfree(clLineNum);
  857     clLineNum = t;
  858       } else
  859     if((strcmp(opt, "cl_error") == 0)){
  860       if(clError)
  861         myfree(clError);
  862       clError = t;
  863     } else
  864       if((strcmp(opt, "cl_instructions") == 0)){
  865         if(clInstr)
  866           myfree(clInstr);
  867         clInstr = t;
  868       } else{
  869         myfree(t);
  870       }
  871 }
  872 
  873 void set_default_colors(){
  874   if(clError == NULL){
  875     clError = (char*)mymalloc(8 * sizeof(char));
  876     strcpy(clError, "\033[1;31m");
  877   }
  878   if(clInstr == NULL){
  879     clInstr = (char*)mymalloc(6 * sizeof(char));
  880     strcpy(clInstr, "\033[33m");
  881   }
  882   if(clHeader == NULL){
  883     clHeader = (char*)mymalloc(8 * sizeof(char));
  884     strcpy(clHeader, "\033[1;37m");
  885   }
  886   if(clLineNum == NULL){
  887     clLineNum = (char*)mymalloc(6 * sizeof(char));
  888     strcpy(clLineNum, "\033[35m");
  889   }
  890   if(clMenuSep == NULL){
  891     clMenuSep = (char*)mymalloc(6 * sizeof(char));
  892     strcpy(clMenuSep, "\033[34m");
  893   }
  894 }
  895 
  896 BOOLEAN read_options(){
  897   char *s, b[255], opt[128], value[128];
  898   FILE *F;
  899   int i, k;
  900 
  901   if(!ls_cmd){
  902 #ifndef MSDOS
  903     ls_cmd = (char*)mymalloc(3 * sizeof(char));
  904     strcpy(ls_cmd, "ls");
  905 #else
  906     ls_cmd = (char*)mymalloc(4 * sizeof(char));
  907     strcpy(ls_cmd, "DIR");
  908 #endif
  909   }
  910   if(!(prefs_filename && myexist(prefs_filename)))
  911     return FALSE;
  912 
  913   FOPEN(prefs_filename, "r", F);
  914   while(fgets(b, 254, F)){
  915     s = b;
  916     while(s[0] == ' ' || s[0] == '\t')
  917       s++;
  918     if(strlen(s) < 4)
  919       continue;
  920     if(s[0] == '#')
  921       continue;
  922     memset(opt, 0, 128);
  923     memset(value, 0, 128);
  924     i = 0;
  925     while(i < 128 && ((s[0] >= 'a' && s[0] <= 'z') ||
  926       (s[0] >= '0' && s[0] <= '9') || s[0] == '_')){
  927       opt[i] = s[0];
  928       i++;
  929       s++;
  930     }
  931 
  932     /* Don't remove \" from neither gnuplot_default_term nor gnuplot_png_font */
  933     if(strcmp(opt, "gnuplot_png_font") == 0 || 
  934     strcmp(opt, "gnuplot_default_term") == 0){
  935       while(s[0] == ' ' || s[0] == '\t' || s[0] == '=')
  936     s++;
  937     } else{
  938       while(s[0] == ' ' || s[0] == '\t' || s[0] == '=' || 
  939       s[0] == '\"' || s[0] == '\'')
  940     s++;
  941     }
  942     i = 0;
  943     while(s[i] != '\n'){
  944       value[i] = s[i];
  945       i++;
  946     }
  947     i--;
  948     if(strcmp(opt, "gnuplot_png_font") == 0 || 
  949     strcmp(opt, "gnuplot_default_term") == 0)
  950       while(value[i] == ' ' || value[i] == '\t'){
  951     value[i] = 0;
  952     i--;
  953       }
  954     else
  955       while(value[i] == ' ' || value[i] == '\t' || value[i] == '\"'
  956       || s[0] == '\''){
  957     value[i] = 0;
  958     i--;
  959       }
  960 
  961     if(strcmp(opt, "gnuplot_png_font") == 0){
  962       i = strlen(value) + 1;
  963       if(i > 3){
  964     if(gplt_png)
  965       myfree(gplt_png);
  966     gplt_png = (char*)mymalloc(i * sizeof(char));
  967     strcpy(gplt_png, value);
  968       }
  969     }
  970     if(strcmp(opt, "gnuplot_default_term") == 0){
  971       i = strlen(value) + 1;
  972       if(i > 3){
  973     if(gplt_default_term)
  974       myfree(gplt_default_term);
  975     gplt_default_term = (char*)mymalloc(i * sizeof(char));
  976     strcpy(gplt_default_term, value);
  977       }
  978     }
  979     if(strcmp(opt, "use_gnuplot") == 0)
  980       if(strcmp(value, "no") == 0)
  981     noplot = TRUE;
  982     if(strcmp(opt, "graphs_title_prefix") == 0){
  983       i = strlen(value) + 1;
  984       if(i > 1){
  985     if(gtprefix)
  986       myfree(gtprefix);
  987     gtprefix = (char*)mymalloc(i * sizeof(char));
  988     strcpy(gtprefix, value);
  989       }
  990     }
  991     if(strcmp(opt, "color") == 0)
  992       if(strcmp(value, "yes") == 0)
  993     color = TRUE;
  994     if(opt[0] == 'c' && opt[1] == 'l' && opt[2] == '_')
  995       set_color(opt, value);
  996     if(strcmp(opt, "log") == 0)
  997       if(strcmp(value, "yes") == 0)
  998     log_set = TRUE;
  999     if(strcmp(opt, "bell") == 0)
 1000       if(strcmp(value, "no") == 0)
 1001     nobell = TRUE;
 1002     if(strcmp(opt, "text_histogram") == 0)
 1003       if(strcmp(value, "yes") == 0)
 1004     thist = TRUE;
 1005     if(strcmp(opt, "bernhard") == 0)
 1006       if(strcmp(value, "yes") == 0)
 1007     bernhard = TRUE;
 1008     if(strcmp(opt, "verbose") == 0)
 1009       if(strcmp(value, "no") == 0)
 1010     verbose = FALSE;
 1011     if(strcmp(opt, "max_results") == 0){
 1012       k = atoi(value);
 1013       if(k > 5 && k < 1000000)
 1014     MRESULT = k;
 1015     }
 1016     if(strcmp(opt, "screen_lines") == 0){
 1017       k = atoi(value);
 1018       if(k > 10 && k < 100)
 1019     rlines = k;
 1020     }
 1021     if(strcmp(opt, "screen_columns") == 0){
 1022       k = atoi(value);
 1023       if(k > 10 && k < 200)
 1024     rcols = k;
 1025     }
 1026     if(strcmp(opt, "format_columns_out") == 0)
 1027       if(strcmp(value, "no") == 0)
 1028     format_columns_out = FALSE;
 1029     if(strcmp(opt, "use_system_ls") == 0 && strcmp(value, "yes") == 0)
 1030     system_ls = TRUE;
 1031     if(strcmp(opt, "field_separator") == 0 && strlen(value) > 0)
 1032       sep = value[0];
 1033     if(strcmp(opt, "autodetect_header") == 0 && strcmp(value, "no") == 0)
 1034     detect_header = FALSE;
 1035     if(strcmp(opt, "int_as_int_in_ascii_files") == 0 && strcmp(value, "yes") == 0)
 1036     int_as_int = TRUE;
 1037     if(strcmp(opt, "ask_fileformat") == 0 && strcmp(value, "yes") == 0)
 1038     ask_fileformat = TRUE;
 1039     if(strcmp(opt, "na_string") == 0 && (strlen(value)) > 1){
 1040       if(NODATA)
 1041     myfree(NODATA);
 1042       NODATA = (char*)mymalloc(sizeof(char) * (strlen(value) + 1));
 1043       strcpy(NODATA, value);
 1044     }
 1045     if(strcmp(opt, "system_ls_command") == 0 && (strlen(value)) > 1){
 1046       if(ls_cmd)
 1047     myfree(ls_cmd);
 1048       ls_cmd = (char*)mymalloc(sizeof(char) * (strlen(value) + 1));
 1049       strcpy(ls_cmd, value);
 1050     }
 1051     if(strcmp(opt, "gnuplot_charset") == 0 && (strlen(value)) > 1){
 1052       if(gnuplot_charset)
 1053     myfree(gnuplot_charset);
 1054       gnuplot_charset = (char*)mymalloc(sizeof(char) * (strlen(value) + 1));
 1055       strcpy(gnuplot_charset, value);
 1056     }
 1057   }
 1058   FCLOSE(F);
 1059   return TRUE;
 1060 }
 1061 
 1062 char * STRCAT(char *d, char *o, int *max){
 1063   if((strlen(d) + strlen(o)) >= *max){
 1064     *max += 1000;
 1065     d = (char*)myrealloc(d, *max * sizeof(char));
 1066   }
 1067   strcat(d, o);
 1068   return d;
 1069 }
 1070 
 1071 void save_prefs(){
 1072   char *s, b[255], *b2, value[255], opt[255];
 1073   FILE *F;
 1074   int max = 1000, i;
 1075   BOOLEAN found = TRUE, o1 = TRUE, o2 = TRUE, o3 = TRUE, o4 = TRUE,
 1076       o5 = TRUE, o6 = TRUE, o7 = TRUE, o8 = TRUE, o9 = TRUE;
 1077 
 1078   if(prefs_filename == NULL){
 1079     out_err(ERR, ERR_FILE, ERR_LINE,
 1080     _("Could not build the name of the preferences file!"));
 1081     return;
 1082   }
 1083   b2 = (char*)mymalloc(max * sizeof(char));
 1084   b2[0] = 0;
 1085 
 1086   /* Reading the statistrc file, and replacing option values (in the buffer)*/
 1087   if(myexist(prefs_filename)){
 1088     FOPEN(prefs_filename, "r", F);
 1089     while(fgets(b, 254, F)){
 1090       s = b;
 1091       while(s[0] == ' ' || s[0] == '\t')
 1092     s++;
 1093       if(strlen(s) < 4){
 1094     b2 = STRCAT(b2, b, &max);
 1095     continue;
 1096       }
 1097       if(s[0] == '#'){
 1098     b2 = STRCAT(b2, b, &max);
 1099     continue;
 1100       }
 1101       for(i = 0; i < 20; i++){
 1102     opt[i] = 0;
 1103     value[i] = 0;
 1104       }
 1105       i = 0;
 1106       while((s[0] >= 'a' && s[0] <= 'z') || s[0] == '_'){
 1107     opt[i] = s[0];
 1108     i++;
 1109     s++;
 1110       }
 1111       while(s[0] == ' ' || s[0] == '\t' || s[0] == '=')
 1112     s++;
 1113       i = 0;
 1114       while((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= '0' && s[i] <= '9')
 1115       || s[i] == '-' || s[i] == ' '){
 1116     value[i] = s[i];
 1117     i++;
 1118       }
 1119       i--;
 1120       while(value[i] == ' ' || value[i] == '\t'){
 1121     value[i] = 0;
 1122     i--;
 1123       }
 1124       if(strcmp(opt, "verbose") == 0){
 1125     found = TRUE;
 1126     o1 = FALSE;
 1127     if(verbose)
 1128       strcpy(value, "verbose = yes\n");
 1129     else
 1130       strcpy(value, "verbose = no\n");
 1131       }
 1132       if(strcmp(opt, "use_gnuplot") == 0){
 1133     found = TRUE;
 1134     o2 = FALSE;
 1135     if(noplot)
 1136       strcpy(value, "use_gnuplot = no\n");
 1137     else
 1138       strcpy(value, "use_gnuplot = yes\n");
 1139       }
 1140       if(strcmp(opt, "bell") == 0){
 1141     found = TRUE;
 1142     o3 = FALSE;
 1143     if(nobell)
 1144       strcpy(value, "bell = no\n");
 1145     else
 1146       strcpy(value, "bell = yes\n");
 1147       }
 1148       if(strcmp(opt, "text_histogram") == 0){
 1149     found = TRUE;
 1150     o4 = FALSE;
 1151     if(thist)
 1152       strcpy(value, "text_histogram = yes\n");
 1153     else
 1154       strcpy(value, "text_histogram = no\n");
 1155       }
 1156       if(strcmp(opt, "bernhard") == 0){
 1157     found = TRUE;
 1158     o5 = FALSE;
 1159     if(bernhard)
 1160       strcpy(value, "bernhard = yes\n");
 1161     else
 1162       strcpy(value, "bernhard = no\n");
 1163       }
 1164       if(strcmp(opt, "use_system_ls") == 0){
 1165     found = TRUE;
 1166     o6 = FALSE;
 1167     if(system_ls)
 1168       sprintf(value, "use_system_ls = yes\n");
 1169     else
 1170       sprintf(value, "use_system_ls = no\n");
 1171       }
 1172       if(strcmp(opt, "max_results") == 0){
 1173     found = TRUE;
 1174     o7 = FALSE;
 1175     sprintf(value, "max_results = %i\n", MRESULT);
 1176       }
 1177       if(strcmp(opt, "screen_lines") == 0){
 1178     found = TRUE;
 1179     o8 = FALSE;
 1180     sprintf(value, "screen_lines = %i\n", rlines);
 1181       }
 1182       if(strcmp(opt, "screen_columns") == 0){
 1183     found = TRUE;
 1184     o9 = FALSE;
 1185     sprintf(value, "screen_columns = %i\n", rcols);
 1186       }
 1187       if(found)
 1188     b2 = STRCAT(b2, value, &max);
 1189       else
 1190     b2 = STRCAT(b2, b, &max);
 1191       found = FALSE;
 1192     }
 1193     FCLOSE(F);
 1194   }
 1195   FOPEN(prefs_filename, "w", F);
 1196 
 1197   /* Saving preferences if they weren't found in statistrc yet, and if they
 1198    * don't have the default values */
 1199   if(o1 && !(verbose))
 1200     STRCAT(b2, "verbose = no\n", &max);
 1201   if(o2 && noplot)
 1202     STRCAT(b2, "use_gnuplot = no\n", &max);
 1203   if(o3 && nobell)
 1204     STRCAT(b2, "bell = no\n", &max);
 1205   if(o4 && thist)
 1206     STRCAT(b2, "text_histogram = yes\n", &max);
 1207   if(o5 && bernhard)
 1208     STRCAT(b2, "bernhard = yes\n", &max);
 1209   if(o6 && system_ls)
 1210     STRCAT(b2, "use_system_ls = yes\n", &max);
 1211   if(o7 && MRESULT != 200){
 1212     sprintf(value, "max_results = %i\n", MRESULT);
 1213     STRCAT(b2, value, &max);
 1214   }
 1215 #ifdef MSDOS
 1216   i = 24;
 1217 #else
 1218   i = 40;
 1219 #endif
 1220   if(o8 && rlines){
 1221     sprintf(value, "screen_lines = %i\n", rlines);
 1222     STRCAT(b2, value, &max);
 1223   }
 1224   if(o9 && rcols){
 1225     sprintf(value, "screen_columns = %i\n", rcols);
 1226     STRCAT(b2, value, &max);
 1227   }
 1228   FWRITE(b2, 1, strlen(b2), F);
 1229   FCLOSE(F);
 1230 
 1231   out_d(_("File \"%s\" saved!"), prefs_filename);
 1232   out_d("\n\n");
 1233   mywait();
 1234   myfree(b2);
 1235 }
 1236 
 1237 void set_winsize(){
 1238   SCRLINES = 0;
 1239   SCRCOLS = 0;
 1240 #ifndef NO_IOCTIL_H
 1241   struct winsize ws;
 1242   if(ioctl(1, TIOCGWINSZ, &ws) != -1) {
 1243     SCRCOLS = ws.ws_col;
 1244     SCRLINES = ws.ws_row;
 1245   }
 1246 #endif
 1247   if(rcols)
 1248     SCRCOLS = rcols;
 1249   if(rlines)
 1250     SCRLINES = rlines;
 1251   if(SCRLINES < 10 || SCRLINES > 400){ /* xterm with tiny font: 1020x359 */
 1252 #ifdef MSDOS
 1253     SCRLINES = 24;
 1254 #else
 1255     SCRLINES = 40;
 1256 #endif
 1257   }
 1258   if(SCRCOLS < 10 || SCRCOLS > 2000)
 1259     SCRCOLS = 80;
 1260 }
 1261 
 1262 void colorize(int cl){
 1263   if(!color)
 1264     return;
 1265 #ifdef MSDOS
 1266   return;
 1267 #endif
 1268   switch(cl){
 1269     case ClDefault :
 1270       out_d("\033[0m");
 1271       break;
 1272     case ClError :
 1273       fprintf(stderr, "%s", clError);
 1274       break;
 1275     case ClErrorD :
 1276       fprintf(stderr, "\033[0m");
 1277       break;
 1278     case ClInstr :
 1279       out_d(clInstr);
 1280       break;
 1281     case ClHeader :
 1282       out_d(clHeader);
 1283       break;
 1284     case ClLineNum :
 1285       out_d(clLineNum);
 1286       break;
 1287     case ClMenuSep :
 1288       out_d(clMenuSep);
 1289       break;
 1290   }
 1291 }