home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / xpm-3.2a / data.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-16  |  8.7 KB  |  418 lines

  1. /* Copyright 1990,91 GROUPE BULL -- See license conditions in file COPYRIGHT */
  2. /*****************************************************************************\
  3. * data.c:                                                                     *
  4. *                                                                             *
  5. *  XPM library                                                                *
  6. *  IO utilities                                                               *
  7. *                                                                             *
  8. *  Developed by Arnaud Le Hors                                                *
  9. \*****************************************************************************/
  10.  
  11. /* Official version number */
  12. static char *RCS_Version = "$XpmVersion: 3.2a $";
  13.  
  14. /* Internal version number */
  15. static char *RCS_Id = "$Id: xpm.shar,v 3.9 1992/08/17 14:52:41 lehors Exp $";
  16.  
  17. #include "xpmP.h"
  18. #ifdef VMS
  19. #include "sys$library:stat.h"
  20. #include "sys$library:ctype.h"
  21. #else
  22. #include <sys/stat.h>
  23. #include <ctype.h>
  24. #endif
  25.  
  26. FUNC(atoui, unsigned int, (char *p, unsigned int l, unsigned int *ui_return));
  27. LFUNC(ParseComment, int, (xpmData *mdata));
  28.  
  29. unsigned int
  30. atoui(p, l, ui_return)
  31.     register char *p;
  32.     unsigned int l;
  33.     unsigned int *ui_return;
  34. {
  35.     register int n, i;
  36.  
  37.     n = 0;
  38.     for (i = 0; i < l; i++)
  39.     if (*p >= '0' && *p <= '9')
  40.         n = n * 10 + *p++ - '0';
  41.     else
  42.         break;
  43.  
  44.     if (i != 0 && i == l) {
  45.     *ui_return = n;
  46.     return 1;
  47.     } else
  48.     return 0;
  49. }
  50.  
  51. static int
  52. ParseComment(mdata)
  53.     xpmData *mdata;
  54. {
  55.     FILE *file = mdata->stream.file;
  56.     register int c;
  57.     register unsigned int n = 0, a;
  58.     unsigned int notend;
  59.     char *s, *s2;
  60.  
  61.     s = mdata->Comment;
  62.     *s = mdata->Bcmt[0];
  63.  
  64.     /* skip the string beginning comment */
  65.     s2 = mdata->Bcmt;
  66.     do {
  67.     c = getc(file);
  68.     *++s = c;
  69.     n++;
  70.     s2++;
  71.     } while (c == *s2 && *s2 != '\0'
  72.          && c != EOF && c != mdata->Bos);
  73.  
  74.     if (*s2 != '\0') {
  75.     /* this wasn't the beginning of a comment */
  76.     /* put characters back in the order that we got them */
  77.     for (a = n; a > 0; a--, s--)
  78.         ungetc(*s, file);
  79.     return;
  80.     }
  81.  
  82.     /* store comment */
  83.     mdata->Comment[0] = *s;
  84.     s = mdata->Comment;
  85.     notend = 1;
  86.     n = 0;
  87.     while (notend) {
  88.     s2 = mdata->Ecmt;
  89.     while (*s != *s2 && c != EOF && c != mdata->Bos) {
  90.         c = getc(file);
  91.         *++s = c;
  92.         n++;
  93.     }
  94.     mdata->CommentLength = n;
  95.     do {
  96.         c = getc(file);
  97.         n++;
  98.         *++s = c;
  99.         s2++;
  100.     } while (c == *s2 && *s2 != '\0'
  101.          && c != EOF && c != mdata->Bos);
  102.     if (*s2 == '\0') {
  103.         /* this is the end of the comment */
  104.         notend = 0;
  105.         ungetc(*s, file);
  106.     }
  107.     }
  108. }
  109.  
  110. /*
  111.  * skip to the end of the current string and the beginning of the next one
  112.  */
  113. xpmNextString(mdata)
  114.     xpmData *mdata;
  115. {
  116.     if (!mdata->type)
  117.     mdata->cptr = (mdata->stream.data)[++mdata->line];
  118.     else {
  119.     register int c;
  120.     FILE *file = mdata->stream.file;
  121.  
  122.     /* get to the end of the current string */
  123.     if (mdata->Eos)
  124.         while ((c = getc(file)) != mdata->Eos && c != EOF);
  125.  
  126.     /* then get to the beginning of the next string
  127.      * looking for possible comment */
  128.     if (mdata->Bos) {
  129.         while ((c = getc(file)) != mdata->Bos && c != EOF)
  130.         if (mdata->Bcmt && c == mdata->Bcmt[0])
  131.             ParseComment(mdata);
  132.         
  133.     } else {            /* XPM2 natural */
  134.         while (mdata->Bcmt && (c = getc(file)) == mdata->Bcmt[0])
  135.         ParseComment(mdata);
  136.         ungetc(c, file);
  137.     }
  138.     }
  139. }
  140.  
  141.  
  142. /*
  143.  * skip whitespace and compute the following unsigned int,
  144.  * returns 1 if one is found and 0 if not
  145.  */
  146. int
  147. xpmNextUI(mdata, ui_return)
  148.     xpmData *mdata;
  149.     unsigned int *ui_return;
  150. {
  151.     char buf[BUFSIZ];
  152.     int l;
  153.  
  154.     l = xpmNextWord(mdata, buf);
  155.     return atoui(buf, l, ui_return);
  156. }
  157.  
  158. /*
  159.  * skip whitespace and return the following word
  160.  */
  161. unsigned int
  162. xpmNextWord(mdata, buf)
  163.     xpmData *mdata;
  164.     char *buf;
  165. {
  166.     register unsigned int n = 0;
  167.     int c;
  168.  
  169.     if (!mdata->type) {
  170.     while (isspace(c = *mdata->cptr) && c != mdata->Eos)
  171.         mdata->cptr++;
  172.     do {
  173.         c = *mdata->cptr++;
  174.         *buf++ = c;
  175.         n++;
  176.     } while (!isspace(c) && c != mdata->Eos);
  177.     n--;
  178.     mdata->cptr--;
  179.     } else {
  180.     FILE *file = mdata->stream.file;
  181.     while (isspace(c = getc(file)) && c != mdata->Eos);
  182.     while (!isspace(c) && c != mdata->Eos && c != EOF) {
  183.         *buf++ = c;
  184.         n++;
  185.         c = getc(file);
  186.     }
  187.     ungetc(c, file);
  188.     }
  189.     return (n);
  190. }
  191.  
  192. /*
  193.  * return end of string - WARNING: malloc!
  194.  */
  195. int
  196. xpmGetString(mdata, sptr, l)
  197.     xpmData *mdata;
  198.     char **sptr;
  199.     unsigned int *l;
  200. {
  201.     unsigned int i, n = 0;
  202.     int c;
  203.     char *p, *q, buf[BUFSIZ];
  204.  
  205.     if (!mdata->type) {
  206.     if (mdata->cptr) {
  207.         char *start;
  208.         while (isspace(c = *mdata->cptr) && c != mdata->Eos)
  209.         mdata->cptr++;
  210.         start = mdata->cptr;
  211.         while (c = *mdata->cptr)
  212.         mdata->cptr++;
  213.         n = mdata->cptr - start + 1;
  214.         p = (char *) malloc(n);
  215.         if (!p)
  216.         return (XpmNoMemory);
  217.         strncpy(p, start, n);
  218.     }
  219.     } else {
  220.     FILE *file = mdata->stream.file;
  221.     while (isspace(c = getc(file)) && c != mdata->Eos);
  222.     p = NULL;
  223.     i = 0;
  224.     q = buf;
  225.     p = (char *) malloc(1);
  226.     while (c != mdata->Eos && c != EOF) {
  227.         if (i == BUFSIZ) {
  228.         /* get to the end of the buffer */
  229.         /* malloc needed memory */
  230.         q = (char *) realloc(p, n + i);
  231.         if (!q) {
  232.             free(p);
  233.             return (XpmNoMemory);
  234.         }
  235.         p = q;
  236.         q += n;
  237.         /* and copy what we already have */
  238.         strncpy(q, buf, i);
  239.         n += i;
  240.         i = 0;
  241.         q = buf;
  242.         }
  243.         *q++ = c;
  244.         i++;
  245.         c = getc(file);
  246.     }
  247.     if (n + i != 0) {
  248.         /* malloc needed memory */
  249.         q = (char *) realloc(p, n + i + 1);
  250.         if (!q) {
  251.         free(p);
  252.         return (XpmNoMemory);
  253.         }
  254.         p = q;
  255.         q += n;
  256.         /* and copy the buffer */
  257.         strncpy(q, buf, i);
  258.         n += i;
  259.         p[n++] = '\0';
  260.     } else {
  261.         *p = '\0';
  262.         n = 1;
  263.     }
  264.     ungetc(c, file);
  265.     }
  266.     *sptr = p;
  267.     *l = n;
  268.     return (XpmSuccess);
  269. }
  270.  
  271. /*
  272.  * get the current comment line
  273.  */
  274. xpmGetCmt(mdata, cmt)
  275.     xpmData *mdata;
  276.     char **cmt;
  277. {
  278.     if (!mdata->type)
  279.     *cmt = NULL;
  280.     else
  281.     if (mdata->CommentLength) {
  282.         *cmt = (char *) malloc(mdata->CommentLength + 1);
  283.         strncpy(*cmt, mdata->Comment, mdata->CommentLength);
  284.         (*cmt)[mdata->CommentLength] = '\0';
  285.         mdata->CommentLength = 0;
  286.     } else
  287.         *cmt = NULL;
  288. }
  289.  
  290. /*
  291.  * open the given file to be read as an xpmData which is returned.
  292.  */
  293. int
  294. xpmReadFile(filename, mdata)
  295.     char *filename;
  296.     xpmData *mdata;
  297. {
  298.     char *compressfile, buf[BUFSIZ];
  299.     struct stat status;
  300.  
  301.     if (!filename) {
  302.     mdata->stream.file = (stdin);
  303.     mdata->type = XPMFILE;
  304.     } else {
  305. #ifdef ZPIPE
  306.     if ((strlen(filename) > 2) &&
  307.         !strcmp(".Z", filename + (strlen(filename) - 2))) {
  308.         mdata->type = XPMPIPE;
  309.         sprintf(buf, "uncompress -c %s", filename);
  310.         if (!(mdata->stream.file = popen(buf, "r")))
  311.         return (XpmOpenFailed);
  312.  
  313.     } else {
  314.         if (!(compressfile = (char *) malloc(strlen(filename) + 3)))
  315.         return (XpmNoMemory);
  316.  
  317.         strcpy(compressfile, filename);
  318.         strcat(compressfile, ".Z");
  319.         if (!stat(compressfile, &status)) {
  320.         sprintf(buf, "uncompress -c %s", compressfile);
  321.         if (!(mdata->stream.file = popen(buf, "r"))) {
  322.             free(compressfile);
  323.             return (XpmOpenFailed);
  324.         }
  325.         mdata->type = XPMPIPE;
  326.         } else {
  327. #endif
  328.         if (!(mdata->stream.file = fopen(filename, "r"))) {
  329. #ifdef ZPIPE
  330.             free(compressfile);
  331. #endif
  332.             return (XpmOpenFailed);
  333.         }
  334.         mdata->type = XPMFILE;
  335. #ifdef ZPIPE
  336.         }
  337.         free(compressfile);
  338.     }
  339. #endif
  340.     }
  341.     mdata->CommentLength = 0;
  342.     return (XpmSuccess);
  343. }
  344.  
  345. /*
  346.  * open the given file to be written as an xpmData which is returned
  347.  */
  348. int
  349. xpmWriteFile(filename, mdata)
  350.     char *filename;
  351.     xpmData *mdata;
  352. {
  353.     char buf[BUFSIZ];
  354.  
  355.     if (!filename) {
  356.     mdata->stream.file = (stdout);
  357.     mdata->type = XPMFILE;
  358.     } else {
  359. #ifdef ZPIPE
  360.     if (strlen(filename) > 2
  361.         && !strcmp(".Z", filename + (strlen(filename) - 2))) {
  362.         sprintf(buf, "compress > %s", filename);
  363.         if (!(mdata->stream.file = popen(buf, "w")))
  364.         return (XpmOpenFailed);
  365.  
  366.         mdata->type = XPMPIPE;
  367.     } else {
  368. #endif
  369.         if (!(mdata->stream.file = fopen(filename, "w")))
  370.         return (XpmOpenFailed);
  371.  
  372.         mdata->type = XPMFILE;
  373. #ifdef ZPIPE
  374.     }
  375. #endif
  376.     }
  377.     return (XpmSuccess);
  378. }
  379.  
  380. /*
  381.  * open the given array to be read or written as an xpmData which is returned
  382.  */
  383. int
  384. xpmOpenArray(data, mdata)
  385.     char **data;
  386.     xpmData *mdata;
  387. {
  388.     mdata->type = XPMARRAY;
  389.     mdata->stream.data = data;
  390.     mdata->cptr = *data;
  391.     mdata->line = 0;
  392.     mdata->CommentLength = 0;
  393.     mdata->Bcmt = mdata->Ecmt = NULL;
  394.     mdata->Bos = mdata->Eos = '\0';
  395.     return (XpmSuccess);
  396. }
  397.  
  398. /*
  399.  * close the file related to the xpmData if any
  400.  */
  401. XpmDataClose(mdata)
  402.     xpmData *mdata;
  403. {
  404.     switch (mdata->type) {
  405.     case XPMARRAY:
  406.     break;
  407.     case XPMFILE:
  408.     if (mdata->stream.file != (stdout) && mdata->stream.file != (stdin))
  409.         fclose(mdata->stream.file);
  410.     break;
  411. #ifdef ZPIPE
  412.     case XPMPIPE:
  413.     pclose(mdata->stream.file);
  414.     break;
  415. #endif
  416.     }
  417. }
  418.