Back to index

texmacs  1.0.7.15
string.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : string.cpp
00004 * DESCRIPTION: Fixed size strings with reference counting.
00005 *              Zero characters can be part of string.
00006 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00007 *******************************************************************************
00008 * This software falls under the GNU general public license version 3 or later.
00009 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00010 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00011 ******************************************************************************/
00012 
00013 #include "string.hpp"
00014 #include <stdio.h>
00015 #include <string.h>
00016 #include <stdlib.h>
00017 
00018 /******************************************************************************
00019 * Low level routines and constructors
00020 ******************************************************************************/
00021 
00022 static inline int
00023 round_length (int n) {
00024   n=(n+3)&(0xfffffffc);
00025   if (n<24) return n;
00026   register int i=32;
00027   while (n>i) i<<=1;
00028   return i;
00029 }
00030 
00031 string_rep::string_rep (int n2):
00032   n(n2), a ((n==0)?((char*) NULL):tm_new_array<char> (round_length(n))) {}
00033 
00034 void
00035 string_rep::resize (register int m) {
00036   register int nn= round_length (n);
00037   register int mm= round_length (m);
00038   if (mm != nn) {
00039     if (mm != 0) {
00040       register int i, k= (m<n? m: n);
00041       char* b= tm_new_array<char> (mm);
00042       for (i=0; i<k; i++) b[i]= a[i];
00043       if (nn != 0) tm_delete_array (a);
00044       a= b;
00045     }
00046     else if (nn != 0) tm_delete_array (a);
00047   }
00048   n= m;
00049 }
00050 
00051 string::string (char c) {
00052   rep= tm_new<string_rep> (1);
00053   rep->a[0]=c;
00054 }
00055 
00056 string::string (const char* a) {
00057   int i, n=strlen(a);
00058   rep= tm_new<string_rep> (n);
00059   for (i=0; i<n; i++)
00060     rep->a[i]=a[i];
00061 }
00062 
00063 string::string (const char* a, int n) {
00064   register int i;
00065   rep= tm_new<string_rep> (n);
00066   for (i=0; i<n; i++)
00067     rep->a[i]=a[i];
00068 }
00069 
00070 /******************************************************************************
00071 * Common routines for strings
00072 ******************************************************************************/
00073 
00074 bool
00075 string::operator == (const char* s) {
00076   register int i, n= rep->n;
00077   register char* S= rep->a;
00078   for (i=0; i<n; i++) {
00079     if (s[i]!=S[i]) return false;
00080     if (s[i]=='\0') return false;
00081   }
00082   return (s[i]=='\0');
00083 }
00084 
00085 bool
00086 string::operator != (const char* s) {
00087   register int i, n= rep->n;
00088   register char* S= rep->a;
00089   for (i=0; i<n; i++) {
00090     if (s[i]!=S[i]) return true;
00091     if (s[i]=='\0') return true;
00092   }
00093   return (s[i]!='\0');
00094 }
00095 
00096 bool
00097 string::operator == (string a) {
00098   register int i;
00099   if (rep->n!=a->n) return false;
00100   for (i=0; i<rep->n; i++)
00101     if (rep->a[i]!=a->a[i]) return false;
00102   return true;
00103 }
00104 
00105 bool
00106 string::operator != (string a) {
00107   register int i;
00108   if (rep->n!=a->n) return true;
00109   for (i=0; i<rep->n; i++)
00110     if (rep->a[i]!=a->a[i]) return true;
00111   return false;
00112 }
00113 
00114 string
00115 string::operator () (int begin, int end) {
00116   register int i;
00117   string r (end-begin);
00118   for (i=begin; i<end; i++) r[i-begin]=rep->a[i];
00119   return r;
00120 }
00121 
00122 string
00123 copy (string s) {
00124   register int i, n=N(s);
00125   string r (n);
00126   for (i=0; i<n; i++) r[i]=s[i];
00127   return r;
00128 }
00129 
00130 string&
00131 operator << (string& a, char x) {
00132   a->resize (N(a)+ 1);
00133   a [N(a)-1]=x;
00134   return a;
00135 }
00136 
00137 string&
00138 operator << (string& a, string b) {
00139   register int i, k1= N(a), k2=N(b);
00140   a->resize (k1+k2);
00141   for (i=0; i<k2; i++) a[i+k1]= b[i];
00142   return a;
00143 }
00144 
00145 string
00146 operator * (string a, string b) {
00147   register int i, n1=N(a), n2=N(b);
00148   string c(n1+n2);
00149   for (i=0; i<n1; i++) c[i]=a[i];
00150   for (i=0; i<n2; i++) c[i+n1]=b[i];
00151   return c;
00152 }
00153 
00154 string
00155 operator * (const char* a, string b) {
00156   return string (a) * b;
00157 }
00158 
00159 string
00160 operator * (string a, const char* b) {
00161   return a * string (b);
00162 }
00163 
00164 bool
00165 operator <= (string s1, string s2) {
00166   register int i;
00167   for (i=0; i<N(s1); i++) {
00168     if (i>=N(s2)) return false;
00169     if (s1[i]<s2[i]) return true;
00170     if (s2[i]<s1[i]) return false;
00171   }
00172   return true;
00173 }
00174 
00175 tm_ostream&
00176 operator << (tm_ostream& out, string a) {
00177   int i, n=N(a);
00178   if (n==0) return out;
00179   for (i=0; i<n; i++) out << a[i];
00180   return out;
00181 }
00182 
00183 int
00184 hash (string s) {
00185   register int i, h=0, n=N(s);
00186   for (i=0; i<n; i++) {
00187     h=(h<<9)+(h>>23);
00188     h=h+((int) s[i]);
00189   }
00190   return h;
00191 }
00192 
00193 /******************************************************************************
00194 * Conversion routines
00195 ******************************************************************************/
00196 
00197 bool
00198 as_bool (string s) {
00199   return (s == "true");
00200 }
00201 
00202 int
00203 as_int (string s) {
00204   int i=0, n=N(s), val=0;
00205   if (n==0) return 0;
00206   if (s[0]=='-') i++;
00207   while (i<n) {
00208     if (s[i]<'0') break;
00209     if (s[i]>'9') break;
00210     val *= 10;
00211     val += (int) (s[i]-'0');
00212     i++;
00213   }
00214   if (s[0]=='-') val=-val;
00215   return val;
00216 }
00217 
00218 double
00219 as_double (string s) {
00220   double x= 0.0;
00221   {
00222     int i, n= N(s);
00223     STACK_NEW_ARRAY (buf, char, n+1);
00224     for (i=0; i<n; i++) buf[i]=s[i];
00225     buf[n]='\0';
00226     sscanf (buf, "%lf", &x);
00227     STACK_DELETE_ARRAY (buf);
00228   } // in order to avoid segmentation fault due to compiler bug
00229   return x;
00230 }
00231 
00232 char*
00233 as_charp (string s) {
00234   int i, n= N(s);
00235   char *s2= tm_new_array<char> (n+1);
00236   for (i=0; i<n; i++) s2[i]=s[i];
00237   s2[n]= '\0';
00238   return s2;
00239 }
00240 
00241 string
00242 as_string_bool (bool f) {
00243   if (f) return string ("true");
00244   else return string ("false");
00245 }
00246 
00247 string
00248 as_string (int i) {
00249   char buf[64];
00250   sprintf (buf, "%i", i);
00251   // sprintf (buf, "%i\0", i);
00252   return string (buf);
00253 }
00254 
00255 string
00256 as_string (unsigned int i) {
00257   char buf[64];
00258   sprintf (buf, "%i", i);
00259   // sprintf (buf, "%i\0", i);
00260   return string (buf);
00261 }
00262 
00263 string
00264 as_string (long int i) {
00265   char buf[64];
00266   sprintf (buf, "%li", i);
00267   // sprintf (buf, "%i\0", i);
00268   return string (buf);
00269 }
00270 
00271 string
00272 as_string (unsigned long int i) {
00273   char buf[64];
00274   sprintf (buf, "%li", i);
00275   // sprintf (buf, "%i\0", i);
00276   return string (buf);
00277 }
00278 
00279 string
00280 as_string (double x) {
00281   char buf[64];
00282   sprintf (buf, "%g", x);
00283   // sprintf (buf, "%g\0", x);
00284   return string(buf);
00285 }
00286 
00287 string
00288 as_string (const char* s) {
00289   return string (s);
00290 }
00291 
00292 bool
00293 is_bool (string s) {
00294   return (s == "true") || (s == "false");
00295 }
00296 
00297 bool
00298 is_int (string s) {
00299   int i=0, n=N(s);
00300   if (n==0) return false;
00301   if (s[i]=='+') i++;
00302   if (s[i]=='-') i++;
00303   if (i==n) return false;
00304   for (; i<n; i++)
00305     if ((s[i]<'0') || (s[i]>'9')) return false;
00306   return true;
00307 }
00308 
00309 bool
00310 is_double (string s) {
00311   int i=0, n=N(s);
00312   if (n==0) return false;
00313   if (s[i]=='+') i++;
00314   if (s[i]=='-') i++;
00315   if (i==n) return false;
00316   for (; i< n; i++)
00317     if ((s[i]<'0') || (s[i]>'9')) break;
00318   if (i==n) return true;
00319   if (s[i]=='.') {
00320     i++;
00321     if (i==n) return false;
00322     for (; i< n; i++)
00323       if ((s[i]<'0') || (s[i]>'9')) break;
00324   }
00325   if (i==n) return true;
00326   if (s[i++]!='e') return false;
00327   if (s[i]=='+') i++;
00328   if (s[i]=='-') i++;
00329   if (i==n) return false;
00330   for (; i< n; i++)
00331     if ((s[i]<'0') || (s[i]>'9')) return false;
00332   return true;
00333 }
00334 
00335 bool
00336 is_charp (string s) { (void) s;
00337   return true;
00338 }
00339 
00340 bool
00341 is_quoted (string s) {
00342   return (N(s)>=2) && (s[0]=='\042') && (s[N(s)-1]=='\042');
00343 }
00344 
00345 bool
00346 is_id (string s) {
00347   int i=0, n=N(s);
00348   if (n==0) return false;
00349   for (i=0; i< n; i++) {
00350     if ((i>0) && (s[i]>='0') && (s[i]<='9')) continue;
00351     if ((s[i]>='a') && (s[i]<='z')) continue;
00352     if ((s[i]>='A') && (s[i]<='Z')) continue;
00353     if (s[i]=='_') continue;
00354     return false;
00355   }
00356   return true;
00357 }
00358 
00359 /******************************************************************************
00360 * Error messages
00361 ******************************************************************************/
00362 
00363 static void (*the_info_handler) (string, string, int) = NULL;
00364 static void (*the_wait_handler) (string, string, int) = NULL;
00365 static void (*the_warning_handler) (string, string, int) = NULL;
00366 static void (*the_error_handler) (string, string, int) = NULL;
00367 
00368 void
00369 set_info_handler (void (*routine) (string, string, int)) {
00370   the_info_handler= routine; }
00371 
00372 void
00373 system_info (string message, string argument, int level) {
00374   if (DEBUG_AUTO)
00375     cout << "TeXmacs] " << message << " " << argument << LF;
00376   if (the_info_handler != NULL)
00377     the_info_handler (message, argument, level);
00378 }
00379 
00380 void
00381 set_wait_handler (void (*routine) (string, string, int)) {
00382   the_wait_handler= routine; }
00383 
00384 void
00385 system_wait (string message, string argument, int level) {
00386   if (the_wait_handler == NULL) {
00387     if (DEBUG_AUTO) {
00388       if (message == "") cout << "TeXmacs] Done" << LF;
00389       else {
00390        if (argument == "") cout << "TeXmacs] " << message << LF;
00391        else cout << "TeXmacs] " << message << " " << argument << LF;
00392        cout << "TeXmacs] Please wait..." << LF;
00393       }
00394     }
00395   }
00396   else the_wait_handler (message, argument, level);
00397 }
00398 
00399 void
00400 set_warning_handler (void (*routine) (string, string, int)) {
00401   the_warning_handler= routine; }
00402 
00403 void
00404 system_warning (string message, string argument, int level) {
00405   if (DEBUG_AUTO)
00406     cout << "TeXmacs] Warning: " << message << " " << argument << LF;
00407   if (the_info_handler != NULL)
00408     the_info_handler ("Warning: " * message, argument, level);
00409 }
00410 
00411 void
00412 set_error_handler (void (*routine) (string, string, int)) {
00413   the_error_handler= routine; }
00414 
00415 void
00416 system_error (string message, string argument, int level) {
00417   if (DEBUG_AUTO)
00418     cout << "TeXmacs] Error: " << message << " " << argument << LF;
00419   if (the_info_handler != NULL)
00420     the_info_handler ("Error: " * message, argument, level);
00421 }