2000-04-27 22:03:57 +02:00
|
|
|
/**********
|
|
|
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
|
|
|
**********/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* String functions
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
2001-02-11 01:47:21 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_STRING_H
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
#include "ngspice.h"
|
2001-02-11 01:47:21 +01:00
|
|
|
#include "stringutil.h"
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
int
|
|
|
|
|
prefix(register char *p, register char *s)
|
|
|
|
|
{
|
|
|
|
|
while (*p && (*p == *s))
|
|
|
|
|
p++, s++;
|
|
|
|
|
if (!*p)
|
|
|
|
|
return (TRUE);
|
|
|
|
|
else
|
|
|
|
|
return (FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create a copy of a string. */
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
copy(char *str)
|
|
|
|
|
{
|
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
|
|
if ((p = tmalloc(strlen(str) + 1)))
|
|
|
|
|
(void) strcpy(p, str);
|
|
|
|
|
return(p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Determine whether sub is a substring of str. */
|
|
|
|
|
/* Like strstr( ) XXX */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
substring(register char *sub, register char *str)
|
|
|
|
|
{
|
|
|
|
|
char *s, *t;
|
|
|
|
|
|
|
|
|
|
while (*str) {
|
|
|
|
|
if (*str == *sub) {
|
|
|
|
|
t = str;
|
|
|
|
|
for (s = sub; *s; s++) {
|
|
|
|
|
if (!*t || (*s != *t++))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (*s == '\0')
|
|
|
|
|
return (TRUE);
|
|
|
|
|
}
|
|
|
|
|
str++;
|
|
|
|
|
}
|
|
|
|
|
return (FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Append one character to a string. Don't check for overflow. */
|
|
|
|
|
/* Almost like strcat( ) XXX */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
appendc(char *s, char c)
|
|
|
|
|
{
|
|
|
|
|
while (*s)
|
|
|
|
|
s++;
|
|
|
|
|
*s++ = c;
|
|
|
|
|
*s = '\0';
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Try to identify an integer that begins a string. Stop when a non-
|
|
|
|
|
* numeric character is reached.
|
|
|
|
|
*/
|
|
|
|
|
/* Like atoi( ) XXX */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
scannum(char *str)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
while(isdigit(*str))
|
|
|
|
|
i = i * 10 + *(str++) - '0';
|
|
|
|
|
return(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Case insensitive str eq. */
|
|
|
|
|
/* Like strcasecmp( ) XXX */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
cieq(register char *p, register char *s)
|
|
|
|
|
{
|
|
|
|
|
while (*p) {
|
|
|
|
|
if ((isupper(*p) ? tolower(*p) : *p) !=
|
|
|
|
|
(isupper(*s) ? tolower(*s) : *s))
|
|
|
|
|
return(FALSE);
|
|
|
|
|
p++;
|
|
|
|
|
s++;
|
|
|
|
|
}
|
|
|
|
|
return (*s ? FALSE : TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Case insensitive prefix. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
ciprefix(register char *p, register char *s)
|
|
|
|
|
{
|
|
|
|
|
while (*p) {
|
|
|
|
|
if ((isupper(*p) ? tolower(*p) : *p) !=
|
|
|
|
|
(isupper(*s) ? tolower(*s) : *s))
|
|
|
|
|
return(FALSE);
|
|
|
|
|
p++;
|
|
|
|
|
s++;
|
|
|
|
|
}
|
|
|
|
|
return (TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
strtolower(char *str)
|
|
|
|
|
{
|
|
|
|
|
if (str)
|
|
|
|
|
while (*str) {
|
|
|
|
|
*str = tolower(*str);
|
|
|
|
|
str++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
gettok(char **s)
|
|
|
|
|
{
|
|
|
|
|
char buf[BSIZE_SP];
|
|
|
|
|
int i = 0;
|
|
|
|
|
char c;
|
|
|
|
|
int paren;
|
|
|
|
|
|
|
|
|
|
paren = 0;
|
|
|
|
|
while (isspace(**s))
|
|
|
|
|
(*s)++;
|
|
|
|
|
if (!**s)
|
|
|
|
|
return (NULL);
|
|
|
|
|
while ((c = **s) && !isspace(c)) {
|
|
|
|
|
if (c == '('/*)*/)
|
|
|
|
|
paren += 1;
|
|
|
|
|
else if (c == /*(*/')')
|
|
|
|
|
paren -= 1;
|
|
|
|
|
else if (c == ',' && paren < 1)
|
|
|
|
|
break;
|
|
|
|
|
buf[i++] = *(*s)++;
|
|
|
|
|
}
|
|
|
|
|
buf[i] = '\0';
|
|
|
|
|
while (isspace(**s) || **s == ',')
|
|
|
|
|
(*s)++;
|
|
|
|
|
return (copy(buf));
|
|
|
|
|
}
|
|
|
|
|
|
2003-07-23 21:36:39 +02:00
|
|
|
/*-------------------------------------------------------------------------*
|
|
|
|
|
* gettok_noparens was added by SDB on 4.21.2003.
|
|
|
|
|
* It acts like gettok, except that it stops parsing when it hits a paren
|
|
|
|
|
* (i.e. it treats parens like whitespace). It is used in translate (subckt.c)
|
|
|
|
|
* while looking for the POLY token.
|
|
|
|
|
*-------------------------------------------------------------------------*/
|
|
|
|
|
char *
|
|
|
|
|
gettok_noparens(char **s)
|
|
|
|
|
{
|
|
|
|
|
char buf[BSIZE_SP];
|
|
|
|
|
int i = 0;
|
|
|
|
|
char c;
|
|
|
|
|
|
|
|
|
|
while (isspace(**s))
|
|
|
|
|
(*s)++;
|
|
|
|
|
if (!**s)
|
|
|
|
|
return (NULL);
|
|
|
|
|
while ((c = **s) && !isspace(c) &&
|
|
|
|
|
( **s != '(' ) && ( **s != ')' ) ) {
|
|
|
|
|
buf[i++] = *(*s)++;
|
|
|
|
|
}
|
|
|
|
|
buf[i] = '\0';
|
|
|
|
|
while (isspace(**s))
|
|
|
|
|
(*s)++;
|
|
|
|
|
return (copy(buf));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*
|
|
|
|
|
* get_l_paren iterates the pointer forward in a string until it hits
|
|
|
|
|
* the position after the next left paren "(". It returns 0 if it found a left
|
|
|
|
|
* paren, and 1 if no left paren is found.
|
|
|
|
|
*-------------------------------------------------------------------------*/
|
|
|
|
|
int
|
|
|
|
|
get_l_paren(char **s)
|
|
|
|
|
{
|
|
|
|
|
while (**s && ( **s != '(' ) )
|
|
|
|
|
(*s)++;
|
|
|
|
|
if (!**s)
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
(*s)++;
|
|
|
|
|
|
|
|
|
|
if (!**s)
|
|
|
|
|
return (1);
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*
|
|
|
|
|
* get_r_paren iterates the pointer forward in a string until it hits
|
|
|
|
|
* the position after the next right paren ")". It returns 0 if it found a right
|
|
|
|
|
* paren, and 1 if no right paren is found.
|
|
|
|
|
*-------------------------------------------------------------------------*/
|
|
|
|
|
int
|
|
|
|
|
get_r_paren(char **s)
|
|
|
|
|
{
|
|
|
|
|
while (**s && ( **s != ')' ) )
|
|
|
|
|
(*s)++;
|
|
|
|
|
if (!**s)
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
(*s)++;
|
|
|
|
|
|
|
|
|
|
if (!**s)
|
|
|
|
|
return (1);
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef HAVE_BCOPY
|
|
|
|
|
|
|
|
|
|
#ifndef bcopy
|
|
|
|
|
void
|
2003-07-23 21:36:39 +02:00
|
|
|
bcopy(const void *vfrom, void *vto, size_t num)
|
2000-04-27 22:03:57 +02:00
|
|
|
{
|
2003-07-23 21:36:39 +02:00
|
|
|
register const char *from = vfrom;
|
|
|
|
|
register char *to = vto;
|
2000-04-27 22:03:57 +02:00
|
|
|
while (num-- > 0)
|
|
|
|
|
*to++ = *from++;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef bzero
|
|
|
|
|
/* can't declare void here, because we've already used it in this file */
|
|
|
|
|
/* and haven't declared it void before the use */
|
2003-07-23 21:36:39 +02:00
|
|
|
void
|
|
|
|
|
bzero(void *vptr, size_t num)
|
2000-04-27 22:03:57 +02:00
|
|
|
{
|
2003-07-23 21:36:39 +02:00
|
|
|
register char *ptr=vptr;
|
2000-04-27 22:03:57 +02:00
|
|
|
while (num-- > 0)
|
|
|
|
|
*ptr++ = '\0';
|
2003-07-23 21:36:39 +02:00
|
|
|
return;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|