| /* | |
| * 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); | |
| while (*str == ' ') str++; | |
| if (!strncmp (str, match, strlen (match))) | |
| { | |
| *found = 1; | |
| str += strlen (match); | |
| while (*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 (); | |
| } |