/* * Copyright (c) 1997-2024 Ross Cunniff * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* Header file for OADL system library interface. An OADL system * library is a dynamically loaded library in system-dependent format * (e.g. a DLL on Win32, a .dynlib on MacOS, or a .so on Linux). When * loaded (via a "using extern" statement) the library is first sought in a * system-specific location (although the OADLSYS environment variable * is widely recognized). It is then dynamically loaded, and * the entry point "OADL_libname" is queried. This entry point must * be of type OADL_SysInitProc, below. Once that entry point is * determined, it is then called, passing in the OADL_FindProc routine. * The SysInitProc can then use the FindProc routine to find various * entry points required for operation. These entry points * are documented below, but the most important one for a typical * system library is OADL_AddExtern which will define and register an * entry point of type OADL_SysCall - which all OADL extern procs * are. * * On shutdown / reload / restart, the OADL_SysTermProc for your * library is called. It is of type OADL_SysTermProc_fp, and is * named "OADL_libname_term" in your syslib shared library. */ #ifndef _OADL_SYS_INCLUDED // [ #define _OADL_SYS_INCLUDED 1 /* version number for interface purposes */ #define OADL_SYS_VER 101 /* Generic function pointer prototype, since C does not have a * function pointer equivalent to "void *" */ typedef int (*OADLproc)(void); /* Used to find a named OADL procedure - see below for list. "name" * is the name of the procedure (e.g. "OADL_AddExtern"). "version" is the * interface version - pass in OADL_SYS_VER. The procedure * is returned in rProc - you will want to put that in the appropriately * typed pointer as defined below. Returns 1 if found, 0 otherwise. * "ctx" should be passed the same context that SysInitProc was * called with. Additionally, the "ctx" in all of these routines * refers to the "ctx" that the system procedure was called with. */ typedef int (*OADL_FindProc_fp)(void *ctx, const char *name, int version, OADLproc *rProc); /* This is the typedef of your system library initialization proc. * OADL queries the symbol from the dynamic library, as documented above. * "ctx" is an opaque OADL ctx, which needs to be passed back to * the various callback routines. */ typedef int (*OADL_SysInitProc_fp)(void *ctx, OADL_FindProc_fp findProc); /* This is the typedef of your system library termination proc. * OADL queries the symbol from the dynamic library, as documented above. * "ctx" is an opaque OADL ctx, which needs to be passed back to * the various callback routines. */ typedef int (*OADL_SysTermProc_fp)(void *ctx); /* You should make sure that your system library procedures are * compatible with this prototype. Each syslib proc takes a pointer * to a result OadlVar "pRes", the number of arguments the OADL program * passed in "nargs", and the array of arguments "args". Return * value is generally 1. If return value is 0, some error * occurred, and the syslib proc probably has called ThrowError. * Returning 0 without calling ThrowError can cause OADL stack corruption. */ typedef int (*OADL_Extern_fp)(void *ctx, OadlVar *pRes, int nargs, const OadlVar *args); /* The routines that can be queried by FindProc. To find these routines, * ask for the name without the "_fp" suffix. names are case-sensitive. * Generally, if any of these routines return zero, it means an exception * has been raised and the calling system library function should * immediately return 0 (indicating aborted processing) */ /* OADL_AddExtern(ctx, name, proc) * The heart of the system library implementation. Tells OADL * that the "proc" with the given "name" is implemented by this library. * The "name" must include the namespace if it is intended to be part * of that namespace - e.g. io::printf. Note that "name" may be a * UTF-8 encoded wide string. */ typedef int (*OADL_AddExtern_fp)(void *ctx, const char *name, OADL_Extern_fp proc); /* OADL_GetProp(ctx, pRes, propNum) * Gets the (possibly private) property index number "propNum" of the * current "self" object and returns its value in "*pRes" */ typedef int (*OADL_GetProp_fp)(void *ctx, OadlVar *pRes, OadlVar propNum); /* OADL_SetProp(ctx, pRes, propNum, val) * Sets the (possibly private) property index number "propNum" of the * current "self" object to the given "val" */ typedef int (*OADL_SetProp_fp)(void *ctx, OadlVar propNum, OadlVar val); /* OADL_GetIndex(ctx, pRes, v, nIdx, idx[]) * Returns "v[idx]" in "*pRes". Always safe even in the face * of asynchronous GC */ typedef int (*OADL_GetIndex_fp)(void *ctx, OadlVar *pRes, OadlVar v, int nIdx, int idx[]); /* OADL_SetIndex(ctx, pRes, v, nIdx, idx, val) * Equivalent of "v[idx0,idx1,...] = val". Always safe even in the face * of asynchronous GC */ typedef int (*OADL_SetIndex_fp)(void *ctx, OadlVar v, int nIdx, int idx[], OadlVar val); /* OADL_WriteCopy(ctx, pRes, v) * To write directly into arrData (i.e., instead of calling * OADL_SetIndex), one must first call WriteCopy. The integer at * *pRes will be changed to 1 if a write copy was created, 0 otherwise. * It is not necessary to call OADL_WriteCopy on arrays created * by the current extern call. Note that OADL_WriteCopy can trigger * a GC. */ typedef int (*OADL_WriteCopy_fp)(void *ctx, int *pRes, OadlVar v); /* OADL_GetSubr(ctx, pDst, v, nargs, args ) * Returns "v[v0:v1...vn:vm]" in *pDst. Note that this allocates memory * and may result in an asynchronous GC which may invalidate any * locally cached pointers to OADL heap objects. */ typedef int (*OADL_GetSubr_fp)(void *, OadlVar *, OadlVar, int, OadlVar *); /* Structure for querying array information */ #define OADL_ARRAY_READONLY 0x01 /* Do not modify contents */ #define OADL_ARRAY_PERMANENT 0x02 /* Versus dyamic / GC memory */ #define OADL_ARRAY_USER_DATA 0x04 /* Points to user data, not OADL data */ #define OADL_ARRAY_ITERATOR 0x08 /* Iterator - only if not expanded */ /* If the array is an iterator and the caller requested the parameters, * the arrData is a pointer to an array of the following items (in the * type given by arrType): */ #define OADL_ARR_ITER_PARAM_FIRST 0 #define OADL_ARR_ITER_PARAM_LAST 1 #define OADL_ARR_ITER_PARAM_INCR 2 #define OADL_ARR_ITER_PARAM_COUNT 3 // Total size of iterator param array typedef struct { uint32_t arrSize; /* Total size of array, in elements */ uint8_t arrType; /* One of OADL_VT_* */ uint8_t elemSize; /* size of a single element, in bytes */ uint8_t arrRank; /* Rank - number of dimensions */ uint8_t pad0; /* Pad, ignored */ uint32_t arrFlags; /* flags from OADL_ARRAY_*, above */ uint32_t arrShape[OADL_MAX_RANK]; /* Shape of the array */ uint32_t arrStrides[OADL_MAX_RANK]; /* Dimension strides, in elements */ OadlVar arrVar; /* Only if iter. expanded to heap */ void *arrData; /* Pointer to array data or params */ void *arrAlloc; /* Only if iter. expanded to malloc */ } OADL_ArrayInfo; /* Iterator flags for OADL_GetArrayInfo */ #define OADL_AIF_ITERATOR_EXPANSION 0x00000007 // Mask for AIF_ITERATOR* #define OADL_AIF_ITERATOR_HEAP 0x00000001 // ...expand into heap #define OADL_AIF_ITERATOR_MALLOC 0x00000002 // ...expand into malloc #define OADL_AIF_ITERATOR_SCRATCH 0x00000003 // ...expand into scratch #define OADL_AIF_ITERATOR_PARAMS 0x00000004 // ...raw params in arrData // (i.e. not expanded) /* OADL_GetArrayInfo(ctx, pArr, a) * Returns info about a in OADL_ArrayInfo *pArr. flags are from * OADL_AIF_*, above. * * If the OADL_AIF_ITERATOR_EXPANSION flags are set, one of the * following actions are performed: * * OADL_AIF_ITERATOR_HEAP * Allocates a new array from the heap and returns the * newly created array expansion * * OADL_AIF_ITERATOR_MALLOC * Allocates a new pseudo-array via OADL_malloc and * returns the newly created array expansion. The caller * must OADL_free the returned arrAlloc pointer * * OADL_AIF_ITERATOR_SCRATCH * Allocates a new pseudo-array via OADL_AllocScratch and * returns the newly created array expansion. */ typedef int (*OADL_GetArrayInfo_fp)(void *ctx, OADL_ArrayInfo *pArr, OadlVar a, int flags); /* OADL_GetGcCounter(ctx) * Returns the GC counter - if it changes a GC has happened * and any local pointers to array/objects will be invalid */ typedef int (*OADL_GetGcCounter_fp)(void *ctx); /* OADL_Writable(ctx, pRes, v) * Returns "1" in *pRes if "v" is writable, and "0" if it is * read-only. */ typedef int (*OADL_Writeable_fp)(void *ctx, int *pRes, OadlVar v); /* OADL_TypeOf(ctx, pRes, v) * Returns "typeof(v)" in "*pRes" */ typedef int (*OADL_TypeOf_fp)(void *ctx, int *pRes, OadlVar v); /* OADL_FatalError(ctx, ErrNum) * Raises fatal exception "ErrNum" from oadlerr.h */ typedef int (*OADL_FatalError_fp)(void *ctx, int ErrNum); /* OADL_ThrowError(ctx, ErrNum) * Throws exception "ErrNum" from oadlerr.h */ typedef int (*OADL_ThrowError_fp)(void *ctx, int ErrNum); /* OADL_FindPublic(ctx, pRes, name) * Find the public named "name" and returns its value in *pRes * Note that "name" may be a UTF-8 encoded wide string. */ typedef int (*OADL_FindPublic_fp)(void *ctx, OadlVar *pRes, const char *name); /* OADL_FindExtern(ctx, pRes, name) * Find the extern named "name" and returns its value in *pRes * Note that "name" may be a UTF-8 encoded wide string. */ typedef int (*OADL_FindExtern_fp)(void *ctx, OadlVar *pRes, const char *name); /* OADL_FindObject(ctx, pRes, name) * Find the object named "name" and returns its value in *pRes * Note that "name" may be a UTF-8 encoded wide string. */ typedef int (*OADL_FindObject_fp)(void *ctx, OadlVar *pRes, const char *name); /* OADL_FindClass(ctx, pRes, name) * Find the object named "name" and returns its value in *pRes * Note that "name" may be a UTF-8 encoded wide string. */ typedef int (*OADL_FindClass_fp)(void *ctx, OadlVar *pRes, const char *name); /* OADL_GetSelf(ctx, pRes) * Returns the value of "self" in *pRes */ typedef int (*OADL_GetSelf_fp)(void *ctx, OadlVar *pSelf); /* OADL_GetPublic(ctx, pRes, obj, pub) * Returns "obj.pub" in *pRes */ typedef int (*OADL_GetPublic_fp)(void *ctx, OadlVar *pRes, OadlVar obj, OadlVar pub); /* Return values from OADL_SetPublic */ #define PUBLIC_OK 0 // Public was set OK #define PUBLIC_ERROR 1 // Can't set a read-only constant #define PUBLIC_OVERLOAD 2 // Needs a call to := operator #define PUBLIC_DO_TC 3 // Needs intrinsic type conversion /* OADL_SetPublic(ctx, obj, pub, v) * Equivalent of "obj.pub = v" * Returns one of PUBLIC_*, above */ typedef int (*OADL_SetPublic_fp)(void *ctx, OadlVar obj, OadlVar pub, OadlVar v); /* OADL_FindGlobal(ctx, pRes, name) * Returns the index of the global variable named "name" in *pRes * Note that "name" may be a UTF-8 encoded wide string. */ typedef int (*OADL_FindGlobal_fp)(void *ctx, int *pRes, const char *name); /* OADL_GetGlobal(ctx, pRes, idx) * Gets the global variable at index idx and puts it in pRes */ typedef int (*OADL_GetGlobal_fp)(void *ctx, OadlVar *pRes, int idx); /* OADL_SetGlobal(ctx, idx, val) * Sets the global variable at index idx to val */ typedef int (*OADL_SetGlobal_fp)(void *ctx, int idx, OadlVar val); /* OADL_AllocMach(ctx, pRes, stackAlloc) * Creates an OADL Machine capable of calling procedures * immediately. It allocates "stackAlloc" entries * for the execution stack. */ typedef int (*OADL_AllocMach_fp)(void *ctx, void **pRes, int stackAlloc); /* OADL_FreeMach(ctx, pRes, stackAlloc) * Frees a machine previously allocated by OADL_AllocMach() */ typedef int (*OADL_FreeMach_fp)(void *ctx, void *ptr); /* OADL_CallProc(ctx, typ, pRes, mach, obj, proc, nargs, args) * Makes an immediate or deferred call to the OADL procedure * whose value is "proc", or to the method whose value * is "obj.proc" if obj is not nil (proc must be of type * Public in that case). * * The "typ" parameter defines how the call will be executed: * * OADL_CALL_IMMEDIATE * Make an immediate call. The "mach" parameter must * be allocated by OADL_AllocMach() OADL_CallProc will * not return until the OADL procedure has completed * execution. The return value of the immediate call * will be placed in the OadlVar pointed to by the * "pRes" parameter. Most OADL procedures allocate * heap objects. This may trigger a GC cycle which * will invalidate any cached heap pointers. The * calling routine must revalidate any pointers to * heap objects after OADL_CallProc returns. * * OADL_CALL_DEFERRED * Make a deferred call (a call placed on the current * executing mach stack). OADL_CallProc returns * immediately. Note that deferred calls do not return * any value to the calling context. This allows * multiple deferred calls to be scheduled * simultaneously without overflowing the stack with * unused results. Since the call is deferred, no heap * allocations will occur at the time of the * OADL_CallProc call. The extern that defers one * or more calls must return OADL_CALL_DEFERRED to * OADL. * * OADL_CALL_CHAINED * Make a chained call. Chained calls are also * deferred; however, their results *are* returned to * the calling context. The extern that chains a call * must return OADL_CALL_CHAINED to OADL. * * * OADL_CallProc returns 1 on success and 0 on failure. */ // These start at "2" so normal extern return values of 0 and 1 don't // interfere #define OADL_CALL_IMMEDIATE 2 #define OADL_CALL_DEFERRED 3 #define OADL_CALL_CHAINED 4 typedef int (*OADL_CallProc_fp)(void *ctx, OadlVar *pRes, int typ, void *mach, OadlVar obj, OadlVar proc, int nargs, const OadlVar *args); /* OADL_CreateDict(ctx, pRes, pList, nList) * Creates a Dictionary holding exactly the key-value pairs found * in the given list. nList must be a multiple of two. */ typedef int (*OADL_CreateDict_fp)(void *ctx, OadlVar *pRes, OadlVar *pList, int nList); /* OADL_CreateArray(ctx, pRes, pArr) * Creates an array with parameters taken from OADL_ArrayInfo *pArr. * Returns the resulting array in *pRes. This does allocate * heap memory which could trigger a GC and invalidate any * cached heap pointers. * * Note that if pArr->arrData and pArr->arrStrides are ignored * unless OADL_ARRAY_USER_DATA is specified in pArr->arrFlags. * * pArr->arrSize and pArr->elemSize are always ignored, as they * are calculated from the input in pArr->arrType and pArr->arrShape. * * The pArr structure is updated with the actual array created. */ typedef int (*OADL_CreateArray_fp)(void *ctx, OadlVar *pRes, OADL_ArrayInfo *pArr); /* OADL_CreateObject(ctx, pRes, vClass) * Creates a new instance of class vClass. Note that neither * the create() nor the complete() method of the class will * be invoked; this must be done manually by the syslib. */ typedef int (*OADL_CreateObject_fp)(void *ctx, OadlVar *pRes, OadlVar vClass); /* OADL_MakePointer(ctx, pRes, ptr) * Registers the given C pointer as an OADL pointer, returning * the result in *pRes. */ typedef int (*OADL_MakePointer_fp)(void *ctx, OadlVar *pRes, void *ptr); /* OADL_DelPointer(ctx, v) * De-registers the given OADL pointer. */ typedef int (*OADL_DelPointer_fp)(void *ctx, OadlVar v); /* OADL_FindPointer(pRes, v) * Finds the C pointer referred to by OADL pointer v and returns * it in *pRes */ typedef int (*OADL_FindPointer_fp)(void *ctx, void **pRes, OadlVar v); /* OADL_GetPubName(ctx, pRes, v) * Returns the name of the public v. Same as "pubname(v)" * Note that "*pRes" will be UTF-8 encoded if the result is * a wide string. */ typedef int (*OADL_GetPubName_fp)(void *ctx, char **pRes, OadlVar v); /* OADL_GetExtName(ctx, pRes, v) * Returns the name of the extern v. * Note that "*pRes" will be UTF-8 encoded if the result is * a wide string. */ typedef int (*OADL_GetExtName_fp)(void *ctx, char **pRes, OadlVar v); /* OADL_GetObjName(ctx, pRes, v) * Returns the name of the object v. Same as "objname(v)" * Note that "*pRes" will be UTF-8 encoded if the result is * a wide string. */ typedef int (*OADL_GetObjName_fp)(void *ctx, char **pRes, OadlVar v); /* OADL_fgets(ctx, pRes, f) * Reads a string from the UTF8 stream f returning the resulting OADL * String or WideString object in *pRes */ typedef int (*OADL_fgets_fp)(void *ctx, OadlVar *pRes, OadlVar f); /* OADL_fgetc(ctx, f) * Reads a UTF8 character from the UTF8 stream f and returns * the character as *pRes (note - returns the int, not the OadlVar) */ typedef int (*OADL_fgetc_fp)(void *ctx, int *pRes, OadlVar f); /* OADL_fputc(ctx, f, c) * Puts the (possibly wide) character c into UTF8 stream f */ typedef int (*OADL_fputc_fp)(void *ctx, OadlVar f, int c); /* OADL_fputs(ctx, f, s) * Puts the 8-bit character string "s" into UTF8 stream f */ typedef int (*OADL_fputs_fp)(void *ctx, OadlVar f, const char *s, int len); /* OADL_wfputs(ctx, f, s) * Puts the 32-bit character string "s" into UTF8 stream f */ typedef int (*OADL_wfputs_fp)(void *ctx, OadlVar f, const OADL_WCH *s, int len); /* OADL_ungetc(ctx, f, c) * Pushes the character "c" back onto UTF8 stream f to be * returned by subsequent UTF8 reads */ typedef int (*OADL_ungetc_fp)(void *ctx, OadlVar f, int c); /* OADL_fopen(ctx, pRes, name, access) * Opens a UTF8 stream and returns the File result in *pRes */ typedef int (*OADL_fopen_fp)(void *ctx, OadlVar *pRes, const char *name, const char *access); /* OADL_fclose(ctx, f) * Close the UTF8 stream "f" */ typedef int (*OADL_fclose_fp)(void *ctx, OadlVar f); /* Other OADL equivalents to stdio routines. If you use * OADL_fopen, you need to use these. */ typedef int (*OADL_fflush_fp)(void *ctx, OadlVar f); typedef int64_t (*OADL_fseek_fp)(void *ctx, OadlVar, int64_t, int); typedef int64_t (*OADL_ftell_fp)(void *ctx, OadlVar); typedef int (*OADL_fread_fp)(void *ctx, void *p, int n, int s, OadlVar f); typedef int (*OADL_fwrite_fp)(void *ctx, void *p, int n, int s, OadlVar f); typedef int (*OADL_feof_fp)(void *ctx, OadlVar f); typedef int (*OADL_ferror_fp)(void *ctx, OadlVar f); typedef int (*OADL_clearerr_fp)(void *ctx, OadlVar f); /* Determines the Unicode Character Type from a given widechar value * between 0 and 0x110000. Returns -1 on error. See unicode.h for * possible character types. */ typedef int (*OADL_ucCharType_fp)(int); /* Converts a widechar value between 0 and 0x110000. Returns the * original character if no single-character conversion is found. */ typedef int (*OADL_ucToUpper_fp)(int); typedef int (*OADL_ucToLower_fp)(int); /* OADL_utf8_bytelen(src, n) * Returns the number of bytes that would be required to encode * the 32-bit string src */ typedef int (*OADL_utf8_bytelen_fp)(OADL_WCH *src, int n); /* OADL_utf8_wcharLen(src, n) * Returns the number of WCHARS that would be required to decode * the UTF-8 encoded string "src[n]" */ typedef int (*OADL_utf8_wcharlen_fp)(uint8_t *src, int n); /* OADL_utf8_encode(ctx, dst, src, n) * Copies the 32-bit string "src[n]" into the UTF8 string * "dst" which must have enough space allocated to hold the * complete string. Returns a pointer to the byte after * the last byte placed. */ typedef uint8_t *(*OADL_utf8_encode_fp)(uint8_t *dst, uint32_t *src, int n); /* OADL_utf8_decode(dst, src, len) * Decodes a UTF-8 encoded string "src[n]" into the * 32-bit string "dst" which must have enough space allocated * to hold the complete string. Returns a pointer to the * uint32 after the last uint32 placed. */ typedef uint32_t *(*OADL_utf8_decode_fp)(uint32_t *dst, uint8_t *src, int n); /* OADL_PushIntrinsic(ctx) * Increments the intrinsic depth. Returns 1 on success, 0 if * an error occured. */ typedef int (*OADL_PushIntrinsic_fp)(void *ctx); /* OADL_PopIntrinsic(ctx) * Decrements the intrinsic depth. Returns 1 on success, 0 if * an error occured. */ typedef int (*OADL_PopIntrinsic_fp)(void *ctx); /* OADL_EnumDict(ctx, dict, arg, func) * Enumerates the contents of a dictionary, passing the * arg to the func with each key/value pair. Note that * a "nil" key or value indicates an undefined entry. * Func should return 1 to terminate the enumeration * early, and 0 otherwise. * * Returns 1 if an invocation of func returned 1, * and 0 otherwise (this facilitates the search * for a specific set of keys). * * func MUST NOT provoke a garbage collection cycle */ typedef int (*OADL_EnumDict_fp)(void *ctx, OadlVar dict, void *arg, int (*func)(void *, OadlVar, OadlVar)); /* OADL_AddProc(ctx, pVar, instrs, numInst) * Adds a new proc based on the numInst instructions * in instrs. The instrs/numInst are typically based on * a cvtintr process. Result is returned in *pVar. */ typedef int (*OADL_AddProc_fp)(void *ctx, OadlVar *pVar, const uint8_t instrs[], int numInst); /* OADL_NewPublic(ctx, pVar, vName) * Creates a new public with name vName. Returns result in *pVar. */ typedef int (*OADL_NewPublic_fp)(void *ctx, OadlVar *pVar, OadlVar vName); /* OADL_NewClass(ctx, pVar, vName, vPublics) * Creates a new class with name vName (which can be nil) * and initial key-value pairs vPublics (which must be a List). * Returns result in *pVar. */ typedef int (*OADL_NewClass_fp)(void *ctx, OadlVar *pVar, OadlVar vName, OadlVar vPublics); /* OADL_RegComp(ctx, pRE, pattStr) * Compiles the PCRE pattern "pattStr" into *pRE for subsequent * use with OADL_RegEx(). Options are standard PCRE options, * found in oadlpcre.h */ typedef int (*OADL_RegComp_fp)(void *ctx, void **pRE, char *pattStr, int options); /* OADL_RegEx(ctx, pRes, re, str, first, len, options, patOffs, patOffSize) * Executes the PCRE reg exp. machine with compiled expression "RE". * The matches are returned in patOffs[]. patOffs will be * an array of [begin,end+1] pairs indicating the captured * substrings, with patOffs[0]/patOffs[1] indicating the entire * match. first/len indicate the substring which is to be matched. * Options are PCRE options, from the list found in oadlpcre.h. * The number of pairs is returned in *pRes. */ typedef int (*OADL_RegEx_fp)(void *ctx, int *pRes, void *re, char *str, int first, int len, int options, int patOffs[], int patOffSize); /* OADL_RegFree(ctx, re) * Frees a PCRE regular expression previously created by OADL_RegComp() */ typedef int (*OADL_RegFree_fp)(void *ctx, void *re); /* OADL_malloc / OADL_realloc / OADL_free * Just like libc malloc/realloc/free but with OADL * debugging hooks. Also more likely to work independent * of how malloc pools are implemented with shared libraries. */ typedef int (*OADL_malloc_fp)(void *ctx, void **pRes, int nBytes); typedef int (*OADL_realloc_fp)(void *ctx, void **pRes, void *ptr, int nBytes); typedef int (*OADL_free_fp)(void *ctx, void *ptr); /* OADL_AllocScratch - allocates scratch space that is only valid * until the next OADL_AllocScratch. No need to free this memory; * it is recycled by client of OADL_AllocScratch */ typedef int (*OADL_AllocScratch_fp)(void *ctx, void **pRes, int nBytes); /* If the extern library wants to hook/intercept say() and read(), it should * call this routine with the three entry points specified. Note that * the OADL_GetChar, OADL_SayChar, OADL_SayStr, and OADL_SayLStr functions * are NOT queryable via the normal OADL_FindProc mechanism; use the * OADL_GetIoProcs() function to get them instead. */ typedef int (*OADL_GetChar_fp)(void *ctx, OadlVar vf); typedef void (*OADL_SayChar_fp)(void *ctx, int wch); typedef void (*OADL_SayStr_fp)(void *ctx, char *s, int n); typedef void (*OADL_SayLStr_fp)(void *ctx, OADL_WCH *s, int n); typedef int (*OADL_IoProcs_fp)(void *ctx, OADL_GetChar_fp getChar, OADL_SayChar_fp sayChar, OADL_SayStr_fp sayStr, OADL_SayLStr_fp sayLStr); /* Retrieve the current IO procs */ typedef int (*OADL_GetIoProcs_fp)(void *ctx, OADL_GetChar_fp *pGetChar, OADL_SayChar_fp *pSayChar, OADL_SayStr_fp *pSayStr, OADL_SayLStr_fp *pSayLStr); /* OADL_ArrayIncr * Increment a multidimensional array index and return the * new offset to the current element. Note that a scalar may * be aliased as an array by using a rank of 0. Note also * that the proper offset to the next element (based on the * contents of index[]) is computed if an offs of 0 is * consistently provided in a loop over all elements. * * Inputs: * offs Current offset (start at 0) * rank Rank (dimensionality) of array * strides[] Array of strides, from OADL_ArrayInfo * shape[] Shape of array, from OADL_ArrayInfo * index[] Current indices of array (start at {0}) * Result: * Updated offs and index[] array */ static inline int OADL_ArrayIncr(int offs, int rank, const uint32_t strides[], const uint32_t shape[], uint32_t index[]) { int i; for (i = rank-1; i >= 0; i--) { /* Increment to next element in this rank */ if (strides) offs += strides[i]; if (shape[i] > ++index[i]) { /* We are done rolling up the odometer at this point */ break; } /* Roll over the odometer and continue with the next higher index */ index[i] = 0; /* Decrement back to beginning of this rank */ if (strides) offs -= shape[i]*strides[i]; } return offs; } /* OADL_IdxOffset * Calculates the offset to an array element given an index, rank * and strides. It is presumed that the index has been range-checked! */ static inline int OADL_IdxOffset(int rank, const uint32_t index[], const uint32_t strides[]) { int offs = 0; for (int i = 0; i < rank; i++) { offs += index[i] * strides[i]; } return offs; } #endif // ] _OADL_SYS_INCLUDED