-
-
Save meijeru/960678 to your computer and use it in GitHub Desktop.
| Red/System [ | |
| Title: "String functions" | |
| Purpose: {proposed library functions for c-string manipulation} | |
| Author: "Rudolf W. MEIJER" | |
| File: %stringf.reds | |
| Version: 0.1.0 | |
| Date: 27-May-2011 | |
| ] | |
| #import [ | |
| "msvcrt.dll" cdecl [ ; Windows | |
| calloc: "calloc" [ ; Allocate zero-filled memory. | |
| chunks [integer!] | |
| size [integer!] | |
| return: [c-string!] | |
| ] | |
| free: "free" [ ; Recycle memory. | |
| memory [c-string!] | |
| ] | |
| memcpy: "memcpy" [ ; Copy memory range. | |
| target [c-string!] | |
| source [c-string!] | |
| size [integer!] | |
| return: [c-string!] | |
| ] | |
| length?: "strlen" [ ; Return string length. | |
| command [c-string!] | |
| return: [integer!] | |
| ] | |
| ] | |
| ] | |
| max: func [ | |
| i1 [integer!] | |
| i2 [integer!] | |
| ][ | |
| either i1 > i2 [i1][i2] | |
| ] | |
| min: func [ | |
| i1 [integer!] | |
| i2 [integer!] | |
| ][ | |
| either i1 < i2 [i1][i2] | |
| ] | |
| make-string: func [ | |
| ; allocates space for string | |
| n [integer!] ; length of string | |
| return: [c-string!] | |
| ][ | |
| as c-string! calloc n + 1 1 | |
| ] | |
| copy-part: func [ | |
| ; implements sub-stringing | |
| s [c-string!] ; pointer to string to be copied | |
| n [integer!] ; number of characters to be copied | |
| return: [c-string!] ; a pointer to a new string | |
| /local r [c-string!] | |
| ][ | |
| n: max n 0 ; do not crash | |
| n: min n length? s ; idem | |
| r: make-string n | |
| memcpy r s n | |
| r | |
| ; note: the memory area pointed to by r has to be de-allocated | |
| ; by the user himself (no GC) | |
| ] | |
| concat: func [ | |
| ; implements string concatenation | |
| s1 [c-string!] ; pointer to the first string | |
| s2 [c-string!] ; pointer to the second string | |
| return: [c-string!] ; a pointer to a new string | |
| /local r [c-string!] n1 [integer!] n2 [integer!] | |
| ][ | |
| n1: length? s1 | |
| n2: length? s2 | |
| r: make-string (n1 + n2) | |
| memcpy r s1 n1 | |
| memcpy r + n1 s2 n2 | |
| r | |
| ; note: the memory area pointed to by r has to be de-allocated | |
| ; by the user himself (no GC) | |
| ] | |
| &: func [ | |
| ; infix version of concat | |
| [infix] | |
| s1 [c-string!] ; pointer to the first string | |
| s2 [c-string!] ; pointer to the second string | |
| return: [c-string!] ; a pointer to a new string | |
| ][ | |
| concat s1 s2 | |
| ] |
I have two remarks:
- The
memcpyname does not really fit well with the usual REBOL naming conventions that Red tries to follow to (even if not properly documented yet). Something likecopy-memory(verb-object) would be more appropriate. - Red/System lacks a mechanism to define bindings for multiple OS in the same source code (adding this to the todo list)
The calloc, free and memcpy names are identical to the C-library ones, I have not tried to change them. Instead, I have hidden them in the "real" functions that I want to make available.
Right, ignore my remark about naming. As long as they are for internal use, you are free to name them as you want (sticking to the C names is usual way).
Your Max and Min functions are missing a return value declaration.
The & symbol has become a reserved keyword for future use (might be required to support new literals value). If you are strongly attached to this symbol for your infix version of 'concat, I can free it again, as this would be a good use of this symbol too.
I know only one other obvious sign for concatenation: +. If you think that can be overloaded, than we can indeed free &.
PL/1 uses || for concatenation. Though that would only be obvious to people like me who have coded PL/1
These functions could not have been written without recourse to calloc and free. Since these have to be imported from msvcrt.dll I added an implementation of length? through strlen.