home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magazyn Amiga Shareware Floppies
/
ma01.dms
/
ma01.adf
/
wasp
/
src
/
io.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-01
|
8KB
|
412 lines
/* wasp - Copyright 1991 by Steven Reiz
* see COPYING and wasp.c for further info
* io.c, 30/5/91 - 2/6/91, 8/7/91, 8/12/91,
* 27/12/91 - 1/1/92
*/
/* all Wasp I/O should go through the functions which are defined
* in this file, copen_in/out, cseek_in/out, cread, cwrite and wrl
* for handling the input- and outputimagefiles,
* cout_tmp, cout_default and ctmp_move for working with temporary
* output files,
* printe and pute for messages that cannot be handled by errorx,
* init_counter, counter and erase_counter for producing a counter,
* errorx (not called directly, use error0, error1, etc.) for error-
* messages.
*/
static char *sourcefile=__FILE__;
#include "wasp.h"
#ifdef AMIGA
#define TMP_PREFIX "t:"
#else
#define TMP_PREFIX "/tmp/"
#endif
extern int errno;
/* to make it possible to read the start of the input file multiple
* times (so each reader can try to recognize it), even when reading
* from stdin, the first MAXINBUF bytes are stored in a buffer, inbuf.
*/
#define MAXINBUF 256
static char *inbuf;
static int inbufn; /* actual number of bytes in inbuf */
static long infdpos, incpos; /* the real and virtual positions of infd */
static long outfdpos, outcpos; /* and outfd */
/* temporary file stuff */
static int ran_nr; /* for tmp files, to not clash with other wasps */
static long tmp_ctr=0;
static int tmpfd= -1;
static char tmpfilename[30];
void
copen_in(char *filename)
{
srand(time(NULL));
ran_nr=rand();
if (!strcmp(filename, "-"))
infd=0;
else if ((infd=open(filename, O_RDONLY))<0)
error1(E0_FATAL, E1_IO, E2_OPEN, E3_ERRNO, filename);
outcpos=0;
inbuf=Malloc(MAXINBUF);
inbufn=read(infd, inbuf, MAXINBUF);
if (inbufn<0)
error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, filename);
else if (!inbufn)
error1(E0_FATAL, E1_IO, E2_READ, E3_UNEXPEND, infilename);
infdpos=inbufn;
}
void
copen_out(char *filename)
{
if (!strcmp(filename, "-"))
outfd=1;
else if ((outfd=open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644))<0)
error1(E0_FATAL, E1_IO, E2_CREAT, E3_ERRNO, filename);
outfdpos=0;
outcpos=0;
}
long
cseek_in(long offset, int whence)
{
if (whence==0)
incpos=offset;
else if (whence==1)
incpos+=offset;
else
assert(0);
assert(incpos>=0);
if (incpos!=infdpos && incpos>=inbufn) {
if (infd>2) {
if (lseek(infd, incpos, 0)<0)
error1(E0_FATAL, E1_IO, E2_SEEK, E3_ERRNO, infilename);
infdpos=incpos;
} else if (incpos>infdpos) {
char *m;
int n;
n=incpos-infdpos;
m=Malloc(n);
if (read(infd, m, n)!=n)
error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, infilename);
free(m);
infdpos=incpos;
} else
error0(E0_FATAL, E1_IO, E2_SEEK, E3_SEEK_STDIN);
}
return incpos;
}
long
cseek_out(long offset, int whence)
{
assert(tmpfd== -1);
if (whence==0)
outcpos=offset;
else if (whence==1)
outcpos+=offset;
else {
assert(!offset);
if ((outfdpos=lseek(outfd, 0L, 2))<0)
error1(E0_FATAL, E1_IO, E2_SEEK, E3_ERRNO, outfilename);
outcpos=outfdpos;
}
assert(outcpos>=0);
if (outcpos!=outfdpos) {
if (outfd>2) {
if (lseek(outfd, outcpos, 0)<0)
error1(E0_FATAL, E1_IO, E2_SEEK, E3_ERRNO, outfilename);
outfdpos=outcpos;
} else
error0(E0_FATAL, E1_IO, E2_SEEK, E3_SEEK_STDOUT);
}
return outcpos;
}
int
read1(void *buf, int len)
{
int todo, rr;
todo=len;
if (incpos<inbufn) {
int min;
min=inbufn-incpos;
if (min>todo)
min=todo;
memcpy(buf, inbuf+incpos, min);
todo-=min;
incpos+=min;
if (!todo)
return min;
}
assert(incpos==infdpos);
rr=read(infd, (char *)buf+(len-todo), todo);
if (rr<0) {
if (todo!=len)
return len-todo;
return rr;
}
infdpos+=rr;
incpos+=rr;
todo-=rr;
return len-todo;
}
void
cread(void *buf, int len)
{
assert(cread_type>=CREAD_STRICT && cread_type<=CREAD_OPTIONAL);
if ((cread_result=read1(buf, len))!=len) {
if (cread_result<0) {
if (cread_type==CREAD_STRICT)
error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, infilename);
else
error1(E0_ERROR, E1_IO, E2_READ, E3_ERRNO, infilename);
} else if (cread_type==CREAD_STRICT)
error1(E0_FATAL, E1_IO, E2_READ, E3_UNEXPEND, infilename);
else if (cread_type==CREAD_NONFATAL
|| (cread_type==CREAD_VARLEN && !cread_result))
error1(E0_ERROR, E1_IO, E2_READ, E3_UNEXPEND, infilename);
}
}
void
cwrite(void *buf, int len)
{
if (tmpfd== -1) {
assert(outcpos==outfdpos);
if (write(outfd, buf, len)!=len)
error1(E0_FATAL, E1_IO, E2_WRITE, E3_ERRNO, outfilename);
outfdpos+=len;
outcpos+=len;
} else {
if (write(tmpfd, buf, len)!=len)
error1(E0_FATAL, E1_IO, E2_WRITE, E3_ERRNO, tmpfilename);
}
}
void
wrl(unsigned long l)
{
cwrite(&l, 4); /* BYTEORDER */
}
void
wrs(unsigned short s)
{
cwrite(&s, 2); /* BYTEORDER */
}
void
cout_tmp(void)
{
assert(tmpfd== -1);
sprintf(tmpfilename, "%swasp.%04d.%03ld", TMP_PREFIX, ran_nr%10000,
tmp_ctr%1000L);
if ((tmpfd=open(tmpfilename, O_WRONLY|O_CREAT|O_TRUNC, 0644))<0)
error1(E0_FATAL, E1_IO, E2_CREAT, E3_ERRNO, tmpfilename);
}
void
cout_default(long *tmp_num, long *tmp_size)
{
assert(tmpfd!= -1);
*tmp_size=lseek(tmpfd, 0L, 1);
*tmp_num=tmp_ctr++;
close(tmpfd);
tmpfd= -1;
}
void
ctmp_move(long tmp_num)
{
int fd, n;
char *buf;
#define CTMP_BUF 16384
long len=0;
assert(tmp_ctr>tmp_num && tmpfd== -1);
buf=Malloc(CTMP_BUF);
sprintf(tmpfilename, "%swasp.%04d.%03ld", TMP_PREFIX, ran_nr%10000,
tmp_num%1000L);
if ((fd=open(tmpfilename, O_RDONLY))<0)
error1(E0_FATAL, E1_IO, E2_OPEN, E3_ERRNO, tmpfilename);
assert(outcpos==outfdpos);
while ((n=read(fd, buf, CTMP_BUF))>0) {
if (write(outfd, buf, n)!=n)
error1(E0_FATAL, E1_IO, E2_WRITE, E3_ERRNO, outfilename);
len+=n;
}
if (n<0)
error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, tmpfilename);
outfdpos+=len;
outcpos+=len;
close(fd);
unlink(tmpfilename);
free(buf);
}
int
printe(char *s, ...)
{
va_list argp;
int res;
va_start(argp, s);
res=vfprintf(stderr, s, argp);
va_end(argp);
return res;
}
void
pute(char c)
{
putc(c, stderr);
}
static int co, cur, step, dir=0, len, last1;
void
init_counter(int start, int end, int instep, char *s, ...)
{
va_list argp;
va_start(argp, s);
if (start<=end)
dir=1;
else
dir= -1;
step=instep;
if (step<0)
step= -step;
cur=start;
co=1;
last1=end;
len=printe("\r [%d..%d] ", start, end)-1;
if (s)
len+=vfprintf(stderr, s, argp);
pute('\r');
fflush(stderr);
va_end(argp);
}
void
counter(void)
{
if (--co && (co!=1 || ((dir<0 && cur-step>last1) || (dir>=0 && cur+step<last1))))
return;
printe("\r%6d", cur);
co=step;
if (dir<0)
cur-=step;
else
cur+=step;
fflush(stderr);
}
void
erase_counter(char *s, ...)
{
va_list argp;
int l1;
va_start(argp, s);
pute('\r');
if (s)
l1=vfprintf(stderr, s, argp);
else
l1=0;
while (l1++ <len)
pute(' ');
pute(s ? '\n' : '\r');
fflush(stderr);
dir=0;
va_end(argp);
}
void
prin1(char *p)
{
if (p)
printe("%s ", p);
}
void
errorx(long code, ...)
{
va_list argp;
char c0, c1, c2, c3;
char *p;
int l1;
va_start(argp, code);
if (dir) {
pute('\r');
l1=0;
while (l1++ <len)
pute(' ');
pute('\r');
fflush(stderr);
}
c0=code>>24;
c1=code>>16;
c2=code>>8;
c3=code;
if (c0==E0_INTERNAL) {
printe("internal error in wasp %s, file %s, line %ld; please report to sreiz@cs.vu.nl\n",
version+14, va_arg(argp, char *), code&0x00ffffff);
exit(1);
}
assert(c0>E0_INTERNAL && c0<E0_NUM && c1>0 && c1<E1_NUM && c2>0
&& c2<E2_NUM && c3>0 && c3<E3_NUM);
prin1(e0_s[c0].s1);
prin1(e1_s[c1]);
prin1(e2_s[c2]);
p=e0_s[c0].s2;
if (p)
printe("%s", p);
if (c3==E3_ERRNO) {
printe(" in ");
perror(va_arg(argp, char *));
} else {
p=e3_s[c3];
if (p) {
printe(": ");
vfprintf(stderr, p, argp);
}
pute('\n');
}
if (c0==E0_FATAL)
exit(1);
va_end(argp);
}