3 Copyright (C) 2008 Lutz Mueller
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 extern SYMBOL
* sysSymbol
[];
28 #define OVECCOUNT (MAX_REGEX_EXP * 3) /* max sub expressions in PCRE */
30 void regexError(char * msg_1
, int num
, const char * msg_2
);
31 pcre
* pcreCachedCompile(char * pattern
, int options
);
33 CELL
* cellTokenString(char * *source
, size_t * srclen
, char *separator
, pcre
*re
);
35 #ifdef USE_WIN_UTF16PATH
36 int open_utf16(const char* a
, int b
, int c
);
39 /* ---------------------------- string processing ----------------------- */
41 int my_strnicmp(char * s1
, char * s2
, ssize_t size
)
43 while(toupper(*s1
) == toupper(*s2
))
45 if(--size
<= 0) return(0);
48 return(toupper(*s1
) - toupper(*s2
));
52 CELL
* substring(char * string
, ssize_t slen
, ssize_t offset
, ssize_t len
)
56 offset
= slen
+ offset
;
57 if(offset
< 0) offset
= 0;
60 offset
= (offset
> slen
) ? slen
: offset
;
64 len
= slen
- offset
+ len
;
71 len
= ((offset
+ len
) > slen
) ? (slen
- offset
) : len
;
73 return(stuffStringN(string
+ offset
, len
));
76 #define SEARCH_SIZE 0x1000
78 CELL
* p_search(CELL
* params
)
92 ssize_t foundPosition
;
100 params
= getInteger(params
, (UINT
*)&fileHandle
);
101 params
= getStringSize(params
, &searchString
, &len
, TRUE
);
102 if(len
== 0) return(nilCell
);
105 if(params
!= nilCell
)
108 params
= evaluateExpression(params
);
109 if(isNumber(params
->type
))
110 getIntegerExt(params
, (UINT
*)&options
, FALSE
);
113 flag
= (params
->type
!= CELL_NIL
);
115 getInteger(next
, (UINT
*)&options
);
119 buffer
= (char *)allocMemory(SEARCH_SIZE
+ 1);
120 if((filePosition
= lseek((int)fileHandle
, 0, SEEK_CUR
)) == -1)
127 memset(buffer
, 0, SEARCH_SIZE
+ 1);
128 bytesRead
= read((int)fileHandle
, buffer
, SEARCH_SIZE
);
131 position
= searchBuffer(buffer
, bytesRead
, searchString
, len
, 1);
133 position
= searchBufferRegex(buffer
, 0, searchString
, (int)bytesRead
, options
, (int *)&len
);
138 foundPosition
= filePosition
+ position
+ len
;
140 foundPosition
= filePosition
+ position
;
144 filePosition
= filePosition
+ bytesRead
- len
;
145 lseek((int)fileHandle
, filePosition
, SEEK_SET
);
146 } while (bytesRead
== SEARCH_SIZE
);
150 if(position
== -1) return(nilCell
);
152 lseek((int)fileHandle
, foundPosition
, SEEK_SET
);
154 result
= foundPosition
;
155 return(stuffFloat(&result
));
157 return(stuffInteger(foundPosition
));
163 CELL
* implicitIndexString(CELL
* cell
, CELL
* params
)
173 ptr
= (char*)cell
->contents
;
174 getInteger(params
, (UINT
*)&index
);
177 index
= adjustNegativeIndex(index
, cell
->aux
- 1);
178 str
[0] = *(ptr
+ index
);
180 return(stuffString(str
));
182 index
= adjustNegativeIndex(index
, utf8_wlen(ptr
));
183 for(i
= 0; i
< index
; i
++)
185 p
= utf8_1st_len(ptr
);
188 return(stuffStringN(ptr
, utf8_1st_len(ptr
)));
193 CELL
* p_char(CELL
* params
)
203 datCell
= evaluateExpression(params
);
204 switch(datCell
->type
)
207 string
= (char *)datCell
->contents
;
210 len
= (size_t)datCell
->aux
- 1;
212 len
= utf8_wlen(string
);
215 if(params
->next
!= nilCell
)
216 getInteger(params
->next
, (UINT
*)&offset
);
219 offset
= adjustNegativeIndex(offset
, len
);
222 return(stuffInteger((UINT
)*((unsigned char *)string
+ (UINT
)offset
)));
225 buff
[0] = (int)datCell
->contents
;
229 num
= *(INT64
*)&datCell
->aux
;
233 num
= *(double*)&datCell
->aux
;
235 #else /* NEWLISP64 */
237 num
= *(double*)&datCell
->contents
;
239 #endif /* NEWLISP64 */
243 #else /* SUPPORT_UTF8 */
244 while(offset
--) string
+= utf8_1st_len(string
);
245 utf8_wchar(string
, &num
);
246 return(stuffInteger(num
));
252 string
= allocMemory(UTF8_MAX_BYTES
+ 1);
253 if(datCell
->type
== CELL_FLOAT
)
254 num
= *(double*)&datCell
->aux
;
255 else if(datCell
->type
== CELL_INT64
)
256 num
= *(INT64
*)&datCell
->aux
;
258 num
= datCell
->contents
;
259 #else /* NEWLISP64 */
262 string
= allocMemory(UTF8_MAX_BYTES
+ 1);
263 if(datCell
->type
== CELL_FLOAT
)
264 num
= *(double*)&datCell
->contents
;
266 num
= (int)datCell
->contents
;
267 #endif /* NEWLISP 64 */
268 len
= wchar_utf8(num
, string
);
269 datCell
= stuffStringN(string
, len
);
272 #endif /* SUPPORT_UTF8 */
277 return(stuffStringN(buff
, 1));
281 CELL
* p_explode(CELL
* params
)
293 cell
= evaluateExpression(params
);
294 if(isList(cell
->type
))
295 return(explodeList((CELL
*)cell
->contents
, params
->next
));
297 getStringSize(cell
, &string
, (size_t *)&size
, TRUE
);
298 if(params
->next
!= nilCell
)
300 params
= getInteger(params
->next
, (UINT
*)&len
);
301 flag
= getFlag(params
);
302 if(!flag
&& len
> size
) len
= size
;
305 result
= cell
= getCell(CELL_EXPRESSION
);
306 if(size
== 0 || len
<= 0) return(result
);
309 if(flag
&& size
< len
) return(result
);
311 cell
->contents
= (UINT
)stuffStringN(string
, len
);
312 cell
= (CELL
*)cell
->contents
;
315 while((size
-= len
) > 0)
317 if(flag
&& size
< len
) break;
318 cell
->next
= stuffStringN(string
, (size
>= len
) ? len
: size
);
323 size
= utf8_wlen(string
);
324 for(i
= 0, clen
= 0; i
< len
; i
++)
325 clen
+= utf8_1st_len(string
+ clen
);
327 if(flag
&& size
< len
) return(result
);
329 cell
->contents
= (UINT
)stuffStringN(string
, clen
);
330 cell
= (CELL
*)cell
->contents
;
332 while((size
-= len
) > 0)
334 if(flag
&& size
< len
) break;
335 for(i
= 0, clen
= 0; i
< len
; i
++)
336 clen
+= utf8_1st_len(string
+ clen
);
337 cell
->next
= stuffStringN(string
, clen
);
352 CELL
* strUpperLower(CELL
* params
, int type
)
367 params
= getString(params
, &string
);
368 if(params
!= nilCell
)
370 params
= evaluateExpression(params
);
371 if(params
->contents
!= (UINT
)nilCell
)
375 cell
= stuffString(string
);
376 ptr
= (void *)cell
->contents
;
378 if(type
== STR_UPPER
)
379 while(*ptr
) { *ptr
= toupper(*ptr
); ptr
++; }
382 if(type
== STR_TITLE
)
383 if(*ptr
) { *ptr
= toupper(*ptr
); ptr
++; }
384 if(((type
== STR_TITLE
) && option
) || (type
== STR_LOWER
))
385 while(*ptr
) { *ptr
= tolower(*ptr
); ptr
++; }
389 params
= getString(params
, &utf8str
);
390 option
= getFlag(params
);
392 size
= utf8_wlen(utf8str
);
394 unicode
= allocMemory((size
+ 1) * sizeof(int));
395 size
= utf8_wstr(unicode
, utf8str
, size
);
399 /* Note that on many platforms towupper/towlower
400 do not work correctly for non-ascii unicodes */
402 if(type
== STR_UPPER
)
403 while(*ptr
) { *ptr
= towupper(*ptr
); ptr
++; }
406 if(type
== STR_TITLE
)
407 if(*ptr
) { *ptr
= towupper(*ptr
); ptr
++; }
408 if(((type
== STR_TITLE
) && option
) || (type
== STR_LOWER
))
409 while(*ptr
) { *ptr
= towlower(*ptr
); ptr
++; }
412 utf8str
= allocMemory(size
* UTF8_MAX_BYTES
+ 1);
413 size
= wstr_utf8(utf8str
, unicode
, size
* UTF8_MAX_BYTES
+ 1);
414 utf8str
= reallocMemory(utf8str
, size
+ 1);
417 cell
= getCell(CELL_STRING
);
418 cell
->contents
= (UINT
)utf8str
;
419 cell
->aux
= size
+ 1;
425 CELL
* p_upper(CELL
* params
) {return(strUpperLower(params
, STR_UPPER
));}
426 CELL
* p_lower(CELL
* params
) {return(strUpperLower(params
, STR_LOWER
));}
427 CELL
* p_title(CELL
* params
) {return(strUpperLower(params
, STR_TITLE
));}
429 char * getFormatType(char * fmt
, int * type
)
434 while(*fmt
!= '%' && *fmt
!= 0) fmt
++;
442 /* is it double %% for '%' */
451 /* force + before numbers */
456 /* left align numbers or strings */
460 /* force + before numbers */
461 if(*fmt
== '+') fmt
++;
465 while(isdigit((int)*fmt
) && *fmt
!= 0) fmt
++;
466 if(*fmt
== 0) return(NULL
);
468 /* its a float or string with dot precision*/
472 while(isdigit((int)*fmt
) && *fmt
!=0) fmt
++;
473 if(*fmt
== 0) return(NULL
);
475 if(*fmt
== 'f' || *fmt
== 'g' || *fmt
=='G' || *fmt
== 'e' || *fmt
== 'E')
488 /* its a float without dot */
489 if(*fmt
== 'f' || *fmt
== 'g' || *fmt
=='G' || *fmt
== 'e' || *fmt
== 'E')
495 /* its an integer or character */
497 if(*fmt
== 'd' || *fmt
== 'i' || *fmt
== 'u' || *fmt
== 'x' || *fmt
== 'X' || *fmt
== 'c' || *fmt
== 'o')
499 if(*fmt
== 'd' || *fmt
== 'u' || *fmt
== 'x' || *fmt
== 'X' || *fmt
== 'c' || *fmt
== 'o')
522 #ifdef TRU64 /* supporting ld, li, lu, lx, lX formats */
524 (*(fmt
+ 1) == 'd' || *(fmt
+ 1) == 'i' || *(fmt
+ 1) == 'u' || *(fmt
+ 1) =='x' || *(fmt
+ 1) == 'X'))
533 #else /* all other UNIX suporting lld, llu, llx, llX formats */
534 if(*fmt
== 'l' && *(fmt
+ 1) == 'l' &&
535 (*(fmt
+ 2) == 'd' || *(fmt
+ 2) == 'u' || *(fmt
+ 2) =='x' || *(fmt
+ 2) == 'X'))
545 #else /* MinGW uses MS conventions */
546 if(memcmp(fmt
, "I64", 3) == 0 &&
547 (*(fmt
+ 3) == 'd' || *(fmt
+ 3) == 'u' || *(fmt
+ 3) =='x' || *(fmt
+ 3) == 'X'))
554 /* L and q seem not to be suported on most GCC although in the docs
555 if(*fmt == 'L' && (*(fmt + 1) == 'd' || *(fmt + 1) =='x' || *(fmt + 1) == 'X'))
562 /* its a wchar_t unicode string */
563 if(*fmt
== 'l' && *(fmt
+ 1) == 's')
572 CELL
* p_format(CELL
* params
)
588 params
= getString(params
, &format
);
591 openStrStream(&fmtStream
, MAX_STRING
, 0);
593 while(params
->type
!= CELL_NIL
)
595 /* printf("entry>%s<\n", fmt); */
596 nextfmt
= getFormatType(fmt
, &fType
);
597 /* printf("exit>%s<\n", nextfmt); */
601 closeStrStream(&fmtStream
);
602 return(errorProcExt2(ERR_FORMAT_STRING
, stuffString(format
)));
609 cell
= evaluateExpression(params
);
613 if(cell
->type
== CELL_EXPRESSION
&& fmt
== format
)
615 params
= (CELL
*)cell
->contents
;
623 closeStrStream(&fmtStream
);
624 return(errorProcExt(ERR_FORMAT_NUM_ARGS
, params
));
627 if(fType
== CELL_LONG
)
629 if(isNumber(cell
->type
))
630 cell
= getIntegerExt(cell
, &intNum
, FALSE
);
631 else goto FORMAT_DATA_ERROR
;
633 varPrintf((UINT
)&fmtStream
, fmt
, intNum
);
637 if(fType
== CELL_INT64
)
639 if(isNumber(cell
->type
))
640 cell
= getInteger64(cell
, &bigNum
);
641 else goto FORMAT_DATA_ERROR
;
643 varPrintf((UINT
)&fmtStream
, fmt
, bigNum
);
647 if(fType
== CELL_FLOAT
)
649 if(cell
->type
== CELL_FLOAT
)
651 floatNum
= *(double *)&cell
->aux
;
652 else if(cell
->type
== CELL_INT64
)
653 floatNum
= *(INT64
*)&cell
->aux
;
655 floatNum
= *(double *)&cell
->contents
;
657 else if(cell
->type
== CELL_LONG
)
658 floatNum
= (long)cell
->contents
;
659 else goto FORMAT_DATA_ERROR
;
661 varPrintf((UINT
)&fmtStream
, fmt
, floatNum
);
665 if(fType
!= cell
->type
)
666 goto FORMAT_DATA_ERROR
;
668 /* printf("stream>%s< with >%s<\n", (char *)cell->contents, fmt); */
669 varPrintf((UINT
)&fmtStream
, fmt
, cell
->contents
);
674 params
= params
->next
;
679 closeStrStream(&fmtStream
);
680 return(errorProcExt(ERR_FORMAT_DATA_TYPE
, params
));
683 getFormatType(fmt
, &fType
);
686 closeStrStream(&fmtStream
);
687 errorProcExt2(ERR_FORMAT_NUM_ARGS
, stuffString(format
));
690 varPrintf((UINT
)&fmtStream
, fmt
);
691 /* writeStreamStr(&fmtStream, fmt, 0); */
693 cell
= getCell(CELL_STRING
);
694 cell
->aux
= fmtStream
.position
+ 1;
695 cell
->contents
= (UINT
)fmtStream
.buffer
;
700 void openStrStream(STREAM
* stream
, size_t buffSize
, int reopenFlag
)
702 if(stream
->buffer
!= NULL
&& reopenFlag
)
703 freeMemory(stream
->buffer
);
704 stream
->buffer
= stream
->ptr
= callocMemory(buffSize
+ 1);
705 stream
->size
= buffSize
;
706 stream
->position
= stream
->handle
= 0;
709 void closeStrStream(STREAM
* stream
)
711 if(stream
->buffer
!= NULL
)
712 freeMemory(stream
->buffer
);
713 stream
->buffer
= stream
->ptr
= NULL
;
714 stream
->size
= stream
->position
= 0;
715 if(stream
->handle
!= 0)
717 close((int)stream
->handle
);
723 void writeStreamChar(STREAM
* stream
, char chr
)
725 if(stream
->position
== stream
->size
)
727 stream
->size
+= stream
->size
/ 2;
728 stream
->buffer
= reallocMemory(stream
->buffer
, stream
->size
+ 1);
729 memset(stream
->buffer
+ stream
->position
, 0, stream
->size
- stream
->position
+ 1);
730 stream
->ptr
= stream
->buffer
+ stream
->position
;
732 *(stream
->ptr
++) = chr
;
737 void writeStreamStr(STREAM
* stream
, char * buff
, size_t length
)
741 if(length
== 0) length
= strlen(buff
);
742 newPosition
= stream
->position
+ length
;
744 if(newPosition
>= stream
->size
)
746 while(newPosition
>= stream
->size
)
747 stream
->size
+= stream
->size
/ 2;
748 stream
->buffer
= reallocMemory(stream
->buffer
, stream
->size
+ 1);
749 memset(stream
->buffer
+ stream
->position
, 0, stream
->size
- stream
->position
+ 1);
750 stream
->ptr
= stream
->buffer
+ stream
->position
;
753 memcpy(stream
->ptr
, buff
, length
);
754 stream
->ptr
+= length
;
755 stream
->position
= newPosition
;
759 /* creates a memory buffer and reads byte into it until
763 char * readStreamText(STREAM
* stream
, char * limit
)
766 ssize_t findPos
= -1;
768 size_t llen
= strlen(limit
);
771 memset(&outStream
, 0, sizeof(STREAM
));
772 openStrStream(&outStream
, MAX_STRING
, 0);
775 if((searchLen
= strlen(stream
->ptr
)) < llen
)
777 findPos
= searchBuffer(stream
->ptr
, searchLen
, limit
, llen
, TRUE
);
781 writeStreamStr(&outStream
, stream
->ptr
, findPos
);
782 stream
->ptr
+= findPos
+ llen
;
783 result
= allocMemory(outStream
.position
+ 1);
784 memcpy(result
, outStream
.buffer
, outStream
.position
);
785 *(result
+ outStream
.position
) = 0;
786 closeStrStream(&outStream
);
790 writeStreamStr(&outStream
, stream
->ptr
, searchLen
- llen
);
792 /* adjustment for the first time, after it will be 0 always */
793 stream
->position
+= (stream
->ptr
- stream
->buffer
);
795 stream
->position
+= searchLen
- llen
;
797 if(stream
->handle
== 0) /* its not a file */
799 stream
->buffer
= stream
->ptr
;
804 lseek(stream
->handle
, stream
->position
, SEEK_SET
);
805 memset(stream
->buffer
, 0, stream
->size
+ 1);
806 if(read(stream
->handle
, stream
->buffer
, stream
->size
) > 0)
807 stream
->ptr
= stream
->buffer
;
816 closeStrStream(&outStream
);
822 /* this is only used for reading with getToken()
823 stream->size does not reflect the real size of
824 the buffer as in makeStreamFromFile()
826 void makeStreamFromString(STREAM
* stream
, char * str
)
828 memset(stream
, 0, sizeof(STREAM
));
829 stream
->buffer
= stream
->ptr
= str
;
830 /* make getToken work to the end of str */
831 stream
->size
= strlen(str
) + 4 * MAX_STRING
;
834 int makeStreamFromFile(STREAM
* stream
, char * fileName
, size_t size
, size_t offset
)
836 if((stream
->handle
= open(fileName
, O_RDONLY
| O_BINARY
, 0)) == -1)
839 stream
->ptr
= stream
->buffer
= (char *)callocMemory(size
+ 1);
841 lseek((int)stream
->handle
, offset
, SEEK_SET
);
843 stream
->position
= offset
;
846 /* load first buffer */
847 if(read(stream
->handle
, stream
->buffer
, size
) <= 0)
849 closeStrStream(stream
);
857 ssize_t
searchBuffer(char * buffer
, size_t length
, char * string
, size_t size
, int caseFlag
)
861 if(caseFlag
== FALSE
)
863 while(position
< length
)
865 if(toupper(*buffer
) == toupper(*string
))
866 if(my_strnicmp(buffer
, string
, size
) == 0) break;
871 else /* case sensitive */
873 while(position
< length
)
875 if(*buffer
== *string
)
876 if(memcmp(buffer
, string
, size
) == 0) break;
882 if(position
== length
) return(-1);
886 /* eliminated in v.8.4.1
887 CELL * patternMatchS(char * pattern, char * string)
895 start = string; starLen = len = 0;
901 if(*pattern != *string) return(nilCell);
904 if(*string != 0) return(nilCell);
905 return(stuffStringN(start, len));
907 if(*string == 0) return(nilCell);
910 if(*string == 0) return(nilCell);
911 if(!isDigit((unsigned char)*string)) return(nilCell);
915 if(*(pattern + 1) == 0)
918 plus = stuffString("");
919 else if(*(string + 1) == 0)
920 plus = stuffStringN(string, 1);
921 else return(nilCell);
923 if(len == 0) return(plus);
924 cell = stuffStringN(start, len);
929 if((match = patternMatchS(pattern+1, string)) != nilCell)
930 plus = stuffString("");
931 else if((match = patternMatchS(pattern+1, string+1)) != nilCell)
932 plus = stuffStringN(string, 1);
933 else return(nilCell);
935 if(len == 0) cell = plus;
938 cell = stuffStringN(start, len);
945 if(*(pattern + 1) == 0)
947 if(len == 0) return(stuffString(string));
948 cell = stuffStringN(start, len);
949 cell->next = stuffString(string);
953 if((match = patternMatchS(pattern+1, string)) != nilCell)
955 star = stuffStringN(start+len, starLen);
956 if(len == 0) cell = star;
959 cell = stuffStringN(start, len);
966 if(*string != 0) ++string, ++starLen;
967 else return(nilCell);
971 if(*pattern != *string) return(nilCell);
982 CELL
* p_integer(CELL
* params
)
990 deflt
= params
->next
;
991 params
= evaluateExpression(params
);
993 if(params
->type
== CELL_STRING
)
994 intString
= (char *)params
->contents
;
995 else if(isNumber(params
->type
))
997 getInteger64(params
, &num
);
998 return(stuffInteger64(num
));
1001 return(copyCell(evaluateExpression(deflt
)));
1003 while(isspace((int)*intString
)) intString
++;
1004 if(!isDigit((unsigned char)*intString
))
1006 if(*intString
!= '-' && *intString
!= '+')
1007 return(copyCell(evaluateExpression(deflt
)));
1008 if(!isDigit((unsigned char)*(intString
+1)))
1009 return(copyCell(evaluateExpression(deflt
)));
1012 if(deflt
->next
!= nilCell
)
1013 getInteger(deflt
->next
, (UINT
*)&base
);
1016 result
= strtoul(intString
, NULL
, base
);
1018 result
= strtoull(intString
,(char **)0, base
);
1020 return(stuffInteger64(result
));
1023 CELL
* p_float(CELL
* params
)
1029 deflt
= params
->next
;
1030 params
= evaluateExpression(params
);
1032 if(params
->type
== CELL_STRING
)
1033 fltString
= (char *)params
->contents
;
1034 else if(isNumber(params
->type
))
1036 getFloat(params
, &value
);
1037 return(stuffFloat(&value
));
1040 return(copyCell(evaluateExpression(deflt
)));
1042 while(isspace((int)*fltString
)) fltString
++;
1043 if(!isDigit((unsigned char)*fltString
))
1045 if(*fltString
!= '-' && *fltString
!= '+' && *fltString
!= lc_decimal_point
)
1046 return(copyCell(evaluateExpression(deflt
)));
1047 if(!isDigit((unsigned char)*(fltString
+1)))
1048 return(copyCell(evaluateExpression(deflt
)));
1051 value
= atof(fltString
);
1052 return( stuffFloat(&value
) );
1056 CELL
* p_symbol(CELL
* params
)
1064 char * fmt
= "%I64d";
1068 cell
= evaluateExpression(params
);
1072 snprintf(number
, 30, "%ld", cell
->contents
);
1078 snprintf(number
, 30, "%ld", *(INT64
*)&cell
->aux
);
1082 snprintf(number
, 30, fmt
, *(INT64
*)&cell
->aux
);
1084 snprintf(number
, 30, "%lld", *(INT64
*)&cell
->aux
);
1090 #endif /* NEWLISP64 */
1093 snprintf(number
, 30, "%1.10g",*(double *)&cell
->aux
);
1095 snprintf(number
, 30, "%1.10g",*(double *)&cell
->contents
);
1100 token
= (char*)cell
->contents
;
1103 sPtr
= (SYMBOL
*)cell
->contents
;
1107 return(errorProcExt(ERR_NUMBER_OR_STRING_EXPECTED
, params
));
1109 params
= params
->next
;
1111 if(params
== nilCell
)
1112 context
= currentContext
;
1113 else if((context
= getCreateContext(params
, TRUE
)) == NULL
)
1114 return(errorProcExt(ERR_SYMBOL_OR_CONTEXT_EXPECTED
, params
));
1116 if(params
->next
!= nilCell
)
1118 cell
= evaluateExpression(params
->next
);
1119 if(cell
->type
== CELL_NIL
)
1121 sPtr
= lookupSymbol(token
, context
);
1122 if(sPtr
== NULL
) return(nilCell
);
1123 return(stuffSymbol(sPtr
));
1127 sPtr
= translateCreateSymbol(token
, CELL_NIL
, context
, TRUE
);
1128 return(stuffSymbol(sPtr
));
1133 CELL
* p_symbolSource(CELL
* params
)
1138 openStrStream(&strStream
, MAX_STRING
, 0);
1139 serializeSymbols(params
, (UINT
)&strStream
);
1140 cell
= stuffString(strStream
.buffer
);
1141 closeStrStream(&strStream
);
1146 CELL
* p_string(CELL
* params
)
1151 openStrStream(&strStream
, MAX_STRING
, 0);
1152 prettyPrintFlags
|= PRETTYPRINT_STRING
;
1153 while (params
!= nilCell
)
1155 cell
= evaluateExpression(params
);
1156 if(cell
->type
== CELL_STRING
) /* speed optimization for strings */
1157 writeStreamStr(&strStream
, (char *)cell
->contents
, 0);
1159 printCell(cell
, FALSE
, (UINT
)&strStream
);
1160 params
= params
->next
;
1162 prettyPrintFlags
&= ~PRETTYPRINT_STRING
;
1163 cell
= stuffString(strStream
.buffer
);
1165 closeStrStream(&strStream
);
1170 UINT
getAddress(CELL
* params
)
1174 params
= evaluateExpression(params
);
1177 if(params
->type
== CELL_INT64
)
1179 num
= *(INT64
*)¶ms
->aux
;
1182 else if(params
->type
== CELL_FLOAT
)
1184 num
= *(INT64
*)¶ms
->aux
;
1188 if(params
->type
== CELL_FLOAT
)
1190 num
= *(double *)¶ms
->contents
;
1195 return(params
->contents
);
1199 CELL
* p_getChar(CELL
* params
)
1201 return(stuffInteger((UINT
)*(char*)getAddress(params
)));
1204 CELL
* p_getString(CELL
* params
)
1206 return(stuffString((char *)getAddress(params
)));
1209 CELL
* p_getInteger(CELL
* params
)
1211 return(stuffInteger(*(unsigned int *)getAddress(params
)));
1214 CELL
* p_getLong(CELL
* params
)
1217 return(stuffInteger64(*(INT64
*)getAddress(params
)));
1219 return(stuffInteger(*(UINT
*)getAddress(params
)));
1223 CELL
* p_getFloat(CELL
* params
)
1225 return(stuffFloat((double*)getAddress(params
)));
1229 CELL
* p_address(CELL
* params
)
1231 params
= evaluateExpression(params
);
1232 switch(params
->type
)
1235 return(stuffInteger((UINT
)¶ms
->contents
));
1239 return(stuffInteger((UINT
)¶ms
->aux
));
1242 return(stuffInteger((UINT
)¶ms
->contents
));
1247 return(stuffInteger(params
->contents
));
1251 CELL
* p_copyMemory(CELL
* params
)
1253 UINT toAddress
, fromAddress
, nBytes
;
1256 cell
= evaluateExpression(params
);
1257 params
= params
->next
;
1258 fromAddress
= getAddress(cell
);
1260 cell
= evaluateExpression(params
);
1261 toAddress
= getAddress(cell
);
1263 getInteger(params
->next
, &nBytes
);
1265 memcpy((char*)toAddress
, (char*)fromAddress
, nBytes
);
1267 return(stuffInteger(nBytes
));
1271 CELL
* cellTokenString(char * * source
, size_t * srclen
, char * separator
, pcre
* re
)
1276 int ovector
[OVECCOUNT
];
1279 if(*source
== NULL
) return(stuffString(""));
1280 start
= src
= *source
;
1282 slen
= strlen(separator
);
1288 if(*src
== *separator
)
1290 if(strncmp(src
, separator
, slen
) == 0)
1293 if(**source
== 0) /* last token is separator */
1295 return(stuffStringN(start
, len
));
1302 if(len
== 0) return(NULL
);
1303 return(stuffStringN(start
, len
));
1308 rc
= pcre_exec(re
, NULL
, src
, len
, 0, 0, ovector
, OVECCOUNT
);
1310 /* matching failed */
1313 *source
= src
+ len
;
1314 return(stuffStringN(src
, len
));
1317 /* error in pcre_exec() */
1319 regexError("error in pcre_exec()", rc
, "");
1321 *source
= src
+ ovector
[1];
1322 *srclen
-= ovector
[1];
1323 if(**source
== 0) /* last token is separator */
1326 if(ovector
[1] - ovector
[0] == 0)
1329 return(stuffStringN(src
, ovector
[0]));
1336 CELL
* p_parse(CELL
* params
)
1343 char token
[MAX_STRING
];
1351 params
= getStringSize(params
, &string
, &srclen
, TRUE
);
1352 if(params
== nilCell
) separator
= NULL
;
1355 params
= getString(params
, &separator
);
1356 if(params
!= nilCell
)
1358 getInteger(params
, (UINT
*)&options
);
1359 /* Compile the regular expression in separator */
1360 re
= pcreCachedCompile(separator
, options
);
1365 if(separator
== NULL
)
1366 makeStreamFromString(&stream
, string
);
1368 result
= cell
= getCell(CELL_EXPRESSION
);
1369 while(string
!= NULL
)
1371 if(separator
!= NULL
)
1373 if((newCell
= cellTokenString(&string
, &srclen
, separator
, re
)) == NULL
)
1378 if(getToken(&stream
, token
, &tklen
) == TKN_EMPTY
) break;
1379 newCell
= stuffString(token
);
1383 result
->contents
= (UINT
)newCell
;
1385 cell
->next
= newCell
;
1389 newCell
->next
= stuffString("");
1399 #define PACK_UNSIGNED_INT 4
1401 #define PACK_UNSIGNED_LONG 6
1402 #define PACK_LONG_LONG 7
1403 #define PACK_UNSIGNED_LONG_LONG 8
1404 #define PACK_FLOAT 9
1405 #define PACK_DOUBLE 10
1406 #define PACK_STRING 11
1407 #define PACK_NULL 12
1408 #define PACK_BIG_ENDIAN 13
1409 #define PACK_LITTLE_ENDIAN 14
1412 void swapEndian(char * data
, int n
)
1418 while(i
) { tmp
[n
- i
] = data
[i
- 1]; i
--; }
1420 memcpy(data
, &tmp
[0], n
);
1424 CELL
* p_pack(CELL
* params
)
1434 int bigEndian
= 1, endianSwitch
= 0;
1436 unsigned char byteV
;
1438 unsigned short int uint16V
; /* 16 bit */
1439 unsigned int uint32V
; /* 32 bit */
1440 unsigned long long uint64V
; /* 64 bit */
1444 /* find out endianess */
1445 bigEndian
= (*((char *)&bigEndian
) == 0) ;
1447 params
= getString(params
, &format
);
1450 while((source
= parsePackFormat(source
, &len
, &type
)) != NULL
)
1453 if(length
== 0) return(stuffString(""));
1454 pPtr
= packed
= allocMemory(length
);
1458 while((source
= parsePackFormat(source
, &len
, &type
)) != NULL
)
1460 if(type
== PACK_NULL
)
1462 memset(pPtr
, 0, len
);
1468 else if(type
== PACK_LITTLE_ENDIAN
|| type
== PACK_BIG_ENDIAN
)
1470 endianSwitch
= ((type
== PACK_BIG_ENDIAN
) != bigEndian
);
1474 if(params
->type
== CELL_NIL
) break;
1478 cell
= evaluateExpression(params
);
1479 /* accept data in a list, (will recurse into it but never come out) */
1480 if(isList(cell
->type
))
1482 cell
= (CELL
*)cell
->contents
;
1487 if(cell
->type
== CELL_FLOAT
|| cell
->type
== CELL_INT64
)
1488 uint64V
= *(INT64
*)&cell
->aux
;
1489 else /* CELL_LONG and CELL_STRING */
1490 uint64V
= cell
->contents
;
1492 uint64V
= cell
->contents
;
1501 byteV
= (char)uint64V
;
1502 memcpy(pPtr
, &byteV
, 1);
1506 chrV
= (char)uint64V
;
1507 memcpy(pPtr
, &chrV
, 1);
1511 shortV
= (short int)uint64V
;
1512 memcpy(pPtr
, &shortV
, 2);
1513 if(endianSwitch
) swapEndian(pPtr
, 2);
1516 case PACK_UNSIGNED_INT
:
1517 uint16V
= (unsigned short int)uint64V
;
1518 memcpy(pPtr
, &uint16V
, 2);
1519 if(endianSwitch
) swapEndian(pPtr
, 2);
1523 case PACK_UNSIGNED_LONG
:
1524 uint32V
= (unsigned int)uint64V
;
1525 memcpy(pPtr
, &uint32V
, 4);
1526 if(endianSwitch
) swapEndian(pPtr
, 4);
1529 case PACK_LONG_LONG
:
1530 case PACK_UNSIGNED_LONG_LONG
:
1531 memcpy(pPtr
, &uint64V
, 8);
1532 if(endianSwitch
) swapEndian(pPtr
, 8);
1537 if(cell
->type
== CELL_FLOAT
)
1538 doubleV
= *(double *)&uint64V
;
1539 else doubleV
= (double)uint64V
;
1540 if(type
== PACK_FLOAT
)
1543 memcpy(pPtr
, &floatV
, 4);
1544 if(endianSwitch
) swapEndian(pPtr
, 4);
1548 memcpy(pPtr
, &doubleV
, 8);
1549 if(endianSwitch
) swapEndian(pPtr
, 8);
1554 if(cell
->type
== CELL_STRING
)
1558 memcpy(pPtr
, (void *)cell
->contents
, len
);
1561 memcpy(pPtr
, (void*)cell
->contents
, ln
);
1562 memset(pPtr
+ ln
, 0, len
- ln
);
1565 else memset(pPtr
, 0, len
);
1573 params
= params
->next
;
1577 cell
= stuffStringN(packed
, length
);
1583 char * parsePackFormat(char * format
, int * length
, int * type
)
1586 while(*format
== ' ') format
++;
1588 if(*format
== 0) return(NULL
);
1593 *type
= PACK_LITTLE_ENDIAN
;
1598 *type
= PACK_BIG_ENDIAN
;
1615 *type
= (*format
== 's') ? PACK_STRING
: PACK_NULL
;
1617 if(isdigit((int)*format
) )
1619 *length
= atol(format
);
1620 while(isdigit((int)*format
)) format
++;
1627 *type
= (*format
== 'd') ? PACK_INT
: PACK_UNSIGNED_INT
;
1632 if(*(format
+ 1) == 'd' || *(format
+ 1) == 'u')
1635 *type
= (*(format
+ 1) == 'd') ? PACK_LONG
: PACK_UNSIGNED_LONG
;
1638 else if(*(format
+ 1) == 'f')
1641 *type
= PACK_DOUBLE
;
1651 if(*(format
+ 1) == 'd' || *(format
+ 1) == 'u')
1654 *type
= (*(format
+ 1) == 'd') ? PACK_LONG_LONG
: PACK_UNSIGNED_LONG_LONG
;
1678 CELL
* p_unpack(CELL
* params
)
1686 size_t length
, maxlen
;
1689 int bigEndian
= 1, endianSwitch
= 0;
1691 unsigned char byteV
;
1693 unsigned short uint16V
;
1695 unsigned int uint32V
;
1696 unsigned long long int uint64V
;
1700 /* find out endianess */
1701 bigEndian
= (*((char *)&bigEndian
) == 0) ;
1703 params
= getString(params
, &format
);
1704 params
= evaluateExpression(params
);
1706 if(params
->type
== CELL_STRING
)
1708 pPtr
= (char *)params
->contents
;
1709 maxlen
= params
->aux
- 1;
1713 getIntegerExt(params
, (void*)&pPtr
, FALSE
);
1719 result
= getCell(CELL_EXPRESSION
);
1722 while( (source
= parsePackFormat(source
, &len
, &type
))!= NULL
)
1724 if(length
+ len
> maxlen
) break;
1726 if(type
== PACK_LITTLE_ENDIAN
|| type
== PACK_BIG_ENDIAN
)
1728 endianSwitch
= ((type
== PACK_BIG_ENDIAN
) != bigEndian
);
1740 memcpy(&byteV
, pPtr
, 1);
1741 cell
= getCell(CELL_LONG
);
1742 cell
->contents
= byteV
;
1746 memcpy(&chrV
, pPtr
, 1);
1747 cell
= getCell(CELL_LONG
);
1748 cell
->contents
= chrV
;
1752 memcpy(&shortV
, pPtr
, 2);
1753 if(endianSwitch
) swapEndian((char*)&shortV
, 2);
1754 cell
= getCell(CELL_LONG
);
1755 cell
->contents
= (int)shortV
;
1758 case PACK_UNSIGNED_INT
:
1759 memcpy(&uint16V
, pPtr
, 2);
1760 if(endianSwitch
) swapEndian((char*)&uint16V
, 2);
1761 cell
= getCell(CELL_LONG
);
1762 cell
->contents
= uint16V
;
1766 memcpy(&int32V
, pPtr
, 4);
1767 if(endianSwitch
) swapEndian((char *)&int32V
, 4);
1769 cell
= getCell(CELL_INT64
);
1770 *(INT64
*)&cell
->aux
= int32V
;
1772 cell
= getCell(CELL_LONG
);
1773 *(long *)&cell
->contents
= int32V
;
1777 case PACK_UNSIGNED_LONG
:
1778 memcpy(&uint32V
, pPtr
, 4);
1779 if(endianSwitch
) swapEndian((char*)&uint32V
, 4);
1781 cell
= getCell(CELL_INT64
);
1782 *(INT64
*)&cell
->aux
= uint32V
;
1784 cell
= getCell(CELL_LONG
);
1785 cell
->contents
= uint32V
;
1789 case PACK_LONG_LONG
:
1790 case PACK_UNSIGNED_LONG_LONG
:
1791 memcpy(&uint64V
, pPtr
, 8);
1792 if(endianSwitch
) swapEndian((char*)&uint64V
, 8);
1794 cell
= getCell(CELL_INT64
);
1795 memcpy(&cell
->aux
, &uint64V
, 8);
1797 cell
= getCell(CELL_LONG
);
1798 cell
->contents
= uint64V
;
1803 memcpy(&floatV
, pPtr
, 4);
1804 if(endianSwitch
) swapEndian((char*)&floatV
, 4);
1806 cell
= stuffFloat(&doubleV
);
1810 memcpy(&doubleV
, pPtr
, 8);
1811 if(endianSwitch
) swapEndian((char*)&doubleV
, 8);
1812 cell
= stuffFloat(&doubleV
);
1816 cell
= stuffStringN(pPtr
, len
);
1820 cell
= getCell(CELL_NIL
);
1824 pPtr
+= len
; length
+= len
;
1826 result
->contents
= (UINT
)cell
;
1837 CELL
* p_trim(CELL
* params
)
1840 size_t left
, right
, len
;
1842 #ifndef SUPPORT_UTF8
1852 params
= getString(params
, &str
);
1854 #ifndef SUPPORT_UTF8
1858 len
= utf8_wlen(str
);
1859 wptr
= wstr
= allocMemory((len
+ 1) * sizeof(int));
1860 len
= utf8_wstr(wstr
, str
, len
);
1864 return(stuffString(str
));
1866 if(params
== nilCell
)
1870 params
= getString(params
, &trimChr
);
1871 #ifndef SUPPORT_UTF8
1874 utf8_wchar(trimChr
, &lchr
);
1876 if(params
!= nilCell
)
1878 getString(params
, &trimChr
);
1879 #ifndef SUPPORT_UTF8
1882 utf8_wchar(trimChr
, &rchr
);
1889 #ifndef SUPPORT_UTF8
1890 while(*str
== lchr
) str
++, left
++;
1892 while(*wstr
== lchr
) wstr
++, left
++;
1896 return(stuffString(""));
1898 #ifndef SUPPORT_UTF8
1899 str
= ptr
+ len
- 1;
1900 while(*str
== rchr
&& right
< len
) str
--, ++right
;
1902 return(stuffStringN(ptr
+ left
, len
- left
- right
));
1906 wstr
= wptr
+ len
- 1;
1907 while(*wstr
== rchr
&& right
< len
) wstr
--, ++right
;
1909 *(wptr
+ len
- right
) = 0;
1911 str
= allocMemory((len
- left
- right
+ 1) * UTF8_MAX_BYTES
);
1912 len
= wstr_utf8(str
, wptr
+ left
, (len
- left
- right
) * UTF8_MAX_BYTES
);
1914 result
= stuffStringN(str
, len
);
1923 /* ------- PRCE Perl Compatible Regular Expressions for all platforms ------- */
1924 /* see also http://www.pcre.org/ */
1927 void regexError(char * msg_1
, int num
, const char * msg_2
);
1931 CELL
* p_regex(CELL
* params
)
1934 int ovector
[OVECCOUNT
];
1940 CELL
* cell
, * result
, * strCell
;
1942 cell
= getString(params
, &pattern
);
1943 strCell
= evaluateExpression(cell
);
1944 if(strCell
->type
!= CELL_STRING
)
1945 return(errorProcExt(ERR_STRING_EXPECTED
, cell
));
1947 string
= (char *)strCell
->contents
;
1949 params
= cell
->next
;
1950 if(params
!= nilCell
)
1951 params
= getInteger(params
, (UINT
*)&options
);
1953 /* Compile the regular expression in the first argument */
1954 re
= pcreCachedCompile(pattern
, (int)options
);
1956 /* Compilation succeeded: match the subject in the second argument */
1958 re
, /* the compiled pattern */
1959 NULL
, /* no extra data - we didn't study the pattern */
1960 string
, /* the subject string */
1961 (int)strCell
->aux
- 1, /* the length of the subject */
1962 0, /* start at offset 0 in the subject */
1963 0, /* default options */
1964 ovector
, /* output vector for substring information */
1965 OVECCOUNT
); /* number of elements in the output vector */
1967 /* Matching failed */
1971 /* error in pcre_exec() */
1973 regexError("error in pcre_exec()", rc
, "");
1975 /* Match succeded */
1977 /* Show substrings stored in the output vector */
1978 result
= cell
= getCell(CELL_EXPRESSION
);
1979 for(idx
= 0; idx
< rc
; idx
++)
1981 len
= ovector
[2*idx
+1] - ovector
[2*idx
];
1982 strCell
= stuffStringN(string
+ ovector
[2*idx
], len
);
1984 deleteList((CELL
*)sysSymbol
[idx
]->contents
);
1985 sysSymbol
[idx
]->contents
= (UINT
)copyCell(strCell
);
1989 cell
->contents
= (UINT
)strCell
;
1990 cell
= (CELL
*)cell
->contents
;
1994 cell
->next
= strCell
;
1998 cell
->next
= stuffInteger(ovector
[2*idx
]);
2000 cell
->next
= stuffInteger(len
);
2008 ssize_t
searchBufferRegex(char * string
, int offset
,
2009 char * pattern
, int length
, int options
, int * len
)
2012 int ovector
[OVECCOUNT
];
2016 options
&= ~REPLACE_ONCE
; /* turn custom bit off for PCRE */
2018 /* Compile the regular expression in the first argument */
2019 re
= pcreCachedCompile(pattern
, options
);
2021 /* Compilation succeeded: match the subject in the second argument */
2022 rc
= pcre_exec(re
, NULL
, string
, length
, offset
, 0, ovector
, OVECCOUNT
);
2024 /* matching failed */
2028 /* error in pcre_exec() */
2030 regexError("error in pcre_exec()", rc
, "");
2033 for(idx
= 0; idx
< rc
; idx
++)
2035 cell
= stuffStringN(string
+ ovector
[2*idx
], ovector
[2*idx
+1] - ovector
[2*idx
]);
2036 deleteList((CELL
*)sysSymbol
[idx
]->contents
);
2037 sysSymbol
[idx
]->contents
= (UINT
)cell
;
2041 *len
= ovector
[1] - ovector
[0];
2043 return((UINT
)ovector
[0]);
2047 pcre
* pcreCachedCompile(char * pattern
, int options
)
2051 static char * cPattern
= NULL
;
2052 static pcre
* re
= NULL
;
2053 static int cacheOptions
= -1;
2056 if((cPattern
== NULL
) || (strcmp(cPattern
, pattern
) != 0) || (options
!= cacheOptions
))
2058 cacheOptions
= options
;
2059 if(cPattern
!= NULL
) freeMemory(cPattern
);
2060 len
= strlen(pattern
);
2061 cPattern
= (char *)allocMemory(len
+ 1);
2062 memcpy(cPattern
, pattern
, len
+ 1);
2064 if(re
!= NULL
) free(re
);
2066 if(re
!= NULL
) (pcre_free
)(re
);
2068 re
= pcre_compile(pattern
, options
, &error
, &errOffset
, NULL
);
2070 /* Compilation failed: print the error message and exit */
2073 freeMemory(cPattern
);
2075 regexError("offset", errOffset
, error
);
2083 void regexError(char * msg_1
, int number
, const char * msg_2
)
2086 char * errorBuff
= malloc(256);
2087 snprintf(errorBuff
, 256, "%s %d %s:", msg_1
, number
, msg_2
);
2088 cell
= stuffString(errorBuff
);
2090 fatalError(ERR_REGEX
, cell
, 0);
2095 /* replace string with or without (options = -1) regular expressions */
2105 void freeRegex(REGEX
* regex
);
2107 char * replaceString
2108 (char * keyStr
, int keyLen
, char * buff
, size_t buffLen
, CELL
* exprCell
,
2109 UINT
* cnt
, int options
, size_t * newLen
)
2111 ssize_t oldLen
, findPos
;
2112 size_t count
, offset
;
2116 REGEX
* start_rx
= NULL
, * end_rx
= NULL
;
2117 int resultStackIdxSave
;
2121 *newLen
= oldLen
= 0;
2125 /* save all found string and fill sys variables $0, $1 ... etc */
2126 while(offset
<= buffLen
)
2129 findPos
= searchBuffer(buff
+ offset
, buffLen
- offset
, keyStr
, keyLen
, TRUE
);
2131 findPos
= searchBufferRegex(buff
, (int)offset
, keyStr
, (int)buffLen
, options
, &keyLen
);
2133 if(findPos
== -1) break;
2135 if(options
!= -1) findPos
-= offset
;
2138 start_rx
= end_rx
= (REGEX
*)callocMemory(sizeof(REGEX
));
2141 end_rx
->next
= callocMemory(sizeof(REGEX
));
2142 end_rx
= end_rx
->next
;
2145 end_rx
->next
= NULL
;
2146 end_rx
->offset
= findPos
+ offset
; /* pos where pattern found */
2148 resultStackIdxSave
= resultStackIdx
;
2150 if((cell
= evaluateExpressionSafe(exprCell
, &errNo
)) == NULL
)
2152 freeRegex(start_rx
);
2153 longjmp(errorJump
, errNo
);
2156 end_rx
->length
= keyLen
; /* length of pattern found */
2157 if(cell
->type
== CELL_STRING
)
2159 repLen
= end_rx
->repLen
= cell
->aux
-1;
2160 end_rx
->repStr
= (char *)allocMemory(repLen
+ 1); /* replacement string */
2161 memcpy(end_rx
->repStr
, (char *)cell
->contents
, cell
->aux
);
2163 else /* if replacement expression is not string leave old content */
2165 repLen
= end_rx
->repLen
= keyLen
;
2166 end_rx
->repStr
= (char *)callocMemory(repLen
+ 1);
2167 memcpy(end_rx
->repStr
, buff
+ offset
+ findPos
, keyLen
);
2170 cleanupResults(resultStackIdxSave
);
2173 offset
+= findPos
+ keyLen
; /* next start for search */
2174 oldLen
+= keyLen
; /* space occupied by old content */
2175 *newLen
+= repLen
; /* space needed by new replacement content */
2177 bias
= (keyLen
== 0);
2181 if(options
& REPLACE_ONCE
) break;
2184 if(count
== 0) return(NULL
);
2186 *newLen
= buffLen
- oldLen
+ *newLen
;
2187 newBuff
= callocMemory(*newLen
+ 1);
2191 /* count is now offset into the new buffer */
2193 count
= start_rx
->offset
;
2194 memcpy(newBuff
, buff
, count
);
2196 while(start_rx
!= NULL
) /* replace */
2198 repLen
= start_rx
->repLen
;
2199 memcpy(newBuff
+ count
, start_rx
->repStr
, repLen
);
2201 freeMemory(start_rx
->repStr
);
2203 end_rx
= start_rx
->next
;
2204 if(end_rx
!= NULL
) /* copy from buffer */
2206 repLen
= end_rx
->offset
- start_rx
->offset
- start_rx
->length
;
2207 memcpy(newBuff
+ count
, buff
+ start_rx
->offset
+ start_rx
->length
, repLen
);
2211 freeMemory(start_rx
);
2215 printf("count %d buffLen %d offset %d bias %d str %s lencpy %d\n",
2216 count, buffLen, offset, bias, buff + offset - bias, buffLen - offset + bias);
2218 memcpy(newBuff
+ count
, buff
+ offset
- bias
, buffLen
- offset
+ bias
);
2223 void freeRegex(REGEX
* regex
)
2227 while(regex
!= NULL
)
2229 if(regex
->repStr
!= NULL
)
2230 freeMemory(regex
->repStr
);
2232 regex
= regex
->next
;