/* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #ifdef G_OS_WIN32 #ifndef S_ISREG #define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) #endif #endif #include "general.h" char* search_in_path (char *search_path, char *filename) { static char path[256]; gchar *local_path; gchar *token; gchar *next_token; struct stat buf; int err; local_path = g_strdup (search_path); next_token = local_path; token = strtok (next_token, G_SEARCHPATH_SEPARATOR_S); while (token) { sprintf (path, "%s", token); if (token[strlen (token) - 1] != G_DIR_SEPARATOR) strcat (path, G_DIR_SEPARATOR_S); strcat (path, filename); err = stat (path, &buf); if (!err && S_ISREG (buf.st_mode)) { token = path; break; } token = strtok (NULL, G_SEARCHPATH_SEPARATOR_S); } g_free (local_path); return token; } /*****/ /* FIXME: This is straight from the GNU libc sources. We should use * autoconf to test for a system having strsep() and similar * stuff... then use HAVE_STRSEP to decide whether to include or not * our own functions. */ char * xstrsep (char **pp, char *delim) { char *p, *q; if (!(p = *pp)) return NULL; if ((q = strpbrk (p, delim))) { *pp = q + 1; *q = '\0'; } else *pp = NULL; return p; } /* xstrsep */ char *token_str; char *token_sym; double token_num; int token_int; int get_token (ParseInfo *info) { char *buffer; char *tokenbuf; int tokenpos = 0; int state; int count; int slashed; state = 0; buffer = info->buffer; tokenbuf = info->tokenbuf; slashed = FALSE; while (1) { if (info->inc_charnum && info->charnum) info->charnum += 1; if (info->inc_linenum && info->linenum) { info->linenum += 1; info->charnum = 1; } info->inc_linenum = FALSE; info->inc_charnum = FALSE; if (info->position >= (info->buffer_size - 1)) info->position = -1; if ((info->position == -1) || (buffer[info->position] == '\0')) { count = fread (buffer, sizeof (char), info->buffer_size - 1, info->fp); if ((count == 0) && feof (info->fp)) return TOKEN_EOF; buffer[count] = '\0'; info->position = 0; } info->inc_charnum = TRUE; if ((buffer[info->position] == '\n') || (buffer[info->position] == '\r')) info->inc_linenum = TRUE; switch (state) { case 0: if (buffer[info->position] == '#') { info->position += 1; state = 4; } else if (buffer[info->position] == '(') { info->position += 1; return TOKEN_LEFT_PAREN; } else if (buffer[info->position] == ')') { info->position += 1; return TOKEN_RIGHT_PAREN; } else if (buffer[info->position] == '"') { info->position += 1; state = 1; slashed = FALSE; } else if ((buffer[info->position] == '-') || isdigit (buffer[info->position])) { tokenbuf[tokenpos++] = buffer[info->position]; info->position += 1; state = 3; } else if ((buffer[info->position] != ' ') && (buffer[info->position] != '\t') && (buffer[info->position] != '\n') && (buffer[info->position] != '\r')) { tokenbuf[tokenpos++] = buffer[info->position]; info->position += 1; state = 2; } else if (buffer[info->position] == '\'') { info->position += 1; state = 2; } else { info->position += 1; } break; case 1: if ((buffer[info->position] == '\\') && (!slashed)) { slashed = TRUE; info->position += 1; } else if (slashed || (buffer[info->position] != '"')) { if (slashed && buffer[info->position] == 'n') tokenbuf[tokenpos++] = '\n'; else if (slashed && buffer[info->position] == 'r') tokenbuf[tokenpos++] = '\r'; else if (slashed && buffer[info->position] == 'z') /* ^Z */ tokenbuf[tokenpos++] = '\032'; else if (slashed && buffer[info->position] == '0') /* \0 */ tokenbuf[tokenpos++] = '\0'; else if (slashed && buffer[info->position] == '"') tokenbuf[tokenpos++] = '"'; else tokenbuf[tokenpos++] = buffer[info->position]; slashed = FALSE; info->position += 1; } else { tokenbuf[tokenpos] = '\0'; token_str = tokenbuf; token_sym = tokenbuf; token_int = tokenpos; info->position += 1; return TOKEN_STRING; } break; case 2: if ((buffer[info->position] != ' ') && (buffer[info->position] != '\t') && (buffer[info->position] != '\n') && (buffer[info->position] != '\r') && (buffer[info->position] != '"') && (buffer[info->position] != '(') && (buffer[info->position] != ')')) { tokenbuf[tokenpos++] = buffer[info->position]; info->position += 1; } else { tokenbuf[tokenpos] = '\0'; token_sym = tokenbuf; return TOKEN_SYMBOL; } break; case 3: if (isdigit (buffer[info->position]) || (buffer[info->position] == '.')) { tokenbuf[tokenpos++] = buffer[info->position]; info->position += 1; } else if ((buffer[info->position] != ' ') && (buffer[info->position] != '\t') && (buffer[info->position] != '\n') && (buffer[info->position] != '\r') && (buffer[info->position] != '"') && (buffer[info->position] != '(') && (buffer[info->position] != ')')) { tokenbuf[tokenpos++] = buffer[info->position]; info->position += 1; state = 2; } else { tokenbuf[tokenpos] = '\0'; token_sym = tokenbuf; token_num = atof (tokenbuf); token_int = atoi (tokenbuf); return TOKEN_NUMBER; } break; case 4: if (buffer[info->position] == '\n') state = 0; info->position += 1; break; } } } /* Parse "line" and look for a string of characters without spaces following a '(' and copy them into "token_r". Return the number of characters stored, or 0. */ int find_token (char *line, char *token_r, int maxlen) { char *sp; char *dp; int i; /* FIXME: This should be replaced by a more intelligent parser which checks for '\', '"' and nested parentheses. See get_token(). */ for (sp = line; *sp; sp++) if (*sp == '(' || *sp == '#') break; if (*sp == '\000' || *sp == '#') { *token_r = '\000'; return 0; } dp = token_r; sp++; i = 0; while ((*sp != '\000') && (*sp != ' ') && (*sp != '\t') && i < maxlen) { *dp = *sp; dp++; sp++; i++; } if (*sp == '\000' || i >= maxlen) { *token_r = '\000'; return 0; } *dp = '\000'; return i; } /* Generate a string containing the date and time and return a pointer to it. If user_buf is not NULL, the string is stored in that buffer (21 bytes). If strict is FALSE, the 'T' between the date and the time is replaced by a space, which makes the format a bit more readable (IMHO). */ char * iso_8601_date_format (char *user_buf, int strict) { static char static_buf[21]; char *buf; time_t clock; struct tm *now; if (user_buf != NULL) buf = user_buf; else buf = static_buf; clock = time (NULL); now = gmtime (&clock); /* date format derived from ISO 8601:1988 */ sprintf(buf, "%04d-%02d-%02d%c%02d:%02d:%02d%c", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, (strict ? 'T' : ' '), now->tm_hour, now->tm_min, now->tm_sec, (strict ? 'Z' : '\000')); return buf; }