ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libukcprog/doc/ukcprog.3
Revision: 1.1
Committed: Sat Mar 29 16:30:32 2003 UTC (21 years, 8 months ago) by tdb
Branch: MAIN
Log Message:
libukcprog is now a seperate package. I doubt this will be much use to
anyone other than us, but I see no reason why we can't package it up
and distribute it. Obviously we can't attach the GPL to this, as we
don't own it.

File Contents

# Content
1 .\" $Id: ukcprog.3,v 1.18 1993/02/23 11:31:42 gjap Exp $ UKC
2 .\" .fX - print the argument in a fixed font
3 .de fX
4 \&\\$3\f(CR\\$1\fP\\$2
5 ..
6 .\" .Vs - start example
7 .de Vs
8 .LP
9 .ne 1i
10 .RS
11 .nf
12 .ft CR
13 ..
14 .\" .Ve - end example
15 .de Ve
16 .ft P
17 .fi
18 .hy 0
19 .RE
20 .LP
21 ..
22 .TH UKCPROG 3 "February 1991" "UKC Local"
23 .SH NAME
24 ukcprog \- Library of utilities for C programmers
25 .SH SYNOPSIS
26 .nf
27 .LP
28 In source code,
29 .Vs
30 #include <local/ukcprog.h>
31 .Ve
32 and link with
33 .Vs
34 cc ... -lukcprog
35 .Ve
36 .SH AVAILABILITY
37 .LP
38 .\"
39 .\" The following sentence motivated the port to MS-DOG.
40 .\"
41 This is a UKC library, available for the \s-1UNIX\s0 and \s-1VMS\s0
42 operating systems, and for MS-DOS.
43 .\"
44 .\" It was worth it ...
45 .\"
46 The source code is freely available so if you want to make
47 a source release of your application you can include a copy of the
48 source of this library as well.
49 To obtain a copy of the source code contact either of the authors
50 named below.
51 .SH DESCRIPTION
52 .LP
53 The ukcprog library contains generally useful low level routines.
54 The
55 .fX ukcprog.h
56 header file contains prototypes for the
57 routines as well as defining some useful macros and types.
58 .Vs
59 #ifdef __STDC__
60 #define PROTO(a) a
61 typedef void *voidptr;
62 #else
63 #define PROTO(a) ()
64 #define const
65 #define volatile
66 #define signed
67 typedef char *voidptr;
68 #endif
69 .Ve
70 .LP
71 The definitions of
72 .fX const ,
73 .fX volatile
74 and
75 .fX signed
76 allow these ANSI C keywords to be used in code which must be portable
77 to pre-ANSI C compilers.
78 .LP
79 The
80 .fX voidptr
81 typedef is similarly there to help with code for pre-ANSI compilers
82 which do not support the
83 .fX "void *" ' `
84 type.
85 Functions which are documented here as returning
86 .fX "void *" ' `
87 return
88 .fX "char *" ' `
89 when compiling with a non-ANSI C compiler.
90 .LP
91 The
92 .fX PROTO
93 macro is useful for declaring function prototypes
94 for use with ANSI C while still allowing the code to be compiled with
95 K&R compilers.
96 It is used thus:
97 .Vs
98 int myfunc PROTO((int arg1, char *arg2));
99 .Ve
100 With an ANSI C compiler this expands to
101 .Vs
102 int myfunc (int arg1, char *arg2);
103 .Ve
104 whereas a pre-ANSI compiler sees:
105 .Vs
106 int myfunc ();
107 .Ve
108 .LP
109 Note the double brackets; these are necessary to make all the parameters
110 a single argument to the
111 .fX PROTO
112 macro.
113 .Vs
114 #ifndef FALSE
115 #define FALSE 0
116 #endif
117 #ifndef TRUE
118 #define TRUE 1
119 #endif
120 #ifndef bool
121 #define bool int
122 #endif
123 .Ve
124 These define the commonly used
125 .fX TRUE
126 and
127 .fX FALSE
128 macros to their usual values.
129 The definitions are protected in case these are already defined.
130 The
131 .fX bool
132 macro is intended to be used to declared variables
133 that are conceptually boolean.
134 A
135 .fX #define
136 is used rather than a typedef because there might already be a typedef
137 for
138 .fX bool .
139 .Vs
140 #ifdef __STDC__
141 #define CAT(a,b) a ## b
142 #else
143 #define _IDENT(a) a
144 #define CAT(a,b) _IDENT(a)b
145 #endif /* !__STDC__ */
146 .Ve
147 The
148 .fX CAT
149 macro can be used to glue two tokens together in the same way as
150 the ANSI C
151 .fX ##
152 operator.
153 .fX CAT
154 also works with many (but not all) pre-ANSI C preprocessors.
155 .Vs
156 void panic(const char *message)
157 .sp
158 typedef void (*panic_handler_t)(const char *message);
159 panic_handler_t install_panic_handler(panic_hander_t handler)
160 .Ve
161 By default
162 .fX panic()
163 produces a message on stderr of the form
164 .Vs
165 fatal internal error: \fIsomething\fP (aborting)...
166 .Ve
167 It then calls
168 .fX abort(3)
169 to produce a core dump.
170 Alternative `panic handlers' can be installed using
171 .fX install_panic_handler()
172 which returns the previous handler.
173 Panic handlers can perform tidy-up tasks, such as
174 removing temporary files or calling
175 .fX chdir(2)
176 to arrange for
177 the core to land in a safe place.
178 If a panic handler is called and returns then the default
179 action is carried out.
180 .Vs
181 void *e_malloc(size_t size)
182 void *e_realloc(void *old, size_t size)
183 char *strsave(const char *str)
184 .Ve
185 .fX e_malloc()
186 and
187 .fX e_realloc()
188 are error-checking versions
189 of the corresponding routines in the standard C library.
190 They call
191 .fX panic()
192 if the request fails.
193 .fX e_realloc()
194 behaves according to the ANSI specification for
195 .fX realloc() ;
196 that is, if
197 .fX old
198 is NULL it behaves like
199 .fX malloc()
200 and if size is 0, it behaves like
201 .fX free() .
202 .fX strsave()
203 allocates some memory using
204 .fX e_malloc() ,
205 copies
206 .fX str
207 into it, and returns a pointer to the copy.
208 .Vs
209 char *fpgetline(FILE *fp)
210 .Ve
211 .fX fpgetline()
212 reads characters from the standard IO stream
213 .fX fp
214 until a newline character or EOF is encountered.
215 .fX fpgetline()
216 returns
217 .fX NULL
218 if EOF or an error occurred before any characters were read;
219 otherwise it returns a pointer to the NUL terminated line.
220 .fX fpgetline()
221 never adds a newline to the buffer.
222 The user can check for a missing final newline in a file by checking
223 the EOF flag of the stream pointer when
224 .fX fpgetline()
225 returns a non-NULL pointer.
226 .LP
227 When
228 .fX fpgetline()
229 returns
230 .fX NULL
231 the caller should check with
232 .fX ferror(3)
233 whether the cause was EOF or an error reading the stream
234 .fX fp .
235 .LP
236 .fX fpgetline()
237 returns a pointer to a static buffer that is resized as necessary
238 to handle long lines.
239 The caller can modify the contents of the buffer but must not free
240 it or realloc it.
241 The buffer is valid only until the next call of
242 .fX fpgetline() .
243 .Vs
244 char *config_trim_line(char *line)
245 .Ve
246 .fX config_trim_line()
247 trims comments and white space in place from a line.
248 First it scans for the first
249 .fX # ' `
250 character in the line.
251 If there is one it is removed along with any following characters.
252 Then leading and trailing whitespace characters (as defined by
253 .IR isspace (3))
254 are removed.
255 .fX config_trim_line()
256 returns a pointer to the trimmed line (which will point into the line
257 that it was given).
258 .LP
259 A typical use of this routine is to skip blank lines and comments from
260 a configuration file.
261 .Vs
262 typedef void (*errf_ofunc_t)(const char *string);
263 .sp
264 void errf(const char *fmt, ...)
265 char *strf(const char *fmt, ...)
266 .sp
267 errf_ofunc_t errf_set_ofunc(errf_ofunc_t func)
268 const char *errf_set_prefix(const char *prefix)
269 const char *errf_get_prefix(void)
270 void_errf_set_progname(const char *progname)
271 const char *errf_get_progname(void)
272 char *formf(char *buffer, int buffer_size,
273 const char *format, va_list args)
274 void errf_usage(const char *usage)
275 .Ve
276 These routines form the basis of a generalised error handling system.
277 .fX errf()
278 formats an error message, much like
279 .fX printf(3) ,
280 but then passes the formatted text to the `current output function'.
281 The default output function appends a newline to the message and
282 sends it to stderr.
283 An alternative output function can be installed with
284 .fX errf_set_ofunc() ;
285 it returns the old one which can be re-installed as required.
286 The default output function can optionally prefix the message with
287 a fixed string; this can be inserted with
288 .fX errf_set_prefix() .
289 A pointer to the current prefix is returned by
290 .fX errf_get_prefix() .
291 By convention, this prefix is derived from the name of the program.
292 .fX errf_set_progname()
293 is a convenience routine which, when passed
294 .fX argv[0] ,
295 munges it in an operating system specific way to produce the program name
296 and sets the prefix to something that looks `nice'.
297 A pointer to the program name (after munging) can be obtained by
298 .fX errf_get_progname().
299 A usage line can be sent to the current output function by
300 .fX errf_usage() ;
301 it prefixes
302 .Vs
303 Usage: \fIprogname\fP
304 .Ve
305 to its argument, and exits with status 1.
306 .LP
307 .fX strf()
308 formats a string in the same way as
309 .fX errf() ,
310 but returns a pointer to a buffer obtained from
311 .fX malloc(3)
312 that
313 contains the result.
314 .LP
315 .fX formf()
316 is used in the internal implementation of
317 .fX errf()
318 and
319 .fX strf()
320 and
321 .fX logf()
322 (see below) and is not for the faint-hearted.
323 It is made visible because it is useful if you need to implement
324 other
325 .fX errf() "-style"
326 functions.
327 In addition to the normal format conversions,
328 .fX formf()
329 provides
330 .fX %m ' `
331 which inserts an error message
332 corresponding to the current value of
333 .fX errno
334 into the output string.
335 .Vs
336 int logf_set_ofile PROTO((const char *filename, const char *prefix));
337 void logf(int level, const char *fmt, ...)
338 int logf_set_level PROTO((int level));
339 void logf_errf_ofunc PROTO((const char *str));
340 .Ve
341 These routines are an alternative to
342 .I syslog (3)
343 for applications that need to log messages to a specified file.
344 .fX logf()
345 handles the
346 .fX fmt
347 format string and arguments in the same same way as
348 .fX errf() .
349 If there has been no prior call to
350 .fX logf_set_ofile ()
351 (see below) the message is
352 displayed on stderr, prefixed with the current date and time.
353 If the output
354 .I is
355 going to a file,
356 .fX logf()
357 tries to ensure that messages from multiple processes to a single log
358 file are interleaved correctly.
359 .LP
360 The
361 .fX level
362 argument specifies the class of the message; it is one of
363 .fX LG_DEBUG ,
364 .fX LG_INFO ,
365 or
366 .fX LG_ERR
367 (which are in increasing numerical order).
368 Messages at a level less than the current log level are discarded.
369 The default log level is
370 .fX LG_INFO ;
371 it can be set using
372 .fX logf_set_level() ,
373 which also returns the previous log level.
374 The log levels
375 .fX LG_ALL
376 and
377 .fX LG_LOG
378 are valid only in calls to
379 .fX logf_set_level() ;
380 .fX LG_ALL
381 means log all messages and
382 .fX LG_LOG
383 means log only messages relating to
384 .fX logf()
385 itself.
386 .LP
387 .fX logf_set_ofile()
388 sets the output file for
389 .fX logf()
390 messages.
391 If the log file does not exist
392 .fX logf_set_ofile()
393 attempts to create it; otherwise it is opened for writing (without
394 discarding any existing contents).
395 If the attempt to create or open the file fails,
396 .fX logf_set_ofile()
397 gives an error message and returns -1, otherwise it returns zero.
398 If the
399 .fX prefix
400 argument is not
401 .fX NULL ,
402 the string specified is prepended to all future log messages.
403 .fX logf_set_ofile()
404 makes a copy of the string so it need not be preserved after the call.
405 .LP
406 .fX logf_errf_ofunc()
407 logs the message
408 .fX str
409 at level
410 .fX LG_ERR .
411 It can be passed as an output function to
412 .fX errf_set_ofunc()
413 to arrange that all error messages are sent to a log file.
414 .Ve
415 .fX ssplit()
416 splits a string into a vector of words, treating
417 occurrences in the string of any of the characters in the
418 .fX delimiters
419 string as word separators.
420 .LP
421 If the delimiters string starts with a NUL character then multiple
422 adjacent delimiters and leading delimiters generate zero length fields.
423 Otherwise, leading delimiter characters are skipped and multiple adjacent
424 delimiters are treated as a single delimiter.
425 Thus
426 .Vs
427 char **words = ssplit(line, " \\t");
428 .Ve
429 will to a shell-like split of a command line into words, and
430 .Vs
431 char **fields = ssplit(pwline, "\\0:");
432 .Ve
433 would be good for splitting lines from the password file.
434 .LP
435 .fX ssplit()
436 returns a
437 .fX NULL
438 terminated vector of words.
439 The space for this vector and the pointed to words is allocated with
440 a (single) call to
441 .fX e_malloc() .
442 .fX ssplit()
443 thus never returns
444 .fX NULL ;
445 it aborts the program
446 by calling
447 .fX panic()
448 if memory runs out.
449 .LP
450 The vector returned by
451 .fX ssplit()
452 should be freed when it is finished
453 with by passing it to
454 .fX free() .
455 .Vs
456 int get_host_addr(const char *hostname, struct in_addr *p_addr)
457 .Ve
458 .fX get_host_addr()
459 looks up the IP address of
460 .fX hostname
461 using
462 .IR gethostbyaddr (3).
463 If the lookup succeeds it sets
464 .fX *p_addr
465 to the IP address of the host in network byte order.
466 If the lookup fails it gives an error message with
467 .fX errf()
468 and returns -1.
469 If
470 .fX hostname
471 consists of four decimal numbers separated by dots then
472 .fX get_host_addr
473 parses this as an IP quad and does not call
474 .IR gethostbyname .
475 .Vs
476 int get_service_port(const char *servname, int *p_port)
477 .Ve
478 .fX get_service_port
479 looks up the port number of the TCP service
480 .fX servname
481 using
482 .IR getservbyname (3).
483 If it succeeds it sets
484 .fX *p_port
485 to the port number in network byte order.
486 Otherwise it gives an error message with
487 .fX errf()
488 and returns -1.
489 If
490 .fX servname
491 is an \s-2ASCII\s0 decimal number then
492 .fX get_service_port()
493 returns that number (again in network byte order).
494 .Vs
495 ebuf_t *ebuf_create(bool errors_are_fatal);
496 void ebuf_reset(ebuf_t *eb);
497 ebuf_t *ebuf_start(ebuf_t *eb, bool errors_are_fatal);
498 int ebuf_add(ebuf_t *eb, const char *buf, int count);
499 char *ebuf_get(ebuf_t *eb, int *p_len);
500 void ebuf_free(ebuf_t *eb);
501 .Ve
502 These routines implement variable sized contiguous buffers to which data
503 can be appended at any time.
504 .fX ebuf_create()
505 creates a new zero length buffer.
506 The
507 .fX errors_are_fatal
508 parameter controls the handling of errors; if it is
509 .fX TRUE
510 then all of the routines will call
511 .fX panic()
512 on failure.
513 .LP
514
515 .fX ebuf_add()
516 appends
517 .fX count
518 bytes of memory pointed at by
519 .fX data
520 to the buffer
521 .fX eb
522 (which must have been created using
523 .fX ebuf_create() ).
524 .fX ebuf_add()
525 returns zero on success.
526 On failure it panics or returns
527 .fX -1
528 (depending on the setting of
529 .fX errors_are_fatal
530 in the call of
531 .fX ebuf_create()).
532 .LP
533 .fX ebuf_get()
534 returns a pointer to the current contents of
535 .fX eb ;
536 if the
537 .fX p_len
538 parameter is not
539 .fX NULL
540 the current length of the buffer in bytes is stored there.
541 The returned buffer and length are only valid up to the next call of
542 .fX ebuf_add() ,
543 .fX ebuf_reset()
544 or
545 .fX ebuf_free().
546 .LP
547 .fX ebuf_reset()
548 frees the data associated with
549 .fX eb
550 and resets the length to zero.
551 Furthur calls of
552 .fX ebuf_add()
553 can be used to add fresh data to
554 .fX eb .
555 .fX ebuf_free()
556 frees and destroys
557 .fX eb .
558 .LP
559 .fX ebuf_start()
560 is a convenience routine which either creates or resets a buffer.
561 If
562 .fX eb
563 is
564 .fX NULL
565 it calls
566 .fX ebuf_create()
567 with the supplied value of
568 .fX errors_are_fatal .
569 If
570 .fX eb
571 is not
572 .fX NULL
573 then it is passed to
574 .fX ebuf_reset().
575 The routine is intended to be used like for static buffers in the following
576 way:
577 .Vs
578 void foo(void)
579 {
580 static ebuf_t *eb = NULL;
581
582 eb = ebuf_start(eb, TRUE);
583 ...
584 }
585 .Ve
586 The first time the function is called the buffer is created; on subsequent
587 calls it is reset.
588 .Vs
589 alloc_pool_t *alloc_create_pool(void)
590 .sp
591 void *alloc(alloc_pool_t *ap, int nbytes)
592 void *alloc_ck(alloc_pool_t *ap, int nbytes)
593 .Ve
594 .fX alloc_create_pool()
595 creates a memory allocation `pool' and
596 returns a handle referring to it.
597 .fX alloc()
598 allocates memory like
599 .fX malloc(3)
600 but from the
601 specified pool rather from the general malloc arena.
602 .fX alloc()
603 calls
604 .fX e_malloc()
605 to obtain memory in reasonably
606 large chunks when necessary.
607 This means that it never returns
608 .fX NULL ;
609 the program is aborted
610 via
611 .fX panic()
612 if there is insufficient memory to satisfy the
613 request.
614 The alternative interface
615 .fX alloc_ck()
616 returns
617 .fX NULL
618 if
619 it runs out of memory; it is otherwise identical to
620 .fX alloc() .
621 Memory obtained with
622 .fX alloc()
623 cannot be freed individually; only
624 entire pools can be freed.
625 .Vs
626 void alloc_free_pool(alloc_pool_t *ap)
627 void alloc_reset_pool(alloc_pool_t *ap)
628 .Ve
629 .fX alloc_free_pool()
630 frees an alloc pool, releasing all memory
631 allocated from it with
632 .fX alloc() .
633 The pool is no longer valid after this call.
634 .fX alloc_reset_pool()
635 conceptually frees all the memory associated with
636 a pool but does not return it via
637 .fX free() .
638 The pool remains valid and subsequent calls to
639 .fX alloc()
640 allocate
641 memory from the existing memory associated with the pool if possible.
642 .LP
643 These routines are suitable for applications which make lots of small
644 allocations for a data structure which is to be freed in one go.
645 .fX alloc()
646 is much faster than
647 .fX malloc()
648 as it does not do
649 the bookkeeping to support individual freeing of allocated memory.
650 It also has no space overhead other than that necessary to correctly
651 align objects in memory.
652 .LP
653 .fX alloc_create_pool()
654 is a lightweight routine \- it involves a
655 single call to
656 .fX malloc()
657 plus some assignments to initialise the
658 pool header structure.
659 It is thus reasonable to use the
660 .fX alloc()
661 routines in situations where
662 there are only going to be a few tens of calls to
663 .fX alloc() .
664 .Vs
665 bool alloc_set_default_debug_flag(bool val)
666 bool alloc_set_debug_flag(alloc_pool_t *ap, bool val)
667 .Ve
668 By default all memory obtained with
669 .fX alloc()
670 and related routines
671 is initialised to the repeated byte
672 .fX 0x53 .
673 When memory is freed (with
674 .fX alloc_free_pool() ,
675 .fX alloc_reset_pool()
676 or
677 .fX alloc_release() )
678 it is set
679 to the repeated byte
680 .fX 0x42 .
681 This is intended to trap erroneous use of uninitialised data and data
682 that has been freed \- newly allocated memory contains obvious garbage
683 and freed memory is immediately stamped on.
684 .LP
685 Of course these safety features cost speed, so they can be turned off
686 globally or per-pool.
687 .fX alloc_set_debug_flag()
688 sets the debugging flag for a pool; memory
689 will be initialised to garbage and stamped on when freed only of the flag
690 is non-zero.
691 .fX alloc_set_default_debug_flag()
692 sets the value of the flag used
693 for pools created from then on with
694 .fX alloc_create_pool() .
695 Both routines return the previous value of the flag they set.
696 .Vs
697 char *allocstr(alloc_pool_t *ap, int nbytes)
698 char *allocstr_ck(alloc_pool_t *ap, int nbytes)
699 .Ve
700 .fX allocstr()
701 is like
702 .fX alloc()
703 except that it assumes that
704 no alignment is required.
705 It is thus suitable only for allocating space for strings.
706 .fX allocstr()
707 is implemented such that interspersed calls to
708 .fX alloc()
709 and
710 .fX allocstr()
711 will pack both
712 the strings and the other objects tightly in memory with no space
713 wasted on alignment.
714 .fX allocstr()
715 never returns
716 .fX NULL
717 \- it panics like
718 .fX alloc()
719 if there is no memory.
720 .fX allocstr_ck()
721 is the same as
722 .fX allocstr()
723 except that
724 it returns
725 .fX NULL
726 if there is no memory.
727 .Vs
728 char *alloc_strdup(alloc_pool_t *ap, const char *s)
729 .Ve
730 .fX alloc_strdup()
731 is a convenience routine that returns a pointer
732 to a copy of a string allocated using
733 .fX allocstr() .
734 Note that it will never return
735 .fX NULL
736 as it uses
737 .fX allocstr()
738 rather than
739 .fX allocstr_ck() .
740 .Vs
741 alloc_mark_t *alloc_mark(alloc_pool_t *ap)
742 void alloc_release(alloc_pool_t *ap, alloc_mark_t *am)
743 .Ve
744 .fX alloc_mark()
745 returns an opaque handle that `remembers' the
746 current position in an alloc pool.
747 A subsequent call to
748 .fX alloc_release()
749 conceptually frees all
750 memory allocated from the pool since the corresponding call of
751 .fX alloc_mark() .
752 Subsequent calls to
753 .fX alloc()
754 et al will reuse the freed memory.
755 A call to
756 .fX alloc_release()
757 renders invalid any marks that were
758 returned after the
759 .fX alloc_mark()
760 call that returned the mark
761 being passed to
762 .fX alloc_release() .
763 .Vs
764 const char *ukcprog_version(void)
765 .Ve
766 .fX ukcprog_version()
767 returns a string giving the current version number of the library.
768 .SH BUGS
769 This library treads rather freely on the name space.
770 .SH AUTHORS
771 .LP
772 Godfrey Paul (gjap@ukc.ac.uk)
773 .br
774 Mark Russell (mtr@ukc.ac.uk)
775 .sp
776 Computing Laboratory, University of Kent at Canterbury.