/* mystring.c Copyright (C) 2002 Georg Post * * This file is part of Numparam, see: readme.txt * Free software under the terms of the GNU Lesser General Public License */ #include "ngspice/ngspice.h" #include #include #include #include #include #include #include "ngspice/config.h" #include "ngspice/memory.h" #ifdef HAS_WINGUI #include "ngspice/wstdio.h" #endif #include "general.h" /* * fetch a human answer to a y/n question from stdin * insist on a single non white-space char on a '\n' terminated line * return this char or '\n' or EOF * return '\0' if the answer doesn't fit this pattern */ int yes_or_no(void) { int first; do { first = getchar(); if (first == '\n' || first == EOF) return first; } while (isspace(first)); for (;;) { int c = getchar(); if (c == EOF) return c; if (c == '\n') return tolower(first); if (!isspace(c)) first = '\0'; } } /******* Strings ************ * are 0-terminated char arrays with a 2-byte trailer: max length. * the string mini-library is "overflow-safe" under these conditions: * use Str(n,s) macro: define and initialize a string s of maxlen n<255 * to allocate a string on the heap, use newstring(n). * use maxlen() and length() to retrieve string max and actual length * use: cadd, sadd, scopy, pscopy to manipulate them * never put '\x0' characters inside strings ! * * the 'killer idea' is the following: * on string overflow and/or on heap allocation failure, a program * MUST die. Now we only die on a heap failure as with dynamic * string we cannot have a string overflow. */ /* ----------------------------------------------------------------- * Function: add string t to dynamic string dstr_p. * ----------------------------------------------------------------- */ void sadd(DSTRINGPTR dstr_p, const char *t) { if (ds_cat_str(dstr_p, t) != DS_E_OK) { controlled_exit(-1); } } /* ----------------------------------------------------------------- * Function: add character c to dynamic string dstr_p. * ----------------------------------------------------------------- */ void cadd(DSTRINGPTR dstr_p, char c) { if (ds_cat_char(dstr_p, c) != DS_E_OK) { controlled_exit(-1); } } /* ----------------------------------------------------------------- * Create copy of the dynamic string. Dynamic strings are always NULL * terminated. * ----------------------------------------------------------------- */ void scopyd(DSTRINGPTR dst, const DSTRINGPTR src) /* returns success flag */ { ds_clear(dst); if (ds_cat_ds(dst, src) != DS_E_OK) { controlled_exit(-1); } } /* ----------------------------------------------------------------- * Create copy of the string in the dynamic string. Dynamic strings * are always NULL terminated. * ----------------------------------------------------------------- */ void scopys(DSTRINGPTR s, const char *t) /* returns success flag */ { ds_clear(s); if (ds_cat_str(s, t) != DS_E_OK) { controlled_exit(-1); } } /* Copy until stop char (exclusive) or end of string if none given */ void pscopy(DSTRINGPTR dstr_p, const char *t, const char *stop) { if (!stop) { /* locate end of string if no stop char given */ stop = strchr(t, '\0'); } ds_clear(dstr_p); if (ds_cat_mem(dstr_p, t, (size_t) (stop - t)) != DS_E_OK) { controlled_exit(-1); } return; } /* end of function pscopy */ bool alfa(char c) { return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || c == '_' || c == '[' || c == ']' || ((c) & 0200); } bool alfanum(char c) { return alfa(c) || ((c >= '0') && (c <= '9')); } /* Additionally '-' allowed in subckt name if ps compatible */ bool alfanumps(char c) { return alfa(c) || ((c >= '0') && (c <= '9')) || c == '-'; }