// // fio.c // // Warning: Do not edit the following four lines. CVS maintains them. // Revision Author: $Author: nicks $ // Revision Date : $Date: 2006/04/19 22:47:33 $ // Revision : $Revision: 1.29 $ // //////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include "bfileio.h" #include "fio.h" #include "machine.h" #include "proto.h" #include "error.h" #include "mghendian.h" #include "utils.h" // strcpyalloc #define FIO_NPUSHES_MAX 100 int fio_npushes = -1; char fio_dirstack[FIO_NPUSHES_MAX][1000]; FILE *MGHopen_file(char *fname, char *rwmode) { FILE *f1; if ((f1 = fopen(fname,rwmode)) == NULL) { printf("Can't open %s\n",fname); exit(1); } return f1; } int putf(float f, FILE *fp) { #if (BYTE_ORDER == LITTLE_ENDIAN) f = swapFloat(f) ; #endif return(fwrite(&f,4,1,fp)); } float getf(FILE *fp) { float f; fread(&f,4,1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) f = swapFloat(f) ; #endif return f; } int fread1(int *v, FILE *fp) { unsigned char c; int ret ; ret = fread(&c,1,1,fp); *v = c; return(ret) ; } int fread2(int *v, FILE *fp) { short s; int ret ; ret = fread(&s,2,1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) s = swapShort(s) ; #endif *v = s; return(ret) ; } int fread3(int *v, FILE *fp) { unsigned int i = 0; int ret ; ret = fread(&i,3,1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) i = (unsigned int)swapInt(i) ; #endif *v = ((i>>8) & 0xffffff); return(ret) ; } int fread4(float *v, FILE *fp) { float f; int ret ; ret = fread(&f,4,1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) f = swapFloat(f) ; #endif *v = f; return(ret) ; } int fwrite1(int v,FILE *fp) { unsigned char c = (unsigned char)v; return(fwrite(&c,1,1,fp)); } int fwrite2(int v, FILE *fp) { short s ; if (v > 0x7fff) /* don't let it overflow */ v = 0x7fff ; else if (v < -0x7fff) v = -0x7fff ; s = (short)v; #if (BYTE_ORDER == LITTLE_ENDIAN) s = swapShort(s) ; #endif return(fwrite(&s,2,1,fp)); } int fwrite3(int v, FILE *fp) { unsigned int i = (unsigned int)(v<<8); #if (BYTE_ORDER == LITTLE_ENDIAN) i = (unsigned int)swapInt(i) ; #endif return(fwrite(&i,3,1,fp)); } int fwrite4(int v,FILE *fp) { #if (BYTE_ORDER == LITTLE_ENDIAN) v = swapInt(v) ; #endif return(fwrite(&v,4,1,fp)); } int fwriteShort(short s, FILE *fp) { #if (BYTE_ORDER == LITTLE_ENDIAN) s = swapShort(s) ; #endif return(fwrite(&s, sizeof(short), 1, fp)) ; } double freadDouble(FILE *fp) { double d; int ret ; ret = fread(&d,sizeof(double),1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) d = swapDouble(d) ; #endif if (ret != 1) ErrorPrintf(ERROR_BADFILE, "freadDouble: fread failed") ; return(d) ; } int freadInt(FILE *fp) { int i, nread ; nread = fread(&i,sizeof(int),1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) i = swapInt(i) ; #endif return(i) ; } long long freadLong(FILE *fp) { int nread ; long long i ; nread = fread(&i,sizeof(long long),1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) i = swapLong64(i) ; #endif return(i) ; } short freadShort(FILE *fp) { int nread ; short s ; nread = fread(&s,sizeof(short),1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) s = swapShort(s) ; #endif if (nread != 1) ErrorPrintf(ERROR_BADFILE, "freadShort: fread failed") ; return(s) ; } /*******************************************************/ /* read routines which can be used for fread */ /* the usage is */ /* */ /* while (fread..Ex(., fp)) */ /* dosomething(); */ /*******************************************************/ int freadFloatEx(float *pf, FILE *fp) { int ret ; ret = fread(pf,sizeof(float),1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) *pf = swapFloat(*pf) ; #endif return ret; } int freadDoubleEx(double *pd, FILE *fp) { int ret ; ret = fread(pd,sizeof(double),1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) *pd = swapDouble(*pd) ; #endif return ret; } int freadIntEx(int *pi, FILE *fp) { int nread ; nread = fread(pi,sizeof(int),1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) *pi = swapInt(*pi) ; /* swapInt(int i) */ #endif return(nread); } int freadShortEx(short *ps, FILE *fp) { int nread ; nread = fread(ps,sizeof(short),1,fp); #if (BYTE_ORDER == LITTLE_ENDIAN) *ps = swapShort(*ps) ; #endif return(nread) ; } /******************************************************/ int fwriteInt(int v, FILE *fp) { #if (BYTE_ORDER == LITTLE_ENDIAN) v = swapInt(v) ; #endif return(fwrite(&v,sizeof(int),1,fp)); } int fwriteLong(long long v, FILE *fp) { #if (BYTE_ORDER == LITTLE_ENDIAN) v = swapLong64(v) ; #endif return(fwrite(&v,sizeof(long long),1,fp)); } /*----------------------------------------*/ float freadFloat(FILE *fp) { char buf[4]; float f; int ret ; ret = fread(buf,4,1,fp); //ret = fread(&f,4,1,fp); // old way if (ret != 1) ErrorPrintf(ERROR_BADFILE, "freadFloat: fread failed") ; #if (BYTE_ORDER == LITTLE_ENDIAN) byteswapbuffloat(buf,1); //f = swapFloat(f); // old way #endif f = *((float*)buf); return(f) ; } /*----------------------------------------*/ int fwriteFloat(float f, FILE *fp) { int ret; char buf[4]; memcpy(buf,&f,4); #if (BYTE_ORDER == LITTLE_ENDIAN) byteswapbuffloat(buf,1); //f = swapFloat(f); // old way #endif ret = fwrite(buf,sizeof(float),1,fp); //ret = fwrite(&f,sizeof(float),1,fp); // old way return(ret); } /*----------------------------------------*/ int fwriteDouble(double d, FILE *fp) { #if (BYTE_ORDER == LITTLE_ENDIAN) d = swapDouble(d) ; #endif return(fwrite(&d,sizeof(double),1,fp)); } /*------------------------------------------------------ fio_dirname() - function to replicate the functionality of the unix dirname. Author: Douglas Greve, 9/10/2001 ------------------------------------------------------*/ char *fio_dirname(char *pathname) { int l,n; char *dirname; if(pathname == NULL) return(NULL); l = strlen(pathname); /* strip off leading forward slashes */ while(l > 0 && pathname[l-1] == '/'){ pathname[l-1] = '\0'; l = strlen(pathname); } if(l < 2){ /* pathname is / or . or single character */ dirname = (char *) calloc(2,sizeof(char)); if(l==0 || pathname[0] == '/') dirname[0] = '/'; else dirname[0] = '.'; return(dirname); } /* Start at the end of the path name and step back until a forward slash is found */ for(n=l; n >= 0; n--)if(pathname[n] == '/') break; if(n < 0){ /* no forward slash found */ dirname = (char *) calloc(2,sizeof(char)); dirname[0] = '.'; return(dirname); } if(n == 0){ /* first forward slash is the first character */ dirname = (char *) calloc(2,sizeof(char)); dirname[0] = '/'; return(dirname); } dirname = (char *) calloc(n+1,sizeof(char)); memcpy(dirname,pathname,n); return(dirname); } /*------------------------------------------------------ fio_basename() - function to replicate the functionality of the unix basename. Author: Douglas Greve, 9/10/2001 ------------------------------------------------------*/ char *fio_basename(char *pathname, char *ext) { int l,n,lext; char *basename, *tmp; if(pathname == NULL) return(NULL); l = strlen(pathname); tmp = strcpyalloc(pathname); // keep a copy /* strip off the extension if it matches ext */ if(ext != NULL){ lext = strlen(ext); if(lext < (l + 2)){ if( strcmp(ext,&(pathname[l-lext]) ) == 0){ memset(&(pathname[l-lext]),'\0',lext+1); l = strlen(pathname); } } } /* strip off leading forward slashes */ while(l > 0 && pathname[l-1] == '/'){ pathname[l-1] = '\0'; l = strlen(pathname); } if(l < 2){ /* basename is / or . or single character */ basename = (char *) calloc(2,sizeof(char)); if(l==0) basename[0] = '/'; else basename[0] = pathname[0]; memcpy(pathname,tmp,strlen(tmp)); free(tmp); return(basename); } /* Start at the end of the path name and step back until a forward slash is found */ for(n=l; n >= 0; n--) if(pathname[n] == '/') break; basename = (char *) calloc(l-n,sizeof(char)); memcpy(basename,&(pathname[n+1]),l-n); // Make sure that pathname does not change memcpy(pathname,tmp,strlen(tmp)); free(tmp); return(basename); } /*-------------------------------------------------------------- fio_extension() - returns the extension of the given filename. Author: Douglas Greve, 1/30/2002 -------------------------------------------------------------*/ char *fio_extension(char *pathname) { int lpathname,n, lext; char *ext; if(pathname == NULL) return(NULL); lpathname = strlen(pathname); lext = 0; n = lpathname - 1; while(n >= 0 && pathname[n] != '.') { n--; lext++; } /* A dot was not found, return NULL */ if(n < 0) return(NULL); /* A dot was not found at the end of the file name */ if(lext == 0) return(NULL); ext = (char *) calloc(sizeof(char),lext+1); memcpy(ext,&(pathname[n+1]),lext); return(ext); } /* ----------------------------------------------------- fio_DirIsWritable(char *dirname, int fname) -- tests whether the given directory is writable by creating and deleting a junk file there. If fname != 0, then dirname is treated as path to a filename. It will return 0 if the directory does not exist. ----------------------------------------------------- */ int fio_DirIsWritable(char *dirname, int fname) { FILE *fp; char tmpstr[2000]; if(fname != 0) sprintf(tmpstr,"%s.junk.54_-_sdfklj",dirname); else sprintf(tmpstr,"%s/.junk.54_-_sdfklj",dirname); fp = fopen(tmpstr,"w"); if(fp == NULL) return(0); fclose(fp); unlink(tmpstr); return(1); } /*----------------------------------------------------- fio_FileExistsReadable() - file exists and is readable -----------------------------------------------------*/ int fio_FileExistsReadable(char *fname) { FILE *fp; fp = fopen(fname,"r"); if(fp != NULL){ fclose(fp); return(1); } return(0); } /*----------------------------------------------------- fio_IsDirectory(fname) - fname exists and is a directory -----------------------------------------------------*/ int fio_IsDirectory(char *fname) { FILE *fp; struct stat buf; int err; fp = fopen(fname,"r"); if(fp == NULL) return(0); fclose(fp); err = stat(fname, &buf); if(err != 0) return(0); return(S_ISDIR(buf.st_mode)); } /*------------------------------------------------------------ fio_NLines() - get the number of lines. The line length should not exceed 4000 characters. ------------------------------------------------------------*/ int fio_NLines(char *fname) { FILE *fp; int nrows; char tmpstring[4001]; fp = fopen(fname,"r"); if(fp == NULL){ printf("ERROR: cannot open %s\n",fname); return(-1); } nrows = 0; while(fgets(tmpstring,4000,fp) != NULL) nrows ++; fclose(fp); return(nrows); } /*------------------------------------------------------------------------*/ int fio_pushd(char *dir) { extern int fio_npushes; extern char fio_dirstack[FIO_NPUSHES_MAX][1000]; int err; fio_npushes ++; if(fio_npushes == FIO_NPUSHES_MAX){ printf("ERROR: fio_pushd: maximum number of pushes reached\n"); return(1); } getcwd(fio_dirstack[fio_npushes],1000); err = chdir(dir); if(err){ printf("ERROR: fio_pushd: %s\n",dir); fio_npushes --; return(1); } //printf("fio_pushd: %d %s\n",fio_npushes+1,dir); return(0); } /*------------------------------------------------------------------------*/ int fio_popd(void) { extern int fio_npushes; extern char fio_dirstack[FIO_NPUSHES_MAX][1000]; int err; if(fio_npushes == -1){ printf("ERROR: fio_popd: dir stack is empty\n"); return(1); } err = chdir(fio_dirstack[fio_npushes]); if(err){ printf("ERROR: fio_popd: %d %s\n",fio_npushes,fio_dirstack[fio_npushes]); return(1); } fio_npushes --; //printf("fio_popd: %d %s\n",fio_npushes+1,fio_dirstack[fio_npushes+1]); return(0); } /*-------------------------------------------------------------------- fio_fullpath() - gets full path to a file. The file must exist. Works by pushing into the file dir, getting the cwd, appending the file basename to the cwd to get the full path, then popping the stack. -------------------------------------------------------------------*/ char *fio_fullpath(char *fname) { static char cwd[1000]; char *dirname, *basename; char *fullpath; int err; basename = fio_basename(fname,NULL); dirname = fio_dirname(fname); err = fio_pushd(dirname); if(err){ free(dirname); free(basename); return(NULL); } getcwd(cwd,1000); fio_popd(); sprintf(cwd,"%s/%s",cwd,basename); fullpath = strcpyalloc(cwd); free(dirname); free(basename); return(fullpath); }