00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include <climits>
00029 #include <cstdlib>
00030 #include <cstdio>
00031
00032 #include <string>
00033
00034 #ifdef HAVE_UNISTD_H
00035 #ifdef HAVE_SYS_TYPES_H
00036 #include <sys/types.h>
00037 #endif
00038 #include <unistd.h>
00039 #endif
00040
00041 #include "lo-error.h"
00042 #include "lo-ieee.h"
00043 #include "lo-mappers.h"
00044 #include "lo-utils.h"
00045
00046
00047
00048
00049 int
00050 NINT (double x)
00051 {
00052 if (x > INT_MAX)
00053 return INT_MAX;
00054 else if (x < INT_MIN)
00055 return INT_MIN;
00056 else
00057 return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5));
00058 }
00059
00060 double
00061 D_NINT (double x)
00062 {
00063 if (xisinf (x) || xisnan (x))
00064 return x;
00065 else
00066 return floor (x + 0.5);
00067 }
00068
00069
00070
00071 char *
00072 strsave (const char *s)
00073 {
00074 if (! s)
00075 return 0;
00076
00077 int len = strlen (s);
00078 char *tmp = new char [len+1];
00079 tmp = strcpy (tmp, s);
00080 return tmp;
00081 }
00082
00083
00084
00085
00086
00087
00088
00089 void
00090 octave_putenv (const std::string& name, const std::string& value)
00091 {
00092 int new_len = name.length () + value.length () + 2;
00093
00094 char *new_item = static_cast<char*> (malloc (new_len));
00095
00096 sprintf (new_item, "%s=%s", name.c_str (), value.c_str ());
00097
00098
00099
00100
00101 if (putenv (new_item) < 0)
00102 (*current_liboctave_error_handler) ("putenv (%s) failed", new_item);
00103 }
00104
00105 std::string
00106 octave_fgets (FILE *f)
00107 {
00108 bool eof;
00109 return octave_fgets (f, eof);
00110 }
00111
00112 std::string
00113 octave_fgets (FILE *f, bool& eof)
00114 {
00115 eof = false;
00116
00117 std::string retval;
00118
00119 int grow_size = 1024;
00120 int max_size = grow_size;
00121
00122 char *buf = static_cast<char *> (malloc (max_size));
00123 char *bufptr = buf;
00124 int len = 0;
00125
00126 do
00127 {
00128 if (fgets (bufptr, grow_size, f))
00129 {
00130 len = strlen (bufptr);
00131
00132 if (len == grow_size - 1)
00133 {
00134 int tmp = bufptr - buf + grow_size - 1;
00135 grow_size *= 2;
00136 max_size += grow_size;
00137 buf = static_cast<char *> (realloc (buf, max_size));
00138 bufptr = buf + tmp;
00139
00140 if (*(bufptr-1) == '\n')
00141 {
00142 *bufptr = '\0';
00143 retval = buf;
00144 }
00145 }
00146 else if (bufptr[len-1] != '\n')
00147 {
00148 bufptr[len++] = '\n';
00149 bufptr[len] = '\0';
00150 retval = buf;
00151 }
00152 else
00153 retval = buf;
00154 }
00155 else
00156 {
00157 if (len == 0)
00158 {
00159 eof = true;
00160
00161 free (buf);
00162
00163 buf = 0;
00164 }
00165
00166 break;
00167 }
00168 }
00169 while (retval.empty ());
00170
00171 if (buf)
00172 free (buf);
00173
00174 return retval;
00175 }
00176
00177 std::string
00178 octave_fgetl (FILE *f)
00179 {
00180 bool eof;
00181 return octave_fgetl (f, eof);
00182 }
00183
00184 std::string
00185 octave_fgetl (FILE *f, bool& eof)
00186 {
00187 std::string retval = octave_fgets (f, eof);
00188
00189 size_t len = retval.length ();
00190
00191 if (retval[len-1] == '\n')
00192 retval.resize (len-1);
00193
00194 return retval;
00195 }
00196
00197 static inline double
00198 read_inf_nan_na (std::istream& is, char c)
00199 {
00200 double d = 0.0;
00201
00202 switch (c)
00203 {
00204 case 'i': case 'I':
00205 {
00206 is >> c;
00207 if (c == 'n' || c == 'N')
00208 {
00209 is >> c;
00210 if (c == 'f' || c == 'F')
00211 d = octave_Inf;
00212 else
00213 is.putback (c);
00214 }
00215 else
00216 is.putback (c);
00217 }
00218 break;
00219
00220 case 'n': case 'N':
00221 {
00222 is >> c;
00223 if (c == 'a' || c == 'A')
00224 {
00225 is >> c;
00226 if (c == 'n' || c == 'N')
00227 d = octave_NaN;
00228 else
00229 {
00230 is.putback (c);
00231 d = octave_NA;
00232 }
00233 }
00234 else
00235 is.putback (c);
00236 }
00237 break;
00238
00239 default:
00240 abort ();
00241 }
00242
00243 return d;
00244 }
00245
00246 double
00247 octave_read_double (std::istream& is)
00248 {
00249 double d = 0.0;
00250
00251 char c = 0;
00252
00253 is >> c;
00254 switch (c)
00255 {
00256 case 'i': case 'I':
00257 case 'n': case 'N':
00258 d = read_inf_nan_na (is, c);
00259 break;
00260
00261 default:
00262 is.putback (c);
00263 is >> d;
00264 }
00265
00266 return d;
00267 }
00268
00269 Complex
00270 octave_read_complex (std::istream& is)
00271 {
00272 double re = 0.0, im = 0.0;
00273
00274 Complex cx = 0.0;
00275
00276 char ch = 0;
00277
00278 is >> ch;
00279
00280 if (ch == '(')
00281 {
00282 re = octave_read_double (is);
00283 is >> ch;
00284
00285 if (ch == ',')
00286 {
00287 im = octave_read_double (is);
00288 is >> ch;
00289
00290 if (ch == ')')
00291 cx = Complex (re, im);
00292 else
00293 is.setstate (std::ios::failbit);
00294 }
00295 else if (ch == ')')
00296 cx = re;
00297 else
00298 is.setstate (std::ios::failbit);
00299 }
00300 else
00301 {
00302 is.putback (ch);
00303 cx = octave_read_double (is);
00304 }
00305
00306 return cx;
00307
00308 }
00309
00310 void
00311 octave_write_double (std::ostream& os, double d)
00312 {
00313 if (lo_ieee_is_NA (d))
00314 os << "NA";
00315 else if (lo_ieee_isnan (d))
00316 os << "NaN";
00317 else if (lo_ieee_isinf (d))
00318 os << (d < 0 ? "-Inf" : "Inf");
00319 else
00320 os << d;
00321 }
00322
00323 void
00324 octave_write_complex (std::ostream& os, const Complex& c)
00325 {
00326 os << "(";
00327 octave_write_double (os, real (c));
00328 os << ",";
00329 octave_write_double (os, imag (c));
00330 os << ")";
00331 }
00332
00333
00334
00335
00336
00337