-
-
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
memcpy
name 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.