c_stdio.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
  1. #include "c_stdio.h"
  2. // #include "driver/uart.h"
  3. int c_stdin = 999;
  4. int c_stdout = 1000;
  5. int c_stderr = 1001;
  6. // FILE *c_fopen(const char *_name, const char *_type){
  7. // }
  8. // FILE *c_freopen(const char *_name, const char *_type, FILE *_f){
  9. // }
  10. // FILE *c_tmpfile(void){
  11. // }
  12. // int c_putchar(int c){
  13. // }
  14. // int c_printf(const char *c, ...){
  15. // }
  16. // int c_sprintf(char *c, const char *s, ...){
  17. // }
  18. // int c_fprintf(FILE *f, const char *s, ...){
  19. // }
  20. // int c_fscanf(FILE *f, const char *s, ...){
  21. // }
  22. // int c_fclose(FILE *f){
  23. // }
  24. // int c_fflush(FILE *f){
  25. // }
  26. // int c_setvbuf(FILE *f, char *c, int d, size_t t){
  27. // }
  28. // void c_clearerr(FILE *f){
  29. // }
  30. // int c_fseek(FILE *f, long l, int d){
  31. // }
  32. // long c_ftell( FILE *f){
  33. // }
  34. // int c_fputs(const char *c, FILE *f){
  35. // }
  36. // char *c_fgets(char *c, int d, FILE *f){
  37. // }
  38. // int c_ungetc(int d, FILE *f){
  39. // }
  40. // size_t c_fread(void *p, size_t _size, size_t _n, FILE *f){
  41. // }
  42. // size_t c_fwrite(const void *p, size_t _size, size_t _n, FILE *f){
  43. // }
  44. // int c_feof(FILE *f){
  45. // }
  46. // int c_ferror(FILE *f){
  47. // }
  48. // int c_getc(FILE *f){
  49. // }
  50. #if defined( LUA_NUMBER_INTEGRAL )
  51. #else
  52. #define FLOATINGPT 1
  53. #define NEWFP 1
  54. #define ENDIAN_LITTLE 1234
  55. #define ENDIAN_BIG 4321
  56. #define ENDIAN_PDP 3412
  57. #define ENDIAN ENDIAN_LITTLE
  58. /* $Id: strichr.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */
  59. /*
  60. * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
  61. *
  62. * Redistribution and use in source and binary forms, with or without
  63. * modification, are permitted provided that the following conditions
  64. * are met:
  65. * 1. Redistributions of source code must retain the above copyright
  66. * notice, this list of conditions and the following disclaimer.
  67. * 2. Redistributions in binary form must reproduce the above copyright
  68. * notice, this list of conditions and the following disclaimer in the
  69. * documentation and/or other materials provided with the distribution.
  70. * 3. All advertising materials mentioning features or use of this software
  71. * must display the following acknowledgement:
  72. * This product includes software developed by Opsycon AB.
  73. * 4. The name of the author may not be used to endorse or promote products
  74. * derived from this software without specific prior written permission.
  75. *
  76. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  77. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  78. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  79. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  80. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  81. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  82. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  83. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  84. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  86. * SUCH DAMAGE.
  87. *
  88. */
  89. //#include <string.h>
  90. #include "c_string.h"
  91. char *
  92. strichr(char *p, int c)
  93. {
  94. char *t;
  95. if (p != NULL) {
  96. for(t = p; *t; t++);
  97. for (; t >= p; t--) {
  98. *(t + 1) = *t;
  99. }
  100. *p = c;
  101. }
  102. return (p);
  103. }
  104. /* $Id: str_fmt.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */
  105. /*
  106. * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
  107. *
  108. * Redistribution and use in source and binary forms, with or without
  109. * modification, are permitted provided that the following conditions
  110. * are met:
  111. * 1. Redistributions of source code must retain the above copyright
  112. * notice, this list of conditions and the following disclaimer.
  113. * 2. Redistributions in binary form must reproduce the above copyright
  114. * notice, this list of conditions and the following disclaimer in the
  115. * documentation and/or other materials provided with the distribution.
  116. * 3. All advertising materials mentioning features or use of this software
  117. * must display the following acknowledgement:
  118. * This product includes software developed by Opsycon AB.
  119. * 4. The name of the author may not be used to endorse or promote products
  120. * derived from this software without specific prior written permission.
  121. *
  122. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  123. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  124. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  125. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  126. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  127. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  128. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  129. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  130. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  131. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  132. * SUCH DAMAGE.
  133. *
  134. */
  135. //#include <string.h>
  136. #include "c_string.h"
  137. #define FMT_RJUST 0
  138. #define FMT_LJUST 1
  139. #define FMT_RJUST0 2
  140. #define FMT_CENTER 3
  141. /*
  142. * Format string by inserting blanks.
  143. */
  144. void
  145. str_fmt(char *p, int size, int fmt)
  146. {
  147. int n, m, len;
  148. len = strlen (p);
  149. switch (fmt) {
  150. case FMT_RJUST:
  151. for (n = size - len; n > 0; n--)
  152. strichr (p, ' ');
  153. break;
  154. case FMT_LJUST:
  155. for (m = size - len; m > 0; m--)
  156. strcat (p, " ");
  157. break;
  158. case FMT_RJUST0:
  159. for (n = size - len; n > 0; n--)
  160. strichr (p, '0');
  161. break;
  162. case FMT_CENTER:
  163. m = (size - len) / 2;
  164. n = size - (len + m);
  165. for (; m > 0; m--)
  166. strcat (p, " ");
  167. for (; n > 0; n--)
  168. strichr (p, ' ');
  169. break;
  170. }
  171. }
  172. /* $Id: strtoupp.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */
  173. /*
  174. * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
  175. *
  176. * Redistribution and use in source and binary forms, with or without
  177. * modification, are permitted provided that the following conditions
  178. * are met:
  179. * 1. Redistributions of source code must retain the above copyright
  180. * notice, this list of conditions and the following disclaimer.
  181. * 2. Redistributions in binary form must reproduce the above copyright
  182. * notice, this list of conditions and the following disclaimer in the
  183. * documentation and/or other materials provided with the distribution.
  184. * 3. All advertising materials mentioning features or use of this software
  185. * must display the following acknowledgement:
  186. * This product includes software developed by Opsycon AB.
  187. * 4. The name of the author may not be used to endorse or promote products
  188. * derived from this software without specific prior written permission.
  189. *
  190. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  191. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  192. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  193. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  194. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  195. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  196. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  197. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  198. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  199. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  200. * SUCH DAMAGE.
  201. *
  202. */
  203. //#include <string.h>
  204. //#include <ctype.h>
  205. #include "c_string.h"
  206. #include "c_ctype.h"
  207. void
  208. strtoupper(char *p)
  209. {
  210. if(!p)
  211. return;
  212. for (; *p; p++)
  213. *p = toupper (*p);
  214. }
  215. /* $Id: atob.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */
  216. /*
  217. * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
  218. *
  219. * Redistribution and use in source and binary forms, with or without
  220. * modification, are permitted provided that the following conditions
  221. * are met:
  222. * 1. Redistributions of source code must retain the above copyright
  223. * notice, this list of conditions and the following disclaimer.
  224. * 2. Redistributions in binary form must reproduce the above copyright
  225. * notice, this list of conditions and the following disclaimer in the
  226. * documentation and/or other materials provided with the distribution.
  227. * 3. All advertising materials mentioning features or use of this software
  228. * must display the following acknowledgement:
  229. * This product includes software developed by Opsycon AB.
  230. * 4. The name of the author may not be used to endorse or promote products
  231. * derived from this software without specific prior written permission.
  232. *
  233. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  234. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  235. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  236. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  237. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  238. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  239. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  240. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  241. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  242. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  243. * SUCH DAMAGE.
  244. *
  245. */
  246. //#include <sys/types.h>
  247. //#include <string.h>
  248. //#include <pmon.h>
  249. #include "c_string.h"
  250. typedef unsigned int u_int32_t;
  251. typedef unsigned int u_int;
  252. typedef unsigned long u_long;
  253. typedef int32_t register_t;
  254. typedef long long quad_t;
  255. typedef unsigned long long u_quad_t;
  256. typedef double rtype;
  257. #ifndef __P
  258. #define __P(args) args
  259. #endif
  260. static char * _getbase __P((char *, int *));
  261. static int _atob __P((unsigned long long *, char *p, int));
  262. static char *
  263. _getbase(char *p, int *basep)
  264. {
  265. if (p[0] == '0') {
  266. switch (p[1]) {
  267. case 'x':
  268. *basep = 16;
  269. break;
  270. case 't': case 'n':
  271. *basep = 10;
  272. break;
  273. case 'o':
  274. *basep = 8;
  275. break;
  276. default:
  277. *basep = 10;
  278. return (p);
  279. }
  280. return (p + 2);
  281. }
  282. *basep = 10;
  283. return (p);
  284. }
  285. /*
  286. * _atob(vp,p,base)
  287. */
  288. static int
  289. _atob (u_quad_t *vp, char *p, int base)
  290. {
  291. u_quad_t value, v1, v2;
  292. char *q, tmp[20];
  293. int digit;
  294. if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
  295. base = 16;
  296. p += 2;
  297. }
  298. if (base == 16 && (q = strchr (p, '.')) != 0) {
  299. if (q - p > sizeof(tmp) - 1)
  300. return (0);
  301. strncpy (tmp, p, q - p);
  302. tmp[q - p] = '\0';
  303. if (!_atob (&v1, tmp, 16))
  304. return (0);
  305. q++;
  306. if (strchr (q, '.'))
  307. return (0);
  308. if (!_atob (&v2, q, 16))
  309. return (0);
  310. *vp = (v1 << 16) + v2;
  311. return (1);
  312. }
  313. value = *vp = 0;
  314. for (; *p; p++) {
  315. if (*p >= '0' && *p <= '9')
  316. digit = *p - '0';
  317. else if (*p >= 'a' && *p <= 'f')
  318. digit = *p - 'a' + 10;
  319. else if (*p >= 'A' && *p <= 'F')
  320. digit = *p - 'A' + 10;
  321. else
  322. return (0);
  323. if (digit >= base)
  324. return (0);
  325. value *= base;
  326. value += digit;
  327. }
  328. *vp = value;
  329. return (1);
  330. }
  331. /*
  332. * atob(vp,p,base)
  333. * converts p to binary result in vp, rtn 1 on success
  334. */
  335. int
  336. atob(u_int32_t *vp, char *p, int base)
  337. {
  338. u_quad_t v;
  339. if (base == 0)
  340. p = _getbase (p, &base);
  341. if (_atob (&v, p, base)) {
  342. *vp = v;
  343. return (1);
  344. }
  345. return (0);
  346. }
  347. /*
  348. * llatob(vp,p,base)
  349. * converts p to binary result in vp, rtn 1 on success
  350. */
  351. int
  352. llatob(u_quad_t *vp, char *p, int base)
  353. {
  354. if (base == 0)
  355. p = _getbase (p, &base);
  356. return _atob(vp, p, base);
  357. }
  358. /*
  359. * char *btoa(dst,value,base)
  360. * converts value to ascii, result in dst
  361. */
  362. char *
  363. btoa(char *dst, u_int value, int base)
  364. {
  365. char buf[34], digit;
  366. int i, j, rem, neg;
  367. if (value == 0) {
  368. dst[0] = '0';
  369. dst[1] = 0;
  370. return (dst);
  371. }
  372. neg = 0;
  373. if (base == -10) {
  374. base = 10;
  375. if (value & (1L << 31)) {
  376. value = (~value) + 1;
  377. neg = 1;
  378. }
  379. }
  380. for (i = 0; value != 0; i++) {
  381. rem = value % base;
  382. value /= base;
  383. if (rem >= 0 && rem <= 9)
  384. digit = rem + '0';
  385. else if (rem >= 10 && rem <= 36)
  386. digit = (rem - 10) + 'a';
  387. buf[i] = digit;
  388. }
  389. buf[i] = 0;
  390. if (neg)
  391. strcat (buf, "-");
  392. /* reverse the string */
  393. for (i = 0, j = strlen (buf) - 1; j >= 0; i++, j--)
  394. dst[i] = buf[j];
  395. dst[i] = 0;
  396. return (dst);
  397. }
  398. /*
  399. * char *btoa(dst,value,base)
  400. * converts value to ascii, result in dst
  401. */
  402. char *
  403. llbtoa(char *dst, u_quad_t value, int base)
  404. {
  405. char buf[66], digit;
  406. int i, j, rem, neg;
  407. if (value == 0) {
  408. dst[0] = '0';
  409. dst[1] = 0;
  410. return (dst);
  411. }
  412. neg = 0;
  413. if (base == -10) {
  414. base = 10;
  415. if (value & (1LL << 63)) {
  416. value = (~value) + 1;
  417. neg = 1;
  418. }
  419. }
  420. for (i = 0; value != 0; i++) {
  421. rem = value % base;
  422. value /= base;
  423. if (rem >= 0 && rem <= 9)
  424. digit = rem + '0';
  425. else if (rem >= 10 && rem <= 36)
  426. digit = (rem - 10) + 'a';
  427. buf[i] = digit;
  428. }
  429. buf[i] = 0;
  430. if (neg)
  431. strcat (buf, "-");
  432. /* reverse the string */
  433. for (i = 0, j = strlen (buf) - 1; j >= 0; i++, j--)
  434. dst[i] = buf[j];
  435. dst[i] = 0;
  436. return (dst);
  437. }
  438. /*
  439. * gethex(vp,p,n)
  440. * convert n hex digits from p to binary, result in vp,
  441. * rtn 1 on success
  442. */
  443. int
  444. gethex(int32_t *vp, char *p, int n)
  445. {
  446. u_long v;
  447. int digit;
  448. for (v = 0; n > 0; n--) {
  449. if (*p == 0)
  450. return (0);
  451. if (*p >= '0' && *p <= '9')
  452. digit = *p - '0';
  453. else if (*p >= 'a' && *p <= 'f')
  454. digit = *p - 'a' + 10;
  455. else if (*p >= 'A' && *p <= 'F')
  456. digit = *p - 'A' + 10;
  457. else
  458. return (0);
  459. v <<= 4;
  460. v |= digit;
  461. p++;
  462. }
  463. *vp = v;
  464. return (1);
  465. }
  466. /* $Id: vsprintf.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */
  467. /*
  468. * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
  469. *
  470. * Redistribution and use in source and binary forms, with or without
  471. * modification, are permitted provided that the following conditions
  472. * are met:
  473. * 1. Redistributions of source code must retain the above copyright
  474. * notice, this list of conditions and the following disclaimer.
  475. * 2. Redistributions in binary form must reproduce the above copyright
  476. * notice, this list of conditions and the following disclaimer in the
  477. * documentation and/or other materials provided with the distribution.
  478. * 3. All advertising materials mentioning features or use of this software
  479. * must display the following acknowledgement:
  480. * This product includes software developed by Opsycon AB.
  481. * 4. The name of the author may not be used to endorse or promote products
  482. * derived from this software without specific prior written permission.
  483. *
  484. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  485. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  486. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  487. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  488. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  489. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  490. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  491. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  492. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  493. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  494. * SUCH DAMAGE.
  495. *
  496. */
  497. //#include <stdio.h>
  498. //#include <stdarg.h>
  499. //#include <string.h>
  500. //#include <ctype.h>
  501. //#include <pmon.h>
  502. #include "c_stdarg.h"
  503. #include "c_string.h"
  504. #include "c_ctype.h"
  505. /*
  506. * int vsprintf(d,s,ap)
  507. */
  508. int
  509. vsprintf (char *d, const char *s, va_list ap)
  510. {
  511. const char *t;
  512. char *p, *dst, tmp[40];
  513. unsigned int n;
  514. int fmt, trunc, haddot, width, base, longlong;
  515. #ifdef FLOATINGPT
  516. double dbl;
  517. #ifndef NEWFP
  518. EP ex;
  519. #endif
  520. #endif
  521. dst = d;
  522. for (; *s;) {
  523. if (*s == '%') {
  524. s++;
  525. fmt = FMT_RJUST;
  526. width = trunc = haddot = longlong = 0;
  527. for (; *s; s++) {
  528. if (strchr("bcdefgilopPrRsuxX%", *s))
  529. break;
  530. else if (*s == '-')
  531. fmt = FMT_LJUST;
  532. else if (*s == '0')
  533. fmt = FMT_RJUST0;
  534. else if (*s == '~')
  535. fmt = FMT_CENTER;
  536. else if (*s == '*') {
  537. if (haddot)
  538. trunc = va_arg(ap, int);
  539. else
  540. width = va_arg(ap, int);
  541. } else if (*s >= '1' && *s <= '9') {
  542. for (t = s; isdigit(*s); s++);
  543. strncpy(tmp, t, s - t);
  544. tmp[s - t] = '\0';
  545. atob(&n, tmp, 10);
  546. if (haddot)
  547. trunc = n;
  548. else
  549. width = n;
  550. s--;
  551. } else if (*s == '.')
  552. haddot = 1;
  553. }
  554. if (*s == '%') {
  555. *d++ = '%';
  556. *d = 0;
  557. } else if (*s == 's') {
  558. p = va_arg(ap, char *);
  559. if (p)
  560. strcpy(d, p);
  561. else
  562. strcpy(d, "(null)");
  563. } else if (*s == 'c') {
  564. n = va_arg (ap, int);
  565. *d = n;
  566. d[1] = 0;
  567. } else {
  568. if (*s == 'l') {
  569. if (*++s == 'l') {
  570. longlong = 1;
  571. ++s;
  572. }
  573. }
  574. if (strchr("bdiopPrRxXu", *s)) {
  575. if (*s == 'd' || *s == 'i')
  576. base = -10;
  577. else if (*s == 'u')
  578. base = 10;
  579. else if (*s == 'x' || *s == 'X')
  580. base = 16;
  581. else if(*s == 'p' || *s == 'P') {
  582. base = 16;
  583. if (*s == 'p') {
  584. *d++ = '0';
  585. *d++ = 'x';
  586. }
  587. fmt = FMT_RJUST0;
  588. if (sizeof(long) > 4) {
  589. width = 16;
  590. longlong = 1;
  591. } else {
  592. width = 8;
  593. }
  594. }
  595. else if(*s == 'r' || *s == 'R') {
  596. base = 16;
  597. if (*s == 'r') {
  598. *d++ = '0';
  599. *d++ = 'x';
  600. }
  601. fmt = FMT_RJUST0;
  602. if (sizeof(register_t) > 4) {
  603. width = 16;
  604. longlong = 1;
  605. } else {
  606. width = 8;
  607. }
  608. }
  609. else if (*s == 'o')
  610. base = 8;
  611. else if (*s == 'b')
  612. base = 2;
  613. if (longlong)
  614. llbtoa(d, va_arg (ap, quad_t),
  615. base);
  616. else
  617. btoa(d, va_arg (ap, int), base);
  618. if (*s == 'X')
  619. strtoupper(d);
  620. }
  621. #ifdef FLOATINGPT
  622. else if (strchr ("eEfgG", *s)) {
  623. //static void dtoa (char *, double, int, int, int);
  624. void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec);
  625. dbl = va_arg(ap, double);
  626. dtoa(d, dbl, *s, width, trunc);
  627. trunc = 0;
  628. }
  629. #endif
  630. }
  631. if (trunc)
  632. d[trunc] = 0;
  633. if (width)
  634. str_fmt (d, width, fmt);
  635. for (; *d; d++);
  636. s++;
  637. } else
  638. *d++ = *s++;
  639. }
  640. *d = 0;
  641. return (d - dst);
  642. }
  643. #ifdef FLOATINGPT
  644. /*
  645. * Floating point output, cvt() onward lifted from BSD sources:
  646. *
  647. * Copyright (c) 1990 The Regents of the University of California.
  648. * All rights reserved.
  649. *
  650. * This code is derived from software contributed to Berkeley by
  651. * Chris Torek.
  652. *
  653. * Redistribution and use in source and binary forms, with or without
  654. * modification, are permitted provided that the following conditions
  655. * are met:
  656. * 1. Redistributions of source code must retain the above copyright
  657. * notice, this list of conditions and the following disclaimer.
  658. * 2. Redistributions in binary form must reproduce the above copyright
  659. * notice, this list of conditions and the following disclaimer in the
  660. * documentation and/or other materials provided with the distribution.
  661. * 3. All advertising materials mentioning features or use of this software
  662. * must display the following acknowledgement:
  663. * This product includes software developed by the University of
  664. * California, Berkeley and its contributors.
  665. * 4. Neither the name of the University nor the names of its contributors
  666. * may be used to endorse or promote products derived from this software
  667. * without specific prior written permission.
  668. *
  669. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  670. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  671. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  672. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  673. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  674. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  675. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  676. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  677. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  678. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  679. * SUCH DAMAGE.
  680. */
  681. #define MAX_FCONVERSION 512 /* largest possible real conversion */
  682. #define MAX_EXPT 5 /* largest possible exponent field */
  683. #define MAX_FRACT 39 /* largest possible fraction field */
  684. #define TESTFLAG(x) 0
  685. typedef double rtype;
  686. extern double modf(double, double *);
  687. #define to_char(n) ((n) + '0')
  688. #define to_digit(c) ((c) - '0')
  689. #define _isNan(arg) ((arg) != (arg))
  690. static int cvt (rtype arg, int prec, char *signp, int fmtch,
  691. char *startp, char *endp);
  692. static char *c_round (double fract, int *exp, char *start, char *end,
  693. char ch, char *signp);
  694. static char *exponent(char *p, int exp, int fmtch);
  695. /*
  696. * _finite arg not Infinity or Nan
  697. */
  698. static int _finite(rtype d)
  699. {
  700. #if ENDIAN == ENDIAN_LITTLE
  701. struct IEEEdp {
  702. unsigned manl:32;
  703. unsigned manh:20;
  704. unsigned exp:11;
  705. unsigned sign:1;
  706. } *ip;
  707. #else
  708. struct IEEEdp {
  709. unsigned sign:1;
  710. unsigned exp:11;
  711. unsigned manh:20;
  712. unsigned manl:32;
  713. } *ip;
  714. #endif
  715. ip = (struct IEEEdp *)&d;
  716. return (ip->exp != 0x7ff);
  717. }
  718. void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec)
  719. {
  720. char buf[MAX_FCONVERSION+1], *cp;
  721. char sign;
  722. int size;
  723. if( !_finite(arg) ) {
  724. if( _isNan(arg) )
  725. strcpy (dbuf, "NaN");
  726. else if( arg < 0)
  727. strcpy (dbuf, "-Infinity");
  728. else
  729. strcpy (dbuf, "Infinity");
  730. return;
  731. }
  732. if (prec == 0)
  733. prec = 6;
  734. else if (prec > MAX_FRACT)
  735. prec = MAX_FRACT;
  736. /* leave room for sign at start of buffer */
  737. cp = buf + 1;
  738. /*
  739. * cvt may have to round up before the "start" of
  740. * its buffer, i.e. ``intf("%.2f", (double)9.999);'';
  741. * if the first character is still NUL, it did.
  742. * softsign avoids negative 0 if _double < 0 but
  743. * no significant digits will be shown.
  744. */
  745. *cp = '\0';
  746. size = cvt (arg, prec, &sign, fmtch, cp, buf + sizeof(buf));
  747. if (*cp == '\0')
  748. cp++;
  749. if (sign)
  750. *--cp = sign, size++;
  751. cp[size] = 0;
  752. memcpy (dbuf, cp, size + 1);
  753. }
  754. static int
  755. cvt(rtype number, int prec, char *signp, int fmtch, char *startp, char *endp)
  756. {
  757. register char *p, *t;
  758. register double fract;
  759. double integer, tmp;
  760. int dotrim, expcnt, gformat;
  761. dotrim = expcnt = gformat = 0;
  762. if (number < 0) {
  763. number = -number;
  764. *signp = '-';
  765. } else
  766. *signp = 0;
  767. fract = modf(number, &integer);
  768. /* get an extra slot for rounding. */
  769. t = ++startp;
  770. /*
  771. * get integer portion of number; put into the end of the buffer; the
  772. * .01 is added for modf(356.0 / 10, &integer) returning .59999999...
  773. */
  774. for (p = endp - 1; integer; ++expcnt) {
  775. tmp = modf(integer / 10, &integer);
  776. *p-- = to_char((int)((tmp + .01) * 10));
  777. }
  778. switch (fmtch) {
  779. case 'f':
  780. /* reverse integer into beginning of buffer */
  781. if (expcnt)
  782. for (; ++p < endp; *t++ = *p);
  783. else
  784. *t++ = '0';
  785. /*
  786. * if precision required or alternate flag set, add in a
  787. * decimal point.
  788. */
  789. if (prec || TESTFLAG(ALTERNATE_FORM))
  790. *t++ = '.';
  791. /* if requires more precision and some fraction left */
  792. if (fract) {
  793. if (prec)
  794. do {
  795. fract = modf(fract * 10, &tmp);
  796. *t++ = to_char((int)tmp);
  797. } while (--prec && fract);
  798. if (fract)
  799. startp = c_round(fract, (int *)NULL, startp,
  800. t - 1, (char)0, signp);
  801. }
  802. for (; prec--; *t++ = '0');
  803. break;
  804. case 'e':
  805. case 'E':
  806. eformat: if (expcnt) {
  807. *t++ = *++p;
  808. if (prec || TESTFLAG(ALTERNATE_FORM))
  809. *t++ = '.';
  810. /* if requires more precision and some integer left */
  811. for (; prec && ++p < endp; --prec)
  812. *t++ = *p;
  813. /*
  814. * if done precision and more of the integer component,
  815. * round using it; adjust fract so we don't re-round
  816. * later.
  817. */
  818. if (!prec && ++p < endp) {
  819. fract = 0;
  820. startp = c_round((double)0, &expcnt, startp,
  821. t - 1, *p, signp);
  822. }
  823. /* adjust expcnt for digit in front of decimal */
  824. --expcnt;
  825. }
  826. /* until first fractional digit, decrement exponent */
  827. else if (fract) {
  828. /* adjust expcnt for digit in front of decimal */
  829. for (expcnt = -1;; --expcnt) {
  830. fract = modf(fract * 10, &tmp);
  831. if (tmp)
  832. break;
  833. }
  834. *t++ = to_char((int)tmp);
  835. if (prec || TESTFLAG(ALTERNATE_FORM))
  836. *t++ = '.';
  837. }
  838. else {
  839. *t++ = '0';
  840. if (prec || TESTFLAG(ALTERNATE_FORM))
  841. *t++ = '.';
  842. }
  843. /* if requires more precision and some fraction left */
  844. if (fract) {
  845. if (prec)
  846. do {
  847. fract = modf(fract * 10, &tmp);
  848. *t++ = to_char((int)tmp);
  849. } while (--prec && fract);
  850. if (fract)
  851. startp = c_round(fract, &expcnt, startp,
  852. t - 1, (char)0, signp);
  853. }
  854. /* if requires more precision */
  855. for (; prec--; *t++ = '0');
  856. /* unless alternate flag, trim any g/G format trailing 0's */
  857. if (gformat && !TESTFLAG(ALTERNATE_FORM)) {
  858. while (t > startp && *--t == '0');
  859. if (*t == '.')
  860. --t;
  861. ++t;
  862. }
  863. t = exponent(t, expcnt, fmtch);
  864. break;
  865. case 'g':
  866. case 'G':
  867. /* a precision of 0 is treated as a precision of 1. */
  868. if (!prec)
  869. ++prec;
  870. /*
  871. * ``The style used depends on the value converted; style e
  872. * will be used only if the exponent resulting from the
  873. * conversion is less than -4 or greater than the precision.''
  874. * -- ANSI X3J11
  875. */
  876. if (expcnt > prec || (!expcnt && fract && fract < .0001)) {
  877. /*
  878. * g/G format counts "significant digits, not digits of
  879. * precision; for the e/E format, this just causes an
  880. * off-by-one problem, i.e. g/G considers the digit
  881. * before the decimal point significant and e/E doesn't
  882. * count it as precision.
  883. */
  884. --prec;
  885. fmtch -= 2; /* G->E, g->e */
  886. gformat = 1;
  887. goto eformat;
  888. }
  889. /*
  890. * reverse integer into beginning of buffer,
  891. * note, decrement precision
  892. */
  893. if (expcnt)
  894. for (; ++p < endp; *t++ = *p, --prec);
  895. else
  896. *t++ = '0';
  897. /*
  898. * if precision required or alternate flag set, add in a
  899. * decimal point. If no digits yet, add in leading 0.
  900. */
  901. if (prec || TESTFLAG(ALTERNATE_FORM)) {
  902. dotrim = 1;
  903. *t++ = '.';
  904. }
  905. else
  906. dotrim = 0;
  907. /* if requires more precision and some fraction left */
  908. if (fract) {
  909. if (prec) {
  910. do {
  911. fract = modf(fract * 10, &tmp);
  912. *t++ = to_char((int)tmp);
  913. } while(!tmp && !expcnt);
  914. while (--prec && fract) {
  915. fract = modf(fract * 10, &tmp);
  916. *t++ = to_char((int)tmp);
  917. }
  918. }
  919. if (fract)
  920. startp = c_round(fract, (int *)NULL, startp,
  921. t - 1, (char)0, signp);
  922. }
  923. /* alternate format, adds 0's for precision, else trim 0's */
  924. if (TESTFLAG(ALTERNATE_FORM))
  925. for (; prec--; *t++ = '0');
  926. else if (dotrim) {
  927. while (t > startp && *--t == '0');
  928. if (*t != '.')
  929. ++t;
  930. }
  931. }
  932. return (t - startp);
  933. }
  934. static char *
  935. c_round(double fract, int *exp, char *start, char *end, char ch, char *signp)
  936. {
  937. double tmp;
  938. if (fract)
  939. (void)modf(fract * 10, &tmp);
  940. else
  941. tmp = to_digit(ch);
  942. if (tmp > 4)
  943. for (;; --end) {
  944. if (*end == '.')
  945. --end;
  946. if (++*end <= '9')
  947. break;
  948. *end = '0';
  949. if (end == start) {
  950. if (exp) { /* e/E; increment exponent */
  951. *end = '1';
  952. ++*exp;
  953. }
  954. else { /* f; add extra digit */
  955. *--end = '1';
  956. --start;
  957. }
  958. break;
  959. }
  960. }
  961. /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */
  962. else if (*signp == '-')
  963. for (;; --end) {
  964. if (*end == '.')
  965. --end;
  966. if (*end != '0')
  967. break;
  968. if (end == start)
  969. *signp = 0;
  970. }
  971. return (start);
  972. }
  973. static char *
  974. exponent(char *p, int exp, int fmtch)
  975. {
  976. char *t;
  977. char expbuf[MAX_FCONVERSION];
  978. *p++ = fmtch;
  979. if (exp < 0) {
  980. exp = -exp;
  981. *p++ = '-';
  982. }
  983. else
  984. *p++ = '+';
  985. t = expbuf + MAX_FCONVERSION;
  986. if (exp > 9) {
  987. do {
  988. *--t = to_char(exp % 10);
  989. } while ((exp /= 10) > 9);
  990. *--t = to_char(exp);
  991. for (; t < expbuf + MAX_FCONVERSION; *p++ = *t++);
  992. }
  993. else {
  994. *p++ = '0';
  995. *p++ = to_char(exp);
  996. }
  997. return (p);
  998. }
  999. #endif /* FLOATINGPT */
  1000. int c_sprintf(char *s, const char *fmt, ...)
  1001. {
  1002. int n;
  1003. va_list arg;
  1004. va_start(arg, fmt);
  1005. n = vsprintf(s, fmt, arg);
  1006. va_end(arg);
  1007. return n;
  1008. }
  1009. #endif