COHERENT manpages

This page displays the COHERENT manpage for libmisc [Library of miscellaneous functions].

List of available manpages
Index


libmisc -- Library

Library of miscellaneous functions

libmisc is a library of miscellaneous C functions.  These functions perform
such  useful tasks  as  handling such  programming tasks  as allocation  of
memory,  copying  strings,  displaying  variables  from C  with  COBOL-like
``picture''  descriptions,  and  supporting  virtual arrays  via  secondary
storage.

Source  code   for  libmisc   is  kept   in  the  compressed   tar  archive
/usr/src/misc.tar.Z. To  extract the files  into a new  subdirectory called
misc, type the command:

    zcat /usr/src/misc.tar.Z | tar xvf -

To build the library, type the following:

    cd misc
    make

This compiles the libmisc routines and builds the library libmisc.a.

Archive misc.tar also includes  the header file misc.h which protypes these
functions, and  declares the global variables and  constants they use.  You
must include this  header file in any program that  uses any of the libmisc
functions.

Functions

The following summarizes the functions in libmisc.a:

char * alloc(n) unsigned n;
     malloc() n bytes and initialize them to zero.  Abort on failure.

int approx(a, b) double a, b;
     If a  and b  are within epsilon,  return one; otherwise,  return zero.
     epsilon is a visable double.

char *ask(reply, msg, ...) char *reply, *msg;
     Print a  message and  retrieve the user's  reply.  msg is  a printf()-
     style format  string that formats the text pointed  to by any trailing
     arguments.  ask() constructs the prompt message from msg and prints it
     on the standard output; then reads a line from stdin, stores it in the
     place pointed to by reply,  and returns its address.  reply must point
     to enough space to hold the user's reply.

     For example,

         sscanf(ask(buff, "%d numbers", 3), &a, &b, &c);

     prints the message

         Enter: 3 numbers

     writes the user's reply into buff, and hands its address to sscanf().

void banner(word, pad) char *word; int pad;
     Print word on stdout as a banner, preceded by pad spaces.  Each letter
     of the  banner is fashioned from many occurrences  of itself.  This is
     especially  useful  if  you wish  your  listings  to  look like  truly
     professional, mainframe printouts.

bedaemon()
     bedaemon() turns  the calling  program into a  daemon.  A daemon  is a
     process that executes in the background, without the usual connections
     to standard  I/O streams and terminals.  Examples  are cron and uuxqt.
     To ensure  proper operation in connection  with other system software,
     any program that you intend to  run as a daemon should call bedaemon()
     as  its  first  step.   This  call  closes  all  inherited,  open-file
     descriptors, detaches the process from its inherited process group and
     controlling terminal, sets current directory to `/', and sets umask to
     zero.  For  further information on daemon  processes, see Unix Network
     Programming by W. Richard Stevens (Englewood Cliffs, NJ, Prentice-Hall
     Inc, 1990), §2.6.

unsigned short crc16(p) char *p;
     Compute  the 16-bit  cyclic  redundency check  (crc16)  of the  string
     pointed to  by p,  and return  it.  This function  is very  useful for
     building hash tables or checking differences between strings.

void fatal(msg, ...) char *msg;
     Print  an error  message  and call  exit(1). msg  is a  printf()-style
     format string; trailing arguments must to point to data.

char *getline(ifp, lineno) FILE *ifp; int *lineno;
     Get  a line  from the  input  file pointed  to by  ifp. This  function
     returns the address of the line,  or NULL to indicate the end of file.
     getline() calls  malloc() to  acquire space  for the line,  and allows
     lines to be continued with a \-whitespace.  It also implements lineno.

     getline() recognizes the following escape sequences:

         #   to end of line is passed
         \   whitespace through end of line is passed
         \n  newline
         \p  literal `#'
         \a  alarm
         \b  backspace
         \r  carrage return
         \f  form feed
         \t  tab
         \\  backslash
         \ddd    octal number

     All other \ sequences are errors that getline() reports on stderr.

tm_t *jday_to_tm(jd) jday_t jd;
     Turn a  Julian date to  tm (time) structure.   The Julian date  is the
     number of days since the  beginning of the Julian calendar, January 1,
     4713 B.C.;  it is a  good way to  store dates in  a system-independent
     manner,  such as  in  a data  base.   Structure jday_t  is defined  in
     misc.h.  Structure tm is defined in <time.h>.

time_t jday_to_time(jd) jday_t jd;
     Turn Julian  date structure to COHERENT time.   Type time_t is defined
     in header file <sys/types.h>.

