/* * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory */ /* * * file.c -- routines to grab file contents, get file size, etc. * */ #include #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; i0 ) 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=] * * where spec is of the form: * * [.][:][] * * 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); }