"Fossies" - the Fresh Open Source Software Archive

Member "wcalc-2.5/src/common/files.c" (20 Dec 2013, 10741 Bytes) of package /linux/privat/wcalc-2.5.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 "files.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.4.1_vs_2.5.

    1 /*
    2  *  files.c
    3  *  Wcalc
    4  *
    5  *  Created by Kyle Wheeler on Sat Mar 22 2003.
    6  *  Copyright (c) 2003 Kyle Wheeler. All rights reserved.
    7  *
    8  */
    9 
   10 #ifdef HAVE_CONFIG_H
   11 # include "config.h"
   12 #endif
   13 
   14 /* System Headers */
   15 #include <fcntl.h>                     /* for open() */
   16 #include <unistd.h>                    /* for close() */
   17 #include <errno.h>                     /* for errno */
   18 #include <sys/types.h>                 /* for open flags */
   19 #include <sys/stat.h>                  /* for open flags */
   20 #include <string.h>                    /* for strlen() */
   21 #include <stdlib.h>                    /* for free() */
   22 #include <assert.h>                    /* for assert() */
   23 #ifdef HAVE_PATH_MAX
   24 # ifdef HAVE_LIMITS_H
   25 #  include <limits.h>                  /* for PATH_MAX */
   26 # endif
   27 #endif
   28 
   29 /* Internal Headers */
   30 #include "historyManager.h"
   31 #include "string_manip.h"
   32 #include "calculator.h"
   33 #include "variables.h"
   34 #include "output.h"
   35 
   36 #include "files.h"
   37 
   38 /* this is for communicating with the scanner */
   39 char *open_file = NULL;
   40 
   41 static inline void tristrncat(char       *dest,
   42                               size_t      len,
   43                               const char *one,
   44                               const char *two,
   45                               const char *three)
   46 {
   47     size_t i;
   48     size_t written = 0;
   49 
   50     strncpy(dest, one, len);
   51     for (i = 0; i < len; i++) {
   52         if (dest[i] == 0) { break; }
   53     }
   54     written = i;
   55     strncat(dest, two, len - written);
   56     for (i = written; i < len; i++) {
   57         if (dest[i] == 0) { break; }
   58     }
   59     written = i;
   60     strncat(dest, three, len - written);
   61 }
   62 
   63 int openDotFile(const char *dotFileName,
   64                 int         flags)
   65 {   /*{{{*/
   66     char       *filename = NULL;
   67     const char *home     = getenv("HOME");
   68     int         namelen;
   69     int         fd;
   70 
   71     if (!home) { return -1; }
   72     assert(dotFileName);
   73     namelen = strlen(home) + strlen(dotFileName) + 3;
   74 #ifdef HAVE_PATH_MAX
   75     if (namelen > PATH_MAX) {
   76         return -2;
   77     }
   78 #endif
   79 
   80     filename = malloc(sizeof(char) * namelen + 1);
   81     tristrncat(filename, namelen, home, "/.", dotFileName);
   82     fd       = open(filename, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   83     free(filename);
   84     if (fd < 0) {
   85         return -3;
   86     } else {
   87         return fd;
   88     }
   89 } /*}}}*/
   90 
   91 int saveState(char *filename)
   92 {                                      /*{{{ */
   93     int fd           = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL,
   94                             S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   95     int return_error = 0;
   96 
   97     free(filename);
   98     if (fd >= 0) {
   99         // success
  100         size_t hindex;
  101         int    retval;
  102         size_t num_vars = numvars();
  103 
  104         /* save variables */
  105         for (hindex = 0; hindex < num_vars; hindex++) {
  106             struct variable *keyval = getrealnvar(hindex);
  107             char            *cptr;
  108 
  109             if (!keyval) {
  110                 continue;
  111             }
  112             if (!strcmp(keyval->key, "a")) {
  113                 continue;
  114             }
  115             retval = write(fd, keyval->key, strlen(keyval->key));
  116             if (retval < (int)strlen(keyval->key)) {
  117                 return_error = errno;
  118                 break;
  119             }
  120             retval = write(fd, "=", 1);
  121             if (retval < 1) {
  122                 return_error = errno;
  123                 break;
  124             }
  125             if (keyval->exp) {
  126                 const size_t len = strlen(keyval->expression) + 3;
  127                 cptr = malloc(len);
  128                 tristrncat(cptr, len, "'", keyval->expression, "'");
  129             } else {
  130                 cptr = strdup(print_this_result(keyval->value, standard_output, NULL, NULL));
  131             }
  132             retval = write(fd, cptr, strlen(cptr));
  133             if (retval < (int)strlen(cptr)) {
  134                 return_error = errno;
  135                 free(cptr);
  136                 break;
  137             }
  138             free(cptr);
  139             if (keyval->description) {
  140                 const size_t len = strlen(keyval->expression) + 4;
  141                 cptr   = malloc(len);
  142                 tristrncat(cptr, len, " '", keyval->description, "'");
  143                 retval = write(fd, cptr, strlen(cptr));
  144                 if (retval < (int)strlen(cptr)) {
  145                     return_error = errno;
  146                     free(cptr);
  147                     break;
  148                 }
  149                 free(cptr);
  150             }
  151             retval = write(fd, "\n", 1);
  152             if (retval < 1) {
  153                 return_error = errno;
  154                 break;
  155             }
  156         }
  157         /* save history */
  158         for (hindex = 0; hindex < historyLength() && return_error == 0;
  159              hindex++) {
  160             char *history_entry = historynum(hindex, 1);
  161 
  162             retval = write(fd, history_entry, strlen(history_entry));
  163             if (retval < (int)strlen(history_entry)) {
  164                 return_error = errno;
  165                 break;
  166             }
  167             retval = write(fd, " # = ", 5);
  168             if (retval < 5) {
  169                 return_error = errno;
  170                 break;
  171             }
  172             history_entry = historynum(hindex, 2);
  173             retval        = write(fd, history_entry, strlen(history_entry));
  174             if (retval < (int)strlen(history_entry)) {
  175                 return_error = errno;
  176                 break;
  177             }
  178             retval = write(fd, "\n", 1);
  179             if (retval < 1) {
  180                 return_error = errno;
  181                 break;
  182             }
  183         }
  184         if (close(fd) != 0) {
  185             return_error = errno;
  186         }
  187     } else {
  188         // failure
  189         return_error = errno;
  190     }
  191     return return_error;
  192 }                                      /*}}} */
  193 
  194 int loadStateFD(int       fd,
  195                 const int into_history)
  196 {   /*{{{*/
  197     assert(fd >= 0);
  198 
  199     int return_error         = 0;
  200     int standard_output_save = standard_output;
  201     standard_output = 0;
  202 
  203     char        *linebuf;
  204     int          retval;
  205     unsigned int linelen = 0, maxlinelen = 99;
  206 
  207     linebuf = calloc(sizeof(char), 100);
  208     retval  = read(fd, linebuf + linelen, 1);
  209     while (retval == 1) {
  210         while (retval == 1 && linebuf[linelen] != '\n') {
  211             linelen++;
  212             if (linelen == maxlinelen) {
  213                 char *newlinebuf = realloc(linebuf,
  214                                            sizeof(char) * (maxlinelen +
  215                                                            100));
  216                 if (newlinebuf) {
  217                     maxlinelen += 100;
  218                     linebuf     = newlinebuf;
  219                 } else {
  220                     return_error = errno;
  221                     retval       = -1;
  222                     break;
  223                 }
  224             }
  225             retval = read(fd, linebuf + linelen, 1);
  226         }
  227         linebuf[linelen] = 0;
  228         if (conf.verbose) {
  229             display_stateline(linebuf);
  230         }
  231         stripComments(linebuf);
  232         while (linebuf[strlen(linebuf) - 1] == ' ') {
  233             linebuf[strlen(linebuf) - 1] = 0;
  234         }
  235         if (strlen(linebuf)) {
  236             extern char *errstring;
  237             char        *safe;
  238 
  239             safe = strdup(linebuf);
  240             parseme(safe);
  241             putval("a", last_answer, "previous answer");
  242             if ((!errstring || (errstring && !strlen(errstring)) ||
  243                  conf.remember_errors) && into_history) {
  244                 addToHistory(linebuf, last_answer);
  245             }
  246             free(safe);
  247         }
  248         linelen = 0;
  249         memset(linebuf, 0, maxlinelen);
  250         if (retval == 1) {
  251             retval = read(fd, linebuf + linelen, 1);
  252         }
  253     }
  254 
  255     free(linebuf);
  256     standard_output = standard_output_save;
  257 
  258     return return_error;
  259 } /*}}}*/
  260 
  261 int loadState(const char *filename,
  262               const int   into_history)
  263 {                                      /*{{{ */
  264     int fd, return_error = 0;
  265 
  266     fd = open(filename, O_RDONLY);
  267     if (fd < 0) { return_error = errno; }
  268     {
  269         int tmp = loadStateFD(fd, into_history);
  270         if (tmp != 0) {
  271             return_error = tmp;
  272         }
  273     }
  274     if (close(fd) != 0) {
  275         return_error = errno;
  276     }
  277 
  278     return return_error;
  279 }                                      /*}}} */
  280 
  281 int storeVar(const char *variable)
  282 {                                      /*{{{ */
  283     int fd, retval = 0, return_error = 0;
  284 
  285     if (!varexists(variable)) {
  286         report_error("Variable is not defined.");
  287         return -1;
  288     }
  289     fd = openDotFile("wcalc_preload", O_WRONLY | O_CREAT | O_APPEND);
  290     switch (fd) {
  291         case -1:
  292             report_error("HOME environment variable unset.");
  293             break;
  294         case -2:
  295             report_error("HOME environment variable is too long.");
  296             break;
  297         default:
  298         {
  299             // success
  300             struct answer keyval = getvar_full(variable);
  301             char         *cptr;
  302 
  303             retval = write(fd, variable, strlen(variable));
  304             if (retval < (int)strlen(variable)) {
  305                 return_error = errno;
  306                 goto exit_storeVar;
  307             }
  308             retval = write(fd, "=", 1);
  309             if (retval < 1) {
  310                 return_error = errno;
  311                 goto exit_storeVar;
  312             }
  313             if (keyval.exp) {
  314                 const size_t len = strlen(keyval.exp) + 4;
  315                 cptr = malloc(len);
  316                 tristrncat(cptr, len, "'", keyval.exp, "' ");
  317             } else {
  318                 cptr = strdup(print_this_result(keyval.val, standard_output, NULL, NULL));
  319             }
  320             retval = write(fd, cptr, strlen(cptr));
  321             if (retval < (int)strlen(cptr)) {
  322                 return_error = errno;
  323                 free(cptr);
  324                 goto exit_storeVar;
  325             }
  326             free(cptr);
  327             if (keyval.desc) {
  328                 const size_t len = strlen(keyval.desc) + 3;
  329                 cptr   = malloc(len);
  330                 tristrncat(cptr, len, "'", keyval.desc, "'");
  331                 retval = write(fd, cptr, strlen(cptr));
  332                 if (retval < (int)strlen(cptr)) {
  333                     return_error = errno;
  334                     free(cptr);
  335                     goto exit_storeVar;
  336                 }
  337                 free(cptr);
  338             }
  339             retval = write(fd, "\n", 1);
  340             if (retval < 1) {
  341                 return_error = errno;
  342                 goto exit_storeVar;
  343             }
  344             retval = close(fd);
  345             if (retval == -1) {
  346                 return_error = errno;
  347                 goto exit_storeVar;
  348             }
  349         }
  350     }
  351 exit_storeVar:
  352     return return_error;
  353 }                                      /*}}} */
  354 
  355 /* vim:set expandtab: */