void splitter(ofp, line, limit) FILE *ofp; char *line; int limit;
     Write line  into file  ofp, splitting it  into chunks less  than limit
     bytes long.  splitter() inserts a \ between chunks, and attempts to do
     this  on  white-space boundaries.   splitter()  produces  a long  line
     rather  than split  on  non-whitespace.  If  line  does not  end in  a
     newline, splitter() adds one.  This is the inverse of getline().

int is_fs(special) char *special;
     Check whether  special names a well-formed  file system.  Users should
     never put  file systems on  /dev/ram1, but for  multi-system software,
     like compress, it is smart to test.

     is_fs() returns -1  if special is not a device,  or if open(), read(),
     or seek() fails.  It returns zero  if no file system was found, or one
     if special names a legal file system.

char *lcase(st) char *str;
     Convert every  character in str  to lower case.  Note  that this works
     only with the U.S. dialect of English; it does not work with German or
     other languages  that use  characters in the  upper half of  the ASCII
     table.

char *match(string, pattern, fin) char *string, *pattern, **fin;
     match() resembles pnmatch(), except that it returns the address of the
     pattern matched.  fin is aimed past the end of the pattern found; that
     is, match() finds a pattern and tells you where it is.

char *metaphone(word) char *word;
     Translate word  into a short phonetic equivalent  for easy lookup.  It
     resembles  Knuth's soundex  method,  except that  it  uses a  superior
     algorithm.

char *newcpy(str) char *str;
     Create  a NUL-terminated  copy of  str and  return its  address.  Call
     fatal() if there is no space.

char *pathn(name, envpath, deflpath, access)
char *name, *envpath, *deflpath, *access;
     pathn() looks for file name.  It searches the directories named in the
     environmental variable envpath. If the user has not set envpath, or if
     it is NULL, pathn() searches the default path deflpath. name must have
     access permission.   pathn() returns the full path  to the file found.
     For example:

         pathn("helpfile", "LIBPATH", "/lib", "r")

     searches the directories named in LIBPATH for file helpfile, for which
     the user  must have read  permission.  If LIBPATH is  not set, pathn()
     searches /lib for helpfile.

#include <regexp.h>
regexp *regcomp(exp) char *exp;
int regexec(prog, string) regexp *prog; char *string;
regsub(prog, source, dest) regexp *prog; char *source; char *dest;
regerror(msg) char *msg;
     These  functions  implement  a  standard  method for  parsing  regular
     expressions.  regcomp() turns a regular expression into a structure of
     type regexp  and returns  a pointer  to it.  regexec()  matches string
     against  the regular  expression in  prog.  It  returns one  if string
     matches exp, and zero if it does not.  regsub() copies source to dest,
     and  makes  substitutions  according  to  the  most  recent  regexec()
     performed  using prog.   regerror()  is called  whenever  an error  is
     detected  in regcomp(),  regexec(),  or regsub().  See regexp.doc  for
     details.

long randl()
     Return  a  long  random number  uniformly  distributed  between 1  and
     2,147,483,562.  This comes  from Communications of the ACM, volume 31,
     number 6.  See srandl(), below.

char *replace(s1, pat, s3, all, matcher) char *s1, *pat, *s3, (matcher)();
     Replace one or  all occurrences of pat in string  s1 by s3, and return
     the result.  The definition of match is set by matcher. This calls the
     user-defined function

         matcher(sw, pat, &amp;fin).

     The matcher must  return the address of the pattern  match and its end
     in &amp;fin.  match() is a  valid example of matcher.  It replaces the
     first occurrence,  or all occurrences of the  pattern, and returns the
     new pattern.  The new pattern has been alloc()'d.

showflag(data, flags, output) long data; char *flags, *output;
     Turn  the bits in  data to  the flags  in flags or  `-' in  the string
     output, which must be as long as flags.

char *skip(s1, matcher, fin) char *s1, **fin; int (*matcher)();
     Skip  all initial  characters  in string  s1 that  fail when  examined
     matcher. matcher is  usually a character function, e.g., isdigit(). It
     returns  the  first  character  skipped.   skip()  points fin  at  the
     character after the skip.

char *span(s1, matcher, fin) char *s1, **fin; int (*matcher)();
     Span all  initial characters in string s1 that  match when examined by
     matcher. matcher is  usually a character function, e.g., isdigit(). It
     returns  the  first  character  spanned.   span()  points fin  at  the
     character after the span.

srandl(seed1, seed2) long seed1, seed2;
     randl() needs two seeds; srandl() sets  them.  Use it only if you need
     to repeat a random-number sequence.

strchtr(from, to, c, def)
char *from, *to; int c, def;
     Look up  the character c in the string  from. Return the corresponding
     character  in the  string to  if  it is  found; otherwise,  return the
     default character def.

     For example, consider the call:

         strchtr("ab", "xy", c, d);

     If variable c equals `a', then strchtr() returns `x'; if c equals `b',
     then it returns `y'; otherwise, it returns the value of d

