217 lines
4.2 KiB
C
217 lines
4.2 KiB
C
/**********
|
|
Copyright 1992 Regents of the University of California. All rights reserved.
|
|
Author: 1992 David A. Gates, U. C. Berkeley CAD Group
|
|
**********/
|
|
|
|
/*
|
|
* Read and write dimension/index arrays via strings.
|
|
*/
|
|
|
|
#include "ngspice/ngspice.h"
|
|
#include "ngspice/dvec.h" /* For MAXDIMS */
|
|
#include "dimens.h"
|
|
|
|
|
|
/*
|
|
* Create a string of the form "12,1,10".
|
|
*/
|
|
void
|
|
dimstring(int *data, int length, char *retstring)
|
|
{
|
|
int i;
|
|
char buf[BSIZE_SP];
|
|
|
|
|
|
if (!data || length < 1)
|
|
retstring = "";
|
|
|
|
buf[0] = '\0';
|
|
for (i=0; i < length; i++) {
|
|
sprintf(buf + strlen(buf), "%d%s", data[i],
|
|
(i < length - 1) ? "," : "");
|
|
}
|
|
/* XXX Should I return a copy instead? */
|
|
/* qui ci devo fare una copia */
|
|
strcpy(retstring, buf);
|
|
}
|
|
|
|
/*
|
|
* Create a string of the form "[12][1][10]".
|
|
*/
|
|
void
|
|
indexstring(int *data, int length, char *retstring)
|
|
{
|
|
int i;
|
|
char buf[BSIZE_SP];
|
|
|
|
if (!data || length < 1)
|
|
retstring = "";
|
|
|
|
buf[0] = '\0';
|
|
for (i=0; i < length; i++) {
|
|
sprintf(buf + strlen(buf), "[%d]", data[i]);
|
|
}
|
|
strcpy(retstring, buf);
|
|
}
|
|
|
|
/*
|
|
* Add one to anstrchr into an array with sizes in dims.
|
|
* Return 1 when all counters overflow at once.
|
|
*/
|
|
int
|
|
incindex(int *counts, int numcounts, int *dims, int numdims)
|
|
{
|
|
int i, start;
|
|
|
|
if (!counts || numcounts < 1 || !dims || numdims < 1)
|
|
return 0;
|
|
|
|
start = numcounts - 1;
|
|
for (i = start; i >= 0; i--) {
|
|
if (++counts[i] < dims[i])
|
|
break; /* This counter is not maxed out. */
|
|
else
|
|
counts[i] = 0;
|
|
}
|
|
if (i == 0)
|
|
return(1);
|
|
else
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* Count number of empty dimensions in an array.
|
|
*/
|
|
int
|
|
emptydims(int *data, int length)
|
|
{
|
|
int i, numempty = 0;
|
|
|
|
for (i=0; i < length; i++) {
|
|
if (data[i] == 0)
|
|
numempty++;
|
|
}
|
|
return(numempty);
|
|
}
|
|
|
|
/*
|
|
* Read a string of one of the following forms into a dimensions array:
|
|
* [12][1][10]
|
|
* [12,1,10]
|
|
* 12,1,10
|
|
* 12, 1, 10
|
|
* 12 , 1 , 10
|
|
* Basically, we require that all brackets be matched, that all numbers
|
|
* be separated by commas or by "][", that all whitespace is ignored, and
|
|
* the beginning [ and end ] are ignored if they exist. The only valid
|
|
* characters in the string are brackets, commas, spaces, and digits.
|
|
* If any dimension is blank, its entry in the array is set to 0.
|
|
*
|
|
* Return 0 on success, 1 on failure.
|
|
*/
|
|
int
|
|
atodims(char *p, int *data, int *outlength)
|
|
{
|
|
int length = 0;
|
|
int state = 0;
|
|
int err = 0;
|
|
int needbracket = 0;
|
|
char sep = '\0';
|
|
|
|
if (!data || !outlength)
|
|
return 1;
|
|
|
|
if (!p) {
|
|
*outlength = 0;
|
|
return 0;
|
|
}
|
|
|
|
while (*p && isspace(*p))
|
|
p++;
|
|
|
|
if (*p == '[') {
|
|
p++;
|
|
while (*p && isspace(*p))
|
|
p++;
|
|
needbracket = 1;
|
|
}
|
|
|
|
while (*p && state != 3) {
|
|
switch (state) {
|
|
case 0: /* p just at or before a number */
|
|
if (length >= MAXDIMS) {
|
|
if (length == MAXDIMS)
|
|
printf("Error: maximum of %d dimensions allowed.\n",
|
|
MAXDIMS);
|
|
length += 1;
|
|
} else if (!isdigit(*p)) {
|
|
data[length++] = 0; /* This position was empty. */
|
|
} else {
|
|
data[length++] = atoi(p);
|
|
while (isdigit(*p))
|
|
p++;
|
|
}
|
|
state = 1;
|
|
break;
|
|
|
|
case 1: /* p after a number, looking for ',' or ']' */
|
|
if (sep == '\0') {
|
|
sep = *p;
|
|
}
|
|
if (*p == ']' && *p == sep) {
|
|
p++;
|
|
state = 2;
|
|
} else if (*p == ',' && *p == sep) {
|
|
p++;
|
|
state = 0;
|
|
} else /* Funny character following a # */
|
|
break;
|
|
break;
|
|
|
|
case 2: /* p after a ']', either at the end or looking for '[' */
|
|
if (*p == '[') {
|
|
p++;
|
|
state = 0;
|
|
} else {
|
|
state = 3;
|
|
}
|
|
break;
|
|
}
|
|
|
|
while (*p && isspace(*p))
|
|
p++;
|
|
}
|
|
|
|
*outlength = length;
|
|
if (length > MAXDIMS) {
|
|
return(1);
|
|
}
|
|
if (state == 3) { /* We finished with a closing bracket */
|
|
err = !needbracket;
|
|
} else if (*p) { /* We finished by hitting a bad character after a # */
|
|
err = 1;
|
|
} else { /* We finished by exhausting the string */
|
|
err = needbracket;
|
|
}
|
|
if (err) {
|
|
*outlength = 0;
|
|
}
|
|
return(err);
|
|
}
|
|
|
|
/*
|
|
* Skip to the first character that cannot be part of a dimension string.
|
|
*/
|
|
char *
|
|
skipdims(char *p)
|
|
{
|
|
if (!p)
|
|
return NULL;
|
|
|
|
while(*p && (*p == '[' || *p == ']' || *p == ','
|
|
|| isspace(*p) || isdigit(*p)))
|
|
p++;
|
|
|
|
return(p);
|
|
}
|