/* * Misc functions * * Copyright 2000 Jon Griffiths */ #include "specmaker.h" /******************************************************************* * str_create * * Create a single string from many substrings */ char *str_create(size_t num_str, ...) { va_list args; size_t len = 1, i = 0; char *tmp, *t; va_start (args, num_str); for (i = 0; i < num_str; i++) if ((t = va_arg(args, char *))) len += strlen (t); va_end (args); if (!(tmp = (char *) malloc (len))) fatal ("Out of memory"); tmp[0] = '\0'; va_start (args, num_str); for (i = 0; i < num_str; i++) if ((t = va_arg(args, char *))) strcat (tmp, t); va_end (args); return tmp; } /******************************************************************* * str_create_num * * Create a single string from many substrings, terminating in a number */ char *str_create_num(size_t num_str, int num, ...) { va_list args; size_t len = 8, i = 0; char *tmp, *t; va_start (args, num); for (i = 0; i < num_str; i++) if ((t = va_arg(args, char *))) len += strlen (t); va_end (args); if (!(tmp = (char *) malloc (len))) fatal ("Out of memory"); tmp[0] = '\0'; va_start (args, num); for (i = 0; i < num_str; i++) if ((t = va_arg(args, char *))) strcat (tmp, t); va_end (args); sprintf (tmp + len - 8, "%d", num); return tmp; } /******************************************************************* * str_substring * * Create a new substring from a string */ char *str_substring(const char *start, const char *end) { char *newstr; assert (start && end && end > start); if (!(newstr = (char *) malloc (end - start + 1))) fatal ("Out of memory"); memcpy (newstr, start, end - start); newstr [end - start] = '\0'; return newstr; } /******************************************************************* * str_replace * * Swap two strings in another string, in place * Modified PD code from 'snippets' */ char *str_replace (char *str, const char *oldstr, const char *newstr) { int oldlen, newlen; char *p, *q; if (!(p = strstr(str, oldstr))) return p; oldlen = strlen (oldstr); newlen = strlen (newstr); memmove (q = p + newlen, p + oldlen, strlen (p + oldlen) + 1); memcpy (p, newstr, newlen); return q; } /******************************************************************* * str_match * * Locate one string in another, ignoring spaces */ const char *str_match (const char *str, const char *match, int *found) { assert(str && match && found); for (; *str == ' '; str++); if (!strncmp (str, match, strlen (match))) { *found = 1; str += strlen (match); for (; *str == ' '; str++); } else *found = 0; return str; } /******************************************************************* * str_find_set * * Locate the first occurence of a set of characters in a string */ const char *str_find_set (const char *str, const char *findset) { assert(str && findset); while (*str) { const char *p = findset; while (*p) if (*p++ == *str) return str; str++; } return NULL; } /******************************************************************* * str_toupper * * Uppercase a string */ char *str_toupper (char *str) { char *save = str; while (*str) { *str = toupper (*str); str++; } return save; } /******************************************************************* * open_file * * Open a file returning only on success */ FILE *open_file (const char *name, const char *ext, const char *mode) { char fname[128]; FILE *fp; if (((unsigned)snprintf (fname, sizeof (fname), "%s%s%s", *mode == 'w' ? "./" : "", name, ext) > sizeof (fname))) fatal ("File name too long"); if (VERBOSE) printf ("Open file %s\n", fname); fp = fopen (fname, mode); if (!fp) fatal ("Cant open file"); return fp; } /******************************************************************* * fatal * * Fatal error handling */ void fatal (const char *message) { if (errno) perror (message); else puts (message); do_usage (); }