/* Copyright (C) 2003 by Sean David Fleming sean@ivec.org 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. The GNU GPL can also be found at http://www.gnu.org */ #include #include #include #include #include #include #include #include #include #include #ifndef __WIN32 #include #include #endif #include "gdis.h" #include "file.h" #include "parse.h" #include "keywords.h" #include "interface.h" /* main structures */ extern struct sysenv_pak sysenv; extern struct elem_pak elements[]; /*****************************************/ /* strip off path and extension (if any) */ /*****************************************/ gchar *strdup_basename(const gchar *name) { gint i; gchar *base, *temp; temp = g_path_get_basename(name); /* get the rightmost '.' */ for (i=strlen(temp) ; i-- ; ) if (*(temp+i) == '.') { base = g_strndup(temp, i); g_free(temp); return(base); } /* not found - return the whole thing */ return(temp); } /**********************************************/ /* enforce (replace or add) a given extension */ /**********************************************/ gchar *parse_extension_set(const gchar *text, const gchar *ext) { gint i; gchar *base, *name; /* get the rightmost '.' */ for (i=strlen(text) ; i-- ; ) if (*(text+i) == '.') { /* replace extension */ base = g_strndup(text, i); name = g_strdup_printf("%s.%s", base, ext); g_free(base); return(name); } /* no extension found - add the extension and return */ name = g_strdup_printf("%s.%s", text, ext); return(name); } /**************************************/ /* search for a character in a string */ /**************************************/ gchar *find_char(const gchar *text, gint target, gint search_type) { gint i; switch(search_type) { case LAST: for (i=strlen(text) ; i-- ; ) if (text[i] == target) return((gchar *) text+i); break; default: g_assert_not_reached(); } return(NULL); } /******************************/ /* count character occurances */ /******************************/ gint char_count(const gchar *text, gchar c) { gint i, n=0; for (i=strlen(text) ; i-- ; ) if (text[i] == c) n++; return(n); } /*************************************************************/ /* replace all space characters in a string with a character */ /*************************************************************/ void parse_space_replace(gchar *text, gchar c) { gchar *t = text; while (*t++) { switch (*t) { /* exceptions */ case EOF: return; case '\r': case '\n': break; default: if (g_ascii_isspace(*t)) *t = c; } } } /******************************************************************************/ /* remove all non-alphanumeric chars before and after (but not in) the string */ /******************************************************************************/ void strip_extra(gchar *text) { gint i, n; n = strlen(text); /* white out preceding */ for (i=0 ; i number actually found */ #define DEBUG_GET_KEYWORD 0 gint *get_keyword(gchar *str, gint max) { gint i, j, n, len, num_tokens; gchar **buff; gint *list; #if DEBUG_GET_KEYWORD printf("extracted: "); #endif list = g_malloc((max+1) * sizeof(gint)); buff = tokenize(str, &num_tokens); n=1; i=0; while(i < num_tokens) { /* default keyword code - nothing */ *(list+n) = -1; j=0; while(keywords[j].code != -1) { len = strlen(keywords[j].label); if (g_ascii_strncasecmp(*(buff+i), keywords[j].label, len) == 0) { #if DEBUG_GET_KEYWORD printf(" %d",keywords[j].code); #endif *(list+n) = keywords[j].code; if (++n == max+1) goto get_keyword_done; } j++; } i++; } get_keyword_done:; g_strfreev(buff); *list = n-1; #if DEBUG_GET_KEYWORD printf("\n"); #endif return(list); } gint num_keys(void) { gint n; n=0; while (keywords[n].code != -1) n++; /* printf("Found %d keywords\n",n); */ return(n); } /*****************************************/ /* get a token's keyword number (if any) */ /*****************************************/ gint get_keyword_code(const gchar *token) { gint j, len; j=0; while(keywords[j].code != -1) { len = strlen(keywords[j].label); if (g_ascii_strncasecmp(token, keywords[j].label, len) == 0) return(j); j++; } return(-1); } /*********************/ /* tokenize a string */ /*********************/ /* replacement routine for get_tokens() */ /* will get as many tokens as available (no more messing with MAX_TOKENS) */ #define DEBUG_TOKENIZE 0 gchar **tokenize(const gchar *src, gint *num) { gint i, j, n, len; gchar *tmp, *ptr; gchar **dest; GSList *list=NULL, *item=NULL; /* checks */ if (!src) { *num=0; return(NULL); } /* duplicate & replace all whitespace with a space */ tmp = g_strdup(src); for (i=0 ; i last ptr is NULL, so g_strfreev works */ dest = g_malloc((n+1)*sizeof(gchar *)); i=0; /* fill in the non empty tokens */ item = list; while (idata; if (*ptr == '#') break; *(dest+i) = g_strdup(ptr); #if DEBUG_TOKENIZE printf(" (%s)", ptr); #endif item = g_slist_next(item); } else { /* fake item */ *(dest+i) = g_strdup(" ");; #if DEBUG_TOKENIZE printf(" (empty token)"); #endif } i++; } /* terminate */ *(dest+i) = NULL; *num = i; #if DEBUG_TOKENIZE printf(" %p",*(dest+i)); printf(": found %d tokens\n", *num); #endif /* done */ g_free(tmp); free_slist(list); return(dest); } /************************************************/ /* get the next (non-trivial) line and tokenize */ /************************************************/ /* NULL is returned on EOF */ gchar **get_tokenized_line(FILE *fp, gint *num_tokens) { gchar **buff, line[LINELEN]; do { if (fgetline(fp, line)) { *num_tokens = 0; return(NULL); } buff = tokenize(line, num_tokens); } while (!buff); return(buff); } /*********************/ /* tokenize a string */ /*********************/ /* replacement routine for copy_items */ /* aim is to have one call, rather than multiple copy_item calls */ /* trouble is, g_strsplit doesn't eliminate multiple separators */ /* return number found -> check if enough in file parsing */ /* ensure exactly num tokens returned!!! */ /* strlen = 0 if token is empty */ #define DEBUG_GET_TOKENS 0 gchar **get_tokens(gchar *src, gint num) { gint i, j; gchar **buff, **dest, *tmp; /* duplicate & replace all whitespace with a space */ /* strange errors can be avoided if a strstrip is done */ tmp = g_strdup(src); for (i=0 ; i last ptr is NULL, so g_strfreev works */ dest = g_malloc((num+1)*sizeof(gchar *)); i=j=0; /* fill in the non empty tokens */ while (*(buff+i) != NULL && j