home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga Shareware Floppies / ma01.dms / ma01.adf / wasp / src / io.c < prev    next >
C/C++ Source or Header  |  1992-01-01  |  8KB  |  412 lines

  1. /* wasp - Copyright 1991 by Steven Reiz
  2.  * see COPYING and wasp.c for further info
  3.  * io.c, 30/5/91 - 2/6/91, 8/7/91, 8/12/91,
  4.  * 27/12/91 - 1/1/92
  5.  */
  6.  
  7. /* all Wasp I/O should go through the functions which are defined
  8.  * in this file, copen_in/out, cseek_in/out, cread, cwrite and wrl
  9.  * for handling the input- and outputimagefiles,
  10.  * cout_tmp, cout_default and ctmp_move for working with temporary
  11.  * output files,
  12.  * printe and pute for messages that cannot be handled by errorx,
  13.  * init_counter, counter and erase_counter for producing a counter,
  14.  * errorx (not called directly, use error0, error1, etc.) for error-
  15.  * messages.
  16.  */
  17.  
  18. static char *sourcefile=__FILE__;
  19.  
  20. #include "wasp.h"
  21.  
  22. #ifdef AMIGA
  23. #define TMP_PREFIX "t:"
  24. #else
  25. #define TMP_PREFIX "/tmp/"
  26. #endif
  27.  
  28. extern int errno;
  29.  
  30. /* to make it possible to read the start of the input file multiple
  31.  * times (so each reader can try to recognize it), even when reading
  32.  * from stdin, the first MAXINBUF bytes are stored in a buffer, inbuf.
  33.  */
  34. #define MAXINBUF 256
  35. static char *inbuf;
  36. static int inbufn;        /* actual number of bytes in inbuf */
  37. static long infdpos, incpos;    /* the real and virtual positions of infd */
  38. static long outfdpos, outcpos;  /* and outfd */
  39.  
  40. /* temporary file stuff */
  41. static int ran_nr;        /* for tmp files, to not clash with other wasps */
  42. static long tmp_ctr=0;
  43. static int tmpfd= -1;
  44. static char tmpfilename[30];
  45.  
  46.  
  47. void
  48. copen_in(char *filename)
  49. {
  50.     srand(time(NULL));
  51.     ran_nr=rand();
  52.  
  53.     if (!strcmp(filename, "-"))
  54.         infd=0;
  55.     else if ((infd=open(filename, O_RDONLY))<0)
  56.         error1(E0_FATAL, E1_IO, E2_OPEN, E3_ERRNO, filename);
  57.     outcpos=0;
  58.     inbuf=Malloc(MAXINBUF);
  59.     inbufn=read(infd, inbuf, MAXINBUF);
  60.     if (inbufn<0)
  61.         error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, filename);
  62.     else if (!inbufn)
  63.         error1(E0_FATAL, E1_IO, E2_READ, E3_UNEXPEND, infilename);
  64.     infdpos=inbufn;
  65. }
  66.  
  67.  
  68. void
  69. copen_out(char *filename)
  70. {
  71.     if (!strcmp(filename, "-"))
  72.         outfd=1;
  73.     else if ((outfd=open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644))<0)
  74.         error1(E0_FATAL, E1_IO, E2_CREAT, E3_ERRNO, filename);
  75.     outfdpos=0;
  76.     outcpos=0;
  77. }
  78.  
  79.  
  80. long
  81. cseek_in(long offset, int whence)
  82. {
  83.     if (whence==0)
  84.         incpos=offset;
  85.     else if (whence==1)
  86.         incpos+=offset;
  87.     else
  88.         assert(0);
  89.     assert(incpos>=0);
  90.     if (incpos!=infdpos && incpos>=inbufn) {
  91.         if (infd>2) {
  92.             if (lseek(infd, incpos, 0)<0)
  93.                 error1(E0_FATAL, E1_IO, E2_SEEK, E3_ERRNO, infilename);
  94.             infdpos=incpos;
  95.         } else if (incpos>infdpos) {
  96.             char *m;
  97.             int n;
  98.  
  99.             n=incpos-infdpos;
  100.             m=Malloc(n);
  101.             if (read(infd, m, n)!=n)
  102.                 error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, infilename);
  103.             free(m);
  104.             infdpos=incpos;
  105.         } else
  106.             error0(E0_FATAL, E1_IO, E2_SEEK, E3_SEEK_STDIN);
  107.     }
  108.     return incpos;
  109. }
  110.  
  111.  
  112. long
  113. cseek_out(long offset, int whence)
  114. {
  115.     assert(tmpfd== -1);
  116.     if (whence==0)
  117.         outcpos=offset;
  118.     else if (whence==1)
  119.         outcpos+=offset;
  120.     else {
  121.         assert(!offset);
  122.         if ((outfdpos=lseek(outfd, 0L, 2))<0)
  123.             error1(E0_FATAL, E1_IO, E2_SEEK, E3_ERRNO, outfilename);
  124.         outcpos=outfdpos;
  125.     }
  126.     assert(outcpos>=0);
  127.     if (outcpos!=outfdpos) {
  128.         if (outfd>2) {
  129.             if (lseek(outfd, outcpos, 0)<0)
  130.                 error1(E0_FATAL, E1_IO, E2_SEEK, E3_ERRNO, outfilename);
  131.             outfdpos=outcpos;
  132.         } else
  133.             error0(E0_FATAL, E1_IO, E2_SEEK, E3_SEEK_STDOUT);
  134.     }
  135.     return outcpos;
  136. }
  137.  
  138.  
  139. int
  140. read1(void *buf, int len)
  141. {
  142.     int todo, rr;
  143.  
  144.     todo=len;
  145.     if (incpos<inbufn) {
  146.         int min;
  147.  
  148.         min=inbufn-incpos;
  149.         if (min>todo)
  150.             min=todo;
  151.         memcpy(buf, inbuf+incpos, min);
  152.         todo-=min;
  153.         incpos+=min;
  154.         if (!todo)
  155.             return min;
  156.     }
  157.     assert(incpos==infdpos);
  158.     rr=read(infd, (char *)buf+(len-todo), todo);
  159.     if (rr<0) {
  160.         if (todo!=len)
  161.             return len-todo;
  162.         return rr;
  163.     }
  164.     infdpos+=rr;
  165.     incpos+=rr;
  166.     todo-=rr;
  167.     return len-todo;
  168. }
  169.  
  170.  
  171. void
  172. cread(void *buf, int len)
  173. {
  174.     assert(cread_type>=CREAD_STRICT && cread_type<=CREAD_OPTIONAL);
  175.     if ((cread_result=read1(buf, len))!=len) {
  176.         if (cread_result<0) {
  177.             if (cread_type==CREAD_STRICT)
  178.                 error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, infilename);
  179.             else
  180.                 error1(E0_ERROR, E1_IO, E2_READ, E3_ERRNO, infilename);
  181.         } else if (cread_type==CREAD_STRICT)
  182.             error1(E0_FATAL, E1_IO, E2_READ, E3_UNEXPEND, infilename);
  183.         else if (cread_type==CREAD_NONFATAL
  184.          || (cread_type==CREAD_VARLEN && !cread_result))
  185.             error1(E0_ERROR, E1_IO, E2_READ, E3_UNEXPEND, infilename);
  186.     }
  187. }
  188.  
  189.  
  190. void
  191. cwrite(void *buf, int len)
  192. {
  193.     if (tmpfd== -1) {
  194.         assert(outcpos==outfdpos);
  195.         if (write(outfd, buf, len)!=len)
  196.             error1(E0_FATAL, E1_IO, E2_WRITE, E3_ERRNO, outfilename);
  197.         outfdpos+=len;
  198.         outcpos+=len;
  199.     } else {
  200.         if (write(tmpfd, buf, len)!=len)
  201.             error1(E0_FATAL, E1_IO, E2_WRITE, E3_ERRNO, tmpfilename);
  202.     }
  203. }
  204.  
  205.  
  206. void
  207. wrl(unsigned long l)
  208. {
  209.     cwrite(&l, 4);    /* BYTEORDER */
  210. }
  211.  
  212.  
  213. void
  214. wrs(unsigned short s)
  215. {
  216.     cwrite(&s, 2);    /* BYTEORDER */
  217. }
  218.  
  219.  
  220. void
  221. cout_tmp(void)
  222. {
  223.     assert(tmpfd== -1);
  224.     sprintf(tmpfilename, "%swasp.%04d.%03ld", TMP_PREFIX, ran_nr%10000,
  225.      tmp_ctr%1000L);
  226.     if ((tmpfd=open(tmpfilename, O_WRONLY|O_CREAT|O_TRUNC, 0644))<0)
  227.         error1(E0_FATAL, E1_IO, E2_CREAT, E3_ERRNO, tmpfilename);
  228. }
  229.  
  230.  
  231. void
  232. cout_default(long *tmp_num, long *tmp_size)
  233. {
  234.     assert(tmpfd!= -1);
  235.     *tmp_size=lseek(tmpfd, 0L, 1);
  236.     *tmp_num=tmp_ctr++;
  237.     close(tmpfd);
  238.     tmpfd= -1;
  239. }
  240.  
  241.  
  242. void
  243. ctmp_move(long tmp_num)
  244. {
  245.     int fd, n;
  246.     char *buf;
  247. #define CTMP_BUF 16384
  248.     long len=0;
  249.  
  250.     assert(tmp_ctr>tmp_num && tmpfd== -1);
  251.     buf=Malloc(CTMP_BUF);
  252.     sprintf(tmpfilename, "%swasp.%04d.%03ld", TMP_PREFIX, ran_nr%10000,
  253.      tmp_num%1000L);
  254.     if ((fd=open(tmpfilename, O_RDONLY))<0)
  255.         error1(E0_FATAL, E1_IO, E2_OPEN, E3_ERRNO, tmpfilename);
  256.     assert(outcpos==outfdpos);
  257.     while ((n=read(fd, buf, CTMP_BUF))>0) {
  258.         if (write(outfd, buf, n)!=n)
  259.             error1(E0_FATAL, E1_IO, E2_WRITE, E3_ERRNO, outfilename);
  260.         len+=n;
  261.     }
  262.     if (n<0)
  263.         error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, tmpfilename);
  264.     outfdpos+=len;
  265.     outcpos+=len;
  266.     close(fd);
  267.     unlink(tmpfilename);
  268.     free(buf);
  269. }
  270.  
  271.  
  272. int
  273. printe(char *s, ...)
  274. {
  275.     va_list argp;
  276.     int res;
  277.  
  278.     va_start(argp, s);
  279.     res=vfprintf(stderr, s, argp);
  280.     va_end(argp);
  281.     return res;
  282. }
  283.  
  284.  
  285. void
  286. pute(char c)
  287. {
  288.     putc(c, stderr);
  289. }
  290.  
  291.  
  292. static int co, cur, step, dir=0, len, last1;
  293.  
  294. void
  295. init_counter(int start, int end, int instep, char *s, ...)
  296. {
  297.     va_list argp;
  298.  
  299.     va_start(argp, s);
  300.     if (start<=end)
  301.         dir=1;
  302.     else
  303.         dir= -1;
  304.     step=instep;
  305.     if (step<0)
  306.         step= -step;
  307.     cur=start;
  308.     co=1;
  309.     last1=end;
  310.     len=printe("\r       [%d..%d] ", start, end)-1;
  311.     if (s)
  312.         len+=vfprintf(stderr, s, argp);
  313.     pute('\r');
  314.     fflush(stderr);
  315.     va_end(argp);
  316. }
  317.  
  318.  
  319. void
  320. counter(void)
  321. {
  322.     if (--co && (co!=1 || ((dir<0 && cur-step>last1) || (dir>=0 && cur+step<last1))))
  323.         return;
  324.     printe("\r%6d", cur);
  325.     co=step;
  326.     if (dir<0)
  327.         cur-=step;
  328.     else
  329.         cur+=step;
  330.     fflush(stderr);
  331. }
  332.  
  333.  
  334. void
  335. erase_counter(char *s, ...)
  336. {
  337.     va_list argp;
  338.     int l1;
  339.  
  340.     va_start(argp, s);
  341.     pute('\r');
  342.     if (s)
  343.         l1=vfprintf(stderr, s, argp);
  344.     else
  345.         l1=0;
  346.     while (l1++ <len)
  347.         pute(' ');
  348.     pute(s ? '\n' : '\r');
  349.     fflush(stderr);
  350.     dir=0;
  351.     va_end(argp);
  352. }
  353.  
  354.  
  355. void
  356. prin1(char *p)
  357. {
  358.     if (p)
  359.         printe("%s ", p);
  360. }
  361.  
  362.  
  363. void
  364. errorx(long code, ...)
  365. {
  366.     va_list argp;
  367.     char c0, c1, c2, c3;
  368.     char *p;
  369.     int l1;
  370.  
  371.     va_start(argp, code);
  372.     if (dir) {
  373.         pute('\r');
  374.         l1=0;
  375.         while (l1++ <len)
  376.             pute(' ');
  377.         pute('\r');
  378.         fflush(stderr);
  379.     }
  380.     c0=code>>24;
  381.     c1=code>>16;
  382.     c2=code>>8;
  383.     c3=code;
  384.     if (c0==E0_INTERNAL) {
  385.         printe("internal error in wasp %s, file %s, line %ld; please report to sreiz@cs.vu.nl\n",
  386.          version+14, va_arg(argp, char *), code&0x00ffffff);
  387.         exit(1);
  388.     }
  389.     assert(c0>E0_INTERNAL && c0<E0_NUM && c1>0 && c1<E1_NUM && c2>0
  390.      && c2<E2_NUM && c3>0 && c3<E3_NUM);
  391.     prin1(e0_s[c0].s1);
  392.     prin1(e1_s[c1]);
  393.     prin1(e2_s[c2]);
  394.     p=e0_s[c0].s2;
  395.     if (p)
  396.         printe("%s", p);
  397.     if (c3==E3_ERRNO) {
  398.         printe(" in ");
  399.         perror(va_arg(argp, char *));
  400.     } else {
  401.         p=e3_s[c3];
  402.         if (p) {
  403.             printe(": ");
  404.             vfprintf(stderr, p, argp);
  405.         }
  406.         pute('\n');
  407.     }
  408.     if (c0==E0_FATAL)
  409.         exit(1);
  410.     va_end(argp);
  411. }
  412.