strcmpl(s1, s2)
     Case-insensitive string comparison.  Resembles strcmp().

jday_t time_to_jday(time) time_t time;
     Turn COHERENT  time to Julian date structure.  The  Julian date is the
     number of days since the  beginning of the Julian calendar, January 1,
     4713 B.C.  The structure jday_t  is defined in misc.h.  Type time_t is
     defined in <sys/types.h>.

jday_t tm_to_jday(tm) tm_t *tm;
     Turn the time structure tm date into Julian date structure.  Structure
     tm is defined in <time.h>.

char *trim(s) char *s;
     Remove trailing whitespace from string s.

ucase(s) char *s;
     Convert a string to upper case.

usage(s) char *s;
     Print string s and call exit(1).

xdump(p, length) char *p;
     Print on stdout a vertical hexadecimal dump of string p.

     A vertical  hexadecimal dump prints  as three lines.  The  top line is
     the display  character, or  `.' if  the character cannot  be displayed
     cleanly.  The  next two lines are the  hexadecimal numerals.  The data
     are blocked into groups of four bytes.

xopen(filename, acs) char *filename, *acs;
     Like fopen(), but call fatal() if the open fails.

yn(question, ...) char *question;
     Ask  a question  and retrieve  a  `Y' or  `N' answer.   question is  a
     printf()-style format string;  any trailing parameters should point to
     data used  in question. yn()  returns one if  the user answers  `Y' or
     `y', and returns zero if she answers `N' or `n'.

Virtual Memory

The following  functions are part  of a virtual memory  system for COHERENT
286.  Occasionally, users port  programs like compress to COHERENT 286 that
use a small number of very  large arrays.  Because COHERENT 286 is a SMALL-
model operating system, special provision must be made for arrays too large
to fit  into a  64-kilobyte data  segment.  The following  functions enable
programs that are to be run under COHERENT 286 use very large arrays:

void vinit(filename, ram) char *filename; unsigned ram;
     Initialize  the  virtual-memory   system,  using  filename  for  work.
     filename may be a raw device, such as /dev/rram1. ram is the amount of
     buffer space to give the system -- the more, the better.

void vshutdown()
     Shut the virtual-memory system, and make it restartable.

unsigned vopen(amt) unsigned long amt;
     Set up  a virtual-memory object.  For example, if  you want to emulate
     having a 100,000-byte array and a 50,000-byte array, use the call

         vid1 = vopen(100000L); vid2 = vopen(50000L);

     This does  some checking  and tells the  system that any  reference to
     vid2 will be between 100,000 and 150,000 in the virtual file.

char *vfind(vid, disp, dirty)
unsigned vid, dirty; unsigned long disp;
     Find a character in the virtual  system, mark the block's dirty bit if
     the access is to write.  Given  the example in vopen(), if you want to
     find the 1,000th byte in vdi1, use the call:

         c = *(vfind(vdi1, 1000L, 0));

     To change the 2000th byte in vid2 d, use the call

         *(vfind(vid2, 2000L, 1)) = d;

     Note that the  dirty indicator tells the system of  the change so that
     the block will be written back before it is read over.  Blocks are 512
     bytes long, so int's or long's can be read or written without multiple
     accesses to vfind().

File Locking

libmisc holds a number of routines with which you can lock and unlock files
and  devices.   It is  adapted  from  the mechanism  used  by the  COHERENT
implementation of UUCP.

Lock  files  are created  in  $SPOOLDIR.  A lock  file  is  given the  name
LCK..resource.   It  contains  a  decimal  representation  of  the  process
identifier (pid) of the process that created the lock.

You can provide an alternate pid  by using one of the `n' routines -- i.e.,
locknrm(), lockntty(),  and unlockntty().  The unlocking routines  regard a
pid of  zero as  an override  -- they remove  the lock regardless  of which
process created the lock.

For  a  tty  device, resource  is  a  string  that  consists of  a  decimal
representation of  its major  number, a decimal  point, and the  lower five
bits of its minor number.

Each routine takes a string that names the resource to lock or unlock.  The
``tty''   routines   (i.e.,   lockntty(),  locktty(),   unlockntty(),   and
unlocktty()) want the base name of  the tty to be locked (without the /dev/
part).

Every lock routine returns zero on failure and one on success.

lockit(resource) char *resource;
     Use a resource string to lock a tty.

lockexist(resource) char *resource;
     Check whether a lock file exists for the tty with resource.

locknrm(resource, pid) char *resource; int pid;
     Remove a lock file for a tty owned by process pid.

lockntty(tty, pid) char *tty; int pid;
     Lock a tty for process pid.

