butils.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021   Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 #include "eyedbconfig.h"
00025 
00026 #ifdef HAVE_TIME_H
00027 #include <time.h>
00028 #endif
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 
00032 #include <eyedblib/machtypes.h>
00033 #include <eyedblib/butils.h>
00034 #include <eyedblib/thread.h>
00035 
00036 #define IS_INT(c) (c == 'D' || c == 'I' || c == 'O' || c == 'X')
00037 
00038 #define NBUFS 8
00039 
00040 namespace eyedblib {
00041   static Mutex mt;
00042 }
00043 
00044 namespace eyedblib {
00045   char *
00046   getFBuffer(const char *fmt, va_list ap)
00047   {
00048     static int argstr_alloc;
00049     static enum Type {INT, LONG, STR} *argstr;
00050     static int buffer_which;
00051     static int buffer_len[NBUFS];
00052     static char *buffer[NBUFS];
00053 
00054     MutexLocker _(mt);
00055     int n;
00056     int argstr_cnt = 0;
00057     int argint_cnt = 0;
00058     int arg_cnt = 0;
00059     unsigned int len = 0;
00060 
00061     unsigned int len_1 = strlen(fmt);
00062     for (; ;fmt++)
00063       {
00064         char c = *fmt;
00065         char num[32];
00066         char *pnum;
00067         int is_long;
00068 
00069         if (!c)
00070           break;
00071 
00072         if (c != '%')
00073           {
00074             len++;
00075             continue;
00076           }
00077 
00078         is_long = 0;
00079         pnum = num;
00080         while (c = *++fmt)
00081           {
00082             if (!c)
00083               break;
00084           
00085             if (c >= '0' && c <= '9')
00086               {
00087                 *pnum++ = c;
00088                 continue;
00089               }
00090 
00091             if (c == 'l')
00092               {
00093                 is_long++;
00094                 continue;
00095               }
00096 
00097             c = (c >= 'a' && c <= 'z' ? c + 'A'-'a' : c);
00098 
00099             if (IS_INT(c) || c == 'U' || c == 'E' || c == 'G' || c == 'C')
00100               {
00101                 if (c == 'U' && (IS_INT(*(fmt+1)) || *(fmt+1) == 'l'))
00102                   continue;
00103 
00104                 if (arg_cnt >= argstr_alloc)
00105                   {
00106                     argstr_alloc = arg_cnt + 12;
00107                     argstr = (enum Type *)
00108                       realloc(argstr, sizeof(enum Type)*argstr_alloc);
00109                   }
00110 
00111                 if (is_long > 1)
00112                   {
00113                     argstr[arg_cnt++] = LONG;
00114                     argint_cnt++;
00115                   }
00116                 else
00117                   argstr[arg_cnt++] = INT;
00118 
00119                 argint_cnt++;
00120                 break;
00121               }
00122 
00123             if (c == 'S')
00124               {
00125                 if (arg_cnt >= argstr_alloc)
00126                   {
00127                     argstr_alloc = arg_cnt + 12;
00128                     argstr = (enum Type *)
00129                       realloc(argstr, sizeof(enum Type)*argstr_alloc);
00130                   }
00131 
00132                 argstr[arg_cnt++] = STR;
00133                 argstr_cnt++;
00134                 break;
00135               }
00136           
00137             if (c == '%')
00138               {
00139                 len++;
00140                 break;
00141               }
00142 
00143             /* and what about float and double!!!!!! */
00144             /* len += 512; */
00145 
00146             /* unknown format sequence !? */
00147             len += 2;
00148             break;
00149           }
00150 
00151         if (pnum != num)
00152           {
00153             *pnum = 0;
00154             len += atoi(num);
00155           }
00156       }
00157 
00158     len += argint_cnt * 20;
00159 
00160     for (n = 0; n < arg_cnt; n++)
00161       {
00162         if (argstr[n] == STR)
00163           len += strlen(va_arg(ap, char *));
00164         else if (argstr[n] == LONG)
00165           (void)va_arg(ap, long long);
00166         else
00167           (void)va_arg(ap, int);
00168       }
00169 
00170     if (buffer_which >= NBUFS)
00171       buffer_which = 0;
00172 
00173     if (len+1 >= buffer_len[buffer_which])
00174       {
00175         free(buffer[buffer_which]);
00176         buffer_len[buffer_which] = len + 128 + 1024; // test
00177         buffer[buffer_which] = (char *)malloc(buffer_len[buffer_which]);
00178       }
00179 
00180     return buffer[buffer_which++];
00181   }
00182 
00183   void display_time(const char *fmt, ...)
00184   {
00185     va_list ap;
00186     struct timeval tp;
00187 
00188     gettimeofday(&tp, NULL);
00189 
00190 #ifdef HAVE_UNSIGNED_LONG_LONG
00191     unsigned long long ms = (unsigned long long)tp.tv_sec * 1000 + tp.tv_usec/1000;
00192 #endif
00193 
00194     va_start(ap, fmt);
00195 
00196     vfprintf(stdout, fmt, ap);
00197     fprintf(stdout, ": %lld ms\n", ms);
00198     va_end(ap);
00199   }
00200 
00201   int
00202   is_number(const char *s)
00203   {
00204     char c;
00205     if (!*s)
00206       return 0;
00207   
00208     while (c = *s++)
00209       if (!(c >= '0' && c <= '9'))
00210         return 0;
00211 
00212     return 1;
00213   }
00214 
00215 #define USEC_PER_SECOND 1000000
00216 #define USEC_PER_MS        1000
00217 
00218   const char *setbuftime(eyedblib::int64 t)
00219   {
00220 #define NT 4
00221     static char buftim[NT][64];
00222     static int nt;
00223     char *ds;
00224 
00225     time_t sec = t / USEC_PER_SECOND;
00226     eyedblib::int64 usec = t % USEC_PER_SECOND;
00227     const char *s = ctime(&sec);
00228 
00229     if (nt == NT)
00230       nt = 0;
00231 
00232     ds = buftim[nt++];
00233     strcpy(ds, s);
00234     ds[strlen(ds)-1] = 0;
00235 
00236     char buf[64];
00237     sprintf(buf, " %03d.%03dms", (int)(usec / USEC_PER_MS),
00238             (int)(usec % USEC_PER_MS));
00239     strcat(ds, buf);
00240 
00241     return ds;
00242   }
00243 }

Generated on Mon Dec 22 18:15:50 2008 for eyedb by  doxygen 1.5.3