Jspice3
inpcom.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1985 Wayne A. Christopher
5  1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 /*
9  * For dealing with input decks and command scripts
10  */
11 
12 #include "spice.h"
13 #include "ftedefs.h"
14 #include "fteinp.h"
15 
16 #define STRGROW 256
17 
18 
19 char *
21 
22 /* This routine reads a line (of arbitrary length), up to a '\n' or 'EOF'
23  * and returns a pointer to the resulting null terminated string.
24  * The '\n' if found, is included in the returned string.
25  * From: jason@ucbopal.BERKELEY.EDU (Jason Venner)
26  * Newsgroups: net.sources
27  */
28 FILE *fd;
29 {
30  int c;
31  int memlen;
32  char *strptr;
33  int strlen;
34 
35  strptr = NULL;
36  strlen = 0;
37  memlen = STRGROW;
38  strptr = tmalloc(memlen);
39  memlen -= 1; /* Save constant -1's in while loop */
40  while((c = getc(fd)) != EOF) {
41  strptr[strlen] = c;
42  strlen++;
43  if( strlen >= memlen ) {
44  memlen += STRGROW;
45  if( !(strptr = trealloc(strptr, memlen + 1))) {
46  return (NULL);
47  }
48  }
49  if (c == '\n') {
50  break;
51  }
52  }
53  if (!strlen) {
54  txfree(strptr);
55  return (NULL);
56  }
57  strptr[strlen] = '\0';
58  /* Trim the string */
59  strptr = trealloc(strptr, strlen + 1);
60  return (strptr);
61 }
62 
63 
64 FILE *
65 inp_pathopen(name, mode)
66 
67 /* Look up the variable sourcepath and try everything in the list in order
68  * if the file isn't in . and it isn't an abs path name.
69  */
70 char *name, *mode;
71 {
72  FILE *fp;
73  char buf[BSIZE_SP];
74  struct variable *v = NULL;
75  extern char *kw_sourcepath;
76 
77  /* If this is an abs pathname, or there is no sourcepath var, just
78  * do an fopen.
79  */
80  if (strchr(name, DIR_TERM) || strchr(name,'/')
81  || !cp_getvar(kw_sourcepath, VT_LIST, (char *) &v)) {
82  strcpy(buf,name);
83  cp_pathfix(buf);
84  return (fopen(buf, mode));
85  }
86 
87  while (v) {
88  switch (v->va_type) {
89  case VT_STRING:
90  cp_wstrip(v->va_string);
91  (void) sprintf(buf, "%s/%s", v->va_string, name);
92  break;
93  case VT_NUM:
94  (void) sprintf(buf, "%d/%s", v->va_num, name);
95  break;
96  case VT_REAL: /* This is foolish */
97  (void) sprintf(buf, "%lg/%s", v->va_real, name);
98  break;
99  }
100  cp_pathfix(buf);
101  if (fp = fopen(buf, mode))
102  return (fp);
103  v = v->va_next;
104  }
105  return (NULL);
106 }
107 
108 
109 void
110 inp_readall(fp, data, title)
111 
112 /* Read the entire input file and return a pointer to the first line of
113  * the linked list of 'card' records in data.
114  */
115 FILE *fp;
116 struct line **data;
117 char *title;
118 {
119  struct line *cc, *end = NULL, *prev = NULL, *working, *newcard;
120  char *buffer, *s, *t;
121  int line = 1;
122  FILE *newfp;
123 
124  for (;;) {
125  if (title) {
126  buffer = title;
127  title = NULL;
128  }
129  else if ((buffer = readline(fp)) == NULL)
130  break;
131 
132  if (*buffer == '@')
133  break;
134 
135  /* Zap the newline. */
136  for (s = buffer; *s && (*s != '\n'); s++)
137  ;
138  if (!*s) {
139  fprintf(cp_err, "Warning: premature EOF\n");
140  }
141  *s = '\0';
142 
143  /* strip any leading white space */
144  s = buffer;
145  while (*s == ' ' || *s == '\t')
146  s++;
147  if (s != buffer) {
148  t = buffer;
149  while (*s)
150  *t++ = *s++;
151  *t = '\0';
152  }
153 
154  if (prefix(".include", buffer)) {
155  for (s = buffer; *s && !isspace(*s); s++)
156  ;
157  while (isspace(*s))
158  s++;
159  if (!*s) {
160  fprintf(cp_err,
161  "Error: .include filename missing\n");
162  continue;
163  }
164  for (t = s; *t && !isspace(*t); t++)
165  ;
166  *t = '\0';
167  if (*s == '~')
168  s = cp_tildexpand(s);
169  if (!(newfp = inp_pathopen(s, "r"))) {
170  perror(s);
171  continue;
172  }
173  inp_readall(newfp, &newcard,NULL);
174  (void) fclose(newfp);
175 
176  /* Make the .include a comment */
177  *buffer = '*';
178  if (end) {
179  end->li_next = alloc(struct line);
180  end = end->li_next;
181  }
182  else {
183  end = cc = alloc(struct line);
184  }
185  end->li_line = copy(buffer);
186  end->li_linenum = line++;
187  end->li_next = newcard;
188 
189  /* Renumber the cards */
190  for (end = newcard; end && end->li_next; end = end->li_next)
191  end->li_linenum = line++;
192 
193  /* Fix the buffer up a bit. */
194  (void) strncpy(buffer + 1, "end of:", 7);
195  }
196 
197  if (end) {
198  end->li_next = alloc(struct line);
199  end = end->li_next;
200  }
201  else {
202  end = cc = alloc(struct line);
203  }
204  end->li_line = buffer;
205  end->li_linenum = line++;
206  }
207  if (!end) { /* No stuff here */
208  *data = NULL;
209  return;
210  }
211 
212  /* Now make logical lines. */
213  working = cc->li_next; /* Skip title. */
214 
215  while (working) {
216  switch (*working->li_line) {
217  case '*':
218  case '\0':
219  prev = NULL;
220  working = working->li_next;
221  break;
222  case '+':
223  if (!prev) {
224  working->li_error = copy(
225  "Illegal continuation card: ignored.");
226  working = working->li_next;
227  break;
228  }
229  buffer = tmalloc(strlen(prev->li_line) +
230  strlen(working->li_line) + 2);
231  (void) sprintf(buffer, "%s %s", prev->li_line,
232  working->li_line + 1);
233  s = prev->li_line;
234  prev->li_line = buffer;
235  prev->li_next = working->li_next;
236  working->li_next = NULL;
237  if (prev->li_actual) {
238  for (end = prev->li_actual;
239  end->li_next; end = end->li_next)
240  ;
241  end->li_next = working;
242  tfree(s);
243  }
244  else {
245  newcard = alloc(struct line);
246  newcard->li_linenum = prev->li_linenum;
247  newcard->li_line = s;
248  newcard->li_next = working;
249  prev->li_actual = newcard;
250  }
251  working = prev->li_next;
252  break;
253  default:
254  prev = working;
255  working = working->li_next;
256  break;
257  }
258  }
259 
260  *data = cc;
261  return;
262 }
263 
264 
265 void
266 inp_casefix(string)
267 
268 char *string;
269 {
270  if (string)
271  while (*string) {
272  *string = strip(*string);
273  if (!isspace(*string) && !isprint(*string))
274  *string = '_';
275  if (isupper(*string))
276  *string = tolower(*string);
277  string++;
278  }
279  return;
280 }
281 
282 
283 void
285 
286 struct line *deck;
287 {
288  struct line *d, *dd;
289 
290  d = deck;
291  while (d) {
292  tfree(d->li_line);
293  tfree(d->li_error);
294  if (d->li_actual) inp_deckfree(d->li_actual);
295  dd = d;
296  d = d->li_next;
297  tfree(dd);
298  }
299 }
300 
301 
302 struct line *
304 
305 /* Copy a deck, including the actual lines. */
306 struct line *deck;
307 {
308  struct line *d = NULL, *nd = NULL;
309 
310  while (deck) {
311  if (nd) {
312  d->li_next = alloc(struct line);
313  d = d->li_next;
314  }
315  else
316  nd = d = alloc(struct line);
317  d->li_linenum = deck->li_linenum;
318  d->li_line = copy(deck->li_line);
319  if (deck->li_error)
320  d->li_error = copy(deck->li_error);
321  d->li_actual = inp_deckcopy(deck->li_actual);
322  deck = deck->li_next;
323  }
324  return (nd);
325 }
int li_linenum
Definition: fteinp.h:15
void cp_pathfix(char *buf)
Definition: help.c:198
struct line * li_actual
Definition: fteinp.h:19
static char buf[MAXPROMPT]
Definition: arg.c:18
#define BSIZE_SP
Definition: misc.h:19
Definition: subckt.c:18
bool cp_getvar(char *n, int t, char *r)
Definition: help.c:184
#define strip(c)
Definition: cpdefs.h:75
char * cp_tildexpand()
#define prefix(x, y)
Definition: readhelp.c:39
char * strcpy()
Definition: cddefs.h:119
void inp_readall(FILE *fp, struct line **data, char *title)
Definition: inpcom.c:110
char * readline(FILE *fd)
Definition: inpcom.c:20
#define VT_LIST
Definition: cpstd.h:64
#define STRGROW
Definition: inpcom.c:16
#define alloc(type)
Definition: cdmacs.h:21
char * copy()
char va_type
Definition: cpstd.h:42
FILE * cp_err
Definition: help.c:101
char * tmalloc()
Definition: fteinp.h:14
Definition: cddefs.h:237
#define tfree(x)
Definition: cdmacs.h:22
void txfree()
#define NULL
Definition: spdefs.h:121
char * li_error
Definition: fteinp.h:17
char * li_line
Definition: fteinp.h:16
#define VT_NUM
Definition: cpstd.h:61
static double c
Definition: vectors.c:16
#define VT_STRING
Definition: cpstd.h:63
void perror()
struct line * li_next
Definition: fteinp.h:18
void inp_deckfree(struct line *deck)
Definition: inpcom.c:284
FILE * inp_pathopen(char *name, char *mode)
Definition: inpcom.c:65
#define VT_REAL
Definition: cpstd.h:62
struct line * inp_deckcopy(struct line *deck)
Definition: inpcom.c:303
Definition: cddefs.h:192
struct variable * va_next
Definition: cpstd.h:51
void cp_wstrip()
char * trealloc()
Definition: cpstd.h:41
char * kw_sourcepath
Definition: options.c:417
void inp_casefix(char *string)
Definition: inpcom.c:266