RXSTRING.LIB
RXSTRING.LIB is a static utility library distributed with the IBM OS/2 Developer's Toolkit that provides C helper functions for working with the RXSTRING data type used by the OS/2 REXX interpreter. It is a companion to REXX.LIB (the REXX External Application Interface import library) and is intended for developers writing REXX external functions, subcommand handlers, and exit handlers in C.
Unlike REXX.LIB and other Toolkit import libraries, RXSTRING.LIB is a static library: its object code is linked directly into the calling application at build time. It has no corresponding DLL and adds no run-time dependency beyond REXX.DLL (which external functions already require). All functions are 32-bit only; for 16-bit RXSTRING support, the OS/2 1.2 or 1.3 Toolkit version of RXSTRING.LIB must be used.
File size in the OS/2 Warp 4.52 Toolkit 4.5: 6,191 bytes. Copyright: IBM Corporation 1992, 1996. Distributed with the Toolkit in os2tk45\lib\rxstring.lib; documentation in os2tk45\book\rxstring.doc.
Background
The REXX External Application Interface passes all string data between C code and the REXX interpreter as RXSTRING structures:
typedef struct _RXSTRING {
ULONG strlength; /* byte length of the string */
PCH strptr; /* pointer to string data (NOT null-terminated) */
} RXSTRING;
Because RXSTRING strings are length-delimited rather than null-terminated, the standard C library string functions (strcpy, strlen, strcmp, etc.) cannot be applied directly. RXSTRING.LIB provides analogues for these functions that operate on the RXSTRING structure, plus conversion utilities for moving data between C strings/PUCHAR buffers and RXSTRINGs.
Include Files
RXSTRING.LIB has no distributed header in the Toolkit 4.5. Function prototypes must be declared by the application. The RXSTRING type itself is declared in rexxsaa.h:
#define INCL_REXXSAA #include <rexxsaa.h>
Suggested forward declarations for the functions most commonly used:
/* Numeric conversion */ INT rxtoi(RXSTRING rx); LONG rxtol(RXSTRING rx); ULONG rxtoul(RXSTRING rx); /* Memory management */ RXSTRING rxalloc(ULONG ulSize); VOID rxfree(RXSTRING rx); /* Return value helper */ RXSTRING rxreturn_value(PRXSTRING presult, PUCHAR pdata, ULONG ulLen); /* Length helpers */ ULONG rxstrlen(RXSTRING rx); RXSTRING rxset_null(PRXSTRING prx); RXSTRING rxset_zerolen(PRXSTRING prx); /* Copy / cat */ RXSTRING rxstrcpy(PRXSTRING pdest, PRXSTRING psrc); RXSTRING rxstrcat(PRXSTRING pdest, PRXSTRING psrc); RXSTRING strcpy2rx(PRXSTRING pdest, PSZ pszSrc); RXSTRING strcat2rx(PRXSTRING pdest, PSZ pszSrc); RXSTRING strdup2rx(PUCHAR pSrc, ULONG ulLen); /* Comparison */ LONG rxstrcmp(PRXSTRING p1, PRXSTRING p2); LONG rxstricmp(PRXSTRING p1, PRXSTRING p2); PUCHAR rxstrchr(PRXSTRING prx, UCHAR ch); PUCHAR rxstrrchr(PRXSTRING prx, UCHAR ch); /* I/O */ VOID rxprint(RXSTRING rx);
API Reference
Group 1: Numeric Conversion
These functions convert an RXSTRING containing a numeric string into a C integer value, analogous to atoi(), atol(), and strtoul().
INT rxtoi(RXSTRING rx)- Converts the RXSTRING
rxto anINT. Equivalent toatoi()on the string data. Leading whitespace is skipped; conversion stops at the first non-numeric character.
LONG rxtol(RXSTRING rx)- Converts the RXSTRING
rxto aLONG. Equivalent toatol().
ULONG rxtoul(RXSTRING rx)- Converts the RXSTRING
rxto aULONG. Equivalent tostrtoul(). Useful for parsing numeric REXX arguments passed to an external function.
Group 2: File I/O
These functions read and write RXSTRING data to OS/2 file handles, and print RXSTRING contents to stdout. They operate on the raw bytes in the RXSTRING (not null-terminated output).
LONG rxwrite(HFILE hf, RXSTRING rx)- Writes the string data in
rxto file handlehfusingDosWrite. Returns the number of bytes written, or a negative error code.
LONG rxread(HFILE hf, PRXSTRING prx)- Reads data from file handle
hfinto the RXSTRING pointed to byprxusingDosRead. The RXSTRING must already have allocated storage (strptrpointing to a buffer ofstrlengthbytes). Returns the number of bytes read.
VOID rxprint(RXSTRING rx)- Writes the string data contained in
rxtostdoutusingfputc. No newline is appended. Useful for quick debugging output from REXX external functions.
Group 3: Copy and Conversion
These functions copy, duplicate, and concatenate RXSTRING data. The "2rx" suffix functions convert from C strings or raw buffers to RXSTRING; the rx* functions operate on RXSTRING-to-RXSTRING.
Important: Except for the "dup" variants, all functions require that the destination RXSTRING already contains sufficient allocated storage. Concatenation functions append starting at the current strlength position — the destination buffer must hold the existing data plus the new data.
RXSTRING rxstrdup(RXSTRING rx)- Allocates a new RXSTRING and copies the data from
rxinto it. The caller is responsible for freeing the result withrxfree. Returns a null RXSTRING on allocation failure.
RXSTRING rxmemcpy(PRXSTRING pdest, PRXSTRING psrc, ULONG ulLen)- Copies exactly
ulLenbytes frompsrcintopdest. The destination must already have at leastulLenbytes allocated. Setspdest->strlength = ulLen.
RXSTRING rxstrcpy(PRXSTRING pdest, PRXSTRING psrc)- Copies the full contents of
psrcintopdest. The destination must have storage forpsrc->strlengthbytes.
RXSTRING rxstrncpy(PRXSTRING pdest, PRXSTRING psrc, ULONG ulLen)- Copies at most
ulLenbytes frompsrcintopdest.
RXSTRING rxstrcat(PRXSTRING pdest, PRXSTRING psrc)- Appends the contents of
psrctopdest, starting atpdest->strlength. Updatespdest->strlengthaccordingly. The destination buffer must have sufficient space.
RXSTRING rxstrncat(PRXSTRING pdest, PRXSTRING psrc, ULONG ulLen)- Appends at most
ulLenbytes frompsrctopdest.
RXSTRING strdup2rx(PUCHAR pSrc, ULONG ulLen)- Allocates a new RXSTRING and copies
ulLenbytes from the raw bufferpSrcinto it. Equivalent to combiningDosAllocMem+memcpy. The caller must free the result withrxfree.
RXSTRING memcpy2rx(PRXSTRING pdest, PUCHAR pSrc, ULONG ulLen)- Copies
ulLenbytes from the raw bufferpSrcinto the pre-allocated RXSTRINGpdest.
RXSTRING strcpy2rx(PRXSTRING pdest, PSZ pszSrc)- Copies a null-terminated C string
pszSrcinto the pre-allocated RXSTRINGpdest. Setsstrlengthto the C string length (not counting the null terminator).
RXSTRING strcat2rx(PRXSTRING pdest, PSZ pszSrc)- Appends the null-terminated C string
pszSrcto the pre-allocated RXSTRINGpdest.
RXSTRING strncat2rx(PRXSTRING pdest, PSZ pszSrc, ULONG ulLen)- Appends at most
ulLenbytes from the C stringpszSrctopdest.
Group 4: Comparison and Character Search
These functions are RXSTRING analogues of the standard C library comparison and character-search functions.
LONG rxstrcmp(PRXSTRING p1, PRXSTRING p2)- Case-sensitive comparison. Returns negative if
p1 < p2, 0 if equal, positive ifp1 > p2. Analogous tostrcmp().
LONG rxstricmp(PRXSTRING p1, PRXSTRING p2)- Case-insensitive comparison. Analogous to
stricmp()/strcasecmp().
LONG rxmemcmp(PRXSTRING p1, PRXSTRING p2, ULONG ulLen)- Compares exactly
ulLenbytes from each RXSTRING, case-sensitively. Analogous tomemcmp().
LONG rxmemicmp(PRXSTRING p1, PRXSTRING p2, ULONG ulLen)- Compares exactly
ulLenbytes case-insensitively. Analogous tomemicmp().
PUCHAR rxstrchr(PRXSTRING prx, UCHAR ch)- Searches for the first occurrence of byte
chin the RXSTRING. Returns a pointer to the matching byte within the string buffer, or NULL if not found. Analogous tostrchr().
PUCHAR rxstrrchr(PRXSTRING prx, UCHAR ch)- Searches for the last occurrence of byte
chin the RXSTRING. Returns a pointer to the last matching byte, or NULL. Analogous tostrrchr().
Group 5: Miscellaneous
RXSTRING rxalloc(ULONG ulSize)- Allocates a new RXSTRING with a data buffer of
ulSizebytes, usingDosAllocMem. Setsstrlength = ulSizeandstrptrto the allocated memory. Returns a null RXSTRING (both fields zero) on failure. Free the result withrxfree.
VOID rxfree(RXSTRING rx)- Frees the storage associated with an RXSTRING previously allocated by
rxalloc,rxstrdup, orstrdup2rx, usingDosFreeMem. Passing a null RXSTRING is safe (no-op).
VOID rxstrnset(RXSTRING rx, UCHAR ch, ULONG ulLen)- Fills the first
ulLenbytes ofrx's buffer with the byte valuech. Analogous tomemset(). Does not modifystrlength.
ULONG rxstrlen(RXSTRING rx)- Returns the
strlengthfield of the RXSTRING. This is a convenience accessor that does not compute the length from the data (unlikestrlen()on C strings). Returns 0 for a null or zero-length RXSTRING.
RXSTRING rxset_length(PRXSTRING prx, ULONG ulLen)- Sets the
strlengthfield of the RXSTRING toulLenwithout modifying the associated memory. Useful for trimming or extending the reported length of an RXSTRING after manual buffer manipulation.
RXSTRING rxset_null(PRXSTRING prx)- Sets the RXSTRING to a null string:
strptr = NULL,strlength = 0. The equivalent ofMAKERXSTRING(*prx, NULL, 0).
RXSTRING rxset_zerolen(PRXSTRING prx)- Sets the RXSTRING to a zero-length string:
strlength = 0without clearingstrptr. The RXSTRING is valid (non-null) but contains an empty string.
RXSTRING rxreturn_value(PRXSTRING presult, PUCHAR pdata, ULONG ulLen)- Helper for filling in the return value RXSTRING in a REXX external function or subcommand handler callback. If the pre-allocated buffer in
presultis large enough forulLenbytes, the data is copied there; otherwise a new buffer is allocated (the original is freed). This removes the need for callers to manually implement the "use pre-allocated buffer or allocate a new one" pattern required by the REXX External API. Returns the updated RXSTRING.
PUCHAR _make_hptr(RXSTRING rx)- Returns a flat 32-bit pointer to the string data buffer of
rx, converting from the selector:offset representation used in 16-bit OS/2 segments if necessary (via_DosSelToFlat). In 32-bit flat-model code this is equivalent to returningrx.strptrdirectly; the function exists for source compatibility with 16-bit code paths.
Additional Symbols (Undocumented)
The following symbols are present in the library object code but are not documented in the official rxstring.doc:
| Symbol | Notes |
|---|---|
RXNUMBER / RXNUMBERN |
Format a numeric value into an RXSTRING buffer |
RXSTRCMP |
Uppercase alias for rxstrcmp
|
RXSTRCPY2 |
Variant of rxstrcpy
|
rxstrcmpn / rxstricmpn |
Bounded (n-byte) comparison variants |
rxmemcmpn / rxmemicmpn |
Bounded memory comparison variants |
rxstrchr0 |
Variant of rxstrchr, possibly including a null-byte search
|
rxstrrchrl |
Variant of rxstrrchr
|
rxstrcatX / rxstrncatx |
Extended concatenation variants |
rxallocL |
Large-allocation variant of rxalloc
|
rxprintt |
Variant of rxprint
|
rxreturn_valuet |
Variant of rxreturn_value
|
strdup2rx8 |
Variant of strdup2rx
|
Usage
Build Instructions
RXSTRING.LIB is a static library; link it directly alongside the standard OS/2 import libraries. No separate DLL is needed at run time.
IBM VisualAge C++ / ILINK
icc -O2 -Gm -c myfunc.c ilink /PM:VIO myfunc.obj os2386.lib rexx.lib rxstring.lib
OpenWatcom
wcl386 -bt=os2 -mf -c myfunc.c wlink system os2v2 file myfunc.obj library os2386.lib library rexx.lib library rxstring.lib
EMX/GCC
gcc -Zomf -c myfunc.c gcc -Zomf -o myfunc.exe myfunc.o -los2386 -lrexx -lrxstring
Writing an External REXX Function
The following example shows a complete external function STRREVERSE using RXSTRING.LIB helpers:
#define INCL_REXXSAA
#include <rexxsaa.h>
#include <string.h>
/* Forward declarations for RXSTRING.LIB functions (no header supplied) */
RXSTRING rxalloc(ULONG ulSize);
VOID rxfree(RXSTRING rx);
RXSTRING rxreturn_value(PRXSTRING presult, PUCHAR pdata, ULONG ulLen);
ULONG rxstrlen(RXSTRING rx);
/* STRREVERSE(string) — returns the string with its bytes reversed */
ULONG APIENTRY StrReverseFunc(PUCHAR funcname,
ULONG argc,
PRXSTRING argv,
PSZ queuename,
PRXSTRING result)
{
ULONG len, i;
RXSTRING tmp;
PUCHAR p;
if (argc != 1 || !RXVALIDSTRING(argv[0]))
return 40; /* invalid call */
len = rxstrlen(argv[0]);
tmp = rxalloc(len);
if (!RXVALIDSTRING(tmp))
return 40; /* allocation failure */
p = tmp.strptr;
for (i = 0; i < len; i++)
p[i] = argv[0].strptr[len - 1 - i];
rxreturn_value(result, tmp.strptr, len);
rxfree(tmp);
return 0;
}
Parsing a Numeric Argument
#define INCL_REXXSAA
#include <rexxsaa.h>
ULONG rxtoul(RXSTRING rx);
RXSTRING rxalloc(ULONG);
RXSTRING rxreturn_value(PRXSTRING, PUCHAR, ULONG);
/* FACTSTR(n) — returns n! as a string (demo; overflows past 12!) */
ULONG APIENTRY FactorialFunc(PUCHAR name, ULONG argc, PRXSTRING argv,
PSZ queue, PRXSTRING result)
{
ULONG n, f, i;
CHAR buf[32];
ULONG len;
if (argc != 1 || !RXVALIDSTRING(argv[0]))
return 40;
n = rxtoul(argv[0]); /* convert RXSTRING "12" → ULONG 12 */
f = 1;
for (i = 2; i <= n; i++) f *= i;
len = sprintf(buf, "%lu", f);
rxreturn_value(result, (PUCHAR)buf, len);
return 0;
}
Converting a C String Result to RXSTRING
#define INCL_REXXSAA
#include <rexxsaa.h>
#include <string.h>
RXSTRING strdup2rx(PUCHAR pSrc, ULONG ulLen);
RXSTRING rxreturn_value(PRXSTRING presult, PUCHAR pdata, ULONG ulLen);
VOID rxfree(RXSTRING rx);
/* ENVVAR(name) — returns the value of an environment variable */
ULONG APIENTRY EnvVarFunc(PUCHAR name, ULONG argc, PRXSTRING argv,
PSZ queue, PRXSTRING result)
{
PSZ pszVal;
ULONG len;
if (argc != 1 || !RXVALIDSTRING(argv[0]))
return 40;
/* Null-terminate the argument for DosScanEnv */
CHAR szName[256];
memcpy(szName, argv[0].strptr, argv[0].strlength);
szName[argv[0].strlength] = '\0';
if (DosScanEnv(szName, &pszVal) != 0) {
/* Return empty string if not found */
result->strlength = 0;
return 0;
}
len = strlen(pszVal);
rxreturn_value(result, (PUCHAR)pszVal, len);
return 0;
}
Notes
- Not null-terminated: RXSTRING data is never null-terminated. Do not pass
rx.strptrdirectly to standard C library functions that expect aPSZ/char *. Use thestrcpy2rx/strdup2rxfamily to convert, or null-terminate manually before calling C string functions. rxreturn_valueownership: Whenrxreturn_valueallocates a new buffer (because the pre-allocated one was too small), the data pointer is replaced viaDosAllocMem; the REXX interpreter then owns and will free that buffer. Do not double-free it.rxalloc/rxfreeuseDosAllocMem: This means allocated memory is page-aligned. Do not mix withmalloc/free.- 32-bit only: All functions are compiled for the 32-bit flat address model. The 16-bit Toolkit variant (OS/2 1.x Toolkit) must be used for 16-bit applications.
- RXFILEIO module: The I/O functions (
rxwrite,rxread,rxprint) are compiled as a separate OMF module namedRXFILEIOwithin the library. Linking will only pull in this module if one of the I/O functions is referenced.
Version History
| Toolkit version | OS/2 release | Notes |
|---|---|---|
| OS/2 1.2 / 1.3 Toolkit | OS/2 1.x | 16-bit RXSTRING.LIB; original release |
| OS/2 2.0 Toolkit | OS/2 2.0 (1992) | 32-bit rewrite; "Cruiser" development codename visible in OMF segment names; functions documented in rxstring.doc
|
| Toolkit 4.5 | OS/2 Warp 4.52 | Final release; 6,191 bytes; copyright 1992, 1996; rxstring.doc in os2tk45\book\
|
See Also
- REXX.LIB — REXX External Application Interface (RexxStart, RexxVariablePool, etc.)
- IBM OS/2 Developer's Toolkit
- REXX (language overview)