"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;