basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : file_port.cpp 00004 * DESCRIPTION: Ports from file descriptors 00005 * COPYRIGHT : (C) 2010 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00013 #include <basix/posix_port.hpp> 00014 #include <basix/system.hpp> 00015 00017 00018 namespace mmx { 00019 00020 /****************************************************************************** 00021 * File ports 00022 ******************************************************************************/ 00023 00024 class file_port_rep: public posix_port_rep { 00025 FILE* f; 00026 bool cf; 00027 string name; 00028 int next; 00029 00030 public: 00031 syntactic expression () const { 00032 if (this->kind == 1) return syn ("output_file_port", syntactic (name)); 00033 if (this->kind == 2) return syn ("input_file_port", syntactic (name)); 00034 return syn ("input_output_file_port", syntactic (name)); 00035 } 00036 00037 bool busy () { 00038 if (this->kind == 2) return can_read () > 0; 00039 return true; 00040 } 00041 nat can_write () { 00042 if (this->kind == 2) return 0; 00043 return (nat) (-1); 00044 } 00045 nat can_read () { 00046 if (next != -1) return 1; 00047 if (this->kind == 1 || feof (f) != 0) return 0; 00048 next= fgetc (f); 00049 if (next != -1) return 1; 00050 return 0; 00051 } 00052 00053 void write (const char* s, nat n) { 00054 for (nat i=0; i<n; i++) fputc (s[i], f); } 00055 void read (char* s, nat n) { 00056 if (next != -1 && n > 0) { s[0]= next; s++; n--; next= -1; } 00057 for (nat i=0; i<n; i++) s[i]= fgetc (f); } 00058 00059 void flush () { fflush (f); } 00060 00061 public: 00062 inline file_port_rep (int kind, FILE* f2, bool cf2, const string& name2): 00063 posix_port_rep (kind, fileno (f2)), 00064 f (f2), cf (cf2), name (name2), next (-1) {} 00065 inline ~file_port_rep () { 00066 if (cf) fclose (f); } 00067 }; 00068 00069 port 00070 output_file_port (FILE* f, bool close_flag, const string& name) { 00071 return (port_rep*) new file_port_rep (1, f, close_flag, name); 00072 } 00073 00074 port 00075 input_file_port (FILE* f, bool close_flag, const string& name) { 00076 return (port_rep*) new file_port_rep (2, f, close_flag, name); 00077 } 00078 00079 port 00080 input_output_file_port (FILE* f, bool close_flag, const string& name) { 00081 return (port_rep*) new file_port_rep (3, f, close_flag, name); 00082 } 00083 00084 /****************************************************************************** 00085 * Standard constructors 00086 ******************************************************************************/ 00087 00088 table<int,int> out_count (0); 00089 table<int,int> in_count (0); 00090 00091 port mmin = input_file_port (stdin , false, "mmin"); 00092 port mmout= formatting_port (output_file_port (stdout, false, "mmout")); 00093 port mmerr= formatting_port (output_file_port (stderr, false, "mmerr")); 00094 00095 port 00096 output_file_port (const string& name) { 00097 string name_s= decode_name (name); 00098 char* temp= as_charp (name_s); 00099 FILE* f= fopen (temp, "w"); 00100 free_charp (temp); 00101 if (f == NULL) return error_port ("file '" * name * "' not writable"); 00102 return output_file_port (f, true, name); 00103 } 00104 00105 port 00106 input_file_port (const string& name) { 00107 string name_s= decode_name (name); 00108 char* temp= as_charp (name_s); 00109 FILE* f= fopen (temp, "r"); 00110 free_charp (temp); 00111 if (f == NULL) return error_port ("file '" * name * "' not found"); 00112 return input_file_port (f, true, name); 00113 } 00114 00115 port 00116 input_output_file_port (const string& name) { 00117 string name_s= decode_name (name); 00118 char* temp= as_charp (name_s); 00119 FILE* f= fopen (temp, "w+"); 00120 free_charp (temp); 00121 if (f == NULL) return error_port ("file '" * name * "' did not open"); 00122 return input_output_file_port (f, true, name); 00123 } 00124 00125 } // namespace mmx