diff options
Diffstat (limited to 'util/file.c')
-rw-r--r-- | util/file.c | 629 |
1 files changed, 629 insertions, 0 deletions
diff --git a/util/file.c b/util/file.c new file mode 100644 index 0000000..06d83a6 --- /dev/null +++ b/util/file.c @@ -0,0 +1,629 @@ +/* + * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory + */ + +/* + * + * file.c -- routines to grab file contents, get file size, etc. + * + */ + +#include <file.h> + +#define BUFSIZE 8192 +#define DIR_SEPARATOR '/' + +/* + * FileExists -- determine if a string is a file + * + * This should get re-implemented on slower systems that have + * a system to call to check for a file's existance. + * + */ +#ifdef ANSI_FUNC +int +FileExists(char *filename) +#else +int FileExists(filename) + char *filename; +#endif +{ + FILE *fp; + + if((fp = fopen(filename,"r")) == NULL){ + return(0); + } + else{ + fclose(fp); + return(1); + } +} + +/* + * + * IsFile -- parse a string and determine if it contains a file name + * + * We skip white space, etc and return the actual file name + * + */ +#ifdef ANSI_FUNC +int +IsFile(char *s, char *filename, int len) +#else +int IsFile(s, filename, len) + char *s; + char *filename; + int len; +#endif +{ + int i; + + /* skip white space */ + while( *s && isspace((int)*s) ) + s++; + /* grab the file name up to a max, null, or CR */ + for(i=0; i<len && *s && *s != '\n'; i++, s++) + filename[i] = *s; + /* null terminate */ + filename[i] = '\0'; + /* try to open as a file */ + return(FileExists(filename)); +} + +/* + * IsFits -- determine if a string is a FITS file + * + */ +#ifdef ANSI_FUNC +int +IsFits(char *filename) +#else +int IsFits(filename) + char *filename; +#endif +{ + int got = 0; + char tbuf[10]; + FILE *fp=NULL; + + tbuf[9] = '\0'; + if( !(fp = fopen(filename,"r")) ) + goto done; + if( fread(tbuf, sizeof(char), 9, fp) != 9 ) + goto done; + if( !strcmp(tbuf, "SIMPLE =") ) + got = 1; + +done: + if( fp) fclose(fp); + return(got); +} + +/* + * + * FileNameFromPath -- return file name, given a path + * + */ +#ifdef ANSI_FUNC +char * +FileNameFromPath(char *s) +#else +char *FileNameFromPath(s) + char *s; +#endif +{ + char *idx; + + idx = strrchr(s, DIR_SEPARATOR); + if( idx != NULL ) + return(++idx); + else + return(s); +} + +/* + * + * FileContents -- return contents of a file + * + */ +#ifdef ANSI_FUNC +char * +FileContents(char *path, int isize, int *osize) +#else +char *FileContents(path, isize, osize) + char *path; + int isize; + int *osize; +#endif +{ + FILE *fd; + char *npath; + char *tbuf; + struct stat buf; + int get; + int got; + + /* start pessimisticly */ + if( osize != NULL ) + *osize = 0; + + /* expand environment variables */ + npath = (char *)ExpandMacro(path, NULL, NULL, 0, NULL, NULL); + + /* make sure the file exists */ + if( stat(npath, &buf) <0 ){ + free(npath); + return(NULL); + } + + /* open the file */ + if( (fd=fopen(npath, "r")) == NULL ){ + free(npath); + return(NULL); + } + + /* use may have specified amount of data to get */ + if( isize >0 ) + get = isize; + else + get = buf.st_size; + + /* get contents */ + tbuf = (char *)malloc(get+1); + got = fread(tbuf, sizeof(char), get, fd); + fclose(fd); + tbuf[got] = '\0'; + + /* user may want to know how much was read */ + if( osize != NULL ) + *osize = got; + + free(npath); + return(tbuf); +} + +/* + * + * FileSize -- return the size of a file + * + */ +#ifdef ANSI_FUNC +int +FileSize(char *path) +#else +int FileSize(path) + char *path; +#endif +{ + char *npath; + struct stat buf; + + /* expand environment variables */ + npath = (char *)ExpandMacro(path, NULL, NULL, 0, NULL, NULL); + /* make sure the file exists */ + if( stat(npath, &buf) <0 ){ + free(npath); + return(-1); + } + else{ + free(npath); + return(buf.st_size); + } +} + +/* + * + * FileCopy -- copy a file to another file + * + */ +#ifdef ANSI_FUNC +int +FileCopy(char *iname, char *oname) +#else +int FileCopy(iname, oname) + char *iname; + char *oname; +#endif +{ + FILE *ifd; + FILE *ofd; + char *ipath; + char *opath; + char tbuf[BUFSIZE]; + int got; + + ipath = (char *)ExpandMacro(iname, NULL, NULL, 0, NULL, NULL); + opath = (char *)ExpandMacro(oname, NULL, NULL, 0, NULL, NULL); + if( (ifd=fopen(ipath, "r")) == NULL ) + return(0); + if( (ofd=fopen(opath, "w")) == NULL ) + return(0); + while( (got = fread(tbuf, sizeof(char), BUFSIZE, ifd)) != 0 ){ + fwrite(tbuf, sizeof(char), got, ofd); + } + fclose(ifd); + fclose(ofd); + free(ipath); + free(opath); + return(1); +} + +/* + * + * FileRoot -- strip the [...] extension from a file name and return root + * + */ +#ifdef ANSI_FUNC +char * +FileRoot(char *fname) +#else +char *FileRoot(fname) + char *fname; +#endif +{ + int i; + int len; + char *file; + + len = strlen(fname)+1; + file = (char *)malloc(len); + for(i=0; (fname[i]!='\0') && (fname[i]!='['); i++) + file[i] = fname[i]; + file[i] = '\0'; + return(file); +} + +/* + * + * FileExtension -- extract the [...] extension from a file name + * + */ +#ifdef ANSI_FUNC +char * +FileExtension(char *fname) +#else +char *FileExtension(fname) + char *fname; +#endif +{ + int i; + int len; + char *s; + char *extn; + + /* look for opening bracket */ + if( (s=strchr(fname, '[')) == NULL ){ + return(NULL); + } + /* grab extension(s) */ + else{ + len = strlen(s); + extn = (char *)malloc(len+1); + strcpy(extn, s); + for(i=len-1; i>=0; i--){ + if( extn[i] == ']' ){ + extn[i+1] = '\0'; + break; + } + } + return(extn); + } +} + +/* + * + * GenerateArraySpecification -- generate an array specification of the + * form [xdim=x,ydim=y,...] from various valid inputs + * + */ +#ifdef ANSI_FUNC +int +GenerateArraySpecification(char *ispec, char *ospec, int olen) +#else +int GenerateArraySpecification(ispec, ospec, olen) + char *ispec; + char *ospec; + int olen; +#endif +{ + int got; + int size; + int dsize; + int bitpix; + char s1[SZ_LINE]; + char s2[SZ_LINE]; + char s3[SZ_LINE]; + char s4[SZ_LINE]; + char s5[SZ_LINE]; + + if( (ispec == NULL) || (*ispec == '\0') ) + return(0); + + got = sscanf(ispec, "%s %s %s %s %s", s1, s2, s3, s4, s5); + switch(got){ + case 0: + *ospec = '\0'; + return(0); + case 1: + snprintf(ospec, olen, "%s", s1); + return(1); + case 2: + /* make a guess at the data type by looking at the file size ... + we probably should not work this hard!! */ + size = FileSize(s1); + if( size > 0 ){ + dsize = atoi(s2)*atoi(s2); + bitpix = (size/dsize)*8; + snprintf(ospec, olen, + "%s[xdim=%s,ydim=%s,bitpix=%d]", s1, s2, s2, bitpix); + return(2); + } + else { + *ospec = '\0'; + return(0); + } + case 3: + snprintf(ospec, olen, "%s[xdim=%s,ydim=%s,bitpix=%s]", s1, s2, s2, s3); + return(3); + case 4: + snprintf(ospec, olen, "%s[xdim=%s,ydim=%s,bitpix=%s]", s1, s2, s3, s4); + return(4); + case 5: + snprintf(ospec, olen, "%s[xdim=%s,ydim=%s,bitpix=%s,skip=%s]", + s1, s2, s3, s4, s5); + return(5); + default: + return(0); + } +} + +/* + * + * GenerateArraySpec2 -- generate an array specification from separate name + * and spec strings + * + */ +#ifdef ANSI_FUNC +int +GenerateArraySpec2(char *iname, char *ispec, char *ospec, int olen) +#else +int GenerateArraySpec2(iname, ispec, ospec, olen) + char *iname; + char *ispec; + char *ospec; + int olen; +#endif +{ + + char *buf; + int len; + int got=0; + + len = strlen(iname)+strlen(ispec)+2; + buf = (char *)malloc(len); + snprintf(buf, len, "%s %s", iname, ispec); + if( *buf ){ + got = GenerateArraySpecification(buf, ospec, olen); + free(buf); + } + return(got); +} + +/* + * + * GetNextFileName -- return next file name, given a list + * + */ +#ifdef ANSI_FUNC +int +GetNextFileName(char *filenames, int *ip, char *filename, int len) +#else +int GetNextFileName(filenames, ip, filename, len) + char *filenames; + int *ip; + char *filename; + int len; +#endif +{ + int i; + int j; + + /* start with a clean slate */ + *filename = '\0'; + i = *ip; + /* make sure there is a string */ + if( filenames == NULL || filenames[i] == '\0' ) + return(0); + /* skip white space */ + while((isspace((int)filenames[i]) || (filenames[i] == ':'))) + i++; + /* copy string up to a terminator */ + j = 0; + while(filenames[i] && !isspace((int)filenames[i]) && filenames[i]!= ':'){ + if( j < len ) filename[j++] = filenames[i++]; + } + /* null terminate */ + filename[j] = '\0'; + /* update the filenames pointer */ + *ip = i; + /* return the news */ + if( *filename ) + return(1); + else + return(0); +} + +/* + * + * ParseArraySpec -- parse the special array spec + * + * Generally used in syntax such as: + * + * foo.arr[aa=<spec>] + * + * where spec is of the form: + * + * <type><xdim>[.<ydim>][:<skip>][<endian>] + * + * where type is: + * b (8-bit unsigned char) + * s (16-bit short int) + * u (16-bit unsigned short int) + * i (32-bit int) + * r,f (32-bit float) + * d (64-bit float) + * + * xdim is required, ydim is optional and defaults to xdim + * skip is optional + * endian is optional and can be 'l' or 'b' + * + * + * e.g.: + * + * r512 bitpix=-32 xdim=512 ydim=512 + * r512.400 bitpix=-32 xdim=512 ydim=400 + * r512.400 bitpix=-32 xdim=512 ydim=400 + * r512.400:2880 bitpix=-32 xdim=512 ydim=400 skip=2880 + * r512l bitpix=-32 xdim=512 ydim=512 endian=little + * + */ +#ifdef ANSI_FUNC +int +ParseArraySpec(char *tbuf, int *xdim, int *ydim, int *bitpix, + int *skip, int *bigendian) +#else +int ParseArraySpec(tbuf, xdim, ydim, bitpix, skip, bigendian) + char *tbuf; + int *xdim; + int *ydim; + int *bitpix; + int *skip; + int *bigendian; +#endif +{ + int txdim=0; + int tydim=0; + int tbitpix=0; + int tskip=-1; + int tbigendian=0; + int isarr=0; + long lval; + char *tptr; + char *tptr2; + tptr = tbuf; + + /* get type and use it to set bitpix */ + switch(*tptr){ + case 'b': + case 'B': + tbitpix = 8; + isarr |= 4; + break; + case 's': + case 'S': + tbitpix = 16; + isarr |= 4; + break; + case 'u': + case 'U': + tbitpix = -16; + isarr |= 4; + break; + case 'i': + case 'I': + tbitpix = 32; + isarr |= 4; + break; + case 'r': + case 'R': + case 'f': + case 'F': + tbitpix = -32; + isarr |= 4; + break; + case 'd': + case 'D': + tbitpix = -64; + isarr |= 4; + break; + default: + return(0); + } + tptr++; + + /* check for the required xdim value */ + lval = strtol(tptr, &tptr2, 10); + if( (tptr == tptr2) || (lval <=0) ) + return(0); + else{ + txdim = lval; + /* seed the y value as well, in case we don't get one */ + tydim = txdim; + isarr |= 3; + } + /* update pointer */ + tptr = tptr2; + + /* there are 2 possible delims here */ + switch( *tptr ){ + case '.': + /* now check for the optional ydim value */ + tptr++; + lval = strtol(tptr, &tptr2, 10); + if( tptr == tptr2 ) + tydim = txdim; + else{ + if( lval <=0 ) + return(0); + else + tydim = lval; + } + /* update pointer */ + tptr = tptr2; + /* look for skip after this */ + if( *tptr != ':' ) + break; + case ':': + /* check for the optional skip value */ + tptr++; + lval = strtol(tptr, &tptr2, 10); + if( (tptr != tptr2) && (lval >0) ){ + tskip = lval; + isarr |= 8; + } + /* update pointer */ + tptr = tptr2; + break; + } + + switch(*tptr){ + case 'l': + case 'L': + tbigendian = 0; + isarr |= 16; + break; + case 'b': + case 'B': + tbigendian = 1; + isarr |= 16; + break; + } + + /* make sure required values were set */ + if( (isarr&7) != 7 ) + return(0); + + /* fill in required values */ + *xdim = txdim; + *ydim = tydim; + *bitpix = tbitpix; + + /* see if optional values were set */ + if( isarr & 8 ) + *skip = tskip; + if( isarr & 16 ) + *bigendian = tbigendian; + + /* success */ + return(1); +} |