/* util.c */ /* utility functions of gtkfind */ /* Copyright (C) 1999 Matthew Grossman 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"util.h" extern void print_error(const char *format, ...); static char * expand_local_path(char *path) /* if the first character is a . or not a /, allocate and return absolute path else return NULL */ { char *rv = NULL; char *offset = NULL; char tmp[MAXPATHLEN]; if(path[0] != '/' && path[0] != '~') { rv = (char *)malloc(sizeof(char) * MAXPATHLEN); if(!rv) { goto ERROR; } if(!getcwd(tmp, MAXPATHLEN)) { print_error("getcwd: %s\n", strerror(errno)); goto ERROR; } strncpy(rv, tmp, strlen(tmp)); rv[strlen(tmp)] = '\0'; offset = path; if(*offset == '.') offset++; if(*offset != '\0') { if(*offset != '/') strcat(rv, "/"); strcat(rv, offset); } } DONE: return(rv); ERROR: if(rv) free(rv); rv = NULL; goto DONE; } static char * expand_tilde(char *path) /* if this is a ~ path, allocate and return an absolute path, else return NULL */ { char *rv = NULL; char *login = NULL; struct passwd *pwd = NULL; char *offset = NULL; /* expand ~ */ if(path[0] == '~') { if(path[1] == '\0' || path[1] == '/') { login = getenv("USER"); if(!login) { print_error("expand_tilde: Cannot get USER environment variable.\n"); goto ERROR; } if(path[1]) offset = path + 1; } else { /* we are trying to read something form ~mattg/src */ offset = strchr(path, '/'); if(offset) { login = (char *)alloca(offset - path); strncpy(login, path + 1, (offset - path) - 1); login[(offset - path) - 1] = '\0'; } else { login = (char *)alloca(strlen(path)); strcpy(login, path + 1); } } pwd = getpwnam(login); if(!pwd) { print_error("expand_tilde: Cannot getpwnam for %s\n", login); goto ERROR; } rv = (char *)malloc(strlen(pwd->pw_dir) + 1); if(!rv) { print_error("expand_tilde: malloc failed!\n"); goto ERROR; } strcpy(rv, pwd->pw_dir); if(offset) { rv = (char *)realloc(rv, strlen(rv) + strlen(offset) + 1); strcat(rv, offset); } } else { rv = NULL; } DONE: /* we don't free pwd */ return(rv); ERROR: if(rv) free(rv); rv = NULL; goto DONE; } char * expand_path(char *path) /* given a path, return the absolute path. Expand ~, . and if there is no leading slash assume a relative path */ { char *rv = NULL; if(strlen(path) > 0) { if(!((rv = expand_tilde(path)) || (rv = expand_local_path(path)))) { rv = (char *)malloc(strlen(path) + 1); strcpy(rv, path); } } return(rv); } int get_max_line_width(char *buffer, int c_width) /* given a buffer of text, return the length of the longest line in the buffer * c_width */ { int longest = 0, offset = 0; char *p = NULL, *q = NULL; int rv = 0; q = buffer; while(q && (p = strchr(q, '\n'))) { offset = p - q; q = p + 1; if(offset > longest) longest = offset; } if(longest == 0) { print_error("get_max_line_width: Can't find newline in string buffer!"); rv = strlen(buffer) * c_width; } else rv = longest * c_width; return(rv); } int leap_year_p(int year) /* return 1 if year is a leap year, formula from comp.lang.c FAQ */ { int rv = 0; if(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) rv = 1; return(rv); } char * glob2regex(char *pattern) /* convert a wildcard pattern to an egrep expression */ /* doesn't use gtkfind registers... */ { char *rv = NULL; char *s = NULL; char *source = NULL, *dest = NULL; char c = 0; int state = 1; /* 1 == normal, 2 == inside {} */ s = (char *)malloc(strlen(pattern) * 2 + 1); if(!s) { print_error("glob2regex: Can't allocate string for %s.", pattern); goto DONE; } source = pattern; dest = s; while(source && *source) { switch((c = *source++)) { case '*': if(source != pattern + 1 && *source != '\0') { /* get rid of leading and trailing *'s */ *dest++ = '.'; *dest++ = '*'; } break; case '?': *dest++ = '.'; break; case '\\': *dest++ = '\\'; *dest++ = *source++; break; case '^': /* special regex characters in a wildcard pattern */ case '$': case '.': case '+': case '(': case ')': case '|': *dest++ = '\\'; *dest++ = c; break; case '{': if(state != 2) state = 2; *dest++ = '('; break; case '}': if(state != 1) state = 1; *dest++ = ')'; break; case ',': if(state == 2) *dest++ = '|'; else *dest++ = c; break; default: *dest++ = c; break; } } *dest = '\0'; rv = s; DONE: return(rv); } char * get_text_option(int argc, char *argv[], char *option) /* return a pointer to the option's value, or NULL */ { char *rv = NULL; int i = 0; for(i = 0; i < argc; i++) { if(strcmp(argv[i], option) == 0) { rv = argv[i + 1]; goto DONE; } } DONE: return(rv); } int get_bool_option(int argc, char *argv[], char *option) { int i = 0, rv = 0; for(i = 0; i < argc; i++) { if(strcmp(argv[i], option) == 0) { rv = 1; goto DONE; } } DONE: return(rv); }