home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-src.tgz / tar.out / contrib / unixtex / xdvik / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-28  |  5.7 KB  |  256 lines

  1. /*
  2.  * Copyright (c) 1994 Paul Vojta.  All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  * 1. Redistributions of source code must retain the above copyright
  8.  *    notice, this list of conditions and the following disclaimer.
  9.  * 2. Redistributions in binary form must reproduce the above copyright
  10.  *    notice, this list of conditions and the following disclaimer in the
  11.  *    documentation and/or other materials provided with the distribution.
  12.  *
  13.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  14.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  17.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  19.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23.  * SUCH DAMAGE.
  24.  *
  25.  * NOTE:
  26.  *    xdvi is based on prior work as noted in the modification history, below.
  27.  */
  28.  
  29. /*
  30.  * DVI previewer for X.
  31.  *
  32.  * Eric Cooper, CMU, September 1985.
  33.  *
  34.  * Code derived from dvi-imagen.c.
  35.  *
  36.  * Modification history:
  37.  * 1/1986    Modified for X.10    --Bob Scheifler, MIT LCS.
  38.  * 7/1988    Modified for X.11    --Mark Eichin, MIT
  39.  * 12/1988    Added 'R' option, toolkit, magnifying glass
  40.  *                    --Paul Vojta, UC Berkeley.
  41.  * 2/1989    Added tpic support    --Jeffrey Lee, U of Toronto
  42.  * 4/1989    Modified for System V    --Donald Richardson, Clarkson Univ.
  43.  * 3/1990    Added VMS support    --Scott Allendorf, U of Iowa
  44.  * 7/1990    Added reflection mode    --Michael Pak, Hebrew U of Jerusalem
  45.  * 1/1992    Added greyscale code    --Till Brychcy, Techn. Univ. Muenchen
  46.  *                      and Lee Hetherington, MIT
  47.  * 4/1994    Added DPS support, bounding box
  48.  *                    --Ricardo Telichevesky
  49.  *                      and Luis Miguel Silveira, MIT RLE.
  50.  */
  51.  
  52. #include "config.h"
  53. #include <kpathsea/c-fopen.h>
  54. #include <kpathsea/c-vararg.h>
  55.  
  56. #ifdef    Mips
  57. extern    int    errno;
  58. #endif
  59.  
  60. #ifdef VMS
  61. #include <rmsdef.h>
  62. #endif /* VMS */
  63.  
  64.  
  65. /*
  66.  *    General utility routines.
  67.  */
  68.  
  69. /*
  70.  *    Print error message and quit.
  71.  */
  72.  
  73. #if    NeedVarargsPrototypes
  74. NORETURN void
  75. oops(_Xconst char *message, ...)
  76. #else
  77. /* VARARGS */
  78. NORETURN void
  79. oops(va_alist)
  80.     va_dcl
  81. #endif
  82. {
  83. #if    !NeedVarargsPrototypes
  84.     _Xconst char *message;
  85. #endif
  86.     va_list    args;
  87.  
  88.     Fprintf(stderr, "%s: ", prog);
  89. #if    NeedVarargsPrototypes
  90.     va_start(args, message);
  91. #else
  92.     va_start(args);
  93.     message = va_arg(args, _Xconst char *);
  94. #endif
  95.     (void) vfprintf(stderr, message, args);
  96.     va_end(args);
  97.     Putc('\n', stderr);
  98.     exit(1);
  99. }
  100.  
  101. /*
  102.  *    Either allocate storage or fail with explanation.
  103.  */
  104.  
  105. char *
  106. xmalloc(size, why)
  107.     unsigned    size;
  108.     _Xconst char    *why;
  109. {
  110.     /* Avoid malloc(0), though it's not clear if it ever actually
  111.        happens any more.  */
  112.     char *mem = malloc(size ? size : 1);
  113.  
  114.     if (mem == NULL)
  115.         oops("! Cannot allocate %u bytes for %s.\n", size, why);
  116.     return mem;
  117. }
  118.  
  119. /*
  120.  *    Allocate bitmap for given font and character
  121.  */
  122.  
  123. void
  124. alloc_bitmap(bitmap)
  125.     register struct bitmap *bitmap;
  126. {
  127.     register unsigned int    size;
  128.  
  129.     /* width must be multiple of 16 bits for raster_op */
  130.     bitmap->bytes_wide = ROUNDUP((int) bitmap->w, BITS_PER_BMUNIT) *
  131.         BYTES_PER_BMUNIT;
  132.     size = bitmap->bytes_wide * bitmap->h;
  133.     bitmap->bits = xmalloc(size != 0 ? size : 1, "character bitmap");
  134. }
  135.  
  136.  
  137. /*
  138.  *    Close the pixel file for the least recently used font.
  139.  */
  140.  
  141. static    void
  142. close_a_file()
  143. {
  144.     register struct font *fontp;
  145.     unsigned short oldest = ~0;
  146.     struct font *f = NULL;
  147.  
  148.     for (fontp = font_head; fontp != NULL; fontp = fontp->next)
  149.         if (fontp->file != NULL && fontp->timestamp <= oldest) {
  150.         f = fontp;
  151.         oldest = fontp->timestamp;
  152.         }
  153.     if (f == NULL)
  154.         oops("Can't find an open pixel file to close");
  155.     Fclose(f->file);
  156.     f->file = NULL;
  157.     ++n_files_left;
  158. }
  159.  
  160. /*
  161.  *    Open a file in the given mode.
  162.  */
  163.  
  164. FILE *
  165. #ifndef    VMS
  166. xfopen(filename, type)
  167.     _Xconst char    *filename;
  168.     _Xconst char    *type;
  169. #define    TYPE    type
  170. #else
  171. xfopen(filename, type, type2)
  172.     _Xconst char    *filename;
  173.     _Xconst char    *type;
  174.     _Xconst char    *type2;
  175. #define    TYPE    type, type2
  176. #endif    /* VMS */
  177. {
  178.     FILE    *f;
  179.  
  180.         /* Try not to let the file table fill up completely.  */
  181.     if (n_files_left <= 5)
  182.       close_a_file();
  183.     f = fopen(filename, OPEN_MODE);
  184.     /* If the open failed, try closing a file unconditionally.
  185.          Interactive Unix 2.2.1, at least, doesn't set errno to EMFILE
  186.          or ENFILE even when it should.  In any case, it doesn't hurt
  187.          much to always try.  */
  188.     if (f == NULL)
  189.     {
  190.         n_files_left = 0;
  191.         close_a_file();
  192.         f = fopen(filename, TYPE);
  193.     }
  194.     return f;
  195. }
  196. #undef    TYPE
  197.  
  198.  
  199. #ifdef    PS_GS
  200. /*
  201.  *    Create a pipe, closing a file if necessary.  This is (so far) used only
  202.  *    in psgs.c.
  203.  */
  204.  
  205. int
  206. xpipe(fd)
  207.     int    *fd;
  208. {
  209.     int    retval;
  210.  
  211.     for (;;) {
  212.         retval = pipe(fd);
  213.         if (retval == 0 || (errno != EMFILE && errno != ENFILE)) break;
  214.         n_files_left = 0;
  215.         close_a_file();
  216.     }
  217.     return retval;
  218. }
  219. #endif    /* PS_GS */
  220.  
  221.  
  222. /*
  223.  *
  224.  *      Read size bytes from the FILE fp, constructing them into a
  225.  *      signed/unsigned integer.
  226.  *
  227.  */
  228.  
  229. unsigned long
  230. num(fp, size)
  231.     register FILE *fp;
  232.     register int size;
  233. {
  234.     register long x = 0;
  235.  
  236.     while (size--) x = (x << 8) | one(fp);
  237.     return x;
  238. }
  239.  
  240. long
  241. snum(fp, size)
  242.     register FILE *fp;
  243.     register int size;
  244. {
  245.     register long x;
  246.  
  247. #ifdef    __STDC__
  248.     x = (signed char) getc(fp);
  249. #else
  250.     x = (unsigned char) getc(fp);
  251.     if (x & 0x80) x -= 0x100;
  252. #endif
  253.     while (--size) x = (x << 8) | one(fp);
  254.     return x;
  255. }
  256.