/usr/include/simgear/nasal/nasal.h is in libsimgear-dev 3.4.0-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | #ifndef _NASAL_H
#define _NASAL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "naref.h"
#if __GNUC__ > 2
/* This marks the function as having no side effects and depending on
* nothing but its arguments, which allows the optimizer to avoid
* duplicate calls to naNil(). */
#define GCC_PURE __attribute__((__pure__))
#else
#define GCC_PURE
#endif
typedef struct Context* naContext;
// The function signature for an extension function:
typedef naRef (*naCFunction)(naContext ctx, naRef me, int argc, naRef* args);
// The function signature for an extension function with userdata passed back:
typedef naRef (*naCFunctionU)
(naContext ctx, naRef me, int argc, naRef* args, void* user_data);
// All Nasal code runs under the watch of a naContext:
naContext naNewContext();
void naFreeContext(naContext c);
// Use this when making a call to a new context "underneath" a
// preexisting context on the same stack. It allows stack walking to
// see through the boundary, and eliminates the need to release the
// mod lock (i.e. must be called with the mod lock held!)
naContext naSubContext(naContext super);
// The naContext supports a user data pointer that can be used to
// store data specific to an naCall invocation without exposing it to
// Nasal as a ghost. FIXME: this API is semi-dangerous, there is no
// provision for sharing it, nor for validating the source or type of
// the pointer returned.
void naSetUserData(naContext c, void* p);
void* naGetUserData(naContext c) GCC_PURE;
// run GC now (may block)
void naGC();
// "Save" this object in the context, preventing it (and objects
// referenced by it) from being garbage collected.
// TODO do we need a context? It is not used anyhow...
void naSave(naContext ctx, naRef obj);
// "Save" this object and get a key which allows do mark the object as free
// later on (with naGCFree).
int naGCSave(naRef obj);
// Release an object previously passed to naGCSave to allow it being cleaned up
// by the garbage collector.
void naGCRelease(int key);
// Drop all saved references
void naClearSaved();
// Similar, but the object is automatically released when the
// context next runs native bytecode. Useful for saving off C-space
// temporaries to protect them before passing back into a naCall.
void naTempSave(naContext c, naRef r);
// Parse a buffer in memory into a code object. The srcFile parameter
// is a Nasal string representing the "file" from which the code is
// read. The "first line" is typically 1, but is settable for
// situations where the Nasal code is embedded in another context with
// its own numbering convetions. If an error occurs, returns nil and
// sets the errLine pointer to point to the line at fault. The string
// representation of the error can be retrieved with naGetError() on
// the context.
naRef naParseCode(naContext c, naRef srcFile, int firstLine,
char* buf, int len, int* errLine);
// Binds a bare code object (as returned from naParseCode) with a
// closure object (a hash) to act as the outer scope / namespace.
naRef naBindFunction(naContext ctx, naRef code, naRef closure);
// Similar, but it binds to the current context's closure (i.e. the
// namespace at the top of the current call stack).
naRef naBindToContext(naContext ctx, naRef code);
// Call a code or function object with the specified arguments "on"
// the specified object and using the specified hash for the local
// variables. Passing a null args array skips the parameter variables
// (e.g. "arg") assignments; to get a zero-length arg instead, pass in
// argc==0 and a non-null args vector. The obj or locals parameters
// may be nil. Will attempt to acquire the mod lock, so call
// naModUnlock() first if the lock is already held.
naRef naCall(naContext ctx, naRef func, int argc, naRef* args,
naRef obj, naRef locals);
// As naCall(), but continues execution at the operation after a
// previous die() call or runtime error. Useful to do "yield"
// semantics, leaving the context in a condition where it can be
// restarted from C code. Cannot be used currently to restart a
// failed operation. Will attempt to acquire the mod lock, so call
// naModUnlock() first if the lock is already held.
naRef naContinue(naContext ctx);
// Does a naCall() in a given context. Wrapped here to make lock
// tracking easier. Extension functions are called with the lock, but
// we have to release it before making a new naCall(). So rather than
// drop the lock in every extension function that might call back into
// Nasal, we keep a stack depth counter here and only unlock/lock
// around the naCall if it isn't the first one.
naRef naCallMethodCtx( naContext ctx,
naRef code,
naRef self,
int argc,
naRef* args,
naRef locals );
// Same as naCallMethodCtx but creates (and afterwards destroyes) a new context
naRef naCallMethod(naRef code, naRef self, int argc, naRef* args, naRef locals);
typedef void (*naErrorHandler)(naContext);
// Register a handler to be called if an error is raised during the execution of
// naCallMethodCtx or naCallMethod.
naErrorHandler naSetErrorHandler(naErrorHandler cb);
// Throw an error from the current call stack. This function makes a
// longjmp call to a handler in naCall() and DOES NOT RETURN. It is
// intended for use in library code that cannot otherwise report an
// error via the return value, and MUST be used carefully. If in
// doubt, return naNil() as your error condition. Works like
// printf().
void naRuntimeError(naContext c, const char* fmt, ...);
// "Re-throws" a runtime error caught from the subcontext. Acts as a
// naRuntimeError() called on the parent context. Does not return.
void naRethrowError(naContext subc);
// Retrieve the specified member from the object, respecting the
// "parents" array as for "object.field". Returns zero for missing
// fields.
int naMember_get(naContext c, naRef obj, naRef field, naRef* out);
int naMember_cget(naContext c, naRef obj, const char* field, naRef* out);
// Returns a hash containing functions from the Nasal standard library
// Useful for passing as a namespace to an initial function call
naRef naInit_std(naContext c);
// Ditto, for other core libraries
naRef naInit_math(naContext c);
naRef naInit_bits(naContext c);
naRef naInit_io(naContext c);
naRef naInit_regex(naContext c);
naRef naInit_unix(naContext c);
naRef naInit_thread(naContext c);
naRef naInit_utf8(naContext c);
naRef naInit_sqlite(naContext c);
naRef naInit_readline(naContext c);
naRef naInit_gtk(naContext ctx);
naRef naInit_cairo(naContext ctx);
// Returns a hash which can be used to add methods callable on strings
naRef naInit_string(naContext c);
// Context stack inspection, frame zero is the "top"
int naStackDepth(naContext ctx);
int naGetLine(naContext ctx, int frame);
naRef naGetSourceFile(naContext ctx, int frame);
char* naGetError(naContext ctx);
// Type predicates
int naIsNil(naRef r) GCC_PURE;
int naIsNum(naRef r) GCC_PURE;
int naIsString(naRef r) GCC_PURE;
int naIsScalar(naRef r) GCC_PURE;
int naIsVector(naRef r) GCC_PURE;
int naIsHash(naRef r) GCC_PURE;
int naIsCode(naRef r) GCC_PURE;
int naIsFunc(naRef r) GCC_PURE;
int naIsCCode(naRef r) GCC_PURE;
// Object equality (check for same instance, aka. pointer equality)
int naIsIdentical(naRef l, naRef r) GCC_PURE;
// Allocators/generators:
naRef naNil() GCC_PURE;
naRef naNum(double num) GCC_PURE;
naRef naNewString(naContext c);
naRef naNewVector(naContext c);
naRef naNewHash(naContext c);
naRef naNewFunc(naContext c, naRef code);
/**
* Register extension function
*
* @param fptr Pointer to C-function
* @param user_data Optional user data passed back on calling the function
* @param destroy Optional callback called if function gets freed by garbage
* collector to free user data if required.
*/
naRef naNewCCode(naContext c, naCFunction fptr);
naRef naNewCCodeU(naContext c, naCFunctionU fptr, void* user_data);
naRef naNewCCodeUD(naContext c, naCFunctionU fptr, void* user_data,
void (*destroy)(void*));
// Some useful conversion/comparison routines
int naEqual(naRef a, naRef b) GCC_PURE;
int naStrEqual(naRef a, naRef b) GCC_PURE;
int naTrue(naRef b) GCC_PURE;
naRef naNumValue(naRef n) GCC_PURE;
naRef naStringValue(naContext c, naRef n);
// String utilities:
int naStr_len(naRef s) GCC_PURE;
char* naStr_data(naRef s) GCC_PURE;
naRef naStr_fromdata(naRef dst, const char* data, int len);
naRef naStr_concat(naRef dest, naRef s1, naRef s2);
naRef naStr_substr(naRef dest, naRef str, int start, int len);
naRef naInternSymbol(naRef sym);
naRef getStringMethods(naContext c);
// Vector utilities:
int naVec_size(naRef v);
naRef naVec_get(naRef v, int i);
void naVec_set(naRef vec, int i, naRef o);
int naVec_append(naRef vec, naRef o);
void naVec_setsize(naContext c, naRef vec, int sz);
/**
* Remove and retrieve the first element of the vector.
*
* This operation reduces the size of the vector by one and moves all elements
* by one towards the begin of the vector.
*
* @return The element removed from the begin
*/
naRef naVec_removefirst(naRef vec);
/**
* Remove and retrieve the last element of the vector.
*
* This operation reduces the size of the vector by one.
*
* @return The element removed from the end
*/
naRef naVec_removelast(naRef vec);
// Hash utilities:
int naHash_size(naRef h);
int naHash_get(naRef hash, naRef key, naRef* out);
naRef naHash_cget(naRef hash, char* key);
void naHash_set(naRef hash, naRef key, naRef val);
void naHash_cset(naRef hash, char* key, naRef val);
void naHash_delete(naRef hash, naRef key);
/**
* Store the keys in ::hash into the vector at ::dst
*
* @see ::naNewVector
*/
void naHash_keys(naRef dst, naRef hash);
// Ghost utilities:
typedef struct naGhostType {
void(*destroy)(void*);
const char* name;
const char*(*get_member)(naContext c, void*, naRef key, naRef* out);
void(*set_member)(naContext c, void*, naRef key, naRef val);
} naGhostType;
/**
* Create a ghost for an object without any attributes. If ::t contains pointers
* to get_member or set_member function they will be ignored.
*/
naRef naNewGhost(naContext c, naGhostType* t, void* ghost);
/**
* Create a ghost for an object. This version uses the get_member and set_member
* function pointers in ::t upon trying to get or set a member respectively from
* Nasal.
*/
naRef naNewGhost2(naContext c, naGhostType* t, void* ghost);
naGhostType* naGhost_type(naRef ghost);
void* naGhost_ptr(naRef ghost);
/**
* Attach a nasal object to the given ghost. Binds the lifetime of @a data to
* the lifetime of the @a ghost.
*/
void naGhost_setData(naRef ghost, naRef data);
/**
* Retrieve the object attached to the @a ghost, previously set with
* naGhost_setData().
*/
naRef naGhost_data(naRef ghost);
int naIsGhost(naRef r);
// Acquires a "modification lock" on a context, allowing the C code to
// modify Nasal data without fear that such data may be "lost" by the
// garbage collector (nasal data on the C stack is not examined in
// GC!). This disallows garbage collection until the current thread
// can be blocked. The lock should be acquired whenever nasal objects
// are being modified. It need not be acquired when only read access
// is needed, PRESUMING that the Nasal data being read is findable by
// the collector (via naSave, for example) and that another Nasal
// thread cannot or will not delete the reference to the data. It
// MUST NOT be acquired by naCFunction's, as those are called with the
// lock already held; acquiring two locks for the same thread will
// cause a deadlock when the GC is invoked. It should be UNLOCKED by
// naCFunction's when they are about to do any long term non-nasal
// processing and/or blocking I/O. Note that naModLock() may need to
// block to allow garbage collection to occur, and that garbage
// collection by other threads may be blocked until naModUnlock() is
// called. It must also be UNLOCKED by threads that hold a lock
// already before making a naCall() or naContinue() call -- these
// functions will attempt to acquire the lock again.
void naModLock();
void naModUnlock();
// Library utilities. Generate namespaces and add symbols.
typedef struct { char* name; naCFunction func; } naCFuncItem;
naRef naGenLib(naContext c, naCFuncItem *funcs);
void naAddSym(naContext c, naRef ns, char *sym, naRef val);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _NASAL_H
|