"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "q-7.11/modules/clib/clib.q" of archive q-7.11.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 
    2 /* clib.q: C/C++ extensions for the Q language
    3    $Id: clib.q,v 1.39 2008/02/22 13:03:35 agraef Exp $ */
    4 
    5 /* This file is part of the Q programming system.
    6 
    7    The Q programming system is free software; you can redistribute it and/or
    8    modify it under the terms of the GNU General Public License as published by
    9    the Free Software Foundation; either version 2, or (at your option) any
   10    later version.
   11 
   12    The Q programming system is distributed in the hope that it will be
   13    useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15    GNU General Public License for more details.
   16 
   17    You should have received a copy of the GNU General Public License
   18    along with this program; if not, write to the Free Software
   19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
   20 
   21 /* NOTE: The POSIX system interface, which used to be part of this module, is
   22    now available as a separate 'system' module which, to reduce namespace
   23    pollution, is not part of the prelude anymore and thus has to be imported
   24    explicitly in your programs. The basic features which are so ubiquitous in
   25    Q programs that we retain them in clib (and thus in the prelude) are: C
   26    replacements for common standard library functions, additional string and
   27    GMP integer functions, extended file I/O (including C-style formatted I/O),
   28    byte strings, references, threads, filename globbing, regex and, last but
   29    not least, the exit function. You should be able to access these without
   30    further ado in any standard (i.e., "vanilla") Q installation. All other
   31    types and operations described in Section "Clib" of the manual are now
   32    implemented in the 'system' module. */
   33 
   34 import stdlib, string, tuple;
   35 
   36 /****************************************************************************/
   37 
   38 /* Manifest constants. */
   39 
   40 public var const
   41   // data sizes (useful with byte strings); if a type is undefined then its
   42   // size value is set to zero
   43   SIZEOF_CHAR, SIZEOF_SHORT, SIZEOF_INT, SIZEOF_LONG, SIZEOF_LONG_LONG,
   44   SIZEOF_FLOAT, SIZEOF_DOUBLE,
   45 
   46   // trap action values
   47   SIG_IGN, SIG_DFL, SIG_TRP,
   48 
   49   // signal numbers
   50   SIGABRT, SIGALRM, SIGFPE, SIGHUP, SIGILL, SIGINT, SIGKILL, SIGPIPE,
   51   SIGQUIT, SIGSEGV, SIGTERM, SIGUSR1, SIGUSR2, SIGCHLD, SIGCONT, SIGSTOP,
   52   SIGTSTP, SIGTTIN, SIGTTOU, SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP,
   53   SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ,
   54 
   55   // scheduling policies (setsched, getsched)
   56   SCHED_OTHER, SCHED_RR, SCHED_FIFO,
   57 
   58   // file buffering modes (setvbuf)
   59   IONBF, IOLBF, IOFBF,
   60 
   61   // file positioning modes (fseek)
   62   SEEK_SET, SEEK_CUR, SEEK_END;
   63 
   64 // retrieve system parameters
   65 
   66 private extern sys_vars;
   67 def (SIZEOF_CHAR, SIZEOF_SHORT, SIZEOF_INT, SIZEOF_LONG, SIZEOF_LONG_LONG,
   68      SIZEOF_FLOAT, SIZEOF_DOUBLE,
   69 
   70      SIGABRT, SIGALRM, SIGFPE, SIGHUP, SIGILL, SIGINT, SIGKILL, SIGPIPE,
   71      SIGQUIT, SIGSEGV, SIGTERM, SIGUSR1, SIGUSR2, SIGCHLD, SIGCONT, SIGSTOP,
   72      SIGTSTP, SIGTTIN, SIGTTOU, SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP,
   73      SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ,
   74 
   75      IONBF, IOLBF, IOFBF,
   76 
   77      SEEK_SET, SEEK_CUR, SEEK_END) = sys_vars;
   78 
   79 def SIG_IGN = -1, SIG_DFL = 0, SIG_TRP = 1,
   80   SCHED_OTHER = 0, SCHED_RR = 1, SCHED_FIFO = 2;
   81 
   82 /****************************************************************************/
   83 
   84 /* This is provided as a replacement for the built-in 'quit' function, so that
   85    you can exit your program with a given exit code. */
   86 
   87 public extern exit N;
   88 
   89 /****************************************************************************/
   90 
   91 /* C implementations of common standard library functions. These are *much*
   92    faster than the originals in stdlib.q, string.q and tuple.q. */
   93 
   94 public extern stdlib::append Xs Y, stdlib::cat Xs, stdlib::mklist X N,
   95   stdlib::nums N M, stdlib::numsby K N M, stdlib::reverse Xs,
   96   tuple::tuplecat Xs;
   97 
   98 public extern string::chars S, string::join DELIM Xs, string::split DELIM Xs,
   99   string::strcat Xs;
  100 
  101 /* fast (albeit unstable) quicksort implementation using the qsort routine
  102    from the C library */
  103 
  104 public extern sort P Xs;
  105 
  106 /****************************************************************************/
  107 
  108 /* Additional string functions. Some trivial stuff from the C library you
  109    might have been missing in Q. */
  110 
  111 /* character predicates */
  112 
  113 public extern islower C, isupper C, isalpha C, isdigit C, isxdigit C,
  114   isalnum C, ispunct C, isspace C, isgraph C, isprint C, iscntrl C, isascii C;
  115 
  116 /* convert a string to lower- or uppercase */
  117 
  118 public extern tolower S, toupper S;
  119 
  120 /****************************************************************************/
  121 
  122 /* Additional integer functions from the GMP library. */
  123 
  124 /* exact powers, integer parts of roots, powers/inverses mod K */
  125 
  126 public extern pow M N, root M N, intsqrt M;
  127 public extern powmod K M N, invmod K M;
  128 
  129 /* number-theoretic functions: probabilistic prime test, gcd, lcm,
  130    factorization helper, and Jacobi symbol */
  131 
  132 public extern isprime N;
  133 public extern gcd M N, lcm M N, remove_factor M N;
  134 public extern jacobi M N;
  135 
  136 /****************************************************************************/
  137 
  138 /* Extended file functions. Provide an extended version of fopen which handles
  139    the `+' mode for r/w files, and various other stdio-related stuff from the
  140    C library. */
  141 
  142 public extern ::fopen NAME MODE, fdopen FD MODE, freopen NAME MODE F;
  143 public extern fileno F;
  144 
  145 /* Set the buffering mode for a file. */
  146 
  147 public extern setvbuf F MODE;
  148 
  149 /* Set the encoding of a file. CODESET must be a string denoting a valid
  150    encoding name for the iconv function. This affects all subsequent text
  151    read/write operations on the file. (Only for unicode-capable systems which
  152    have iconv installed.) */
  153 
  154 public extern fconv F CODESET;
  155 
  156 /* Get a temporary file name, or a temporary file opened in "w+b" mode which
  157    will be deleted automatically when it is closed. */
  158 
  159 public extern tmpnam, tmpfile;
  160 
  161 /* File positioning functions. */
  162 
  163 public extern ftell F, fseek F POS WHENCE;
  164 public rewind F;
  165 
  166 rewind F:File				= fseek F 0 SEEK_SET;
  167 
  168 /* Alternative string input functions. */
  169 
  170 public extern gets, fgets F;
  171 public extern fget F;
  172 
  173 /* ungetc. */
  174 
  175 public extern ungetc C, fungetc F C;
  176 
  177 /* Some aliases for C aficionados. */
  178 
  179 public ::readc as getc, ::freadc F as fgetc;
  180 public ::writes S as puts, ::fwrites F S as fputs;
  181 public ::writec C as putc, ::fwritec F C as fputc;
  182 
  183 /****************************************************************************/
  184 
  185 /* C-style formatted I/O. These functions provide an interface to the C printf
  186    and scanf routines. Arguments to the printf routines and the results of the
  187    scanf routines are encoded as tuples or single non-tuple value (if only one
  188    item is read/written). */
  189 
  190 public extern printf FORMAT ARGS, fprintf F FORMAT ARGS, sprintf FORMAT ARGS;
  191 public extern scanf FORMAT, fscanf F FORMAT, sscanf S FORMAT;
  192 
  193 /****************************************************************************/
  194 
  195 /* Byte strings. The following type represents unstructured binary data
  196    implemented as C byte vectors. This data structure is used by the low-level
  197    I/O functions and other clib functions which operate on binary data. */
  198 
  199 public extern type ByteStr;
  200 
  201 public isbytestr B;			// check for byte strings
  202 
  203 isbytestr _:ByteStr			= true;
  204 isbytestr _				= false otherwise;
  205 
  206 /* Byte strings can be constructed from integers, floating point numbers,
  207    string values or lists of unsigned byte values. If X is not a list, an
  208    optional SIZE (as in bytestr (X,SIZE)) denotes the desired byte size of the
  209    object; otherwise a reasonable default size is chosen. If the specified
  210    size differs from the actual size of X, the result is zero-padded or
  211    truncated accordingly. Multiprecision integer values are encoded in the
  212    host byte order, with the least significant limb first. Negative integers
  213    are represented in 2's complement. Floating point values are encoded using
  214    double precision by default or if the byte count is sufficient (i.e., at
  215    least 8 on most systems), and using single precision otherwise. Strings are
  216    by default encoded in the system encoding. You can also specify the desired
  217    target encoding as (X,CODESET) (or (X,CODESET,SIZE) if you also need to
  218    specify a byte size). */
  219 
  220 public extern bytestr X;		// create a byte string
  221 
  222 /* Like ordinary character strings, byte strings can be concatenated, size-
  223    measured, indexed, sliced and compared lexicographically. Moreover, a byte
  224    string can be converted back to a (multiprecision) integer, floating point
  225    number, string value, or a list of byte values. When converting a string
  226    you can specify the source encoding as in bstr (B,CODESET), otherwise the
  227    system encoding is assumed. */
  228 
  229 public extern bcat Bs;			// concatenate list of byte strings
  230 public extern bsize B;			// byte size of B
  231 public extern byte I B;			// Ith byte of B
  232 public extern bsub B I J;		// slice of B (bytes I..J)
  233 public extern bcmp B1 B2;		// compare B1 and B2
  234 
  235 public extern bint B;			// convert to unsigned integer
  236 public extern bfloat B;			// convert to floating point number
  237 public extern bstr B;			// convert to string
  238 public stdlib::null B;			// check for empty byte string
  239 public bytes B;				// convert to list
  240 public ::list B;			// dito
  241 
  242 null B:ByteStr				= (#B=0);
  243 bytes B:ByteStr				= map (B!) [0..#B-1];
  244 list B:ByteStr				= bytes B;
  245 
  246 /* For convenience, the following common operators are overloaded. */
  247 
  248 #B:ByteStr				= bsize B;
  249 B:ByteStr!I:Int				= byte I B;
  250 B1:ByteStr++B2:ByteStr			= bcat [B1,B2];
  251 sub B:ByteStr I J			= bsub B I J;
  252 (B1:ByteStr=B2:ByteStr)			= (bcmp B1 B2=0);
  253 (B1:ByteStr<B2:ByteStr)			= (bcmp B1 B2<0);
  254 (B1:ByteStr>B2:ByteStr)			= (bcmp B1 B2>0);
  255 (B1:ByteStr<>B2:ByteStr)		= (bcmp B1 B2<>0);
  256 (B1:ByteStr<=B2:ByteStr)		= (bcmp B1 B2<=0);
  257 (B1:ByteStr>=B2:ByteStr)		= (bcmp B1 B2>=0);
  258 
  259 /* As of Q 7.11, clib supports a number of additional operations which allow
  260    you to treat byte strings as mutable C vectors of signed/unsigned 8/16/32
  261    bit integers or single/double precision floating point numbers. The
  262    following functions provide read/write access to elements and slices of
  263    such C vectors. Note that the given index argument I is interpreted
  264    relative to the corresponding element type. Thus, e.g., get_int32 B I
  265    returns the Ith 32 bit integer rather than the integer at byte offset I.
  266 
  267    For the get_xxx functions, the index parameter may also be a pair (I,J) to
  268    return a slice of the given byte string instead of a single element
  269    (similar to sub/bsub, but interpreting indices relative to the element
  270    type). The put_xxx functions also accept a byte string instead of an
  271    element as input, and will then overwrite the corresponding slice of the
  272    target byte string with the given source. Similar to sub/bsub, these
  273    variations of get_xxx/put_xxx are "safe" in that they automatically adjust
  274    the given indices to fit within the bounds of the target byte string. */
  275 
  276 /* NOTE: Integer arguments must fit into machine integers, otherwise these
  277    operations will fail. Integers passed for floating point arguments will be
  278    coerced to floating point values automatically. */
  279 
  280 public extern get_int8 B I, get_int16 B I, get_int32 B I;
  281 public extern get_uint8 B I, get_uint16 B I, get_uint32 B I;
  282 public extern get_float B I, get_double B I;
  283 
  284 public extern put_int8 B I X, put_int16 B I X, put_int32 B I X;
  285 public extern put_uint8 B I X, put_uint16 B I X, put_uint32 B I X;
  286 public extern put_float B I X, put_double B I X;
  287 
  288 /* Some convenience functions to convert between byte strings and lists of
  289    integer/floating point elements. */
  290 
  291 public extern int8_list B, int16_list B, int32_list B;
  292 public extern uint8_list B, uint16_list B, uint32_list B;
  293 public extern float_list B, double_list B;
  294 
  295 public extern int8_vect Xs, int16_vect Xs, int32_vect Xs;
  296 public extern uint8_vect Xs, uint16_vect Xs, uint32_vect Xs;
  297 public extern float_vect Xs, double_vect Xs;
  298 
  299 /****************************************************************************/
  300 
  301 /* Expression references. These provide a kind of pointers to expression
  302    values. References can be used to create mutable data structures which can
  303    also be shared by different threads in a multithreaded program. */
  304 
  305 public extern type Ref;			// reference type
  306 
  307 public isref REF;			// check for reference objects
  308 
  309 isref _:Ref				= true;
  310 isref _					= false otherwise;
  311 
  312 public extern ref X;			// initialize a reference object
  313 
  314 public extern put REF X;		// store a new value
  315 public extern get REF;			// retrieve the current value
  316 
  317 public (:=) X Y @ (=);			// assignment operator
  318 
  319 /* The "assignment" operator (syntactic sugar for 'put'). */
  320 
  321 X := Y					= put X Y;
  322 
  323 /* Sentinels are another, lazy kind of references which are evaluated when
  324    they are garbage-collected. There are no other access operations.
  325    Sentinels are a means to implement ordinary Q data structures which perform
  326    automatic cleanup in the same fashion as some built-in and external data
  327    types. */
  328 
  329 public extern type Sentinel;		// sentinel type
  330 
  331 public issentinel S;			// check for sentinel objects
  332 
  333 issentinel _:Sentinel			= true;
  334 issentinel _				= false otherwise;
  335 
  336 public extern special sentinel X;	// create a sentinel object
  337 
  338 /****************************************************************************/
  339 
  340 /* Multithreading. These operations are in close correspondence with POSIX
  341    1003.1b. However, some operations are named differently, and semaphores
  342    provide the extra functionality to send data from one thread to another.
  343    Mutexes are also supported, mostly for the purpose of handling critical
  344    sections involving operations with side-effects (I/O etc.). Mutexes are
  345    *not* required to make conditions work since these have their own internal
  346    mutex handling. For more information on POSIX threads, please refer to the
  347    corresponding section in the UNIX manual. */
  348 
  349 /* These functions will only work as advertised if the interpreter has been
  350    built with POSIX thread support (--with-pthread). It must also be noted
  351    that in the current implementation the interpreter effectively serializes
  352    multithreaded scripts on the reduction level and thus user-level threads
  353    cannot really take advantage of multi-processor machines. */
  354 
  355 /* Thread creation and management. */
  356 
  357 public extern type Thread;		// thread handle type
  358 
  359 public isthread THREAD;			// check for thread objects
  360 
  361 isthread _:Thread			= true;
  362 isthread _				= false otherwise;
  363 
  364 public extern thread_no THREAD;		// thread number
  365 public extern this_thread;		// handle of the current thread
  366 
  367 (T1:Thread = T2:Thread)			= (thread_no T1 = thread_no T2);
  368 (T1:Thread < T2:Thread)			= (thread_no T1 < thread_no T2);
  369 (T1:Thread > T2:Thread)			= (thread_no T1 > thread_no T2);
  370 (T1:Thread <> T2:Thread)		= (thread_no T1 <> thread_no T2);
  371 (T1:Thread <= T2:Thread)		= (thread_no T1 <= thread_no T2);
  372 (T1:Thread >= T2:Thread)		= (thread_no T1 >= thread_no T2);
  373 
  374 /* The main thread (private). Don't remove this definition, it is needed to
  375    prevent the main thread handle from being garbage collected! */
  376 
  377 private var const MAIN_THREAD = this_thread;
  378 
  379 public extern special thread X;		// start a thread, return its handle
  380 public extern return X;			// terminate thread, return X as result
  381 public extern cancel THREAD;		// cancel THREAD
  382 public extern result THREAD;		// wait for THREAD, return its result
  383 public extern yield;			// allow context switch
  384 
  385 public extern active THREAD;		// check if THREAD is active
  386 public extern canceled THREAD;		// check if THREAD was canceled
  387 
  388 /* Realtime scheduling. USE WITH CARE. */
  389 
  390 public extern setsched THREAD POL PRIO;	// set scheduling parameters
  391 public extern getsched THREAD;		// get scheduling parameters
  392 
  393 /* Mutexes. USE WITH CARE. */
  394 
  395 public extern type Mutex;		// mutex type
  396 
  397 public ismutex MUTEX;			// check for mutex objects
  398 
  399 ismutex _:Mutex				= true;
  400 ismutex _				= false otherwise;
  401 
  402 public extern mutex;			// standard, i.e., fast mutex object
  403 public extern errorchecking_mutex;	// error checking mutex object
  404 public extern recursive_mutex;		// recursive mutex object
  405 
  406 public extern lock MUTEX;		// lock MUTEX
  407 public extern unlock MUTEX;		// unlock MUTEX
  408 public extern try MUTEX;		// try MUTEX, (MUTEX,TIME) for timeout
  409 
  410 /* Conditions. */
  411 
  412 public extern type Condition;		// condition type
  413 
  414 public iscondition COND;		// check for condition objects
  415 
  416 iscondition _:Condition			= true;
  417 iscondition _				= false otherwise;
  418 
  419 public extern condition;		// new condition object
  420 
  421 public extern signal COND;		// signal COND
  422 public extern broadcast COND;		// broadcast COND
  423 public extern await COND;		// wait for COND, or (COND,TIME)
  424 
  425 /* Semaphores (semaphore queues, actually). */
  426 
  427 public extern type Semaphore;		// semaphore type
  428 
  429 public issemaphore SEM;			// check for semaphore objects
  430 
  431 issemaphore _:Semaphore			= true;
  432 issemaphore _				= false otherwise;
  433 
  434 public extern semaphore;		// semaphore object
  435 public extern bounded_semaphore MAX;	// bounded semaphore object
  436 
  437 public extern post SEM X;		// enqueue a value
  438 public extern get SEM;			// dequeue a value
  439 public extern try SEM;			// try SEM, (SEM,TIME) for timeout
  440 
  441 public extern get_size SEM;		// get the current queue size
  442 public extern get_bound SEM;		// get the max queue size (0 if none)
  443 
  444 #SEM:Semaphore				= get_size SEM;
  445 
  446 /****************************************************************************/
  447 
  448 /* Filename globbing using the shell's wildcard syntax (*, ? etc.). */
  449 
  450 public extern fnmatch PATTERN S;	// check whether S matches PATTERN
  451 public extern glob PATTERN;		// return the list of all filenames
  452 					// matching PATTERN
  453 
  454 /****************************************************************************/
  455 
  456 /* Regular expression matching using "extended" (egrep-like) syntax as defined
  457    by POSIX 1003.2/D11.2. */
  458 
  459 /* 1. Low-level interface. The following functions are directly implemented in
  460    C using the POSIX regex functions. The regmatch function searches for the
  461    first match, regnext for the next, and regdone terminates a global search
  462    still in progress. The OPTS string allows you to specify various options
  463    for the search. In particular, "g" denotes a global, "i" a
  464    case-insensitive, and "n" a "multi-line" search; see the documentation for
  465    further details. */
  466 
  467 public extern regmatch OPTS REGEX S, regnext, regdone;
  468 
  469 /* 2. High-level interface. The regex function evaluates, for each match of
  470    the given regular expression in the given string, the special EXPR
  471    argument, and returns the collection of all results as a list. The OPTS
  472    argument has the same meaning as with the low-level functions. In
  473    particular, if the "g" option is omitted, then only the first match will be
  474    reported, if any. */
  475 
  476 public special regex ~OPTS ~REGEX ~S EXPR;
  477 
  478 private special regex_next ~Xs EXPR, check ~P X Y;
  479 
  480 regex OPTS:String REGEX:String S:String EXPR
  481 				= check (regmatch OPTS REGEX S)
  482 				  (reverse (regex_next [EXPR] EXPR)) [];
  483 
  484 regex_next Xs EXPR		= check regnext
  485 				  (regex_next [EXPR|Xs] EXPR) Xs;
  486 
  487 check P:Bool X Y		= X if P;
  488 				= Y otherwise;
  489 check P X Y			= P otherwise;
  490 
  491 /* 3. Match state information. These functions are typically invoked after
  492    regmatch, regnext, or in the EXPR argument of regex, to return information
  493    about the current match. The match state is maintained on a hidden stack
  494    manipulated with the regmatch/regnext/regdone functions, hence multiple
  495    nested searches are possible. */
  496 
  497 public extern regstart, regskip, reg N, regpos N, regend N, regs;
  498 
  499 /* An expression of the form `regerr MSG', where MSG is the error message, is
  500    used to return abnormal error conditions such as bad regular expression
  501    syntax. You can redefine `regerr' as appropriate for your application. */
  502 
  503 public regerr MSG;