lockrm(resource) char *resource;
     Remove a lock file for tty with resource.

locktty(tty) char *tty;
     Lock a tty.

lockttyexist(tty) char *tty;
     Check whether a given tty is locked.

unlockntty(tty, pid) char *tty; int pid;
     Unlock a tty for process pid.  Unlocking always succeeds.

unlocktty(tty) char *tty;
     Unlock a tty that the current process owns.

unlockit(resource, pid) char *resource; int pid;
     Unlock something for process pid.

Templates and Pictures

libmisc includes a function, picture(), for formatting numeric strings.  It
has the following syntax:

    double picture(dble, format, output)
    double dble; char *format, *output;

picture()  performs  numeric  formatting  under  C.  It  resembles  masking
functions  built into  COBOL and  BASIC, but is  superior to  either.  dble
gives the number to format; format gives the format mask; and output points
to the area into which the  formatted number is written.  output must be at
least as large as format.  If dble overflows the picture, picture() returns
the overflow.

The following  summarizes the values that can appear  in the format string.
Note that  throughout, the symbol  <sp> indicates a  space character,
not the literal string ``<sp>''.

9  Provide a  slot for a  number.  Passing 5.000  through a mask  of 999 CR
   gives ``005''.   Passing -5.000  through a mask  of 999 CR  yields ``005
   CR''.  Note that picture() does not recognize the characters `C' and `R'
   as  being special.   Trailing non-special characters  print only  if the
   number is negative.

Z  Provide a slot for a  number, but suppress leading zeroes.  For example,
   passing     1034.000    through    a     mask    of     ZZZ,ZZZ    gives
   ``<sp><sp>1,034''.  Note that picture() does not recognize a
   comma  as being  a special  character.   picture() prints  embedded non-
   special characters only if they are preceeded by significant digits.

J  Provide a slot for a number, but shrink out leading zeros.  For example,
   passing 1034.000 through a mask of JJJ,JJJ yields ``1,034''.

K  Provide a  slot for a  number, but shrink  out any zeros.   For example,
   passing 70884.000 through a mask of K9/K9/K9 yields ``7/8/84''.

$  Float a dollar  sign to the left of the  displayed number.  For example,
   passing    105.000     through    a    mask     of    $ZZZ,ZZZ    yields
   ``<sp><sp><sp><sp>$105''.

.  Separate the number  between decimal and integer portions.  For example,
   passing    105.670    through     a    mask    of    Z,ZZZ.999    yields
   ``<sp><sp>105.670''.

T  Provide a slot for a number, but suppress trailing zeroes.  For example,
   passing    105.670    through     a    mask    of    Z,ZZ9.9TT    yields
   ``<sp><sp>105.67<sp>''.

S  Provide  a slot  for  a number,  but  shrink out  trailing zeroes.   For
   example,   passing  105.670   through   a  mask   of  Z,ZZ9.9SS   yields
   ``<sp><sp>105.67''.

-  Float  a  negative sign  in  front of  negitive  numbers.  For  example,
   passing     105.000    through     a    mask     of     -Z,ZZZ    yields
   ``<sp><sp><sp<105'', whereas  passing -105.000 through
   a mask of -Z,ZZZ yields ``<sp><sp>-105''.

(  Acts like  -, but  prints a  parenthesis.  For example,  passing 105.000
   through  a  mask of  (ZZZ)  yields ``<sp>105<sp>'',  whereas
   passing     -5.000     through     a     mask    of     (ZZZ)     yields
   ``<sp><sp>(5)''.

+  Float  a + or  - in  front of  the number, depending  on its  sign.  For
   example,    pasing   5.000    through    a   mask    of   +ZZZ    yields
   ``<sp><sp>+5'',  whereas passing  -5.000 through  a  mask of
   +ZZZ yields ``<sp><sp>-5''.

*  Fill all  spaces to right with asterisks.   For example, passing 104.100
   through a  mask of  *ZZZ,ZZZ.99 yields ``*****104.10'';  whereas passing
   104.100  through   a  mask  of   *$ZZZ,ZZZ.99  yields  ``*****$104.10''.
   picture()  returns  any  overflow  as  a  double. For  example,  passing
   -1234.000 through  a mask of (ZZZ) yields ``(234)''  with an overflow of
   -1.0;  passing  123.400 through  a  mask  of 99  yields  ``23'' with  an
   overflow of 1.0; and passing 1200.000 through a mask of ZZ yields ``00''
   with an overflow of 12.0.

Files

/usr/src/misc.tar.Z -- Compressed tar archive of sources

See Also

libraries,
tar,
zcat

Notes

The misc library is provided on an as-is basis only.  Caveat utilitor!