home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / nethack-3.1 / sys / vms / oldcrtl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-21  |  5.4 KB  |  187 lines

  1. /*       SCCS Id: @(#)oldcrtl.c   3.1      90/05/24
  2. /*        Pat Rankin  May'90                                       */
  3. /* VMS NetHack support, not needed for vms 4.6,4.7,or 5.x.        */
  4.  
  5. #ifdef VERYOLD_VMS
  6. /*
  7.  * The following routines are used by NetHack but were not available
  8.  * from the C Run-Time Library (VAXCRTL) prior to VMS V4.6.
  9.  *
  10.  *      atexit, memcmp, memcpy, qsort, rename, vprintf, vsprintf
  11.  *
  12.  * Most of them are implemented here, but others will have to be worked
  13.  * around in another fashion [such as '#define USE_OLDARGS' (even though
  14.  * <varargs.h> is available) to avoid the need for vprintf & vsprintf].
  15.  *
  16.  */
  17. #define REG register
  18. #define const
  19.  
  20. #ifndef SUPPRESS_MEM_FUNCS
  21. /* note: hand optimized for VAX (hardware pre-decrement & post-increment) */
  22.  
  23. /* void *memset(void *, int, size_t) -- fill chunk of memory.
  24. */
  25. char *memset( dst, fil, cnt )
  26. REG char *dst;
  27. REG char  fil;
  28. REG int   cnt;
  29. {
  30.     char *dst_p = dst;
  31.     while ( --cnt >= 0 )
  32.     *dst++ = fil;
  33.     return dst_p;
  34. }
  35.  
  36. /* void *memcpy(void *, const void *, size_t) -- copy chunk of memory.
  37. */
  38. char *memcpy( dst, src, cnt )
  39. REG char       *dst;
  40. REG const char *src;
  41. REG int        cnt;
  42. {
  43.     char *dst_p = dst;
  44.     while ( --cnt >= 0 )
  45.     *dst++ = *src++;
  46.     return dst_p;
  47. }
  48.  
  49. /* void *memmove(void *, const void *, size_t) -- copy possibly overlapping mem.
  50. */
  51. char *memmove( dst, src, cnt )
  52. REG char       *dst;
  53. REG const char *src;
  54. REG int        cnt;
  55. {
  56.     char *dst_p = dst;
  57.     if ( src == dst || cnt <= 0 ) {
  58.     ;       /* do nothing */
  59.     } else if ( dst < src || dst >= src + cnt ) {
  60.     while ( --cnt >= 0 )
  61.         *dst++ = *src++;
  62.     } else {    /* work backwards */
  63.     dst += cnt,  src += cnt;
  64.     while ( --cnt >= 0 )
  65.         *--dst = *--src;
  66.     }
  67.     return dst_p;
  68. }
  69.  
  70. /* void *memchr(const void *, int, size_t) -- search for a byte.
  71. */
  72. char *memchr( buf, byt, len )
  73. REG const char *buf;
  74. REG char        byt;
  75. REG int        len;
  76. {
  77.     while ( --len >= 0 )
  78.     if ( *buf++ == byt )    /* found */
  79.         return (char *)--buf;
  80.     return (char *)0;       /* not found */
  81. }
  82.  
  83. /* int memcmp(const void *, const void *, size_t) -- compare two chunks.
  84. */
  85. int memcmp( buf1, buf2, len )
  86. REG const char *buf1;
  87. REG const char *buf2;
  88. REG int        len;
  89. {
  90.     while ( --len >= 0 )
  91.     if ( *buf1++ != *buf2++ )
  92.         return (*--buf1 - *--buf2);
  93.     return 0;   /* buffers matched */
  94. }
  95. #endif /*!SUPPRESS_MEM_FUNCS*/
  96.  
  97.  
  98. #ifndef SUPPRESS_ATEXIT
  99. /* int atexit(void (*)(void)) -- register an exit handler.
  100. */
  101. #define MAX_EXIT_FUNCS 32       /* arbitrary (32 matches VAX C v3.x docs) */
  102. struct _ex_hndlr { long reserved, (*routine)(), arg_count, *arg1_addr; };
  103. static int ex_cnt = 0;          /* number of handlers registered so far */
  104. static struct { long dummy_arg; struct _ex_hndlr handler;   /*(black box)*/
  105.        } ex_data[MAX_EXIT_FUNCS];       /* static handler data */
  106.  
  107. int atexit( function )
  108.     int (*function)();          /* note: actually gets called with 1 arg */
  109. {
  110.     if ( ex_cnt < MAX_EXIT_FUNCS ) {
  111.     ex_data[ex_cnt].dummy_arg = 0;  /* ultimately receives exit reason */
  112.     ex_data[ex_cnt].handler.reserved  = 0;
  113.     ex_data[ex_cnt].handler.routine   = (long (*)()) function;
  114.     ex_data[ex_cnt].handler.arg_count = 1;          /*(required)*/
  115.     ex_data[ex_cnt].handler.arg1_addr = &ex_data[ex_cnt].dummy_arg;
  116.     SYS$DCLEXH( &ex_data[ex_cnt].handler);  /* declare exit handler */
  117.     return ++ex_cnt;        /*(non-zero)*/
  118.     } else
  119.     return 0;
  120. }
  121. #endif /*!SUPPRESS_ATEXIT*/
  122.  
  123.  
  124. #ifndef SUPPRESS_RENAME
  125. /* int rename(const char *, const char *) -- rename a file (on same device).
  126. */
  127. #ifndef EVMSERR
  128. #include <errno.h>
  129. #define C$$TRANSLATE(status)    (errno = EVMSERR,  vaxc$errno = (status))
  130. #endif
  131.  
  132. int rename( old_name, new_name )
  133.     const char *old_name;
  134.     const char *new_name;
  135. {
  136.     struct _dsc { int len; const char *adr; } old_dsc, new_dsc;
  137.     unsigned long status, LIB$RENAME_FILE();
  138.  
  139.     /* put strings into descriptors and call run-time library routine */
  140.     old_dsc.len = strlen( old_dsc.adr = old_name );
  141.     new_dsc.len = strlen( new_dsc.adr = new_name );
  142.     status = LIB$RENAME_FILE( &old_dsc, &new_dsc);  /* omit optional args */
  143.     if ( !(status & 1) ) {      /* even => failure */
  144.     C$$TRANSLATE(status);
  145.     return -1;
  146.     } else                      /*  odd => success */
  147.     return 0;
  148. }
  149. #endif /*!SUPPRESS_RENAME*/
  150.  
  151.  
  152. #ifndef SUPPRESS_QSORT
  153. /* void qsort(void *, size_t, size_t, int (*)()) -- sort arbitrary collection.
  154. */
  155. void qsort( base, count, size, compare )
  156.     char *base;
  157.     int   count;
  158. REG int   size;
  159.     int (*compare)();
  160. {
  161. REG int   i, cmp;
  162. REG char *next, *prev, *tmp = 0;
  163.     char  wrk_buf[512], *malloc();      /* assume no alloca() available */
  164.  
  165.     /* just use a shuffle sort (tradeoff between efficiency & simplicity) */
  166.     /*  [Optimal if already sorted; worst case when initially reversed.]  */
  167.     for ( next = base, i = 1;  i < count;  i++ ) {
  168.     prev = next,  next += size;             /* increment front pointer */
  169.     if ( (cmp = (*compare)( next, prev)) < 0 ) {
  170.         /* found element out of order; move other(s) up then re-insert it */
  171.         if ( !tmp )  tmp = (size > sizeof wrk_buf ? malloc(size) : wrk_buf);
  172.         memcpy( tmp, next, size);           /* save smaller element */
  173.         while ( cmp < 0 ) {
  174.         memcpy( prev + size, prev, size);   /* move larger elem. up */
  175.         prev -= size;                   /* decrement back pointer */
  176.         cmp = (prev >= base ? (*compare)( tmp, prev) : 0);
  177.         }
  178.         memcpy( prev + size, tmp, size);    /* restore small element */
  179.     }
  180.     }
  181.     if ( tmp != 0 && tmp != wrk_buf )  free(tmp);
  182.     return;
  183. }
  184. #endif /*!SUPPRESS_QSORT*/
  185.  
  186. #endif /*VERYOLD_VMS*/
  187.