dos_compilers/Zortech C++ v30r1/SAMPLE/FILE.C
2024-07-02 08:01:21 -07:00

899 lines
19 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*_ file.c Wed Mar 22 1989 Modified by: Walter Bright */
/* $Header: /proj/products/merlin/port/RCS/file.c,v 1.28 90/03/01 15:07:42 bright Exp Locker: bright $ */
/* Written by Walter Bright */
/* File manipulation package */
/* Isolate differences in how files are handled to this module */
#if VAX11C
#define __FILE__ "file.c"
#endif
#include <stdio.h>
#include "toolkit.h"
#include "mem.h"
#include "filespec.h"
#include "file.h"
#ifndef assert
#include <assert.h>
#endif
#if BSDUNIX
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <strings.h>
extern long lseek();
extern void *malloc(),*calloc(),*realloc();
#endif
#if VMS
#include <stat.h>
#include <file.h>
#include <descrip.h>
extern long lseek();
extern void *malloc(),*calloc(),*realloc();
#endif
#if DLC && !__ZTC__
#include <dos.h>
#include <string.h>
#include <time.h>
extern void *malloc(),*calloc(),*realloc();
#endif
#if __ZTC__
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <io.h>
#include <direct.h>
#endif
#if MSC
#include <fcntl.h>
#include <sys/stat.h>
#include <io.h>
#include <dos.h>
#include <string.h>
#include <memory.h>
#endif
/********************************/
#ifdef Afiletime
time_t file_time(name)
char *name;
{
#if DLC && !__ZTC__
struct FIND *f;
time_t t;
unsigned date,time,dd,mm,yy;
static signed char adjust[12] =
/* J F M A M J J A S O N D */
/* 31 28 31 30 31 30 31 31 30 31 30 31 */
{ 0, 1,-1, 0, 0, 1, 1, 2, 3, 3, 4, 4 };
f = findfirst(name,0);
assert(f); /* better have found the file */
/* Convert time to seconds since midnight */
time = f->time;
t = ((time & 0x1F) * 2 + /* 2-second increments */
((time >> 5) & 0x3F) * 60) + /* minutes */
(time_t) ((time >> 11) & 0x1F) * 3600; /* hours */
/* Convert date to days since Jan 1, 1980 */
date = f->date;
dd = date & 0x1F; /* 1..31 */
mm = ((date >> 5) & 0x0F) - 1; /* 0..11 */
yy = (date >> 9) & 0x7F; /* 0..119 (1980-2099) */
date = dd + yy * 365 + mm * 30 + adjust[mm] +
((yy + 3) >> 2); /* add day for each previous leap year */
if (mm <= 1 || yy & 3) /* if not a leap year */
date--;
/* Combine date and time to get seconds since Jan 1, 1980 */
return t + (time_t) date * (time_t) (60*60*24L);
#endif
#if BSDUNIX || MSC || VMS || __ZTC__
struct stat buf;
int status;
status = stat(name,&buf);
assert(status == 0); /* must have succeeded */
return buf.st_mtime;
#endif
}
#endif /* Afiletime */
/********************************/
#ifdef Afilesett
int file_settime(name,newtime)
char *name;
time_t newtime;
{ time_t times[2];
times[0] = newtime;
times[1] = newtime;
return utime(name,times);
}
#endif /* Afilesett */
/********************************/
#ifdef Afilesize
unsigned long file_size(name)
char *name;
{
#if BSDUNIX || MSC || VMS
struct stat buf;
int status;
status = stat(name,&buf);
return (status == -1) ? -1L : buf.st_size;
#endif
#if DLC || __ZTC__
return filesize(name);
#endif
}
#endif /* Afilesize */
/********************************/
#ifdef Afileexis
int file_exists(name)
char *name;
{
#if BSDUNIX || MSC || VMS
struct stat buf;
assert(name);
return stat(name,&buf) == 0; /* file exists if stat succeeded */
#endif
#if DLC || __ZTC__
return filesize(name) != -1L;
#endif
}
#endif /* Afileexis */
/********************************/
#ifdef Afilerena
int file_rename(from,to)
char *from,*to;
{
#if IBMRT
int result,mem_malloc();
register char *command;
assert(from && to && *from && *to);
command = mem_malloc(strlen(from) + strlen(to) + 4 + 1);
if (!command)
return 0;
sprintf(command,"mv %s %s",from,to);
result = system(command); /* mv from to */
mem_free(command);
return result >= 0;
#else
#if VMS
$DESCRIPTOR(desc1, from);
$DESCRIPTOR(desc2, to);
int status;
desc1.dsc$w_length = strlen(from);
desc2.dsc$w_length = strlen(to);
status = lib$rename_file(&desc1, &desc2);
return status == 1;
#else
assert(from && to && *from && *to);
return rename(from,to) == 0;
#endif
#endif
}
#endif /* Afilerena */
/********************************/
#if Afilecopy || Afileappe
#if Afilecopy
int file_copy(from,to)
#else
int file_append(from,to)
#endif
char *from,*to;
{ int fdfrom,fdto;
int bufsiz;
fdfrom = open(from,O_RDONLY,0);
if (fdfrom < 0)
return 1;
#if Afileappe
/* Open R/W by owner, R by everyone else */
fdto = open(to,O_WRONLY,0644);
if (fdto < 0)
{ fdto = creat(to,0644);
if (fdto < 0)
goto err;
}
else
if (lseek(fdto,0L,SEEK_END) == -1) /* to end of file */
goto err2;
#else
fdto = creat(to,0644);
if (fdto < 0)
goto err;
#endif
/* Use the largest buffer we can get */
for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1)
{ register char *buffer;
buffer = (char *) malloc(bufsiz);
if (buffer)
{ while (1)
{ register int n;
n = read(fdfrom,buffer,bufsiz);
if (n == -1) /* if error */
break;
if (n == 0) /* if end of file */
{ free(buffer);
close(fdto);
close(fdfrom);
return 0; /* success */
}
n = write(fdto,buffer,(unsigned) n);
if (n == -1)
break;
}
free(buffer);
break;
}
}
err2: close(fdto);
remove(to); /* delete any partial file */
err: close(fdfrom);
return 1;
}
#endif /* Afilecopy || Afileappe */
/********************************/
#ifdef Afiledire
#if BSDUNIX
/****************************************
* Determine if file should be included.
*/
static int file_select(d)
struct direct *d;
{
/* Return 1 if d matches our filespec (regular expression) */
return re_exec(d->d_name) == 1;
}
#endif /* BSDUNIX */
/********************************/
int file_directory(Filespec,Attr,Files_ppp,Nfiles_p)
char *Filespec;
int Attr;
char ***Files_ppp;
unsigned *Nfiles_p;
{
int result;
int nfiles,n;
char **files_pp;
char *path;
#if MSDOS || __OS2__
char *p;
static char allfiles[] = "*.*";
#if DLC || __ZTC__
struct FIND *f;
#endif
#if MSC
struct find_t findbuf;
int f;
#endif
#endif
#if BSDUNIX
char *dirname;
unsigned i;
struct stat buf;
struct direct **namelist;
static char allfiles[] = "*";
extern int alphasort(); /* sort filenames in ascii order */
#endif
assert(Files_ppp && Nfiles_p);
/* free data structure */
for (nfiles = 0; nfiles != *Nfiles_p; nfiles++)
mem_free((*Files_ppp)[nfiles]);
mem_free(*Files_ppp);
*Nfiles_p = 0;
*Files_ppp = NULL;
if (Filespec == NULL)
return 1;
nfiles = 0;
files_pp = NULL;
result = 1; /* assume success */
if (Filespec[0] == 0)
Filespec = allfiles;
#if BSDUNIX
/* If Filespec is really a directory name */
if (stat(Filespec,&buf) == 0 && buf.st_mode & S_IFDIR)
{ if (re_comp(".*")) /* match anything */
return 0;
dirname = Filespec;
}
else
{ char *re,*r1,*p,*p1;
p = filespecname(Filespec);
if (*p == 0)
{ p = allfiles;
dirname = mem_strdup(Filespec);
if (dirname == NULL)
return 0;
}
else
{ dirname = (char *) mem_calloc(p - Filespec + 1);
if (dirname == NULL)
return 0;
memcpy(dirname,Filespec,p - Filespec);
}
/* Form regular expression from filename. The expression must be */
/* translated from what csh handles to what regex(3) handles. Our */
/* translation is a bit crude, but handles most common cases. */
/* In particular, ~ and {} combinations are not handled. */
re = (char *) mem_malloc(1 + strlen(p) * 2 + 1 + 1); /* guarantee enough room */
if (!re)
{ mem_free(dirname);
return 0;
}
r1 = re;
*r1++ = '^'; /* must match start of line */
for (p1 = p; *p1; p1++)
{ switch (*p1)
{
case '*': /* 0 or more of any chars */
*r1++ = '.';
*r1++ = '*';
break;
case '?': /* match any char */
*r1++ = '.';
break;
case '^':
case '$':
case '.':
*r1++ = '\\'; /* prevent special meaning */
/* FALL-THROUGH */
default:
*r1++ = *p1;
break;
}
}
*r1++ = '$'; /* must match end of line */
*r1 = 0;
if (re_comp(re)) /* compile regular expression */
{ mem_free(dirname);
mem_free(re);
return 0; /* if error */
}
mem_free(re);
}
nfiles = scandir(dirname,&namelist,file_select,alphasort);
if (dirname != Filespec) /* if dirname was malloc'd */
mem_free(dirname);
if (nfiles == -1) /* if error */
return 0;
*Files_ppp = (char **) mem_malloc(nfiles * sizeof(**Files_ppp));
if (nfiles && !*Files_ppp)
return 0;
/* Load up the array of filename strings */
for (i = 0; i < nfiles; i++)
{ char *name;
name = mem_strdup(namelist[i]->d_name);
if (!name)
result = 0;
(*Files_ppp)[i] = name;
}
/* Free up the namelist strings */
for (i = 0; i < nfiles; i++)
{ if (result == 0)
mem_free((*Files_ppp)[i]);
free(namelist[i]);
}
if (result == 0)
{ mem_free(*Files_ppp);
nfiles = 0;
}
free(namelist);
*Nfiles_p = nfiles;
return result; /* success */
#endif /* BSDUNIX */
#if MSDOS || __OS2__
/* Fix p to point to filename.ext portion */
p = filespecname(Filespec);
#define DIR 0x10 /* sub-directory attribute */
/* Determine if filename.ext is really a directory name. */
/* If it is, append \*.* to it and use that string. */
if (!*p ||
strchr(p,'*') == NULL && strchr(p,'?') == NULL &&
#if DLC || __ZTC__
(f = findfirst(Filespec,DIR)) != NULL && f->attribute & DIR
#else /* MSC */
_dos_findfirst(Filespec,DIR,&findbuf) == 0 && findbuf.attrib & DIR
#endif
)
{ int len;
p = filespecaddpath(Filespec,"*.*");
if (!p)
return 0; /* error: out of memory */
path = mem_strdup(Filespec);
}
else
{ char c = *p;
*p = 0;
path = mem_strdup(Filespec);
*p = c;
p = Filespec;
}
if (!path)
return 0;
#if DLC || __ZTC__
f = findfirst(p,Attr);
#else
f = _dos_findfirst(p,Attr,&findbuf) == 0;
#endif
if (p != Filespec) /* if didn't specially create a filespec */
mem_free(p);
if (f)
{ int filesmax = 100;
char **pp;
files_pp = (char **) mem_malloc(sizeof(char *) * 100);
if (!files_pp)
goto err;
#if DLC || __ZTC__
*files_pp = filespecaddpath(path,f->name);
#else
*files_pp = filespecaddpath(path,findbuf.name);
#endif
if (!*files_pp)
goto err;
nfiles++;
#if DLC || __ZTC__
while ((f = findnext()) != NULL)
#else
while (_dos_findnext(&findbuf) == 0)
#endif
{
if (filesmax <= nfiles)
{
filesmax += 100;
pp = (char **) mem_realloc(files_pp,sizeof(char **) *
filesmax);
if (!pp)
goto err;
files_pp = pp;
}
#if DLC || __ZTC__
files_pp[nfiles] = filespecaddpath(path,f->name);
#else
files_pp[nfiles] = filespecaddpath(path,findbuf.name);
#endif
if (!files_pp[nfiles])
goto err;
nfiles++;
}
/* Realloc back to final size */
pp = (char **) mem_realloc(files_pp,sizeof(char **) * nfiles);
if (!pp)
goto err;
files_pp = pp;
}
*Nfiles_p = nfiles;
*Files_ppp = files_pp;
mem_free(path);
return result;
err:
for (n = 0; n < nfiles; n++)
mem_free(files_pp[n]); /* free partial data structure */
mem_free(files_pp);
mem_free(path);
return 0; /* failure */
#endif
#if VMS
assert(0);
#endif
}
#endif /* Afiledire */
/********************************/
#ifdef Afilesear
char *file_searchpath(path,filename)
char *path;
char *filename;
{ char *p;
char *filespec;
int namelen;
#ifdef BSDUNIX || M_UNIX || M_XENIX
struct stat buf;
int status;
#endif
filespec = NULL;
if (!filename)
goto ret; /* NULL files don't exist */
if (!path)
{
L1:
/* Search current directory only */
/*printf("looking for 1: '%s'\n",filename);*/
if (file_exists(filename))
filespec = mem_strdup(filename);
goto ret;
}
/* Check for full file specification in filename */
#if MSDOS || __OS2__
#define SEP ';'
if (strchr(filename,':') || *filename == '\\' || *filename == '/')
#endif
#if BSDUNIX || M_UNIX || M_XENIX
#define SEP ':'
if (*filename == '/')
#endif
#if VMS
assert(0); /* not implemented */
#endif
goto L1;
namelen = strlen(filename);
while (1)
{ char c;
while (*path == ' ' || *path == SEP) /* skip leading junk */
path++;
if (*path == 0) /* if no more paths */
{ filespec = NULL;
break;
}
p = path;
do
p++;
while (*p && *p != ' ' && *p != SEP); /* find end of path */
c = *p;
*p = 0;
filespec = filespecaddpath(path,filename);
*p = c;
if (!filespec) /* if out of memory */
break;
/*printf("looking for 2: '%s'\n",filespec);*/
if (file_exists(filespec))
{
#ifdef BSDUNIX || M_UNIX || M_XENIX
status = stat(filespec,&buf);
assert(status == 0); /* must have succeeded */
if ((int)(buf.st_mode & S_IFMT) == (int)S_IFREG)
break; /* only stop for regular files */
#else
break;
#endif
}
mem_free(filespec);
path = p; /* skip to next path */
}
ret:
#if 0
if (filespec)
printf("found: '%s'\n",filespec);
else
printf("didn't find: '%s'\n",filename);
#endif
return filespec;
}
#endif /* Afilesear */
/********************************/
#ifdef Afilesame
int file_same(filespec1,filespec2)
char *filespec1;
char *filespec2;
{
#if BSDUNIX
struct stat stat1;
struct stat stat2;
if (stat(filespec1,&stat1) == -1) /* if file 1 doesn't exist */
{ char *filename1,*filename2;
char c1,c2;
int result;
if (stat(filespec2,&stat2) == 0) /* but file 2 does */
goto notsame;
/* Neither file exists. Therefore, the filespecs point to the */
/* same spot if the parent directories are the same, and the */
/* filenames match. */
filename1 = filespecname(filespec1);
filename2 = filespecname(filespec2);
if (filespeccmp(filename1,filename2) != 0)
goto notsame; /* filenames don't match */
if (*filespec1 == 0) /* if no parent directory */
return 1;
if (filename1 > filespec1)
filename1--;
c1 = *filename1;
*filename1 = 0;
if (filename2 > filespec2)
filename2--;
c2 = *filename2;
*filename2 = 0;
result = file_same(filespec1,filespec2);
*filename1 = c1;
*filename2 = c2;
return result;
}
if (stat(filespec2,&stat2) == -1) /* if file 2 doesn't exist */
goto notsame; /* but file 1 does */
/* Both files exist. They are the same if the inode numbers match */
return stat1.st_ino == stat2.st_ino;
notsame:
return 0;
#endif /* BSDUNIX */
#if MSDOS || __OS2__
struct FIND *f;
char attr1,attr2;
if (!file_exists(filespec1)) /* if file 1 doesn't exist */
{ char *filename1,*filename2;
char c1,c2;
int result;
if (file_exists(filespec2)) /* but file 2 does */
goto notsame;
/* Neither file exists. Therefore, the filespecs point to the */
/* same spot if the parent directories are the same, and the */
/* filenames match. */
filename1 = filespecname(filespec1);
filename2 = filespecname(filespec2);
if (filespeccmp(filename1,filename2) != 0)
goto notsame; /* filenames don't match */
if (*filespec1 == 0) /* if no parent directory */
return 1;
if (filename1 > filespec1)
filename1--;
c1 = *filename1;
*filename1 = 0;
if (filename2 > filespec2)
filename2--;
c2 = *filename2;
*filename2 = 0;
result = file_same(filespec1,filespec2);
*filename1 = c1;
*filename2 = c2;
return result;
}
if (!file_exists(filespec2)) /* if file 2 doesn't exist */
goto notsame; /* but file 1 does */
/* Both files exist. They are the same if the attributes are the */
/* same and if by changing one the attribute of one file you change */
/* the attribute of the other. */
f = findfirst(filespec1,0);
assert(f);
attr1 = f->attribute;
f = findfirst(filespec2,0);
assert(f);
attr2 = f->attribute;
if (attr1 != attr2)
goto notsame;
chmod(filespec1,attr1 ^ FA_RDONLY);
f = findfirst(filespec2,0);
attr2 = f->attribute;
chmod(filespec1,attr1); /* reset back to original */
return (attr1 ^ FA_RDONLY) == attr2;
notsame:
return 0;
#endif
#if VMS
assert(0);
#endif
}
#endif /* Afilesame */
/********************************/
#ifdef Afileread
list_t file_read(name)
char *name;
{ list_t lines = NULL;
list_t list;
FILE *fp;
char *buffer = NULL;
int buflen = 0;
int bufi = 0;
fp = fopen(name,"r");
if (fp)
{ int c;
char *p;
while (1)
{ if (bufi + 1 > buflen)
{ buflen += 80;
buffer = (char *) mem_realloc(buffer,buflen);
assert(buffer);
}
c = fgetc(fp);
switch (c)
{
case EOF:
goto eof;
case 0:
break; /* ignore nulls */
case '\n':
buffer[bufi] = 0;
p = mem_strdup(buffer);
assert(p);
list = list_append(&lines,p);
assert(list);
bufi = 0;
break;
default:
buffer[bufi++] = c;
break;
}
}
eof:
if (bufi)
{ buffer[bufi++] = 0;
buffer = (char *) mem_realloc(buffer,bufi);
assert(buffer);
list = list_append(&lines,buffer);
assert(list);
}
else
mem_free(buffer);
fclose(fp);
}
return lines;
}
#endif /* Afileread */
/********************************/
#ifdef Afilewrit
int file_write(name,lines)
char *name;
list_t lines;
{ FILE *fp;
fp = fopen(name,"w");
if (fp)
{
for (; 1; lines = list_next(lines))
{ char *p;
if (!lines) /* if no more to write */
{ if (fclose(fp) == EOF)
goto L1;
return 0;
}
p = (char *) list_ptr(lines);
if (p && fputs(p,fp))
break;
if (fputc('\n',fp) == EOF)
break;
}
fclose(fp);
L1:
remove(name);
}
return 1;
}
#endif /* Afilewrit */
#ifdef Afilemd
/******************************
*/
int file_mkdir(dir)
char *dir;
{
#if __ZTC__
struct FIND *find;
char *p;
char c;
p = dir;
/* Skip over any drive: */
if (strlen(p) >= 2 && p[1] == ':')
p += 2;
while (*p)
{
if (*p == '\\')
p++;
while (*p && *p != '\\')
p++; /* scan to end of path element */
c = *p;
*p = 0;
/* Turn off LABEL bit because stupid NFS bug: the volume label */
/* always is found, regardless of the dir string! */
find = findfirst(dir,FA_DIREC);
if (find) /* if name already exists */
{ *p = c;
if (!(find->attribute & FA_DIREC))
return 2; /* it's something else */
}
else if (mkdir(dir) != 0)
{ *p = c;
return 3; /* can't make directory */
}
*p = c;
}
return 0; /* success */
#else
return 2; /* not implemented */
#endif
}
#endif /* Afilemd */