1 /*$Id: ap_convert.cc,v 26.138 2013/04/24 03:03:11 al Exp $ -*- C++ -*-
2 * Copyright (C) 2001 Albert Davis
3 * Author: Albert Davis <aldavis@gnu.org>
4 *
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 */
22 //testing=script 2006.07.17
23 #include "u_opt.h"
24 #include "ap.h"
25 /*--------------------------------------------------------------------------*/
26 // char CS::ctoc();
27 // void CS::ctostr(char* d, int l, const string& t);
28 // string CS::ctos(const string& term);
29 // int CS::ctoi();
30 // unsigned CS::ctou();
31 // int CS::ctoo();
32 // int CS::ctox();
33 // double CS::ctof();
34 /*--------------------------------------------------------------------------*/
35 /* ctoc: character input to character
36 */
ctoc()37 char CS::ctoc()
38 {
39 char c=_cmd[_cnt];
40 if(_cnt<=_length) {
41 ++_cnt;
42 }else{untested();
43 }
44 return c;
45 }
46 /*--------------------------------------------------------------------------*/
47 /* ctostr: character input to string
48 * scan (and eat) an input string (cmd) using index (cnt).
49 * result in (des) (null terminated).
50 * max length (actual char count) is (len).
51 * (des) must be at least (len)+1 characters long.
52 * (cmd) unchanged. (*cnt) updated to point to next argument.
53 * skips leading whitespace. skips trailing whitespace and comma
54 * skips parts of input word too big for destination
55 */
ctostr(char * des,int len,const std::string & term)56 void CS::ctostr(char* des, int len, const std::string& term)
57 {
58 skipbl();
59 int ii;
60 for (ii = 0; ii < len && !is_term(term); ++ii) {
61 des[ii] = ctoc();
62 }
63 des[ii] = '\0';
64
65 while (!is_term(term)) {untested();
66 skip();
67 }
68 skipcom();
69 }
70 /*--------------------------------------------------------------------------*/
ctos(const std::string & term,const std::string & begin_quote,const std::string & end_quote,const std::string & trap)71 std::string CS::ctos(const std::string& term,
72 const std::string& begin_quote,
73 const std::string& end_quote,
74 const std::string& trap)
75 {
76 assert(begin_quote.length() == end_quote.length());
77
78 skipbl();
79 unsigned begin_string = cursor();
80 unsigned end_string = cursor();
81
82 std::string s;
83 std::string::size_type which_quote = find1(begin_quote);
84 if (which_quote != std::string::npos) {
85 int quotes = 1;
86 skip(); // the quote
87 begin_string = cursor();
88 char the_begin_quote = begin_quote[which_quote];
89 char the_end_quote = end_quote[which_quote];
90 for (;;) {
91 if (!ns_more()) {itested();
92 end_string = cursor();
93 warn(bDANGER, std::string("need ") + the_end_quote);
94 break;
95 }else if (skip1(the_end_quote)) {
96 if (--quotes <= 0) {
97 end_string = cursor() - 1;
98 break;
99 }else{
100 }
101 }else if (skip1(the_begin_quote)) {
102 ++quotes;
103 skip();
104 }else if (skip1('\\')) {
105 end_string = cursor() - 1;
106 s += _cmd.substr(begin_string, end_string-begin_string);
107 begin_string = cursor();
108 skip1(the_end_quote);
109 }else{
110 skip();
111 }
112 }
113 s += _cmd.substr(begin_string, end_string-begin_string);
114 }else{
115 while(ns_more() && !is_term(term)) {
116 skip();
117 }
118 if (match1(trap)) {untested();
119 warn(bDANGER, "ap_convert trap-exit");
120 }else{
121 }
122 end_string = cursor();
123 s = _cmd.substr(begin_string, end_string-begin_string);
124 }
125
126 skipcom();
127 _ok = end_string > begin_string;
128 return s;
129 }
130 /*--------------------------------------------------------------------------*/
get_to(const std::string & term)131 std::string CS::get_to(const std::string& term)
132 {
133 std::string des;
134 while(ns_more() && !match1(term)) {
135 des += ctoc();
136 }
137 return des;
138 }
139 /*--------------------------------------------------------------------------*/
140 /* ctob: character input to bool
141 * no match makes it true;
142 * Mismatch belongs to next token
143 */
ctob()144 bool CS::ctob()
145 {
146 skipbl();
147 unsigned here = cursor();
148 bool val = true;
149 ONE_OF
150 || Set(*this, "1", &val, true)
151 || Set(*this, "0", &val, false)
152 || Set(*this, "t{rue}", &val, true)
153 || Set(*this, "f{alse}", &val, false)
154 || Set(*this, "y{es}", &val, true)
155 || Set(*this, "n{o}", &val, false)
156 || Set(*this, "#t{rue}", &val, true)
157 || Set(*this, "#f{alse}",&val, false)
158 ;
159 skipcom();
160 _ok = cursor() > here;
161 return val;
162 }
163 /*--------------------------------------------------------------------------*/
164 /* ctoi: character input to integer
165 * Returns signed integer, or 0 if the string is not a number.
166 * Input must be integer: no multipliers, no decimal point.
167 * Dot or letter belongs to the next token.
168 */
ctoi()169 int CS::ctoi()
170 {
171 int val = 0;
172 int sign = 1;
173
174 skipbl();
175 unsigned here = cursor();
176 if (skip1("-")) {
177 sign = -1;
178 }else{
179 skip1("+");
180 }
181
182 while (is_digit()) {
183 val = 10 * val + (ctoc()-'0');
184 }
185 skipcom();
186 _ok = cursor() > here;
187 return val * sign;
188 }
189 /*--------------------------------------------------------------------------*/
190 /* ctou: character input to unsigned integer
191 * Returns unsigned integer, or 0 if the string is not a number.
192 * Input must be integer: no multipliers, no decimal point.
193 * Dot or letter belongs to the next token.
194 */
ctou()195 unsigned CS::ctou()
196 {
197 unsigned val = 0;
198
199 skipbl();
200 unsigned here = cursor();
201 while (is_digit()) {
202 val = 10 * val + static_cast<unsigned>(ctoc()-'0');
203 }
204 skipcom();
205 _ok = cursor() > here;
206 return val;
207 }
208 /*--------------------------------------------------------------------------*/
209 /* ctoo: character octal input to integer
210 * Returns integer, or 0 if the string is not a number.
211 * Input must be integer: no multipliers, no decimal point.
212 * Dot or letter belongs to the next token.
213 * There is no check against '8' and '9'.
214 */
ctoo()215 int CS::ctoo()
216 {
217 int val = 0;
218
219 skipbl();
220 unsigned here = cursor();
221 while (is_digit()) {
222 val = 8 * val + (ctoc()-'0');
223 }
224 skipcom();
225 _ok = cursor() > here;
226 return val;
227 }
228 /*--------------------------------------------------------------------------*/
229 /* ctox: character hex input to unsigned integer
230 * Returns integer, or 0 if the string is not a number.
231 * Input must be hex integer: no multipliers, no decimal point.
232 * Dot or letter belongs to the next token.
233 */
ctox()234 int CS::ctox()
235 {untested();
236 int val = 0;
237
238 skipbl();
239 unsigned here = cursor();
240 while (is_xdigit()) {untested();
241 if (is_digit()) {untested();
242 val = 16 * val + (ctoc()-'0');
243 }else{untested();
244 val = 16 * val + (tolower(ctoc())-'a'+10);
245 }
246 }
247 skipcom();
248 _ok = cursor() > here;
249 return val;
250 }
251 /*--------------------------------------------------------------------------*/
252 /* ctof: floating point input
253 * return double number if got, else 0
254 * supports letter multipliers (spice style)
255 * skips trailing letters (10uhenries == 10u)
256 * skips trailing spaces and one comma
257 * pointer points to char following comma
258 * or first non-space following number just got
259 * or first non-space (if non-number)
260 */
ctof()261 double CS::ctof()
262 {
263 double val = 0.0;
264 double power = 1.0;
265 int sign = 1;
266
267 skipbl();
268 if (!is_float()) {
269 skipcom();
270 _ok = false;
271 return 0.;
272 }else{
273 }
274
275 if (skip1("-")) { // sign
276 sign = -1;
277 }else{
278 skip1("+");
279 }
280
281 while (is_digit()) { // up to dec pt
282 val = 10.0 * val + (ctoc()-'0');
283 }
284 skip1("."); // dec pt
285
286 while (is_digit()) { // after dec pt
287 val = 10.0 * val + (ctoc()-'0');
288 power *= .1;
289 }
290
291 if (skip1("eE")) { // exponent: E form
292 int expo = 0;
293 int es = 1;
294 if (skip1("-")) {
295 es = -1;
296 }else{
297 skip1("+");
298 }
299 while (is_digit())
300 expo = 10 * expo + (ctoc()-'0');
301 expo *= es;
302 power *= pow(10., expo);
303 }else if ((OPT::units == uSPICE) && skip1("mM")) { // M is special
304 if (skip1("eE")) { // meg
305 power *= 1e6;
306 }else if (skip1("iI")) { // mil
307 power *= 25.4e-6;
308 }else{ // plain m (milli)
309 power *= 1e-3;
310 }
311 }else if (skip1("M")) {
312 assert(OPT::units == uSI);
313 power *= 1e6;
314 }else if (skip1("m")) {
315 assert(OPT::units == uSI);
316 power *= 1e-3;
317 }else if (skip1("uU")) { // other letters
318 power *= 1e-6;
319 }else if (skip1("nN")) {
320 power *= 1e-9;
321 }else if (skip1("p")) {
322 power *= 1e-12;
323 }else if (skip1("P")) {
324 power *= ((OPT::units == uSI) ? (1e15) : 1e-12);
325 }else if (skip1("fF")) {
326 power *= 1e-15;
327 }else if (skip1("aA")) {
328 power *= 1e-18;
329 }else if (skip1("kK")) {
330 power *= 1e3;
331 }else if (skip1("gG")) {
332 power *= 1e9;
333 }else if (skip1("tT")) {
334 power *= 1e12;
335 }else if (skip1("%")) {untested();
336 power *= 1e-2;
337 }else{
338 }
339 while (is_alpha()) { // skip letters
340 skip();
341 }
342 skipcom();
343 _ok = true;
344 return (sign*val*power);
345 }
346 /*--------------------------------------------------------------------------*/
347 /*--------------------------------------------------------------------------*/
348