Jspice3
numparse.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  * This routine parses a number.
10  */
11 
12 #include "spice.h"
13 #include "ftedefs.h"
14 
15 bool ft_strictnumparse = false;
16 
17 /* Parse a number. This will handle things like 10M, etc... If the number
18  * must not end before the end of the string, then whole is true.
19  * If whole is false and there is more left to the number, the argument
20  * is advanced to the end of the word. Returns NULL
21  * if no number can be found or if there are trailing characters when
22  * whole is true.
23  * If ft_strictnumparse is true, and whole is false, the first of the
24  * trailing characters must be a '_'.
25  */
26 
27 double *
28 ft_numparse(s, whole)
29 
30 char **s;
31 bool whole;
32 {
33  double mant, expo, tmpn;
34  bool sign = false, exsign = false;
35  static double num;
36  char *string = *s;
37 
38  /* See if the number begins with + or -. */
39  if (*string == '+')
40  string++;
41  else if (*string == '-') {
42  string++;
43  sign = true;
44  }
45 
46  /* We don't want to recognise "P" as 0P, or .P as 0.0P... */
47  if ((!isdigit(*string) && *string != '.') ||
48  ((*string == '.') && !isdigit(string[1])))
49  return (NULL);
50 
51  /* Now accumulate a number. Note ascii dependencies here... */
52  if (isdigit(*string)) {
53  mant = (*string++ - '0');
54  while (isdigit(*string))
55  mant = mant * 10.0 + (*string++ - '0');
56  }
57  else
58  mant = 0.0;
59 
60  /* Now maybe a decimal point. */
61  if (*string == '.') {
62  string++;
63  tmpn = 1.0;
64  while (isdigit(*string))
65  mant += (*string++ - '0') * (tmpn *= 0.1);
66  }
67 
68  /* Now look for the scale factor or the exponent (can't have both). */
69  expo = 1.0;
70  switch (*string) {
71  case 'e':
72  case 'E':
73  /* Parse another number. */
74  string++;
75  if (*string == '+') {
76  string++;
77  }
78  else if (*string == '-') {
79  exsign = true;
80  string++;
81  }
82  if (isdigit(*string)) {
83  expo = (*string++ - '0');
84  while (isdigit(*string))
85  expo = expo * 10.0 + (*string++ - '0');
86  }
87  else
88  expo = 0.0;
89  if (*string == '.') {
90  string++;
91  tmpn = 1.0;
92  while (isdigit(*string))
93  expo += (*string++ - '0') * (tmpn *= 0.1);
94  }
95  if (exsign)
96  expo = pow(10.0,-expo);
97  else
98  expo = pow(10.0,expo);
99  break;
100  case 't':
101  case 'T':
102  expo = 1e12;
103  string++;
104  break;
105  case 'g':
106  case 'G':
107  expo = 1e9;
108  string++;
109  break;
110  case 'k':
111  case 'K':
112  expo = 1e3;
113  string++;
114  break;
115  case 'u':
116  case 'U':
117  expo = 1e-6;
118  string++;
119  break;
120  case 'n':
121  case 'N':
122  expo = 1e-9;
123  string++;
124  break;
125  case 'p':
126  case 'P':
127  expo = 1e-12;
128  string++;
129  break;
130  case 'f':
131  case 'F':
132  expo = 1e-15;
133  string++;
134  break;
135  case 'm':
136  case 'M':
137  /* Can be either m, mil, or meg. */
138  if (string[1] && string[2] &&
139  ((string[1] == 'e') || (string[1] == 'E')) &&
140  ((string[2] == 'g') || (string[2] == 'G'))) {
141  expo = 1e6;
142  string += 3;
143  }
144  else if (string[1] && string[2] &&
145  ((string[1] == 'i') || (string[1] == 'I')) &&
146  ((string[2] == 'l') || (string[2] == 'L'))) {
147  expo = 1e-6;
148  mant *= 25.4;
149  string += 3;
150  }
151  else {
152  expo = 1e-3;
153  string++;
154  }
155  break;
156  }
157 
158  if (whole && *string != '\0') {
159  return (NULL);
160  }
161  else if (ft_strictnumparse && *string && isdigit(string[-1])) {
162  if (*string == '_')
163  while (isalpha(*string) || (*string == '_'))
164  string++;
165  else
166  return (NULL);
167  }
168  else {
169  while (isalpha(*string) || (*string == '_'))
170  string++;
171  }
172  *s = string;
173  if (sign)
174  num = -mant * expo;
175  else
176  num = mant * expo;
177 
178  if (ft_parsedb)
179  fprintf(cp_err, "numparse: got %e, left = %s\n", num, *s);
180  return (&num);
181 }
bool ft_parsedb
Definition: options.c:24
Definition: cddefs.h:119
static double e
Definition: vectors.c:17
FILE * cp_err
Definition: help.c:101
double * ft_numparse(char **s, bool whole)
Definition: numparse.c:28
#define NULL
Definition: spdefs.h:121
bool ft_strictnumparse
Definition: numparse.c:15