/* File: wfileIO3.c Written by: John van Groningen At: University of Nijmegen */ #include "wcon.h" #ifdef WINDOWS # include # define HFILE HANDLE # define ULONG unsigned long # define OS(w,o) w # ifndef FILE_END # define FILE_END 2 # endif # ifndef FILE_BEGIN # define FILE_BEGIN 0 # endif extern DWORD __attribute__ ((stdcall)) GetFileSize (HANDLE,LPDWORD); #else # define INCL_DOSFILEMGR # include "os2.h" # define OS(w,o) o #endif extern void IO_error (char*); extern void *allocate_memory (int); extern void free_memory (void*); #define EOF (-1) #define CLEAN_TRUE 1 #define CLEAN_BOOL int #define MAX_N_FILES 20 #define MAX_FILE_NAME_LENGTH 255 #define FIRST_REAL_FILE 3 #define F_SEEK_SET 0 #define F_SEEK_CUR 1 #define F_SEEK_END 2 struct file { /* 48 bytes */ unsigned char * file_read_p; /* offset 0 */ unsigned char * file_write_p; /* offset 4 */ unsigned char * file_end_buffer_p; /* offset 8 */ short file_mode; /* offset 12 */ char file_unique; /* offset 14 */ char file_error; /* offset 15 */ unsigned char * file_buffer_p; unsigned long file_offset; unsigned long file_length; char * file_name; long file_number; unsigned long file_position; unsigned long file_position_2; HFILE file_refnum; }; struct clean_string { long length; char characters[0]; }; #ifndef WINDOWS static #endif struct file file_table[MAX_N_FILES]; static int number_of_files=FIRST_REAL_FILE; #define is_special_file(f) ((long)(f)<(long)(&file_table[FIRST_REAL_FILE])) static char *clean_to_c_string (struct clean_string *cs) { int l; char *cp,*s; cp=cs->characters; l=cs->length; s=allocate_memory (l+1); if (s!=NULL){ register char *sp; for (sp=s; l!=0; --l) *sp++=*cp++; *sp='\0'; } return s; } #define FILE_IO_BUFFER_SIZE (4*1024) #define F_READ_TEXT 0 #define F_WRITE_TEXT 1 #define F_APPEND_TEXT 2 #define F_READ_DATA 3 #define F_WRITE_DATA 4 #define F_APPEND_DATA 5 #define ERROR_FILE ((struct file*)-(long)&file_table[2]) static OS(DWORD,ULONG) file_permission[]={ #ifdef WINDOWS GENERIC_READ, GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE, GENERIC_READ, GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE #else OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE, OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE, OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYWRITE, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE, OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE, OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYWRITE #endif }; static OS(DWORD,ULONG) file_action[]={ #ifdef WINDOWS OPEN_EXISTING, CREATE_ALWAYS, OPEN_ALWAYS, OPEN_EXISTING, CREATE_ALWAYS, OPEN_ALWAYS #else FILE_OPEN, FILE_TRUNCATE | FILE_CREATE, FILE_OPEN | FILE_CREATE, FILE_OPEN, FILE_TRUNCATE | FILE_CREATE, FILE_OPEN | FILE_CREATE #endif }; struct file *open_file (struct clean_string *file_name,unsigned int file_mode) { char *file_name_s; int fn; struct file *f; long file_length; unsigned char *buffer; HFILE file_handle; ULONG action; OS(DWORD,APIRET) error; if (file_mode>5) IO_error ("fopen: invalid file mode"); file_name_s=clean_to_c_string (file_name); if (file_name_s==NULL){ IO_error ("fopen: out of memory"); return ERROR_FILE; } fn=number_of_files; if (fn>=MAX_N_FILES){ for (fn=FIRST_REAL_FILE; fn=MAX_N_FILES){ free_memory (file_name_s); IO_error ("fopen: too many files"); } } f=&file_table[fn]; #ifdef WINDOWS file_handle=CreateFileA (file_name_s,file_permission[file_mode],file_permission[file_mode]==GENERIC_READ ? FILE_SHARE_READ : 0,NULL, file_action[file_mode],FILE_ATTRIBUTE_NORMAL,NULL); if (file_handle==INVALID_HANDLE_VALUE){ free_memory (file_name_s); return ERROR_FILE; } #else error=DosOpen (file_name_s,&file_handle,&action,0,FILE_NORMAL, file_action[file_mode],file_permission[file_mode],NULL); if (error!=0){ free_memory (file_name_s); return ERROR_FILE; } #endif buffer=allocate_memory (FILE_IO_BUFFER_SIZE); if (buffer==NULL){ free_memory (file_name_s); OS(CloseHandle,DosClose) (file_handle); IO_error ("fopen: out of memory"); } f->file_buffer_p=buffer; f->file_end_buffer_p=buffer; f->file_read_p=buffer; f->file_write_p=buffer; f->file_offset=0; switch (file_mode){ case F_WRITE_TEXT: case F_WRITE_DATA: file_length=0; break; case F_APPEND_TEXT: case F_APPEND_DATA: #ifdef WINDOWS file_length=SetFilePointer (file_handle,0,NULL,FILE_END); if (file_length==-1){ free_memory (file_name_s); free_memory (buffer); OS(CloseHandle,DosClose) (file_handle); IO_error ("fopen: can't seek to eof"); } #else error=DosSetFilePtr (file_handle,0,FILE_END,&file_length); if (error!=0){ free_memory (file_name_s); free_memory (buffer); OS(CloseHandle,DosClose) (file_handle); IO_error ("fopen: can't seek to eof"); } #endif f->file_offset=file_length; break; default: { #ifdef WINDOWS file_length=GetFileSize (file_handle,NULL); if (file_length==-1){ free_memory (file_name_s); free_memory (buffer); OS(CloseHandle,DosClose) (file_handle); IO_error ("fopen: can't get eof"); } #else FILESTATUS file_status; error=DosQueryFileInfo (file_handle,FIL_STANDARD,&file_status,sizeof (file_status)); if (error!=0){ free_memory (file_name_s); free_memory (buffer); OS(CloseHandle,DosClose) (file_handle); IO_error ("fopen: can't get eof"); } file_length=file_status.cbFile; #endif } } f->file_mode=1<file_unique=1; f->file_error=0; f->file_name=file_name_s; f->file_length=file_length; f->file_position=-2; f->file_position_2=-1; f->file_refnum=file_handle; if (fn>=number_of_files) number_of_files=fn+1; return f; } static int stdio_open=0; struct file *open_stdio (void) { if (stdio_open) IO_error ("stdio: already open"); stdio_open=1; return &file_table[1]; } struct file *open_stderr (void) { return file_table; } static int flush_write_buffer (struct file *f) { if (f->file_mode & ((1<file_buffer_p; if (buffer!=f->file_end_buffer_p){ OS(DWORD,APIRET) error; long count; count=f->file_write_p-buffer; if (count==0) error=0; else { #ifdef WINDOWS error=!WriteFile (f->file_refnum,buffer,count,&count,NULL); #else error=DosWrite (f->file_refnum,buffer,count,&count); #endif f->file_offset += count; } if (f->file_offset > f->file_length) f->file_length=f->file_offset; f->file_end_buffer_p=buffer; f->file_read_p=buffer; if (error!=0 || count!=f->file_write_p-buffer){ f->file_write_p=buffer; f->file_error=-1; return 0; } f->file_write_p=buffer; } } return 1; } CLEAN_BOOL flush_file_buffer (struct file *f) { if (is_special_file (f)) return 1; else return flush_write_buffer (f); } CLEAN_BOOL close_file (struct file *f) { if (is_special_file (f)){ if (f==&file_table[1]){ if (!stdio_open) IO_error ("fclose: file not open (stdio)"); stdio_open=0; } return CLEAN_TRUE; } else { int result; if (f->file_mode==0) IO_error ("fclose: file not open"); result=CLEAN_TRUE; if (f->file_error) result=0; if (! flush_write_buffer (f)) result=0; #ifdef WINDOWS if (!CloseHandle (f->file_refnum)) result=0; #else if (DosClose (f->file_refnum)!=0) result=0; #endif free_memory (f->file_name); free_memory (f->file_buffer_p); f->file_mode=0; return result; } } static OS(DWORD,ULONG) file_action_reopen[] ={ #ifdef WINDOWS OPEN_EXISTING, TRUNCATE_EXISTING, OPEN_EXISTING, OPEN_EXISTING, TRUNCATE_EXISTING, OPEN_EXISTING #else FILE_OPEN, FILE_TRUNCATE, FILE_OPEN, FILE_OPEN, FILE_TRUNCATE, FILE_OPEN #endif }; CLEAN_BOOL re_open_file (struct file *f,unsigned int file_mode) { if (file_mode>5) IO_error ("freopen: invalid file mode"); if (is_special_file (f)){ if (f==file_table && (file_mode==F_READ_TEXT || file_mode==F_READ_DATA)) IO_error ("freopen: stderr can't be opened for reading"); if (f==&file_table[2]) IO_error ("freopen: file not open"); return CLEAN_TRUE; } else { long file_length; int result; unsigned char *buffer; HFILE file_handle; OS(DWORD,APIRET) error; ULONG action; result=CLEAN_TRUE; if (f->file_mode!=0){ flush_write_buffer (f); OS(CloseHandle,DosClose) (f->file_refnum); } else { buffer=allocate_memory (FILE_IO_BUFFER_SIZE); if (buffer==NULL) IO_error ("freopen: out of memory"); f->file_buffer_p=buffer; } f->file_mode=0; #ifdef WINDOWS file_handle=CreateFileA (f->file_name,file_permission[file_mode],file_permission[file_mode]==GENERIC_READ ? FILE_SHARE_READ : 0,NULL, file_action_reopen[file_mode],FILE_ATTRIBUTE_NORMAL,NULL); if (file_handle==INVALID_HANDLE_VALUE){ free_memory (f->file_name); free_memory (f->file_buffer_p); return 0; } #else error=DosOpen (f->file_name,&file_handle,&action,0,FILE_NORMAL, file_action_reopen[file_mode],file_permission[file_mode],NULL); if (error!=0){ free_memory (f->file_name); free_memory (f->file_buffer_p); return 0; } #endif f->file_offset=0; switch (file_mode){ case F_WRITE_TEXT: case F_WRITE_DATA: file_length=0; break; case F_APPEND_TEXT: case F_APPEND_DATA: #ifdef WINDOWS file_length=SetFilePointer (file_handle,0,NULL,FILE_END); if (file_length==-1){ free_memory (f->file_name); free_memory (f->file_buffer_p); OS(CloseHandle,DosClose) (file_handle); IO_error ("freopen: can't seek to eof"); } #else error=DosSetFilePtr (file_handle,0,FILE_END,&file_length); if (error!=0){ free_memory (f->file_name); free_memory (f->file_buffer_p); OS(CloseHandle,DosClose) (file_handle); IO_error ("freopen: can't seek to eof"); } #endif f->file_offset=file_length; break; default: { #ifdef WINDOWS file_length=GetFileSize (file_handle,NULL); if (file_length==-1){ free_memory (f->file_name); free_memory (f->file_buffer_p); OS(CloseHandle,DosClose) (file_handle); IO_error ("freopen: can't get eof"); } #else FILESTATUS file_status; error=DosQueryFileInfo (file_handle,FIL_STANDARD,&file_status,sizeof (file_status)); if (error!=0){ free_memory (f->file_name); free_memory (f->file_buffer_p); OS(CloseHandle,DosClose) (file_handle); IO_error ("freopen: can't get eof"); } file_length=file_status.cbFile; #endif } } f->file_refnum=file_handle; f->file_mode=1<file_length=file_length; f->file_position=-2; f->file_position_2=-1; f->file_error=0; buffer=f->file_buffer_p; f->file_end_buffer_p=buffer; f->file_read_p=buffer; f->file_write_p=buffer; return result; } } static void char_to_new_buffer (int c,struct file *f) { long count; unsigned char *buffer; flush_write_buffer (f); count=FILE_IO_BUFFER_SIZE - (f->file_offset & (FILE_IO_BUFFER_SIZE-1)); buffer=f->file_buffer_p; *buffer=c; f->file_write_p=buffer+1; buffer+=count; f->file_end_buffer_p=buffer; f->file_read_p=buffer; } #if defined (__MWERKS__) || defined (powerc) #define write_char(c,f) if ((f)->file_write_p<(f)->file_end_buffer_p) \ *((f)->file_write_p)++=(c); \ else \ char_to_new_buffer((c),(f)) #else #define write_char(c,f) ((f)->file_write_p<(f)->file_end_buffer_p ? (*((f)->file_write_p)++=(c)) : char_to_new_buffer((c),(f))) #endif static int char_from_new_buffer (struct file *f) { OS(DWORD,APIRET) error; long count; unsigned char *buffer; int c; count=FILE_IO_BUFFER_SIZE - (f->file_offset & (FILE_IO_BUFFER_SIZE-1)); buffer=f->file_buffer_p; #ifdef WINDOWS error=!ReadFile (f->file_refnum,buffer,count,&count,NULL); #else error=DosRead (f->file_refnum,buffer,count,&count); #endif f->file_offset += count; if (error!=0) f->file_error=-1; if (error!=0 || count==0){ f->file_end_buffer_p=buffer; f->file_read_p=buffer; f->file_write_p=buffer; return EOF; } c=*buffer; f->file_read_p=buffer+1; buffer+=count; f->file_end_buffer_p=buffer; f->file_write_p=buffer; return c; } #define read_char(f) ((f)->file_read_p<(f)->file_end_buffer_p ? *((f)->file_read_p)++ : char_from_new_buffer(f)) int file_read_char (struct file *f) { if (f->file_read_p < f->file_end_buffer_p){ unsigned char c; c=*(f->file_read_p)++; if (c=='\r' && f->file_mode & (1<file_read_p > f->file_buffer_p) --f->file_read_p; } return c; } else { if (is_special_file (f)){ if (f==file_table){ IO_error ("freadc: can't read from stderr"); return 0; } else if (f==&file_table[1]) return w_get_char(); else { IO_error ("freadc: can't open this file"); return 0; } } else { int c; if (f->file_mode & ~((1<file_mode & (1<file_read_p > f->file_buffer_p) --f->file_read_p; } return c; } } } #define is_digit(n) ((unsigned)((n)-'0')<(unsigned)10) CLEAN_BOOL file_read_int (struct file *f,int *i_p) { if (is_special_file (f)){ if (f==file_table){ IO_error ("freadi: can't read from stderr"); return 0; } else if (f==&file_table[1]) return w_get_int (i_p); else { IO_error ("freadi: can't open this file"); return 0; } } else { *i_p=0; if (f->file_mode & (1<file_error=-1; return 0; } ((char*)i_p)[0]=i; if ((i=read_char (f))==EOF){ f->file_error=-1; return 0; } ((char*)i_p)[1]=i; if ((i=read_char (f))==EOF){ f->file_error=-1; return 0; } ((char*)i_p)[2]=i; if ((i=read_char (f))==EOF){ f->file_error=-1; return 0; } ((char*)i_p)[3]=i; } else if (f->file_mode & (1<file_error=-1; } else { unsigned int i; i=c-'0'; while (is_digit (c=read_char (f))){ i+=i<<2; i+=i; i+=c-'0'; }; if (negative) i=-i; *i_p=i; } if (f->file_read_p > f->file_buffer_p) --f->file_read_p; return result; } else IO_error ("freadi: read from an output file"); return CLEAN_TRUE; } } extern int convert_string_to_real (char *s,double *r_p); CLEAN_BOOL file_read_real (struct file *f,double *r_p) { if (is_special_file (f)){ if (f==file_table){ IO_error ("freadr: can't read from stderr"); return 0; } else if (f==&file_table[1]) return w_get_real (r_p); else { IO_error ("freadr: can't open this file"); return 0; } } else { *r_p=0.0; if (f->file_mode & (1<file_error=-1; return 0; } ((char*)r_p)[n]=i; } } else if (f->file_mode & (1<=256) result=0; if (f->file_read_p > f->file_buffer_p) --f->file_read_p; *r_p=0.0; if (result){ s[n]='\0'; result= convert_string_to_real (s,r_p)==&s[n]; } if (!result) f->file_error=-1; return result; } else IO_error ("freadr: read from an output file"); return CLEAN_TRUE; } } #define OLD_READ_STRING 0 #define OLD_WRITE_STRING 0 #if OLD_READ_STRING unsigned long file_read_string (struct file *f,unsigned long max_length,struct clean_string *s) { #else unsigned long file_read_characters (struct file *f,unsigned long *length_p,char *s) { unsigned long max_length; max_length=*length_p; #endif if (is_special_file (f)){ if (f==file_table){ IO_error ("freads: can't read from stderr"); return 0; } else if (f==&file_table[1]){ char *string; unsigned long length; length=0; #if OLD_READ_STRING string=s->characters; #else string=s; #endif while (length!=max_length){ *string++=w_get_char(); ++length; } #if OLD_READ_STRING s->length=length; #else *length_p=length; #endif return length; } else { IO_error ("freads: can't open this file"); return 0; } } else { unsigned char *string,*end_string,*begin_string; if (f->file_mode & ~((1<characters; #else string=s; #endif begin_string=string; end_string=string+max_length; if (f->file_mode & (1<file_read_p < f->file_end_buffer_p){ unsigned char *read_p; long n; read_p=f->file_read_p; n=f->file_end_buffer_p-read_p; if (n > end_string-string) n=end_string-string; do { *string++ = *read_p++; } while (--n); f->file_read_p=read_p; } else { if (end_string-string>=FILE_IO_BUFFER_SIZE && f->file_offset & (FILE_IO_BUFFER_SIZE-1)==0){ OS(DWORD,APIRET) error; long count; unsigned char *buffer; count=(end_string-string) & (~(FILE_IO_BUFFER_SIZE-1)); #ifdef WINDOWS error=!ReadFile (f->file_refnum,string,count,&count,NULL); #else error=DosRead (f->file_refnum,string,count,&count); #endif f->file_offset += count; if (error!=0) f->file_error=-1; buffer=f->file_buffer_p; f->file_end_buffer_p=buffer; f->file_read_p=buffer; f->file_write_p=buffer; string+=count; if (error!=0 || count==0) #if OLD_READ_STRING return (s->length=string-begin_string); #else return (*length_p=string-begin_string); #endif } else { int c; c=char_from_new_buffer (f); if (c==EOF) break; *string++=c; } } } } else { while (stringfile_read_p < f->file_end_buffer_p){ unsigned char *read_p; long n; read_p=f->file_read_p; n=f->file_end_buffer_p-read_p; if (n > end_string-string) n=end_string-string; do { char c; c = *read_p++; if (c=='\r'){ if (n>1){ if (*read_p=='\n'){ *string++='\n'; ++read_p; --n; } else *string++ = c; } else { int c2; f->file_read_p=read_p; c2=read_char (f); read_p=f->file_read_p; if (c2=='\n') *string++=c2; else { *string++=c; if (read_p > f->file_buffer_p) --read_p; } break; } } else *string++ = c; } while (--n); f->file_read_p=read_p; } else { int c; c=char_from_new_buffer (f); if (c==EOF) break; if (c=='\r'){ if (read_char (f)=='\n') c='\n'; else if (f->file_read_p > f->file_buffer_p) --f->file_read_p; } *string++=c; } } } #if OLD_READ_STRING return (s->length=string-begin_string); #else return (*length_p=string-begin_string); #endif } } unsigned long file_read_line (struct file *f,unsigned long max_length,char *string) { if (is_special_file (f)){ if (f==file_table){ IO_error ("freadline: can't read from stderr"); return 0; } else if (f==&file_table[1]){ unsigned long length; length=0; while (length!=max_length){ int c; c=w_get_char(); *string++=c; ++length; if (c=='\n') return length; } return -1; } else { IO_error ("freadline: can't open this file"); return 0; } } else { unsigned char *end_string,*begin_string; int c; begin_string=string; end_string=string+max_length; c=0; if (f->file_mode & (1<file_read_p < f->file_end_buffer_p){ unsigned char *read_p; long n; read_p=f->file_read_p; n=f->file_end_buffer_p-read_p; if (n > end_string-(unsigned char*)string) n=end_string-(unsigned char*)string; do { char ch; ch=*read_p++; if (ch=='\r'){ if (n>1 || read_p < f->file_end_buffer_p){ if (*read_p=='\n'){ f->file_read_p=++read_p; *string++='\n'; return (unsigned char*)string-begin_string; } else { *string++=ch; } } else { int c; f->file_read_p=read_p; c=char_from_new_buffer(f); read_p=f->file_read_p; if (c=='\n'){ *string++=c; return (unsigned char*)string-begin_string; } else { *string++=ch; if (f->file_read_p > f->file_buffer_p) --read_p; } } } else { *string++=ch; if (ch=='\n'){ f->file_read_p=read_p; return (unsigned char*)string-begin_string; } } } while (--n); c=0; f->file_read_p=read_p; } else { c=char_from_new_buffer(f); if (c==EOF) break; if (c=='\r'){ if (read_char (f)=='\n') c='\n'; else if (f->file_read_p > f->file_buffer_p) --f->file_read_p; } *string++=c; if (c=='\n') return (unsigned char*)string-begin_string; } } } else if (f->file_mode & (1<file_read_p < f->file_end_buffer_p){ unsigned char *read_p; long n; read_p=f->file_read_p; n=f->file_end_buffer_p-read_p; if (n > end_string-(unsigned char*)string) n=end_string-(unsigned char*)string; do { char ch; ch=*read_p++; *string++=ch; if (ch=='\xd'){ if (n>1){ if (*read_p=='\xa'){ *string++='\xa'; ++read_p; } f->file_read_p=read_p; return (unsigned char*)string-begin_string; } else if (read_p < f->file_end_buffer_p){ f->file_read_p=read_p; if (*read_p!='\xa'){ return (unsigned char*)string-begin_string; } else { return -1; /* return \xd, read \xa next time */ } } else { int c; f->file_read_p=read_p; c=char_from_new_buffer(f); read_p=f->file_read_p; if (c!='\xa'){ if (read_p > f->file_buffer_p) --read_p; f->file_read_p=read_p; return (unsigned char*)string-begin_string; } else { if (stringfile_read_p=read_p; return (unsigned char*)string-begin_string; } else { if (read_p > f->file_buffer_p) --read_p; f->file_read_p=read_p; return -1; /* return \xd, read \xa next time */ } } } } else if (ch=='\xa'){ f->file_read_p=read_p; return (unsigned char*)string-begin_string; } } while (--n); c=0; f->file_read_p=read_p; } else { c=char_from_new_buffer(f); if (c==EOF) break; *string++=c; if (c=='\xd'){ c = read_char (f); if (stringfile_read_p > f->file_buffer_p) --f->file_read_p; } else { if (f->file_read_p > f->file_buffer_p) --f->file_read_p; if (c=='\xa') return -1; } return (unsigned char*)string-begin_string; } else if (c=='\xa') return (unsigned char*)string-begin_string; } } } else IO_error ("freadline: read from an output file"); if (c!=EOF) return -1; return (unsigned char*)string-begin_string; } } void file_write_char (int c,struct file *f) { if (f->file_write_p < f->file_end_buffer_p){ if (c=='\n' && f->file_mode & ((1<file_write_p)++='\r'; if (f->file_write_p < f->file_end_buffer_p) *(f->file_write_p)++=c; else char_to_new_buffer (c,f); } else { *(f->file_write_p)++=c; } } else { if (is_special_file (f)){ if (f==file_table) ew_print_char (c); else if (f==&file_table[1]) w_print_char (c); else IO_error ("fwritec: can't open this file"); } else { if (f->file_mode & ~((1<file_mode & ((1<file_mode & ~((1<file_mode & ((1<file_mode & ~((1<file_mode & ((1<characters,s->length); #else ew_print_text (p,length); #endif else if (f==&file_table[1]) #if OLD_WRITE_STRING w_print_text (s->characters,s->length); #else w_print_text (p,length); #endif else IO_error ("fwrites: can't open this file"); } else { #if OLD_WRITE_STRING unsigned char *p,*end_p; #else unsigned char *end_p; #endif if (f->file_mode & ~((1<characters; end_p=p+s->length; #else end_p=p+length; #endif if (f->file_mode & ((1<file_write_p < f->file_end_buffer_p){ unsigned char *write_p; long n; write_p=f->file_write_p; n=f->file_end_buffer_p-write_p; if (n>end_p-p) n=end_p-p; do { *write_p++ = *p++; } while (--n); f->file_write_p=write_p; } else char_to_new_buffer (*p++,f); } } else { while (pfile_write_p < f->file_end_buffer_p){ unsigned char *write_p; long n; write_p=f->file_write_p; n=f->file_end_buffer_p-write_p; if (n>end_p-p) n=end_p-p; do { char c; c = *p++; if (c=='\n'){ *write_p++ = '\r'; if (--n){ *write_p++ = c; } else { f->file_write_p=write_p; write_char (c,f); write_p=f->file_write_p; break; } } else *write_p++ = c; } while (--n); f->file_write_p=write_p; } else { char c; c=*p++; if (c=='\n'){ char_to_new_buffer ('\r',f); write_char (c,f); } else char_to_new_buffer (c,f); } } } } } CLEAN_BOOL file_end (struct file *f) { if (f->file_read_p < f->file_end_buffer_p) return 0; if (is_special_file (f)){ if (f==file_table || f==&file_table[1]) IO_error ("fend: not allowed for stdio and stderr"); else IO_error ("fend: can't open file"); return 0; } else { if (f->file_mode & ~((1<file_offset < f->file_length) return 0; return CLEAN_TRUE; } } CLEAN_BOOL file_error (struct file *f) { if (is_special_file (f)){ if (f==file_table || f==&file_table[1]) return 0; else return CLEAN_TRUE; } else if (f->file_error) return CLEAN_TRUE; else return 0; } unsigned long file_position (struct file *f) { if (is_special_file (f)){ if (f==file_table || f==&file_table[1]) IO_error ("fposition: not allowed for stdio and stderr"); else IO_error ("fposition: can't open file"); return 0; } else { unsigned long position; if (f->file_mode & ((1<file_offset - (f->file_end_buffer_p - f->file_read_p); else position=f->file_offset + (f->file_write_p - f->file_buffer_p); return position; } } CLEAN_BOOL file_seek (struct file *f,unsigned long position,unsigned long seek_mode) { if (is_special_file (f)){ if (seek_mode>(unsigned)2) IO_error ("fseek: invalid mode"); if (f==file_table || f==&file_table[1]) IO_error ("fseek: can't seek on stdio and stderr"); else IO_error ("fseek: can't open file"); return 0; } else { long current_position; unsigned long buffer_size; if (f->file_mode & ((1<file_offset - (f->file_end_buffer_p - f->file_read_p); switch (seek_mode){ case F_SEEK_SET: break; case F_SEEK_CUR: position+=current_position; break; case F_SEEK_END: position=f->file_length-position; break; default: IO_error ("fseek: invalid mode"); } buffer_size=f->file_end_buffer_p - f->file_buffer_p; if ((unsigned long)(position - (f->file_offset-buffer_size)) < buffer_size){ f->file_read_p = f->file_buffer_p + (position - (f->file_offset-buffer_size)); return CLEAN_TRUE; } else { unsigned char *buffer; OS(DWORD file_position,APIRET error); if (position<0 || position>f->file_length){ f->file_error=-1; return 0; } buffer=f->file_buffer_p; f->file_end_buffer_p=buffer; f->file_read_p=buffer; f->file_write_p=buffer; #ifdef WINDOWS file_position=SetFilePointer (f->file_refnum,position,NULL,FILE_BEGIN); if (file_position==-1){ f->file_error=-1; return 0; } f->file_offset=file_position; #else error=DosSetFilePtr (f->file_refnum,position,FILE_BEGIN,&f->file_offset); if (error!=0){ f->file_error=-1; return 0; } #endif return CLEAN_TRUE; } } else { OS(DWORD file_position,APIRET error); int result; result=CLEAN_TRUE; current_position=f->file_offset + (f->file_write_p - f->file_buffer_p); if (current_position > f->file_length) f->file_length=current_position; switch (seek_mode){ case F_SEEK_SET: break; case F_SEEK_CUR: position+=current_position; break; case F_SEEK_END: position=f->file_length-position; break; default: IO_error ("fseek: invalid mode"); } if (position==current_position) return CLEAN_TRUE; if (! flush_write_buffer (f)){ f->file_error=-1; result=0; } if (position<0 || position>f->file_length){ f->file_error=-1; return 0; } #ifdef WINDOWS file_position=SetFilePointer (f->file_refnum,position,NULL,FILE_BEGIN); if (file_position==-1){ f->file_error=-1; result=0; } else f->file_offset=file_position; #else error=DosSetFilePtr (f->file_refnum,position,FILE_BEGIN,&f->file_offset); if (error!=0){ f->file_error=-1; result=0; } #endif return result; } } } /* added 13-1-1999 */ static int equal_string (char *s1,char*s2) { char c; do { c=*s1++; if (c=='\0') return *s2==c; } while (*s2++ == c); return 0; } /* */ struct file *open_s_file (struct clean_string *file_name,unsigned int file_mode) { int fn; char *file_name_s; struct file *f; long file_length; HFILE file_handle; unsigned char *buffer; ULONG action; OS(DWORD,APIRET) error; if (file_mode!=F_READ_TEXT && file_mode!=F_READ_DATA) IO_error ("sfopen: invalid file mode"); file_name_s=clean_to_c_string (file_name); if (file_name_s==NULL){ IO_error ("sfopen: out of memory"); return ERROR_FILE; } fn=number_of_files; if (fn>=MAX_N_FILES){ for (fn=FIRST_REAL_FILE; fn=MAX_N_FILES) IO_error ("sfopen: too many files"); } f=&file_table[fn]; #ifdef WINDOWS file_handle=CreateFileA (file_name_s,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (file_handle==INVALID_HANDLE_VALUE){ /* added 13-1-1999 */ if (GetLastError()==ERROR_SHARING_VIOLATION){ for (fn=FIRST_REAL_FILE; fnfile_mode!=0 && equal_string (file_name_s,f->file_name) && f->file_mode==1<file_buffer_p=buffer; f->file_end_buffer_p=buffer; f->file_read_p=buffer; f->file_write_p=buffer; f->file_offset=0; #ifdef WINDOWS file_length=GetFileSize (file_handle,NULL); if (file_length==-1){ #else { FILESTATUS file_status; error=DosQueryFileInfo (file_handle,FIL_STANDARD,&file_status,sizeof (file_status)); file_length=file_status.cbFile; } if (error!=0){ #endif free_memory (file_name_s); free_memory (buffer); OS(CloseHandle,DosClose) (file_handle); IO_error ("sfopen: can't get eof"); } f->file_refnum=file_handle; f->file_mode=1<file_unique=0; f->file_error=0; f->file_name=file_name_s; f->file_length=file_length; f->file_position=-2; f->file_position_2=-1; if (fn>=number_of_files) number_of_files=fn+1; return f; } void file_share (struct file *f) { f->file_unique=0; } static int simple_seek (struct file *f,long position) { int result; long buffer_size; result=1; buffer_size=f->file_end_buffer_p - f->file_buffer_p; if ((unsigned long)(position - (f->file_offset-buffer_size)) < buffer_size){ f->file_read_p = f->file_buffer_p + (position - (f->file_offset-buffer_size)); f->file_position=position; } else { unsigned char *buffer; OS(DWORD file_position,APIRET error); if (position<0 || position>f->file_length){ f->file_error=-1; result=0; } else { buffer=f->file_buffer_p; f->file_end_buffer_p=buffer; f->file_read_p=buffer; f->file_write_p=buffer; #ifdef WINDOWS file_position=SetFilePointer (f->file_refnum,position,NULL,FILE_BEGIN); if (file_position==-1){ f->file_error=-1; result=0; } else f->file_offset=file_position; #else error=DosSetFilePtr (f->file_refnum,position,FILE_BEGIN,&f->file_offset); if (error!=0){ f->file_error=-1; result=0; } f->file_position=position; #endif } } return result; } int file_read_s_char (struct file *f,unsigned long *position_p) { if (is_special_file (f)){ if (f==file_table) IO_error ("sfreadc: can't read from stderr"); else if (f==&file_table[1]) IO_error ("sfreadc: can't read from stdio, use freadc"); else IO_error ("sfreadc: can't open this file"); return 0; } else { int c; unsigned long position; position=*position_p; if (f->file_position!=position){ if (f->file_unique) IO_error ("sfreadc: can't read from a unique file"); switch (position){ case -1l: if (position!=f->file_position_2) position=f->file_position_2; else { position=f->file_offset + (f->file_write_p - f->file_buffer_p); f->file_position_2=position; break; } default: if (!simple_seek (f,position)) IO_error ("sfreadc: seek failed"); } } if (f->file_read_p < f->file_end_buffer_p){ c=*f->file_read_p++; ++position; } else { c=char_from_new_buffer(f); if (c!=EOF) ++position; } if (c=='\r' && f->file_mode & (1<file_read_p > f->file_buffer_p) --f->file_read_p; } f->file_position=position; *position_p=position; return c; } } CLEAN_BOOL file_read_s_int (struct file *f,int *i_p,unsigned long *position_p) { if (is_special_file (f)){ if (f==file_table) IO_error ("sfreadi: can't read from stderr"); else if (f==&file_table[1]) IO_error ("sfreadi: can't read from stdio, use freadi"); else IO_error ("sfreadi: can't open this file"); return 0; } else { int result; unsigned long position; position=*position_p; if (f->file_position!=position){ if (f->file_unique) IO_error ("sfreadi: can't read from a unique file"); switch (position){ case -1l: if (position!=f->file_position_2) position=f->file_position_2; else { position=position=f->file_offset + (f->file_write_p - f->file_buffer_p); f->file_position_2=position; break; } default: if (!simple_seek (f,position)) IO_error ("sfreadi: seek failed"); } } *i_p=0; result=CLEAN_TRUE; if (f->file_mode & (1<file_error=-1; result=0; } else { ((char*)i_p)[0]=i; if ((i=read_char (f))==EOF){ ++position; f->file_error=-1; result=0; } else { ((char*)i_p)[1]=i; if ((i=read_char (f))==EOF){ position+=2; f->file_error=-1; result=0; } else { ((char*)i_p)[2]=i; if ((i=read_char (f))==EOF){ position+=3; f->file_error=-1; result=0; } else { ((char*)i_p)[3]=i; position+=4; } } } } } else if (f->file_mode & (1<file_error=-1; result=0; } else { unsigned int i; i=c-'0'; ++n_characters; while (is_digit (c=read_char (f))){ i+=i<<2; i+=i; i+=c-'0'; ++n_characters; }; if (negative) i=-i; *i_p=i; } position+=n_characters; if (f->file_read_p > f->file_buffer_p) --f->file_read_p; } f->file_position=position; *position_p=position; return result; } } CLEAN_BOOL file_read_s_real (struct file *f,double *r_p,unsigned long *position_p) { if (is_special_file (f)){ if (f==file_table) IO_error ("sfreadr: can't read from stderr"); else if (f==&file_table[1]) IO_error ("sfreadr: can't read from stdio, use freadr"); else IO_error ("sfreadr: can't open this file"); return 0; } else { int result; unsigned long position; position=*position_p; if (f->file_position!=position){ if (f->file_unique) IO_error ("sfreadr: can't read from a unique file"); switch (position){ case -1l: if (position!=f->file_position_2) position=f->file_position_2; else { position=position=f->file_offset + (f->file_write_p - f->file_buffer_p); f->file_position_2=position; break; } default: if (!simple_seek (f,position)) IO_error ("sfreadr: seek failed"); } } *r_p=0.0; if (f->file_mode & (1<file_error=-1; result=0; break; } ((char*)r_p)[n]=i; } position+=n; } else if (f->file_mode & (1<=256) result=0; position+=n_characters; if (f->file_read_p > f->file_buffer_p) --f->file_read_p; *r_p=0.0; if (result){ s[n]='\0'; result= convert_string_to_real (s,r_p)==&s[n]; } if (!result) f->file_error=-1; } else result=0; f->file_position=position; *position_p=position; return result; } } unsigned long file_read_s_string (struct file *f,unsigned long max_length,struct clean_string *s,unsigned long *position_p) { unsigned long length; if (is_special_file (f)){ if (f==file_table) IO_error ("sfreads: can't read from stderr"); else if (f==&file_table[1]) IO_error ("sfreads: can't read from stdio, use freads"); else IO_error ("sfreads: can't open this file"); return 0; } else { unsigned long position; char *string; int c; position=*position_p; if (f->file_position!=position){ if (f->file_unique) IO_error ("sfreads: can't read from a unique file"); switch (position){ case -1l: if (position!=f->file_position_2) position=f->file_position_2; else { position=f->file_offset + (f->file_write_p - f->file_buffer_p); f->file_position_2=position; break; } default: if (!simple_seek (f,position)) IO_error ("sfreads: seek failed"); } } length=0; string=s->characters; if (f->file_mode & (1<file_read_p > f->file_buffer_p) --f->file_read_p; } *string++=c; ++length; ++position; } } s->length=length; f->file_position=position; *position_p=position; return length; } } unsigned long file_read_s_line (struct file *f,unsigned long max_length,char *string,unsigned long *position_p) { unsigned long length; if (is_special_file (f)){ if (f==file_table) IO_error ("sfreadline: can't read from stderr"); else if (f==&file_table[1]) IO_error ("sfreadline: can't read from stdio, use freadline"); else IO_error ("sfreadline: can't open this file"); return 0; } else { unsigned long position; int c; position=*position_p; if (f->file_position!=position){ if (f->file_unique) IO_error ("sfreadline: can't read from a unique file"); if (f->file_mode & ~(1<file_position_2) position=f->file_position_2; else { position=f->file_offset + (f->file_write_p - f->file_buffer_p); f->file_position_2=position; break; } default: if (!simple_seek (f,position)) IO_error ("sfreadline: seek failed"); } } length=0; c=0; while (length!=max_length && ((c=read_char (f))!=EOF)){ if (c=='\r'){ if (read_char (f)=='\n'){ ++position; c='\n'; } else if (f->file_read_p > f->file_buffer_p) --f->file_read_p; } *string++=c; ++length; ++position; if (c=='\n') break; } f->file_position=position; *position_p=position; if (c!='\n' && c!=EOF) return -1; return length; } } CLEAN_BOOL file_s_end (struct file *f,unsigned long position) { if (is_special_file (f)){ if (f==file_table || f==&file_table[1]) IO_error ("sfend: not allowed for stdio and stderr"); else IO_error ("sfend: can't open file"); return 0; } else { if (f->file_unique){ if (f->file_mode & ~((1<file_read_p < f->file_end_buffer_p) return 0; if (f->file_offset < f->file_length) return 0; return CLEAN_TRUE; } else { if (position==-1l){ if (f->file_position_2!=-1l) position=f->file_position_2; else { position=f->file_offset + (f->file_end_buffer_p - f->file_read_p); f->file_position=position; f->file_position_2=position; } } return (position==f->file_length) ? CLEAN_TRUE : 0; } } } unsigned long file_s_position (struct file *f,unsigned long position) { if (is_special_file (f)){ if (f==file_table || f==&file_table[1]) IO_error ("sfposition: not allowed for stdio and stderr"); else IO_error ("sfposition: can't open file"); return 0; } else { if (f->file_unique){ if (f->file_mode & ((1<file_offset - (f->file_end_buffer_p - f->file_read_p); else position=f->file_offset + (f->file_write_p - f->file_buffer_p); return position; } else { if (position==-1l){ if (f->file_position_2!=-1l) return f->file_position_2; else { position=f->file_offset - (f->file_end_buffer_p - f->file_read_p); f->file_position=position; f->file_position_2=position; } } return position; } } } #define F_SEEK_SET 0 #define F_SEEK_CUR 1 #define F_SEEK_END 2 CLEAN_BOOL file_s_seek (struct file *f,unsigned long position,unsigned long seek_mode,unsigned long *position_p) { if (is_special_file (f)){ if (seek_mode>(unsigned)2) IO_error ("sfseek: invalid mode"); if (f==file_table) IO_error ("sfseek: can't seek on stdio"); else if (f==&file_table[1]) IO_error ("sfseek: can't seek on stderr"); else IO_error ("sfseek: can't open file"); return 0; } else { long current_position,buffer_size; int result; result=CLEAN_TRUE; if (f->file_unique) IO_error ("sfseek: can't seek on a unique file"); current_position=f->file_offset - (f->file_end_buffer_p - f->file_read_p); if (*position_p==-1l){ if (f->file_position_2!=-1l) *position_p=f->file_position_2; else { f->file_position_2=current_position; *position_p=current_position; } } switch (seek_mode){ case F_SEEK_SET: break; case F_SEEK_CUR: position+=*position_p; break; case F_SEEK_END: position=f->file_length+position; break; default: IO_error ("sfseek: invalid mode"); } buffer_size=f->file_end_buffer_p - f->file_buffer_p; if ((unsigned long)(position - (f->file_offset-buffer_size)) < buffer_size){ f->file_read_p = f->file_buffer_p + (position - (f->file_offset-buffer_size)); f->file_position=position; } else { unsigned char *buffer; OS(DWORD file_position,APIRET error); if (position<0 || position>f->file_length){ f->file_error=-1; result=0; f->file_position=current_position; } else { buffer=f->file_buffer_p; f->file_end_buffer_p=buffer; f->file_read_p=buffer; f->file_write_p=buffer; #ifdef WINDOWS file_position=SetFilePointer (f->file_refnum,position,NULL,FILE_BEGIN); if (file_position==-1){ f->file_error=-1; result=0; } else f->file_offset=file_position; #else error=DosSetFilePtr (f->file_refnum,position,FILE_BEGIN,&f->file_offset); if (error!=0){ f->file_error=-1; result=0; } #endif f->file_position=position; } } *position_p=position; return result; } }