/[dtapublic]/projs/dtats/trunk/shared_source/c_datd/bstrfunc.c
ViewVC logotype

Annotation of /projs/dtats/trunk/shared_source/c_datd/bstrfunc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 98 - (hide annotations) (download)
Sun Dec 18 00:57:31 2016 UTC (7 years, 11 months ago) by dashley
File MIME type: text/plain
File size: 30734 byte(s)
Reorganization.
1 dashley 71 //$Header$
2     //-------------------------------------------------------------------------------------------------
3     //This file is part of "David T. Ashley's Shared Source Code", a set of shared components
4     //integrated into many of David T. Ashley's projects.
5     //-------------------------------------------------------------------------------------------------
6     //This source code and any program in which it is compiled/used is provided under the MIT License,
7     //reproduced below.
8     //-------------------------------------------------------------------------------------------------
9     //Permission is hereby granted, free of charge, to any person obtaining a copy of
10     //this software and associated documentation files(the "Software"), to deal in the
11     //Software without restriction, including without limitation the rights to use,
12     //copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the
13     //Software, and to permit persons to whom the Software is furnished to do so,
14     //subject to the following conditions :
15     //
16     //The above copyright notice and this permission notice shall be included in all
17     //copies or substantial portions of the Software.
18     //
19     //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20     //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21     //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
22     //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23     //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24     //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25     //SOFTWARE.
26     //-------------------------------------------------------------------------------------------------
27     #define MODULE_BSTRFUNC
28    
29     #include <assert.h>
30     #include <malloc.h>
31     #include <process.h>
32     #include <stddef.h>
33     #include <string.h>
34    
35    
36     #if defined(APP_TYPE_SIMPLE_DOS_CONSOLE)
37     #include "ccmalloc.h"
38     #elif defined(APP_TYPE_IJUSCRIPTER_IJUCONSOLE)
39     #include "tclalloc.h"
40     #else
41     /* Do nothing. */
42     #endif
43    
44     #include "bstrfunc.h"
45     #include "ccmalloc.h"
46     #include "charfunc.h"
47    
48    
49     /******************************************************************/
50     /*** CUSTOM ALLOCATION FUNCTIONS *******************************/
51     /******************************************************************/
52     //We need wrappers because this software module will be used in
53     //more than one kind of software. This could also be done with
54     //macros, but I like function wrappers better because there
55     //is less ambiguity and more ability to collect information if
56     //something goes wrong.
57     //
58     //07/24/01: Visual inspection only. Function deemed too
59     //simple for unit testing.
60     void *BSTRFUNC_malloc( size_t size )
61     {
62     #if defined(APP_TYPE_SIMPLE_DOS_CONSOLE)
63     return(CCMALLOC_malloc(size));
64     #elif defined(APP_TYPE_IJUSCRIPTER_IJUCONSOLE)
65     return(TclpAlloc(size));
66     #else
67     return(malloc(size));
68     #endif
69     }
70    
71    
72     //07/24/01: Visual inspection only. Function deemed too
73     //simple for unit testing.
74     void *BSTRFUNC_calloc( size_t num, size_t size )
75     {
76     #if defined(APP_TYPE_SIMPLE_DOS_CONSOLE)
77     return(CCMALLOC_calloc(num, size));
78     #elif defined(APP_TYPE_IJUSCRIPTER_IJUCONSOLE)
79     return(TclpCalloc(num, size));
80     #else
81     return(calloc(num, size));
82     #endif
83     }
84    
85    
86     //07/24/01: Visual inspection only. Function deemed too
87     //simple for unit testing.
88     void *BSTRFUNC_realloc( void *memblock, size_t size )
89     {
90     #if defined(APP_TYPE_SIMPLE_DOS_CONSOLE)
91     return(CCMALLOC_realloc(memblock, size));
92     #elif defined(APP_TYPE_IJUSCRIPTER_IJUCONSOLE)
93     return(TclpRealloc(memblock, size));
94     #else
95     return(realloc(memblock, size));
96     #endif
97     }
98    
99    
100     //07/24/01: Visual inspection only. Function deemed too
101     //simple for unit testing.
102     void BSTRFUNC_free( void *memblock )
103     {
104     #if defined(APP_TYPE_SIMPLE_DOS_CONSOLE)
105     CCMALLOC_free(memblock);
106     #elif defined(APP_TYPE_IJUSCRIPTER_IJUCONSOLE)
107     TclpFree(memblock);
108     #else
109     free(memblock);
110     #endif
111     }
112    
113    
114     //07/18/01: Visual inspection and unit tests passed.
115     int BSTRFUNC_is_uint_wo_commas(const char *arg)
116     {
117     assert(arg != NULL);
118    
119     if (!*arg)
120     return(0);
121    
122     if (arg[0] == '0')
123     {
124     if (arg[1])
125     {
126     return(0);
127     }
128     else
129     {
130     return(1);
131     }
132     }
133     else
134     {
135     while (*arg)
136     {
137     if ((*arg < '0') || (*arg > '9'))
138     return(0);
139     arg++;
140     }
141    
142     return(1);
143     }
144     }
145    
146    
147     //07/28/01: Visual inspection only.
148     int BSTRFUNC_is_sint_wo_commas(const char *arg)
149     {
150     //This function will use its unsigned counterpart.
151     //
152     //Eyeball the input parameter.
153     assert(arg != NULL);
154    
155     if (!*arg) //Empty string ain't an integer.
156     return(0);
157    
158     if (*arg == '-')
159     {
160     if (arg[1] == '0')
161     return(0);
162     else
163     return(BSTRFUNC_is_uint_wo_commas(arg+1));
164     }
165     else
166     {
167     return(BSTRFUNC_is_uint_wo_commas(arg));
168     }
169     }
170    
171    
172     //07/18/01: Visual inspection and unit tests passed.
173     int BSTRFUNC_is_uint_w_commas(const char *arg)
174     {
175     int state;
176    
177     //Input pointer cannot be NULL.
178     assert(arg != NULL);
179    
180     //Can't be empty string.
181     if (!*arg)
182     return(0);
183    
184     //If the first digit is 0, that must be the only digit.
185     if (arg[0] == '0')
186     {
187     if (arg[1])
188     {
189     return(0);
190     }
191     else
192     {
193     return(1);
194     }
195     }
196    
197     //The remainder of this function is an efficient state
198     //machine recognizer. The state machine involved is
199     //pretty simple and was drawn and discarded on a sheet
200     //of paper. It doesn't need to be filed because it is
201     //so basic.
202     if ((*arg < '0') || (*arg > '9'))
203     return(0);
204    
205     state = 0;
206     arg++;
207    
208     while(1)
209     {
210     switch (state)
211     {
212     case 0 : if (!*arg)
213     {
214     return(1);
215     }
216     else if (*arg == ',')
217     {
218     state = 3;
219     }
220     else if ((*arg >= '0') && (*arg <= '9'))
221     {
222     state = 1;
223     }
224     else
225     {
226     return(0);
227     }
228     break;
229     case 1 : if (!*arg)
230     {
231     return(1);
232     }
233     else if (*arg == ',')
234     {
235     state = 3;
236     }
237     else if ((*arg >= '0') && (*arg <= '9'))
238     {
239     state = 2;
240     }
241     else
242     {
243     return(0);
244     }
245     break;
246     case 2 : if (!*arg)
247     {
248     return(1);
249     }
250     else if (*arg == ',')
251     {
252     state = 3;
253     }
254     else if ((*arg >= '0') && (*arg <= '9'))
255     {
256     return(0);
257     }
258     else
259     {
260     return(0);
261     }
262     break;
263     case 3 : if (!*arg)
264     {
265     return(0);
266     }
267     else if (*arg == ',')
268     {
269     return(0);
270     }
271     else if ((*arg >= '0') && (*arg <= '9'))
272     {
273     state = 4;
274     }
275     else
276     {
277     return(0);
278     }
279     break;
280     case 4 : if (!*arg)
281     {
282     return(0);
283     }
284     else if (*arg == ',')
285     {
286     return(0);
287     }
288     else if ((*arg >= '0') && (*arg <= '9'))
289     {
290     state = 5;
291     }
292     else
293     {
294     return(0);
295     }
296     break;
297     case 5 : if (!*arg)
298     {
299     return(0);
300     }
301     else if (*arg == ',')
302     {
303     return(0);
304     }
305     else if ((*arg >= '0') && (*arg <= '9'))
306     {
307     state = 6;
308     }
309     else
310     {
311     return(0);
312     }
313     break;
314     case 6 : if (!*arg)
315     {
316     return(1);
317     }
318     else if (*arg == ',')
319     {
320     state = 3;
321     }
322     else if ((*arg >= '0') && (*arg <= '9'))
323     {
324     return(0);
325     }
326     else
327     {
328     return(0);
329     }
330     break;
331     default:
332     abort();
333     break;
334     }
335    
336     arg++;
337     }
338    
339     //We should never get here.
340     }
341    
342    
343     //07/28/01: Visual inspection only.
344     int BSTRFUNC_is_sint_w_commas(const char *arg)
345     {
346     //This function will use its unsigned counterpart.
347     //
348     //Eyeball the input parameter.
349     assert(arg != NULL);
350    
351     if (!*arg) //Empty string ain't an integer.
352     return(0);
353    
354     if (*arg == '-')
355     {
356     if (arg[1] == '0')
357     return(0);
358     else
359     return(BSTRFUNC_is_uint_w_commas(arg+1));
360     }
361     else
362     {
363     return(BSTRFUNC_is_uint_w_commas(arg));
364     }
365     }
366    
367    
368     //07/18/01: Visual verification only due to simplicity.
369     void BSTRFUNC_str_reverse(char *s)
370     {
371     int l, begin, end;
372     char temp;
373    
374     assert(s != NULL);
375    
376     l = strlen(s);
377    
378     begin = 0;
379     end = l-1;
380    
381     while ((end-begin) >=1)
382     {
383     temp = s[begin];
384     s[begin] = s[end];
385     s[end] = temp;
386     begin++;
387     end--;
388     }
389     }
390    
391    
392     void BSTRFUNC_parse_gen_sci_not_num(const char *s,
393     int *failure,
394     char *mant_sign,
395     size_t *mant_bdp,
396     size_t *mant_bdp_len,
397     size_t *mant_adp,
398     size_t *mant_adp_len,
399     char *exp_sign,
400     size_t *exp,
401     size_t *exp_len)
402     {
403     //For the parameters that can be NULL, these are the
404     //local copies we keep. We will assign these back to
405     //the caller's area when appropriate before we leave.
406     char i_mant_sign, i_exp_sign;
407     size_t i_mant_bdp, i_mant_bdp_len, i_mant_adp, i_mant_adp_len,
408     i_exp, i_exp_len;
409     size_t i;
410     int state;
411     const char *arg;
412    
413     //Check out the parameters that can't be NULL.
414     assert(s != NULL);
415     assert(failure != NULL);
416    
417     //Initialize all variables to defaults.
418     *failure = 0 ;
419     i_mant_sign = 'N';
420     i_exp_sign = 'N';
421     i_mant_bdp = 0 ;
422     i_mant_bdp_len = 0 ;
423     i_mant_adp = 0 ;
424     i_mant_adp_len = 0 ;
425     i_exp = 0 ;
426     i_exp_len = 0 ;
427     i = 0 ;
428     state = 0 ;
429    
430     //Process the string. This is a big 10-state state
431     //machine. Because of the complexity, I've included
432     //some state definitions as well in the comments.
433     arg = s;
434    
435     while(1)
436     {
437     switch (state)
438     {
439     //Initial state from which we start processing.
440     case 0 : if (!*arg)
441     {
442     //The string is empty. This is not OK.
443     //Error out.
444     *failure = 1;
445     goto term_seq;
446     }
447     else if (*arg == '-')
448     {
449     //Leading - on the number. Fine.
450     i_mant_sign = '-';
451     state = 1;
452     }
453     else if (*arg == '+')
454     {
455     //Leading + on the number. Fine.
456     i_mant_sign = '+';
457     state = 2;
458     }
459     else if (*arg == '.')
460     {
461     //Leading . on the number. Fine.
462     state = 5;
463     }
464     else if (*arg == '0')
465     {
466     i_mant_bdp = arg - s;
467     state = 4;
468     }
469     else if ((*arg >= '1') && (*arg <= '9'))
470     {
471     i_mant_bdp = arg - s;
472     state = 3;
473     }
474     else
475     {
476     //Unidentifiable crap. This is not OK.
477     //Error out.
478     *failure = 1;
479     goto term_seq;
480     }
481     break;
482     //The leading character of the string was '-'. We
483     //are processing a negative number.
484     case 1 : if (!*arg)
485     {
486     //The string is empty. This is not OK because
487     //it means the string was "-".
488     //Error out.
489     *failure = 1;
490     goto term_seq;
491     }
492     else if (*arg == '.')
493     {
494     //We have a - followed by a decimal point.
495     //This is impolite form, but will accept
496     //it as a number.
497     state = 5;
498     }
499     else if (*arg == '0')
500     {
501     //We have a '-' followed by a '0'.
502     //Seems reasonable.
503     i_mant_bdp = arg - s;
504     state = 4;
505     }
506     else if ((*arg >= '1') && (*arg <= '9'))
507     {
508     //We have a '-' followed by a non-zero
509     //digit. Seems reasonable.
510     i_mant_bdp = arg - s;
511     state = 3;
512     }
513     else
514     {
515     //Unidentifiable crap. This is not OK.
516     //Error out.
517     *failure = 1;
518     goto term_seq;
519     }
520     break;
521     //The leading character of the string was '+'. We
522     //are processing an explicitly declared positive number.
523     case 2 : if (!*arg)
524     {
525     //The string is empty. This is not OK because
526     //it means the string was "+".
527     //Error out.
528     *failure = 1;
529     goto term_seq;
530     }
531     else if (*arg == '.')
532     {
533     //We have a + followed by a decimal point.
534     //This is impolite form, but will accept
535     //it as a number.
536     state = 5;
537     }
538     else if (*arg == '0')
539     {
540     //We have a '-' followed by a '0'.
541     //Seems reasonable.
542     i_mant_bdp = arg - s;
543     state = 4;
544     }
545     else if ((*arg >= '1') && (*arg <= '9'))
546     {
547     //We have a '+' followed by a non-zero
548     //digit. Seems reasonable.
549     i_mant_bdp = arg - s;
550     state = 3;
551     }
552     else
553     {
554     //Unidentifiable crap. This is not OK.
555     //Error out.
556     *failure = 1;
557     goto term_seq;
558     }
559     break;
560     //We've encountered a non-zero digit either first as part
561     //of the string or later after + or -. We are processing
562     //a mantissa that does not begin with "0".
563     case 3 : if (!*arg)
564     {
565     //We've reached the end of the string. This is
566     //fine because we have a simple integer of the
567     //form NNNN, +NNNN, or -NNNN. No problem with that.
568     i_mant_bdp_len = (arg - s) - i_mant_bdp;
569     *failure = 0;
570     goto term_seq;
571     }
572     else if (*arg == '.')
573     {
574     //Number followed by decimal point. This
575     //means the mantissa is terminating. No issue.
576     i_mant_bdp_len = (arg - s) - i_mant_bdp;
577     state = 5;
578     }
579     else if ((*arg >= '0') && (*arg <= '9'))
580     {
581     //Yet more digits. Seems reasonable.
582     //The assignment isn't necessary, but it
583     //is aesthetic.
584     state = 3;
585     }
586     else if ((*arg == 'e') || (*arg == 'E'))
587     {
588     //Beginning of an exponent. This again
589     //means the mantissa is terminating. No issue.
590     i_mant_bdp_len = (arg - s) - i_mant_bdp;
591     state = 6;
592     }
593     else
594     {
595     //Unidentifiable crap. This is not OK.
596     //Error out.
597     *failure = 1;
598     goto term_seq;
599     }
600     break;
601     //We're processing a mantissa that begins with zero. There
602     //is only one zero allowed before the decimal point.
603     case 4 : if (!*arg)
604     {
605     //We've reached the end of the string. This is
606     //fine because it means we have zero. I'm going
607     //to be unusually permissive and allow -0 and +0,
608     //which isn't traditional.
609     i_mant_bdp_len = (arg - s) - i_mant_bdp;
610     *failure = 0;
611     goto term_seq;
612     }
613     else if (*arg == '.')
614     {
615     //Zero followed by decimal point. This
616     //means the mantissa is terminating. No issue.
617     i_mant_bdp_len = (arg - s) - i_mant_bdp;
618     state = 5;
619     }
620     else if ((*arg == 'e') || (*arg == 'E'))
621     {
622     //Beginning of an exponent. This again
623     //means the mantissa is terminating. No issue.
624     i_mant_bdp_len = (arg - s) - i_mant_bdp;
625     state = 6;
626     }
627     else
628     {
629     //Unidentifiable crap. This is not OK.
630     //Error out.
631     *failure = 1;
632     goto term_seq;
633     }
634     break;
635     //A decimal point has been found in the string.
636     //This marks the end of the mantissa, for sure.
637     case 5 : if (!*arg)
638     {
639     //We've reached the end of the string. There are
640     //two possibilities here. Either there have been no
641     //digits before the decimal points, which is a no-no,
642     //or there have been digits, which is fine.
643     if (i_mant_bdp_len)
644     {
645     *failure = 0;
646     goto term_seq;
647     }
648     else
649     {
650     *failure = 1;
651     goto term_seq;
652     }
653     }
654     else if ((*arg >= '0') && (*arg <= '9'))
655     {
656     //Digits after the decimal point. Need to
657     //begin the portion after the decimal point.
658     i_mant_adp = arg - s;
659     state = 10;
660     }
661     else if ((*arg == 'e') || (*arg == 'E'))
662     {
663     //Beginning of an exponent. This means
664     //that have no digits after the decimal point.
665     //This is OK.
666     state = 6;
667     }
668     else
669     {
670     //Unidentifiable crap. This is not OK.
671     //Error out.
672     *failure = 1;
673     goto term_seq;
674     }
675     break;
676     //The exponent has begin.
677     case 6: if (!*arg)
678     {
679     //The string is empty. This is not OK
680     //because it would mean an E with nothing
681     //following it. This is a no-no.
682     //Error out.
683     *failure = 1;
684     goto term_seq;
685     }
686     else if (*arg == '-')
687     {
688     //Leading - on the exponent. Fine.
689     i_exp_sign = '-';
690     state = 8;
691     }
692     else if (*arg == '+')
693     {
694     //Leading + on the exponent. Fine.
695     i_exp_sign = '+';
696     state = 7;
697     }
698     else if ((*arg >= '0') && (*arg <= '9'))
699     {
700     //Beginning the digits of the exponent. Fine.
701     i_exp = arg - s;
702     state = 9;
703     }
704     else
705     {
706     //Unidentifiable crap. This is not OK.
707     //Error out.
708     *failure = 1;
709     goto term_seq;
710     }
711     break;
712    
713     //Had a + sign before the exponent. Now expecting digits.
714     case 7: if (!*arg)
715     {
716     //The string is empty. This is not OK
717     //because it would mean an E+ with nothing
718     //following it. This is a no-no.
719     //Error out.
720     *failure = 1;
721     goto term_seq;
722     }
723     else if ((*arg >= '0') && (*arg <= '9'))
724     {
725     //Beginning the digits of the exponent. Fine.
726     i_exp = arg - s;
727     state = 9;
728     }
729     else
730     {
731     //Unidentifiable crap. This is not OK.
732     //Error out.
733     *failure = 1;
734     goto term_seq;
735     }
736     break;
737     //Had a - sign before the exponent. Now expecting digits.
738     case 8: if (!*arg)
739     {
740     //The string is empty. This is not OK
741     //because it would mean an E- with nothing
742     //following it. This is a no-no.
743     //Error out.
744     *failure = 1;
745     goto term_seq;
746     }
747     else if ((*arg >= '0') && (*arg <= '9'))
748     {
749     //Beginning the digits of the exponent. Fine.
750     i_exp = arg - s;
751     state = 9;
752     }
753     else
754     {
755     //Unidentifiable crap. This is not OK.
756     //Error out.
757     *failure = 1;
758     goto term_seq;
759     }
760     break;
761     //Had one digit of exponent. Am processing remaining ones.
762     case 9 : if (!*arg)
763     {
764     //We've reached the end of the string. This is
765     //fine because we have an exponent of the
766     //form NNNN, +NNNN, or -NNNN. No problem with that.
767     i_exp_len = (arg - s) - i_exp;
768     *failure = 0;
769     goto term_seq;
770     }
771     else if ((*arg >= '0') && (*arg <= '9'))
772     {
773     //Yet more digits. Seems reasonable.
774     //The assignment isn't necessary, but it
775     //is aesthetic.
776     state = 9;
777     }
778     else
779     {
780     //Unidentifiable crap. This is not OK.
781     //Error out.
782     *failure = 1;
783     goto term_seq;
784     }
785     break;
786     //Processing digits after decimal point. This state is out
787     //of sequence because added it after on diagram.
788     case 10: if (!*arg)
789     {
790     //We've reached the end of the string. This is
791     //fine.
792     i_mant_adp_len = (arg - s) - i_mant_adp;
793     *failure = 0;
794     goto term_seq;
795     }
796     else if ((*arg >= '0') && (*arg <= '9'))
797     {
798     //Yet more digits. Seems reasonable.
799     //The assignment isn't necessary, but it
800     //is aesthetic.
801     state = 10;
802     }
803     else if ((*arg == 'e') || (*arg == 'E'))
804     {
805     //Beginning of an exponent. This terminates
806     //the digits after the decimal point.
807     i_mant_adp_len = (arg - s) - i_mant_adp;
808     state = 6;
809     }
810     else
811     {
812     //Unidentifiable crap. This is not OK.
813     //Error out.
814     *failure = 1;
815     goto term_seq;
816     }
817     break;
818     default:
819     abort();
820     break;
821     }
822    
823     arg++;
824     }
825    
826    
827     //This is the setup for returning to the caller. We can
828     //only fill in those data pointer for the caller that are
829     //not NULL.
830     term_seq:
831     if (mant_sign)
832     *mant_sign = i_mant_sign;
833     if (mant_bdp)
834     *mant_bdp = i_mant_bdp;
835     if (mant_bdp_len)
836     *mant_bdp_len = i_mant_bdp_len;
837     if (mant_adp)
838     *mant_adp = i_mant_adp;
839     if (mant_adp_len)
840     *mant_adp_len = i_mant_adp_len;
841     if (exp_sign)
842     *exp_sign = i_exp_sign;
843     if (exp)
844     *exp = i_exp;
845     if (exp_len)
846     *exp_len = i_exp_len;
847     }
848    
849    
850     //07/18/01: Has passed visual verification plus unit tests.
851     void BSTRFUNC_commanate(char *s)
852     {
853     int l;
854     int ncommas;
855     char *putpt, *getpt;
856     int ndigits;
857    
858     //Adds commas to a numeric string. The space
859     //must exist in the area passed.
860     assert(s);
861    
862     //If the leading character on the string is a
863     //'-', bump the pointer. Then everything
864     //else applies as for an unsigned.
865     if (*s == '-')
866     s++;
867    
868     //Be sure the string currently meets the syntax for
869     //a signed integer. If not, don't even touch it.
870     if (!BSTRFUNC_is_uint_wo_commas(s))
871     return;
872    
873     //Get the length of the current string.
874     l = strlen(s);
875    
876     //Let's agree, just in case something slipped through
877     //the cracks, that zero length strings are not of
878     //interest to us.
879     if (l==0)
880     return;
881    
882     //The number of commas to add is precisely
883     //(N-1) div 3.
884     if (l==0)
885     ncommas = 0;
886     else
887     ncommas = (l-1)/3;
888    
889     //Walk through the string, adding commas.
890     getpt = s + l - 1;
891     putpt = s + l + ncommas;
892    
893     *putpt = 0; //Write the zero terminator.
894     putpt--;
895    
896     ndigits = 0;
897    
898     while ((putpt > s) && (getpt > s))
899     {
900     *putpt = *getpt;
901     putpt--;
902     getpt--;
903     ndigits++;
904     if (((ndigits % 3) == 0) && (putpt != s))
905     {
906     *putpt = ',';
907     putpt--;
908     }
909     assert((putpt >= s) && (getpt>=s));
910     }
911     }
912    
913    
914     //07/28/01: Visual inspection only.
915     void BSTRFUNC_decommanate(char *s)
916     {
917     char *src, *dst;
918    
919     assert(s != NULL);
920    
921     src = dst = s;
922    
923     while(1)
924     {
925     if (!*src)
926     {
927     *dst = 0;
928     break;
929     }
930     else if (*src == ',')
931     {
932     src++;
933     }
934     else
935     {
936     *dst = *src;
937     src++;
938     dst++;
939     }
940     }
941     }
942    
943    
944     void BSTRFUNC_parse_str_to_uint32(const char *s,
945     unsigned int *rv,
946     int *error)
947     {
948     unsigned _int64 temp;
949     int digval;
950    
951     //Eyeball the input arguments.
952     assert(s != NULL);
953     assert(error != NULL);
954    
955     //Start off believing there is no error.
956     *error = 0;
957    
958     //The string has to parse out as an unsigned integer or an
959     //unsigned integer with commas, or we won't touch it.
960     if (!BSTRFUNC_is_uint_wo_commas(s) && !BSTRFUNC_is_uint_w_commas(s))
961     {
962     *error = 1;
963     return;
964     }
965    
966     //OK, we know we have an unsigned integer, either without commas,
967     //or with properly placed commas. Our only worry now is that it
968     //is of a size that will fit in 32 bits. The way we can deal with
969     //this is to format it into 64 bits and watch for overflow.
970     temp = 0;
971    
972     while (*s)
973     {
974     digval = CHARFUNC_digit_to_val(*s);
975     if (digval >= 0)
976     {
977     temp *= 10;
978     temp += digval;
979     if ((temp >> 32) & 0xFFFFFFFF)
980     {
981     //We've had an overflow.
982     *error = 1;
983     return;
984     }
985     }
986     s++;
987     }
988    
989     *rv = (unsigned int)temp;
990     }
991    
992    
993     const char *BSTRFUNC_cvcinfo(void)
994     {
995     return("$Header$");
996     }
997    
998    
999     const char *BSTRFUNC_hvcinfo(void)
1000     {
1001     return(BSTRFUNC_H_VERSION);
1002     }
1003    
1004     //End of bstrfunc.c.

Properties

Name Value
svn:eol-style native
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25