source: rtems/c/src/libnetworking/rtems_webserver/value.c @ cd9dac0

Last change on this file since cd9dac0 was a6b4c0df, checked in by Joel Sherrill <joel.sherrill@…>, on 09/01/00 at 10:57:21

2000-08-30 Joel Sherrill <joel@…>

  • Merged version 2.1 of GoAhead? webserver. This update was submitted by Antti P Miettinen <antti.p.miettinen@…>.
  • NOTES, base64.c, ejIntrn.h, emfdb.c, emfdb.h, md5.h, md5c.c, um.c, um.h: New files.
  • wbase64.c: Removed.
  • Makefile.am, asp.c, balloc.c, default.c, ej.h, ejlex.c, ejparse.c, form.c, h.c, handler.c, mime.c, misc.c, ringq.c, rom.c, security.c, socket.c, sym.c, uemf.c, uemf.h, url.c, value.c, webcomp.c, webmain.c, webpage.c, webrom.c, webs.c, webs.h, websuemf.c, wsIntrn.h: Modified.
  • Property mode set to 100644
File size: 22.4 KB
Line 
1/*
2 * value.c -- Generic type (holds all types)
3 *
4 * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
5 */
6
7/******************************** Description *********************************/
8
9/*
10 *      This module provides a generic type that can hold all possible types.
11 *      It is designed to provide maximum effeciency.
12 */
13
14/********************************* Includes ***********************************/
15
16#if UEMF
17        #include        "uemf.h"
18#else
19        #include        "basic/basicInternal.h"
20#endif
21
22/*********************************** Locals ***********************************/
23#if !UEMF
24static value_t value_null;                                      /* All zeros */
25
26/***************************** Forward Declarations ***************************/
27
28static void     coerce_types(value_t* v1, value_t* v2);
29static int      value_to_integer(value_t* vp);
30#endif /*!UEMF*/
31/*********************************** Code *************************************/
32/*
33 *      Initialize a integer value.
34 */
35
36value_t valueInteger(long value)
37{
38        value_t v;
39
40        memset(&v, 0x0, sizeof(v));
41        v.valid = 1;
42        v.type = integer;
43        v.value.integer = value;
44        return v;
45}
46
47/******************************************************************************/
48/*
49 *      Initialize a string value.
50 */
51
52value_t valueString(char_t* value, int flags)
53{
54        value_t v;
55
56        memset(&v, 0x0, sizeof(v));
57        v.valid = 1;
58        v.type = string;
59        if (flags & VALUE_ALLOCATE) {
60                v.allocated = 1;
61                v.value.string = gstrdup(B_L, value);
62        } else {
63                v.allocated = 0;
64                v.value.string = value;
65        }
66        return v;
67}
68
69/******************************************************************************/
70/*
71 *      Free any storage allocated for a value.
72 */
73
74void valueFree(value_t* v)
75{
76        if (v->valid && v->allocated && v->type == string &&
77                        v->value.string != NULL) {
78                bfree(B_L, v->value.string);
79        }
80#if !UEMF
81        if (v->valid && v->type == symbol && v->value.symbol.data != NULL &&
82                        v->value.symbol.freeCb !=NULL) {
83                v->value.symbol.freeCb(v->value.symbol.data);
84        }
85#endif
86        v->type = undefined;
87        v->valid = 0;
88        v->allocated = 0;
89}
90
91#if !UEMF
92
93/******************************************************************************/
94/*
95 *      Initialize an invalid value.
96 */
97
98value_t valueInvalid()
99{
100        value_t v;
101        v.valid = 0;
102        v.type = undefined;
103        return v;
104}
105
106/******************************************************************************/
107/*
108 *      Initialize a flag value.
109 */
110
111value_t valueBool(int value)
112{
113        value_t v;
114
115        memset(&v, 0x0, sizeof(v));
116        v.type = flag;
117        v.valid = 1;
118        v.value.flag = (char) value;
119        return v;
120}
121
122/******************************************************************************/
123/*
124 *      Initialize a byteint value.
125 */
126
127value_t valueByteint(char value)
128{
129        value_t v;
130
131        memset(&v, 0x0, sizeof(v));
132        v.valid = 1;
133        v.type = byteint;
134        v.value.byteint = value;
135        return v;
136}
137
138/******************************************************************************/
139/*
140 *      Initialize a shortint value.
141 */
142
143value_t valueShortint(short value)
144{
145        value_t v;
146
147        memset(&v, 0x0, sizeof(v));
148        v.valid = 1;
149        v.type = shortint;
150        v.value.shortint = value;
151        return v;
152}
153
154#if FLOATING_POINT_SUPPORT
155/******************************************************************************/
156/*
157 *      Initialize a floating value.
158 */
159
160value_t valueFloating(double value)
161{
162        value_t v;
163
164        memset(&v, 0x0, sizeof(v));
165        v.valid = 1;
166        v.type = floating;
167        v.value.floating = value;
168        return v;
169}
170#endif /* FLOATING_POINT_SUPPORT */
171
172/******************************************************************************/
173/*
174 *      Initialize a big value.
175 */
176
177value_t valueBig(long high_word, long low_word)
178{
179        value_t v;
180
181        memset(&v, 0x0, sizeof(v));
182        v.valid = 1;
183        v.type = big;
184        v.value.big[BLOW] = low_word;
185        v.value.big[BHIGH] = high_word;
186        return v;
187}
188
189/******************************************************************************/
190/*
191 *      Initialize a hex value.
192 */
193
194value_t valueHex(int value)
195{
196        value_t v;
197
198        memset(&v, 0x0, sizeof(v));
199        v.valid = 1;
200        v.type = hex;
201        v.value.integer = value;
202        return v;
203}
204
205/******************************************************************************/
206/*
207 *      Initialize a octal value.
208 */
209
210value_t valueOctal(int value)
211{
212        value_t v;
213
214        memset(&v, 0x0, sizeof(v));
215        v.valid = 1;
216        v.type = octal;
217        v.value.integer = value;
218        return v;
219}
220
221/******************************************************************************/
222/*
223 *      Initialize a percent value.
224 */
225
226value_t valuePercent(int value)
227{
228        value_t v;
229
230        memset(&v, 0x0, sizeof(v));
231        v.valid = 1;
232        v.type = percent;
233        v.value.percent = (char) value;
234        return v;
235}
236
237/******************************************************************************/
238/*
239 *      Initialize an byte array. Note: no allocation, just store the ptr
240 */
241
242value_t valueBytes(char* value, int flags)
243{
244        value_t v;
245
246        memset(&v, 0x0, sizeof(v));
247        v.valid = 1;
248        v.type = bytes;
249        if (flags & VALUE_ALLOCATE) {
250                v.allocated = 1;
251                v.value.bytes = bstrdupA(B_L, value);
252        } else {
253                v.allocated = 0;
254                v.value.bytes = value;
255        }
256        return v;
257}
258
259/******************************************************************************/
260/*
261 *      Initialize a symbol value.
262 *      Value parameter can hold a pointer to any type of value
263 *      Free parameter can be NULL, or a function pointer to a function that will
264 *              free the value
265 */
266
267value_t valueSymbol(void *value, freeCallback freeCb)
268{
269        value_t v;
270
271        memset(&v, 0x0, sizeof(v));
272        v.valid = 1;
273        v.type = symbol;
274        v.value.symbol.data = value;
275        v.value.symbol.freeCb = freeCb;
276        return v;
277}
278
279/******************************************************************************/
280/*
281 *      Initialize an error message value.
282 */
283
284value_t valueErrmsg(char_t* value)
285{
286        value_t v;
287
288        memset(&v, 0x0, sizeof(v));
289        v.valid = 1;
290        v.type = errmsg;
291        v.value.errmsg = value;
292        return v;
293}
294
295/******************************************************************************/
296/*
297 *      Copy a value. If the type is 'string' then allocate another string.
298 *      Note: we allow the copy of a null value.
299 */
300
301value_t valueCopy(value_t v2)
302{
303        value_t         v1;
304
305        v1 = v2;
306        if (v2.valid && v2.type == string && v2.value.string != NULL) {
307                v1.value.string = gstrdup(B_L, v2.value.string);
308                v1.allocated = 1;
309        }
310        return v1;
311}
312
313
314/******************************************************************************/
315/*
316 *      Add a value.
317 */
318
319value_t valueAdd(value_t v1, value_t v2)
320{
321        value_t v;
322
323        a_assert(v1.valid);
324        a_assert(v2.valid);
325
326        memset(&v, 0x0, sizeof(v));
327        v.valid = 1;
328
329        if (v1.type != v2.type)
330                coerce_types(&v1, &v2);
331
332        switch (v1.type) {
333        default:
334        case string:
335        case bytes:
336                a_assert(0);
337                break;
338
339#if FLOATING_POINT_SUPPORT
340        case floating:
341                v1.value.floating += v2.value.floating;
342                return v1;
343#endif
344
345        case flag:
346                v1.value.bool |= v2.value.flag;
347                return v1;
348
349        case byteint:
350        case percent:
351                v1.value.byteint += v2.value.byteint;
352                return v1;
353
354        case shortint:
355                v1.value.shortint += v2.value.shortint;
356                return v1;
357
358        case hex:
359        case integer:
360        case octal:
361                v1.value.integer += v2.value.integer;
362                return v1;
363
364        case big:
365                v.type = big;
366                badd(v.value.big, v1.value.big, v2.value.big);
367                return v;
368        }
369
370        return v1;
371}
372
373
374/******************************************************************************/
375/*
376 *      Subtract a value.
377 */
378
379value_t valueSub(value_t v1, value_t v2)
380{
381        value_t v;
382
383        a_assert(v1.valid);
384        a_assert(v2.valid);
385
386        memset(&v, 0x0, sizeof(v));
387        v.valid = 1;
388
389        if (v1.type != v2.type)
390                coerce_types(&v1, &v2);
391        switch (v1.type) {
392        default:
393                a_assert(0);
394                break;
395
396#if FLOATING_POINT_SUPPORT
397        case floating:
398                v1.value.floating -= v2.value.floating;
399                return v1;
400#endif
401
402        case flag:
403                v1.value.flag &= v2.value.flag;
404                return v1;
405
406        case byteint:
407        case percent:
408                v1.value.byteint -= v2.value.byteint;
409                return v1;
410
411        case shortint:
412                v1.value.shortint -= v2.value.shortint;
413                return v1;
414
415        case hex:
416        case integer:
417        case octal:
418                v1.value.integer -= v2.value.integer;
419                return v1;
420
421        case big:
422                v.type = big;
423                bsub(v.value.big, v1.value.big, v2.value.big);
424                return v;
425        }
426
427        return v1;
428}
429
430
431/******************************************************************************/
432/*
433 *      Multiply a value.
434 */
435
436value_t valueMul(value_t v1, value_t v2)
437{
438        value_t v;
439
440        a_assert(v1.valid);
441        a_assert(v2.valid);
442
443        memset(&v, 0x0, sizeof(v));
444        v.valid = 1;
445
446        if (v1.type != v2.type)
447                coerce_types(&v1, &v2);
448        switch (v1.type) {
449        default:
450                a_assert(0);
451                break;
452
453        case flag:
454                a_assert(v1.type != flag);
455                break;
456
457#if FLOATING_POINT_SUPPORT
458        case floating:
459                v1.value.floating *= v2.value.floating;
460                return v1;
461#endif
462
463        case byteint:
464        case percent:
465                v1.value.byteint *= v2.value.byteint;
466                return v1;
467
468        case shortint:
469                v1.value.shortint *= v2.value.shortint;
470                return v1;
471
472        case hex:
473        case integer:
474        case octal:
475                v1.value.integer *= v2.value.integer;
476                return v1;
477
478        case big:
479                v.type = big;
480                bmul(v.value.big, v1.value.big, v2.value.big);
481                return v;
482        }
483
484        return v1;
485}
486
487
488/******************************************************************************/
489/*
490 *      Divide a value.
491 */
492
493value_t valueDiv(value_t v1, value_t v2)
494{
495        value_t v;
496
497        a_assert(v1.valid);
498        a_assert(v2.valid);
499
500        memset(&v, 0x0, sizeof(v));
501        v.valid = 1;
502
503        if (v1.type != v2.type)
504                coerce_types(&v1, &v2);
505        switch (v1.type) {
506        default:
507                a_assert(0);
508                break;
509
510        case flag:
511                a_assert(v1.type != flag);
512                break;
513
514#if FLOATING_POINT_SUPPORT
515        case floating:
516                v1.value.floating /= v2.value.floating;
517                return v1;
518#endif
519
520        case byteint:
521        case percent:
522                v1.value.byteint /= v2.value.byteint;
523                return v1;
524
525        case shortint:
526                v1.value.shortint /= v2.value.shortint;
527                return v1;
528
529        case hex:
530        case integer:
531        case octal:
532                v1.value.integer /= v2.value.integer;
533                return v1;
534
535        case big:
536                v.type = big;
537                bdiv(v.value.big, v1.value.big, v2.value.big);
538                return v;
539        }
540
541        return v1;
542}
543
544
545/******************************************************************************/
546/*
547 *      Compare a value.
548 */
549
550int valueCmp(value_t v1, value_t v2)
551{
552        a_assert(v1.valid);
553        a_assert(v2.valid);
554
555        if (v1.type != v2.type)
556                coerce_types(&v1, &v2);
557        if (v1.type != v2.type) {
558/*
559 *              Make v2 == v1
560 */
561                a_assert(v1.type == v2.type);
562                v2 = v1;
563                return 0;
564        }
565        switch (v1.type) {
566        case string:
567                if (v1.value.string == NULL && v2.value.string == NULL) {
568                        return 0;
569                } else if (v1.value.string == NULL) {
570                        return -1;
571                } else if (v2.value.string == NULL) {
572                        return 1;
573                } else {
574                        return gstrcmp(v1.value.string, v2.value.string);
575                }
576                /* Nobody here */
577
578        case flag:
579                if (v1.value.flag < v2.value.flag)
580                        return -1;
581                else if (v1.value.flag == v2.value.flag)
582                        return 0;
583                else return 1;
584
585#if FLOATING_POINT_SUPPORT
586        case floating:
587                if (v1.value.floating < v2.value.floating)
588                        return -1;
589                else if (v1.value.floating == v2.value.floating)
590                        return 0;
591                else return 1;
592#endif
593
594        case byteint:
595        case percent:
596                if (v1.value.byteint < v2.value.byteint)
597                        return -1;
598                else if (v1.value.byteint == v2.value.byteint)
599                        return 0;
600                else return 1;
601
602        case shortint:
603                if (v1.value.shortint < v2.value.shortint)
604                        return -1;
605                else if (v1.value.shortint == v2.value.shortint)
606                        return 0;
607                else return 1;
608
609        case hex:
610        case integer:
611        case octal:
612                if (v1.value.integer < v2.value.integer)
613                        return -1;
614                else if (v1.value.integer == v2.value.integer)
615                        return 0;
616                else return 1;
617
618        case big:
619                return bcompare(v1.value.big, v2.value.big);
620
621        default:
622                a_assert(0);
623                return 0;
624        }
625}
626
627
628/******************************************************************************/
629/*
630 *      If type mismatch, then coerce types to big.
631 *      Note: Known bug, casting of negative bigs to floats doesn't work.
632 */
633
634static void coerce_types(register value_t* v1, register value_t* v2)
635{
636#if FLOATING_POINT_SUPPORT
637        if (v1->type == floating) {
638                v2->type = floating;
639                v2->value.floating = (double) v2->value.integer;
640                if (v2->type == big)
641                        v2->value.floating = (double) v2->value.big[BLOW] +
642                                (double) v2->value.big[BHIGH] * (double) MAXINT;
643
644        } else if (v2->type == floating) {
645                v1->type = floating;
646                v1->value.floating = (double) v1->value.integer;
647                if (v1->type == big)
648                        v1->value.floating = (double) v1->value.big[BLOW] +
649                                (double) v1->value.big[BHIGH] * (double) MAXINT;
650
651        } else if (v1->type == big) {
652#else
653        if (v1->type == big) {
654#endif /* FLOATING_POINT_SUPPORT */
655                v2->value.big[BLOW] = value_to_integer(v2);
656                if (valueNegative(v2))
657                        v2->value.big[BHIGH] = -1;
658                else
659                        v2->value.big[BHIGH] = 0;
660                v2->type = big;
661
662        } else if (v2->type == big) {
663                if (valueNegative(v1))
664                        v1->value.big[BHIGH] = -1;
665                else
666                        v1->value.big[BHIGH] = 0;
667                v1->value.big[BLOW] = value_to_integer(v1);
668                v1->type = big;
669
670
671        } else if (v1->type == integer) {
672                v2->value.integer = value_to_integer(v2);
673                v2->type = integer;
674
675        } else if (v2->type == integer) {
676                v1->value.integer = value_to_integer(v1);
677                v1->type = integer;
678
679        } else if (v1->type != integer) {
680                v2->type = v1->type;
681
682        } else if (v2->type != integer) {
683                v1->type = v2->type;
684
685        }
686        a_assert(v1->type == v2->type);
687}
688
689
690/******************************************************************************/
691/*
692 *      Return true if the value is numeric and negative. Otherwise return 0.
693 */
694
695int valueNegative(value_t* vp)
696{
697        switch (vp->type) {
698        default:
699        case string:
700        case bytes:
701                return 0;
702
703#if FLOATING_POINT_SUPPORT
704        case floating:
705                if (vp->value.floating < 0)
706                        return 1;
707                return 0;
708#endif
709
710        case flag:
711                if ((signed char)vp->value.flag < 0)
712                        return 1;
713                return 0;
714
715        case byteint:
716        case percent:
717                if ((signed char)vp->value.byteint < 0)
718                        return 1;
719                return 0;
720
721        case shortint:
722                if (vp->value.shortint < 0)
723                        return 1;
724                return 0;
725
726        case hex:
727        case integer:
728        case octal:
729                if (vp->value.integer < 0)
730                        return 1;
731                return 0;
732
733        case big:
734                if (vp->value.big[BHIGH] < 0)
735                        return 1;
736                return 0;
737        }
738}
739
740/******************************************************************************/
741/*
742 *      Return true if the value is numeric and zero. Otherwise return 0.
743 */
744
745int valueZero(value_t* vp)
746{
747        switch (vp->type) {
748        default:
749        case string:
750        case bytes:
751                return 0;
752
753#if FLOATING_POINT_SUPPORT
754        case floating:
755                if (vp->value.floating == 0)
756                        return 1;
757                return 0;
758#endif
759
760        case flag:
761                if (vp->value.flag == 0)
762                        return 1;
763                return 0;
764
765        case byteint:
766        case percent:
767                if (vp->value.byteint == 0)
768                        return 1;
769                return 0;
770
771        case shortint:
772                if (vp->value.shortint == 0)
773                        return 1;
774                return 0;
775
776        case hex:
777        case integer:
778        case octal:
779                if (vp->value.integer == 0)
780                        return 1;
781                return 0;
782
783        case big:
784                if (vp->value.big[BHIGH] == 0 && vp->value.big[BLOW] == 0)
785                        return 1;
786                return 0;
787        }
788}
789
790
791/******************************************************************************/
792/*
793 *      Cast a value to an integer. Cannot be called for floating, non-numerics
794 *      or bigs.
795 */
796
797static int value_to_integer(value_t* vp)
798{
799        switch (vp->type) {
800        default:
801        case string:
802        case bytes:
803        case big:
804#if FLOATING_POINT_SUPPORT
805        case floating:
806                a_assert(0);
807                return -1;
808#endif
809
810        case flag:
811                return (int) vp->value.flag;
812
813        case byteint:
814        case percent:
815                return (int) vp->value.byteint;
816
817        case shortint:
818                return (int) vp->value.shortint;
819
820        case hex:
821        case integer:
822        case octal:
823                return (int) vp->value.integer;
824        }
825}
826
827
828/******************************************************************************/
829/*
830 *      Convert a value to a text based representation of its value
831 */
832
833void valueSprintf(char_t** out, int size, char_t* fmt, value_t vp)
834{
835        char_t          *src, *dst, *tmp, *dst_start;
836
837        a_assert(out);
838
839        *out = NULL;
840
841        if (! vp.valid) {
842                *out = bstrdup(B_L, T("Invalid"));
843                return;
844        }
845
846        switch (vp.type) {
847        case flag:
848                if (fmt == NULL || *fmt == '\0') {
849                        *out = bstrdup(B_L, (vp.value.flag) ? T("true") : T("false"));
850                } else {
851                        fmtAlloc(out, size, fmt, (vp.value.flag) ? T("true") : T("false"));
852                }
853                break;
854
855#if FLOATING_POINT_SUPPORT
856        case floating:
857                if (fmt == NULL || *fmt == '\0') {
858                        fmtAlloc(out, size, T("%f"), vp.value.floating);
859                } else {
860                        fmtAlloc(out, size, fmt, vp.value.floating);
861                }
862                break;
863#endif
864
865        case hex:
866                if (fmt == NULL || *fmt == '\0') {
867                        fmtAlloc(out, size, T("0x%lx"), vp.value.hex);
868                } else {
869                        fmtAlloc(out, size, fmt, vp.value.hex);
870                }
871                break;
872
873        case big:
874                if (*out == NULL) {
875                        *out = btoa(vp.value.big, NULL, 0);
876                } else {
877                        btoa(vp.value.big, *out, size);
878                }
879                break;
880
881        case integer:
882                if (fmt == NULL || *fmt == '\0') {
883                        fmtAlloc(out, size, T("%ld"), vp.value.integer);
884                } else {
885                        fmtAlloc(out, size, fmt, vp.value.integer);
886                }
887                break;
888
889        case octal:
890                if (fmt == NULL || *fmt == '\0') {
891                        fmtAlloc(out, size, T("0%lo"), vp.value.octal);
892                } else {
893                        fmtAlloc(out, size, fmt, vp.value.octal);
894                }
895                break;
896
897        case percent:
898                if (fmt == NULL || *fmt == '\0') {
899                        fmtAlloc(out, size, T("%d%%"), vp.value.percent);
900                } else {
901                        fmtAlloc(out, size, fmt, vp.value.percent);
902                }
903                break;
904
905        case byteint:
906                if (fmt == NULL || *fmt == '\0') {
907                        fmtAlloc(out, size, T("%d"), (int) vp.value.byteint);
908                } else {
909                        fmtAlloc(out, size, fmt, (int) vp.value.byteint);
910                }
911                break;
912
913        case shortint:
914                if (fmt == NULL || *fmt == '\0') {
915                        fmtAlloc(out, size, T("%d"), (int) vp.value.shortint);
916                } else {
917                        fmtAlloc(out, size, fmt, (int) vp.value.shortint);
918                }
919                break;
920
921        case string:
922        case errmsg:
923                src = vp.value.string;
924
925                if (src == NULL) {
926                        *out = bstrdup(B_L, T("NULL"));
927                } else if (fmt && *fmt) {
928                        fmtAlloc(out, size, fmt, src);
929
930                } else {
931
932                        *out = balloc(B_L, size);
933                        dst_start = dst = *out;
934                        for (; *src != '\0'; src++) {
935                                if (dst >= &dst_start[VALUE_MAX_STRING - 5])
936                                        break;
937                                switch (*src) {
938                                case '\a':      *dst++ = '\\';  *dst++ = 'a';           break;
939                                case '\b':      *dst++ = '\\';  *dst++ = 'b';           break;
940                                case '\f':      *dst++ = '\\';  *dst++ = 'f';           break;
941                                case '\n':      *dst++ = '\\';  *dst++ = 'n';           break;
942                                case '\r':      *dst++ = '\\';  *dst++ = 'r';           break;
943                                case '\t':      *dst++ = '\\';  *dst++ = 't';           break;
944                                case '\v':      *dst++ = '\\';  *dst++ = 'v';           break;
945                                case '\\':      *dst++ = '\\';  *dst++ = '\\';          break;
946                                case '"':       *dst++ = '\\';  *dst++ = '\"';          break;
947                                default:
948                                        if (gisprint(*src)) {
949                                                *dst++ = *src;
950                                        } else {
951                                                fmtAlloc(&tmp, size, T("\\x%02x"),
952                                                        (unsigned int) *src);
953                                                gstrcpy(dst, tmp);
954                                                bfreeSafe(B_L, tmp);
955                                                dst += 4;
956                                        }
957                                        break;
958                                }
959                        }
960                        *dst++ = '\0';
961                }
962                break;
963
964#if UNUSED
965        case bytes:
966                asrc = vp.value.bytes;
967
968                if (asrc == NULL) {
969                        *out = bstrdup(B_L, T("NULL"));
970
971                } else if (fmt && *fmt) {
972                        fmtAlloc(out, size, fmt, asrc);
973
974                } else {
975
976                        dst_start = dst;
977                        for (; *asrc != '\0'; asrc++) {
978                                if (dst >= &dst_start[VALUE_MAX_STRING - 5])
979                                        break;
980                                switch (*asrc) {
981                                case '\a':      *dst++ = '\\';  *dst++ = 'a';           break;
982                                case '\b':      *dst++ = '\\';  *dst++ = 'b';           break;
983                                case '\f':      *dst++ = '\\';  *dst++ = 'f';           break;
984                                case '\n':      *dst++ = '\\';  *dst++ = 'n';           break;
985                                case '\r':      *dst++ = '\\';  *dst++ = 'r';           break;
986                                case '\t':      *dst++ = '\\';  *dst++ = 't';           break;
987                                case '\v':      *dst++ = '\\';  *dst++ = 'v';           break;
988                                case '\\':      *dst++ = '\\';  *dst++ = '\\';          break;
989                                case '"':       *dst++ = '\\';  *dst++ = '\"';          break;
990                                default:
991                                        if (gisprint(*asrc)) {
992                                                *dst++ = *asrc;
993                                        } else {
994                                                fmtAlloc(dst, size,
995                                                        T("\\x%02x"), (unsigned int) *asrc);
996                                                dst += 4;
997                                        }
998                                        break;
999                                }
1000                        }
1001                        *dst++ = '\0';
1002                }
1003                break;
1004#endif
1005
1006        default:
1007                a_assert(0);
1008        }
1009}
1010
1011/******************************************************************************/
1012/*
1013 *      Print a value to the named file descriptor
1014 */
1015
1016void valueFprintf(FILE* fp, char_t* fmt, value_t vp)
1017{
1018        char_t  *buf;
1019
1020        buf = NULL;
1021        valueSprintf(&buf, VALUE_MAX_STRING, fmt, vp);
1022        gfputs(buf, fp);
1023        bfreeSafe(B_L, buf);
1024        fflush(fp);
1025}
1026
1027/******************************************************************************/
1028/*
1029 *      Ascii to value conversion
1030 */
1031
1032value_t valueAtov(char_t* s, int pref_type)
1033{
1034        vtype_t type;
1035        value_t                 v;
1036        long                    tmp[2], tmp2[2], base[2];
1037        int                             i, len, num;
1038
1039        a_assert(0 <= pref_type && pref_type < 99);             /* Sanity check */
1040        a_assert(s);
1041
1042        v = value_null;
1043        if (s == NULL) {
1044                return value_null;
1045        }
1046
1047        base[BLOW] = 10;
1048        base[BHIGH] = 0;
1049        len = gstrlen(s);
1050
1051/*
1052 *      Determine the value type
1053 */
1054        type = undefined;
1055        if (pref_type <= 0) {
1056                if (gisdigit(*s)) {
1057                        base[BHIGH] = 0;
1058                        if (s[len - 1] == '%') {
1059                                type = percent;
1060                                len --;
1061                                base[BLOW] = 10;
1062                        } else if (*s == '0') {
1063                                if (s[1] == 'x') {
1064                                        type = hex;
1065                                        s += 2;
1066                                        len -= 2;
1067                                        base[BLOW] = 16;
1068                                } else if (s[1] == '\0') {
1069                                        type = integer;
1070                                        base[BLOW] = 10;
1071                                } else {
1072                                        type = octal;
1073                                        s++;
1074                                        len--;
1075                                        base[BLOW] = 8;
1076                                }
1077                        } else {
1078                                type = integer;
1079                                base[BLOW] = 10;
1080                        }
1081
1082                } else {
1083                        if (gstrcmp(s, T("true")) == 0 || gstrcmp(s, T("false")) == 0) {
1084                                type = flag;
1085                        } else if (*s == '\'' && s[len - 1] == '\'') {
1086                                type = string;
1087                                s++;
1088                                len -= 2;
1089                        } else if (*s == '\"' && s[len - 1] == '\"') {
1090                                type = string;
1091                                s++;
1092                                len -= 2;
1093                        } else {
1094                                type = string;
1095                        }
1096                }
1097                v.type = type;
1098
1099        } else
1100                v.type = pref_type;
1101        v.valid = 1;
1102
1103/*
1104 *      Do the conversion. Always use big arithmetic
1105 */
1106        switch (v.type) {
1107        case hex:
1108                if (!isdigit(s[0])) {
1109                        if (gtolower(s[0]) >= 'a' || gtolower(s[0]) <= 'f') {
1110                                v.value.big[BLOW] = 10 + gtolower(s[0]) - 'a';
1111                        } else {
1112                                v.value.big[BLOW] = 0;
1113                        }
1114                } else {
1115                        v.value.big[BLOW] = s[0] - '0';
1116                }
1117                v.value.big[BHIGH] = 0;
1118                for (i = 1; i < len; i++) {
1119                        if (!isdigit(s[i])) {
1120                                if (gtolower(s[i]) < 'a' || gtolower(s[i]) > 'f') {
1121                                        break;
1122                                }
1123                                num = 10 + gtolower(s[i]) - 'a';
1124                        } else {
1125                                num = s[i] - '0';
1126                        }
1127                        bmul(tmp, v.value.big, base);
1128                        binit(tmp2, 0, num);
1129                        badd(v.value.big, tmp, tmp2);
1130                }
1131                v.value.hex = v.value.big[BLOW];
1132                break;
1133
1134        case shortint:
1135        case byteint:
1136        case integer:
1137        case percent:
1138        case octal:
1139        case big:
1140                v.value.big[BHIGH] = 0;
1141                if (gisdigit(s[0]))
1142                        v.value.big[BLOW] = s[0] - '0';
1143                else
1144                        v.value.big[BLOW] = 0;
1145                for (i = 1; i < len && gisdigit(s[i]); i++) {
1146                        bmul(tmp, v.value.big, base);
1147                        binit(tmp2, 0, s[i] - '0');
1148                        badd(v.value.big, tmp, tmp2);
1149                }
1150                switch (v.type) {
1151                case shortint:
1152                        v.value.shortint = (short) v.value.big[BLOW];
1153                        break;
1154                case byteint:
1155                        v.value.byteint = (char) v.value.big[BLOW];
1156                        break;
1157                case integer:
1158                        v.value.integer = (int) v.value.big[BLOW];
1159                        break;
1160                case percent:
1161                        v.value.percent = (char) v.value.big[BLOW];
1162                        break;
1163                case octal:
1164                        v.value.octal = (int) v.value.big[BLOW];
1165                        break;
1166                default:
1167                        break;
1168                }
1169                break;
1170
1171#if FLOATING_POINT_SUPPORT
1172        case floating:
1173                gsscanf(s, T("%f"), &v.value.floating);
1174                break;
1175#endif
1176
1177        case flag:
1178                if (*s == 't')
1179                        v.value.flag = 1;
1180                else v.value.flag = 0;
1181                break;
1182
1183        case string:
1184/*
1185 *              Note this always ballocs a string
1186 */
1187                v = valueString(s, VALUE_ALLOCATE);
1188                break;
1189
1190        case bytes:
1191                v = valueBytes((char*) s, VALUE_ALLOCATE);
1192                break;
1193
1194#if UNUSED
1195        case literal:
1196                v = value_literal(bstrdup(B_L, s));
1197                v.value.literal[len] = '\0';
1198                break;
1199#endif
1200
1201        case undefined:
1202        case symbol:
1203        default:
1204                v.valid = 0;
1205                a_assert(0);
1206        }
1207        return v;
1208}
1209
1210#endif /* !UEMF */
1211/******************************************************************************/
Note: See TracBrowser for help on using the repository browser.