4 * Revision 1.1 2001/04/04 05:43:37 wang
5 * First commit: compiles on Linux, Amiga, Windows, Windows CE, generic gcc
7 * Revision 1.3 1999/11/26 12:52:25 bnv
8 * Added: Windows CE support
9 * Added: Lwscpy, for unicode string copy
10 * Changed: _Lisnum, it creates immediately a double number contained in
11 * the string, for faster access. The value is hold in lLastScannedNumber
13 * Revision 1.2 1999/05/14 13:11:47 bnv
16 * Revision 1.1 1998/07/02 17:18:00 bnv
30 /* ================= Lstring routines ================== */
32 /* -------------------- Linit ---------------- */
34 Linit( LerrorFunc Lerr
)
38 /* setup error function */
49 for (i
=0; i
<256; i
++) u2l
[i
] = l2u
[i
] = i
;
50 for (i
=0; clower
[i
]; i
++) {
51 l2u
[ (byte
)clower
[i
] & 0xFF ] = cUPPER
[i
];
52 u2l
[ (byte
)cUPPER
[i
] & 0xFF ] = clower
[i
];
59 /* -------------- _Lfree ------------------- */
66 /* ---------------- Lfx -------------------- */
68 Lfx( const PLstr s
, const size_t len
)
73 LSTR(*s
) = (char *) MALLOC( (max
= LNORMALISE(len
))+LEXTRA
, "Lstr" );
76 LTYPE(*s
) = LSTRING_TY
;
82 if (!LOPTION(*s
,LOPTFIX
) && LMAXLEN(*s
)<len
) {
83 LSTR(*s
) = (char *) REALLOC( LSTR(*s
), (max
=LNORMALISE(len
))+LEXTRA
);
87 if (LMAXLEN(*s
)<len
) {
88 LSTR(*s
) = (char *) REALLOC( LSTR(*s
), (max
=LNORMALISE(len
))+LEXTRA
);
94 /* ---------------- Licpy ------------------ */
96 Licpy( const PLstr to
, const long from
)
98 LLEN(*to
) = sizeof(long);
99 LTYPE(*to
) = LINTEGER_TY
;
103 /* ---------------- Lrcpy ------------------ */
105 Lrcpy( const PLstr to
, const double from
)
107 LLEN(*to
) = sizeof(double);
108 LTYPE(*to
) = LREAL_TY
;
112 /* ---------------- Lscpy ------------------ */
114 Lscpy( const PLstr to
, const char *from
)
121 Lfx(to
,len
= STRLEN(from
));
122 MEMCPY( LSTR(*to
), from
, len
);
125 LTYPE(*to
) = LSTRING_TY
;
129 /* ---------------- Lwscpy ------------------ */
131 Lwscpy(const PLstr to
, const wchar_t *from
)
138 Lfx(to
,len
= wcslen(from
));
139 wcstombs(LSTR(*to
), from
,len
);
142 LTYPE(*to
) = LSTRING_TY
;
146 /* ---------------- Lcat ------------------- */
148 Lcat( const PLstr to
, const char *from
)
152 if (from
==NULL
) return;
158 l
=LLEN(*to
) + STRLEN(from
);
159 if (LMAXLEN(*to
)<l
) Lfx(to
,l
);
160 STRCPY( LSTR(*to
) + LLEN(*to
), from
);
165 /* ------------------ Lcmp ------------------- */
167 Lcmp( const PLstr a
, const char *b
)
174 if ( (r
=MEMCMP( LSTR(*a
), b
, MIN(LLEN(*a
),blen
)))!=0 )
180 if (LLEN(*a
) == blen
)
187 /* ---------------- Lstrcpy ----------------- */
189 Lstrcpy( const PLstr to
, const PLstr from
)
191 if (LLEN(*from
)==0) {
193 LTYPE(*to
) = LSTRING_TY
;
195 if (LMAXLEN(*to
)<=LLEN(*from
)) Lfx(to
,LLEN(*from
));
196 switch ( LTYPE(*from
) ) {
198 MEMCPY( LSTR(*to
), LSTR(*from
), LLEN(*from
) );
202 LINT(*to
) = LINT(*from
);
206 LREAL(*to
) = LREAL(*from
);
209 LTYPE(*to
) = LTYPE(*from
);
210 LLEN(*to
) = LLEN(*from
);
214 /* ----------------- Lstrcat ------------------ */
216 Lstrcat( const PLstr to
, const PLstr from
)
219 if (LLEN(*from
)==0) return;
229 l
= LLEN(*to
)+LLEN(*from
);
230 if (LMAXLEN(*to
) <= l
)
232 MEMCPY( LSTR(*to
) + LLEN(*to
), LSTR(*from
), LLEN(*from
) );
236 /* ----------------- _Lstrcmp ----------------- */
237 /* -- Low level strcmp, suppose that both of -- */
238 /* -- are of the same type */
240 _Lstrcmp( const PLstr a
, const PLstr b
)
244 if ( (r
=MEMCMP( LSTR(*a
), LSTR(*b
), MIN(LLEN(*a
),LLEN(*b
))))!=0 )
247 if (LLEN(*a
) > LLEN(*b
))
250 if (LLEN(*a
) == LLEN(*b
)) {
251 if (LTYPE(*a
) > LTYPE(*b
))
254 if (LTYPE(*a
) < LTYPE(*b
))
262 /* ----------------- Lstrcmp ------------------ */
264 Lstrcmp( const PLstr a
, const PLstr b
)
271 if ( (r
=MEMCMP( LSTR(*a
), LSTR(*b
), MIN(LLEN(*a
),LLEN(*b
))))!=0 )
274 if (LLEN(*a
) > LLEN(*b
))
277 if (LLEN(*a
) == LLEN(*b
))
284 /* ----------------- Lstrset ------------------ */
286 Lstrset( const PLstr to
, const size_t length
, const char value
)
289 LTYPE(*to
) = LSTRING_TY
;
291 MEMSET(LSTR(*to
),value
,length
);
294 /* ----------------- _Lsubstr ----------------- */
295 /* WARNING!!! length is size_t type DO NOT PASS A NEGATIVE value */
297 _Lsubstr( const PLstr to
, const PLstr from
, size_t start
, size_t length
)
302 if ((length
==0) || (length
+start
>LLEN(*from
)))
303 length
= LLEN(*from
) - start
;
305 if (start
<LLEN(*from
)) {
306 if (LMAXLEN(*to
)<length
) Lfx(to
,length
);
307 MEMCPY( LSTR(*to
), LSTR(*from
)+start
, length
);
311 LTYPE(*to
) = LSTRING_TY
;
314 /* ------------------------ _Lisnum ----------------------- */
315 /* _Lisnum - returns if it is possible to convert */
316 /* a LSTRING to NUMBER */
317 /* a LREAL_TY or LINTEGER_TY */
318 /* There is one possibility that is missing... */
319 /* that is to hold an integer number as a real in a string. */
320 /* ie. ' 2.0 ' this should be LINTEGER not LREAL */
321 /* -------------------------------------------------------- */
323 _Lisnum( const PLstr s
)
333 lLastScannedNumber
= 0.0;
337 if (LOPT(*s) & (LOPTINT | LOPTREAL)) {
338 if (LOPT(*s) & LOPTINT)
347 if (ch
==NULL
) return LSTRING_TY
;
348 LASCIIZ(*s
); /* ///// Remember to erase LASCIIZ
349 ///// before all the calls to Lisnum */
351 /* skip leading spaces */
352 while (ISSPACE(*ch
)) ch
++;
354 /* accept one sign */
364 /* skip following spaces after sign */
365 while (ISSPACE(*ch
)) ch
++;
367 /* accept many digits */
370 lLastScannedNumber
= 0.0;
375 if (IN_RANGE('0',*ch
,'9')) {
376 lLastScannedNumber
= lLastScannedNumber
*10.0 + (*ch
-'0');
379 while (IN_RANGE('0',*ch
,'9')) {
380 lLastScannedNumber
= lLastScannedNumber
*10.0 + (*ch
-'0');
383 if (!*ch
) goto isnumber
;
392 /* accept many digits */
393 if (IN_RANGE('0',*ch
,'9')) {
394 lLastScannedNumber
= lLastScannedNumber
*10.0 + (*ch
-'0');
397 while (IN_RANGE('0',*ch
,'9')) {
398 lLastScannedNumber
= lLastScannedNumber
*10.0 + (*ch
-'0');
403 if (!F
) return LSTRING_TY
;
405 if (!*ch
) goto isnumber
;
407 if (!F
) return LSTRING_TY
;
410 /* accept on 'e' or 'E' */
411 if (*ch
=='e' || *ch
=='E') {
414 /* accept one sign */
422 /* accept many digits */
423 if (IN_RANGE('0',*ch
,'9')) {
424 exponent
= exponent
*10+(*ch
-'0');
426 while (IN_RANGE('0',*ch
,'9')) {
427 exponent
= exponent
*10+(*ch
-'0');
434 /* accept many blanks */
435 while (ISSPACE(*ch
)) ch
++;
437 /* is it end of string */
438 if (*ch
) return LSTRING_TY
;
441 if (expsign
) exponent
= -exponent
;
443 exponent
-= fractionDigits
;
447 lLastScannedNumber
*= pow10(exponent
);
449 lLastScannedNumber
*= pow(10.0,(double)exponent
);
452 if (lLastScannedNumber
>MAXLONG
)
453 R
= TRUE
; /* Treat it as real number */
456 lLastScannedNumber
= -lLastScannedNumber
;
458 if (R
) return LREAL_TY
;
463 /* ------------------ L2str ------------------- */
465 L2str( const PLstr s
)
467 if (LTYPE(*s
)==LINTEGER_TY
) {
468 #if defined(WCE) || defined(__BORLANDC__)
469 LTOA(LINT(*s
),LSTR(*s
),10);
471 sprintf(LSTR(*s
), "%ld", LINT(*s
));
473 LLEN(*s
) = STRLEN(LSTR(*s
));
474 } else { /* LREAL_TY */
475 /*//// sprintf(LSTR(*s), lFormatStringToReal, LREAL(*s)); */
476 GCVT(LREAL(*s
),lNumericDigits
,LSTR(*s
));
479 /* --- remove the last dot from the number --- */
480 size_t len
= STRLEN(LSTR(*s
));
481 if (LSTR(*s
)[len
-1] == '.') len
--;
485 LLEN(*s
) = STRLEN(LSTR(*s
));
488 LTYPE(*s
) = LSTRING_TY
;
491 /* ------------------ L2int ------------------- */
493 L2int( const PLstr s
)
495 if (LTYPE(*s
)==LREAL_TY
) {
496 if ((double)((long)LREAL(*s
)) == LREAL(*s
))
497 LINT(*s
) = (long)LREAL(*s
);
499 Lerror(ERR_INVALID_INTEGER
,0);
500 } else { /* LSTRING_TY */
502 switch (_Lisnum(s
)) {
504 /*///LINT(*s) = atol( LSTR(*s) ); */
505 LINT(*s
) = (long)lLastScannedNumber
;
509 /*///LREAL(*s) = strtod( LSTR(*s), NULL ); */
510 LREAL(*s
) = lLastScannedNumber
;
511 if ((double)((long)LREAL(*s
)) == LREAL(*s
))
512 LINT(*s
) = (long)LREAL(*s
);
514 Lerror(ERR_INVALID_INTEGER
,0);
518 Lerror(ERR_INVALID_INTEGER
,0);
521 LTYPE(*s
) = LINTEGER_TY
;
522 LLEN(*s
) = sizeof(long);
525 /* ------------------ L2real ------------------- */
527 L2real( const PLstr s
)
529 if (LTYPE(*s
)==LINTEGER_TY
)
530 LREAL(*s
) = (double)LINT(*s
);
531 else { /* LSTRING_TY */
533 if (_Lisnum(s
)!=LSTRING_TY
)
534 /*/////LREAL(*s) = strtod( LSTR(*s), NULL ); */
535 LREAL(*s
) = lLastScannedNumber
;
537 Lerror(ERR_BAD_ARITHMETIC
,0);
539 LTYPE(*s
) = LREAL_TY
;
540 LLEN(*s
) = sizeof(double);
543 /* ------------------- _L2num -------------------- */
544 /* this function is used when we know to what type */
545 /* we should change the string */
547 _L2num( const PLstr s
, const int type
)
552 /*////LINT(*s) = atol( LSTR(*s) ); */
553 LINT(*s
) = (long)lLastScannedNumber
;
554 LTYPE(*s
) = LINTEGER_TY
;
555 LLEN(*s
) = sizeof(long);
559 /*////LREAL(*s) = strtod( LSTR(*s), NULL ); */
560 LREAL(*s
) = lLastScannedNumber
;
561 if ((double)((long)LREAL(*s
)) == LREAL(*s
)) {
562 LINT(*s
) = (long)LREAL(*s
);
563 LTYPE(*s
) = LINTEGER_TY
;
564 LLEN(*s
) = sizeof(long);
566 LTYPE(*s
) = LREAL_TY
;
567 LLEN(*s
) = sizeof(double);
571 Lerror(ERR_BAD_ARITHMETIC
,0);
575 /* ------------------ L2num ------------------- */
577 L2num( const PLstr s
)
579 switch (_Lisnum(s
)) {
581 /*//LINT(*s) = atol( LSTR(*s) ); */
582 LINT(*s
) = (long)lLastScannedNumber
;
583 LTYPE(*s
) = LINTEGER_TY
;
584 LLEN(*s
) = sizeof(long);
588 /*///LREAL(*s) = strtod( LSTR(*s), NULL ); */
589 LREAL(*s
) = lLastScannedNumber
;
591 //// Numbers like 2.0 should be treated as real and not as integer
592 //// because in cases like factorial while give an error result
593 //// if ((double)((long)LREAL(*s)) == LREAL(*s)) {
594 //// LINT(*s) = (long)LREAL(*s);
595 //// LTYPE(*s) = LINTEGER_TY;
596 //// LLEN(*s) = sizeof(long);
599 LTYPE(*s
) = LREAL_TY
;
600 LLEN(*s
) = sizeof(double);
607 Lerror(ERR_BAD_ARITHMETIC
,0);
611 /* ----------------- Lrdint ------------------ */
613 Lrdint( const PLstr s
)
615 if (LTYPE(*s
)==LINTEGER_TY
) return LINT(*s
);
617 if (LTYPE(*s
)==LREAL_TY
) {
618 if ((double)((long)LREAL(*s
)) == LREAL(*s
))
619 return (long)LREAL(*s
);
621 Lerror(ERR_INVALID_INTEGER
,0);
622 } else { /* LSTRING_TY */
624 switch (_Lisnum(s
)) {
626 /*///return atol( LSTR(*s) ); */
627 return (long)lLastScannedNumber
;
630 /*///d = strtod( LSTR(*s), NULL );
631 //////if ((double)((long)d) == d)
632 ////// return (long)d; */
633 if ((double)((long)lLastScannedNumber
) == lLastScannedNumber
)
634 return (long)lLastScannedNumber
;
636 Lerror(ERR_INVALID_INTEGER
,0);
640 Lerror(ERR_INVALID_INTEGER
,0);
643 return 0; /* never gets here but keeps compiler happy */
646 /* ----------------- Lrdreal ------------------ */
648 Lrdreal( const PLstr s
)
650 if (LTYPE(*s
)==LREAL_TY
) return LREAL(*s
);
652 if (LTYPE(*s
)==LINTEGER_TY
)
653 return (double)LINT(*s
);
654 else { /* LSTRING_TY */
656 if (_Lisnum(s
)!=LSTRING_TY
)
657 /*///// return strtod( LSTR(*s), NULL ); */
658 return lLastScannedNumber
;
660 Lerror(ERR_BAD_ARITHMETIC
,0);