home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / general.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-06  |  8.6 KB  |  354 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18. #include <glib.h>
  19.  
  20. #include <ctype.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <sys/types.h>
  25. #include <sys/stat.h>
  26. #include <time.h>
  27.  
  28. #ifdef G_OS_WIN32
  29. #ifndef S_ISREG
  30. #define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
  31. #endif
  32. #endif
  33.  
  34. #include "general.h"
  35.  
  36. char*
  37. search_in_path (char *search_path,
  38.         char *filename)
  39. {
  40.   static char path[256];
  41.   gchar *local_path;
  42.   gchar *token;
  43.   gchar *next_token;
  44.   struct stat buf;
  45.   int err;
  46.  
  47.   local_path = g_strdup (search_path);
  48.   next_token = local_path;
  49.   token = strtok (next_token, G_SEARCHPATH_SEPARATOR_S);
  50.  
  51.   while (token)
  52.     {
  53.       sprintf (path, "%s", token);
  54.  
  55.       if (token[strlen (token) - 1] != G_DIR_SEPARATOR)
  56.     strcat (path, G_DIR_SEPARATOR_S);
  57.       strcat (path, filename);
  58.  
  59.       err = stat (path, &buf);
  60.       if (!err && S_ISREG (buf.st_mode))
  61.     {
  62.       token = path;
  63.       break;
  64.     }
  65.  
  66.       token = strtok (NULL, G_SEARCHPATH_SEPARATOR_S);
  67.     }
  68.  
  69.   g_free (local_path);
  70.   return token;
  71. }
  72.  
  73. /*****/
  74.  
  75. /* FIXME: This is straight from the GNU libc sources.  We should use
  76.  * autoconf to test for a system having strsep() and similar
  77.  * stuff... then use HAVE_STRSEP to decide whether to include or not
  78.  * our own functions.
  79.  */
  80.  
  81. char *
  82. xstrsep (char **pp,
  83.      char  *delim)
  84. {
  85.   char *p, *q;
  86.  
  87.   if (!(p = *pp))
  88.     return NULL;
  89.   if ((q = strpbrk (p, delim))) {
  90.     *pp = q + 1;
  91.     *q = '\0';
  92.   } else
  93.     *pp = NULL;
  94.  
  95.   return p;
  96. } /* xstrsep */
  97.  
  98.  
  99. char *token_str;
  100. char *token_sym;
  101. double token_num;
  102. int token_int;
  103.  
  104. int
  105. get_token (ParseInfo *info)
  106. {
  107.   char *buffer;
  108.   char *tokenbuf;
  109.   int tokenpos = 0;
  110.   int state;
  111.   int count;
  112.   int slashed;
  113.  
  114.   state = 0;
  115.   buffer = info->buffer;
  116.   tokenbuf = info->tokenbuf;
  117.   slashed = FALSE;
  118.  
  119.   while (1)
  120.     {
  121.       if (info->inc_charnum && info->charnum)
  122.     info->charnum += 1;
  123.       if (info->inc_linenum && info->linenum)
  124.     {
  125.       info->linenum += 1;
  126.       info->charnum = 1;
  127.     }
  128.  
  129.       info->inc_linenum = FALSE;
  130.       info->inc_charnum = FALSE;
  131.  
  132.       if (info->position >= (info->buffer_size - 1))
  133.     info->position = -1;
  134.       if ((info->position == -1) || (buffer[info->position] == '\0'))
  135.     {
  136.       count = fread (buffer, sizeof (char), info->buffer_size - 1, info->fp);
  137.       if ((count == 0) && feof (info->fp))
  138.         return TOKEN_EOF;
  139.       buffer[count] = '\0';
  140.       info->position = 0;
  141.     }
  142.  
  143.       info->inc_charnum = TRUE;
  144.       if ((buffer[info->position] == '\n') ||
  145.       (buffer[info->position] == '\r'))
  146.     info->inc_linenum = TRUE;
  147.  
  148.       switch (state)
  149.     {
  150.     case 0:
  151.       if (buffer[info->position] == '#')
  152.         {
  153.           info->position += 1;
  154.           state = 4;
  155.         }
  156.       else if (buffer[info->position] == '(')
  157.         {
  158.           info->position += 1;
  159.           return TOKEN_LEFT_PAREN;
  160.         }
  161.       else if (buffer[info->position] == ')')
  162.         {
  163.           info->position += 1;
  164.           return TOKEN_RIGHT_PAREN;
  165.         }
  166.       else if (buffer[info->position] == '"')
  167.         {
  168.           info->position += 1;
  169.           state = 1;
  170.           slashed = FALSE;
  171.         }
  172.       else if ((buffer[info->position] == '-') || isdigit (buffer[info->position]))
  173.         {
  174.           tokenbuf[tokenpos++] = buffer[info->position];
  175.           info->position += 1;
  176.           state = 3;
  177.         }
  178.       else if ((buffer[info->position] != ' ') &&
  179.            (buffer[info->position] != '\t') &&
  180.            (buffer[info->position] != '\n') &&
  181.            (buffer[info->position] != '\r'))
  182.         {
  183.           tokenbuf[tokenpos++] = buffer[info->position];
  184.           info->position += 1;
  185.           state = 2;
  186.         }
  187.       else if (buffer[info->position] == '\'')
  188.         {
  189.           info->position += 1;
  190.           state = 2;
  191.         }
  192.       else
  193.         {
  194.           info->position += 1;
  195.         }
  196.       break;
  197.     case 1:
  198.       if ((buffer[info->position] == '\\') && (!slashed))
  199.         {
  200.           slashed = TRUE;
  201.           info->position += 1;
  202.         }
  203.       else if (slashed || (buffer[info->position] != '"'))
  204.         {
  205.           if (slashed && buffer[info->position] == 'n')
  206.         tokenbuf[tokenpos++] = '\n';
  207.           else if (slashed && buffer[info->position] == 'r')
  208.         tokenbuf[tokenpos++] = '\r';
  209.           else if (slashed && buffer[info->position] == 'z') /* ^Z */
  210.         tokenbuf[tokenpos++] = '\032';
  211.           else if (slashed && buffer[info->position] == '0') /* \0 */
  212.         tokenbuf[tokenpos++] = '\0';
  213.           else if (slashed && buffer[info->position] == '"')
  214.         tokenbuf[tokenpos++] = '"';
  215.           else
  216.             tokenbuf[tokenpos++] = buffer[info->position];
  217.           slashed = FALSE;
  218.           info->position += 1;
  219.         }
  220.       else
  221.         {
  222.           tokenbuf[tokenpos] = '\0';
  223.           token_str = tokenbuf;
  224.           token_sym = tokenbuf;
  225.               token_int = tokenpos;
  226.           info->position += 1;
  227.           return TOKEN_STRING;
  228.         }
  229.       break;
  230.     case 2:
  231.       if ((buffer[info->position] != ' ') &&
  232.           (buffer[info->position] != '\t') &&
  233.           (buffer[info->position] != '\n') &&
  234.           (buffer[info->position] != '\r') &&
  235.           (buffer[info->position] != '"') &&
  236.           (buffer[info->position] != '(') &&
  237.           (buffer[info->position] != ')'))
  238.         {
  239.           tokenbuf[tokenpos++] = buffer[info->position];
  240.           info->position += 1;
  241.         }
  242.       else
  243.         {
  244.           tokenbuf[tokenpos] = '\0';
  245.           token_sym = tokenbuf;
  246.           return TOKEN_SYMBOL;
  247.         }
  248.       break;
  249.     case 3:
  250.       if (isdigit (buffer[info->position]) ||
  251.           (buffer[info->position] == '.'))
  252.         {
  253.           tokenbuf[tokenpos++] = buffer[info->position];
  254.           info->position += 1;
  255.         }
  256.       else if ((buffer[info->position] != ' ') &&
  257.            (buffer[info->position] != '\t') &&
  258.            (buffer[info->position] != '\n') &&
  259.            (buffer[info->position] != '\r') &&
  260.            (buffer[info->position] != '"') &&
  261.            (buffer[info->position] != '(') &&
  262.            (buffer[info->position] != ')'))
  263.         {
  264.           tokenbuf[tokenpos++] = buffer[info->position];
  265.           info->position += 1;
  266.           state = 2;
  267.         }
  268.       else
  269.         {
  270.           tokenbuf[tokenpos] = '\0';
  271.           token_sym = tokenbuf;
  272.           token_num = atof (tokenbuf);
  273.           token_int = atoi (tokenbuf);
  274.           return TOKEN_NUMBER;
  275.         }
  276.       break;
  277.     case 4:
  278.       if (buffer[info->position] == '\n')
  279.         state = 0;
  280.       info->position += 1;
  281.       break;
  282.     }
  283.     }
  284. }
  285.  
  286. /* Parse "line" and look for a string of characters without spaces
  287.    following a '(' and copy them into "token_r".  Return the number of
  288.    characters stored, or 0. */
  289. int
  290. find_token (char *line,
  291.         char *token_r,
  292.         int maxlen)
  293. {
  294.   char *sp;
  295.   char *dp;
  296.   int   i;
  297.  
  298.   /* FIXME: This should be replaced by a more intelligent parser which
  299.      checks for '\', '"' and nested parentheses.  See get_token().  */
  300.   for (sp = line; *sp; sp++)
  301.     if (*sp == '(' || *sp == '#')
  302.       break;
  303.   if (*sp == '\000' || *sp == '#')
  304.     {
  305.       *token_r = '\000';
  306.       return 0;
  307.     }
  308.   dp = token_r;
  309.   sp++;
  310.   i = 0;
  311.   while ((*sp != '\000') && (*sp != ' ') && (*sp != '\t') && i < maxlen)
  312.     {
  313.       *dp = *sp;
  314.       dp++;
  315.       sp++;
  316.       i++;
  317.     }
  318.   if (*sp == '\000' || i >= maxlen)
  319.     {
  320.       *token_r = '\000';
  321.       return 0;
  322.     }
  323.   *dp = '\000';
  324.   return i;
  325. }
  326.  
  327. /* Generate a string containing the date and time and return a pointer
  328.    to it.  If user_buf is not NULL, the string is stored in that
  329.    buffer (21 bytes).  If strict is FALSE, the 'T' between the date
  330.    and the time is replaced by a space, which makes the format a bit
  331.    more readable (IMHO). */
  332. char *
  333. iso_8601_date_format (char *user_buf, int strict)
  334. {
  335.   static char static_buf[21];
  336.   char *buf;
  337.   time_t clock;
  338.   struct tm *now;
  339.  
  340.   if (user_buf != NULL)
  341.     buf = user_buf;
  342.   else
  343.     buf = static_buf;
  344.   clock = time (NULL);
  345.   now = gmtime (&clock);
  346.   /* date format derived from ISO 8601:1988 */
  347.   sprintf(buf, "%04d-%02d-%02d%c%02d:%02d:%02d%c",
  348.       now->tm_year + 1900, now->tm_mon + 1, now->tm_mday,
  349.       (strict ? 'T' : ' '),
  350.       now->tm_hour, now->tm_min, now->tm_sec,
  351.       (strict ? 'Z' : '\000'));
  352.   return buf;
  353. }
  354.