util.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, The EROS
00004  *   Group, LLC.
00005  * Copyright (C) 2004, 2005, 2006, Johns Hopkins University.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or
00009  * without modification, are permitted provided that the following
00010  * conditions are met:
00011  *
00012  *   - Redistributions of source code must contain the above
00013  *     copyright notice, this list of conditions, and the following
00014  *     disclaimer.
00015  *
00016  *   - Redistributions in binary form must reproduce the above
00017  *     copyright notice, this list of conditions, and the following
00018  *     disclaimer in the documentation and/or other materials
00019  *     provided with the distribution.
00020  *
00021  *   - Neither the names of the copyright holders nor the names of any
00022  *     of any contributors may be used to endorse or promote products
00023  *     derived from this software without specific prior written
00024  *     permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00030  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  **************************************************************************/
00039 
00040 #include <stdint.h>
00041 #include <stdarg.h>
00042 #include <assert.h>
00043 
00044 #include <string>
00045 
00046 #include <openssl/ssl.h>
00047 #include <openssl/err.h>
00048 #include <openssl/rand.h>
00049 
00050 #include "util.hxx"
00051 
00052 namespace sherpa {
00053   std::string
00054   strdowncase(const std::string& s)
00055   {
00056     std::string new_s = s;
00057 
00058     for (size_t i = 0; i < new_s.size(); i++) {
00059       if (isalpha(new_s[i]))
00060         new_s.replace(i, 1, 1, tolower(new_s[i]));
00061     }
00062 
00063     return new_s;
00064   }
00065 
00066   /* Before this used sprintf. I grepped around, and found that this function
00067      was only called _ONCE_, in Browse.c
00068 
00069      Initially, I changed Browse.c to use xunsigned64_str, and removed
00070      xunsigned_str all together. Then I realized people (Shap+JV) might get mad
00071      that this function wasn't around any more, blah blah blah, so I put it back.
00072 
00073      In theory this is less efficient than sprintf, but all in all it doesn't
00074      really matter. It's not called (at all), and using xunsigned*_str implies
00075      doing some form of I/O (always very expensive).
00076 
00077      JL (9/12/02)
00078   */
00079   std::string unsigned_str(uint32_t n)
00080   {
00081     return unsigned64_str(n);
00082   }
00083 
00084   /* This helper routine is here because the logging logic should not
00085    * rely on the availability of mallocable memory. It should not be
00086    * called by anyone else! */
00087 #define BUFSZ 20 /* 19 for digits + 1 for null */
00088 
00089   static char *
00090   unsigned64_to_buffer(uint64_t ul, char *buf)
00091   {
00092     char *p;
00093 
00094     buf[BUFSZ-1] = 0;
00095     p = &buf[BUFSZ-1];
00096 
00097     if (ul == 0)
00098       *(--p) = '0';
00099 
00100     while(ul) {
00101       *(--p) = '0' + (ul % 10);
00102       ul = ul / 10;
00103     }
00104 
00105     return p;
00106   }
00107 
00108   /* bc says that 2^64-1==18446744073709551615, which looks to me like
00109      19 characters. */
00110   std::string
00111   unsigned64_str(uint64_t ul)
00112   {
00113     char buf[BUFSZ];
00114     char *p = unsigned64_to_buffer(ul, buf);
00115 
00116     return p;
00117   }
00118 
00119   uint64_t
00120   atollu(const char *s)
00121   {
00122     uint64_t ull = 0;
00123 
00124     for ( ; *s; s++) {
00125       ull *= 10;
00126       ull += (*s - '0');
00127     }
00128 
00129     return ull;
00130   }
00131 
00132   uint64_t
00133   atollu(const std::string& s)
00134   {
00135     uint64_t ull = 0;
00136 
00137     for (size_t i = 0; i < s.size(); i++) {
00138       ull *= 10;
00139       ull += (s[i] - '0');
00140     }
00141 
00142     return ull;
00143   }
00144 
00145 #if 0
00146   FILE *xprintf_outfile = 0;
00147 
00148   /* The only reason this exists is because I don't want to have to
00149    * bother being careful about printing null strings. Some
00150    * implementations of printf() behave gracelessly about that.
00151    */
00152 
00153 #define xputchar(c)  putc(c, xprintf_outfile)
00154 
00155   /* This is derived from the EROS kprintf code */
00156   size_t
00157   xprintf(const char *fmt, ...)
00158   {
00159     unsigned long len;
00160     unsigned long width = 0;
00161     bool sign;
00162     bool rightAdjust;
00163     char fillchar;
00164     char buf[20];
00165     char *p, *pend;
00166     size_t output_count = 0;
00167 
00168     va_list ap;
00169 
00170     if (xprintf_outfile == 0)
00171       xprintf_outfile = stdout;
00172 
00173     va_start(ap, fmt);
00174 
00175     for( ; *fmt; fmt++) {
00176       if (*fmt != '%') {
00177         xputchar(*fmt);
00178         output_count ++;
00179         continue;
00180       }
00181 
00182       /* largest thing we might convert fits in 20 digits (unsigned long
00183        * long as decimal */
00184 
00185       pend = &buf[20];
00186       p = pend;
00187 
00188       fmt++;                    /* now looking at specification */
00189 
00190       /* check for left adjust.. */
00191       rightAdjust = true;
00192       if (*fmt == '-') {
00193         rightAdjust = false;
00194         fmt++;
00195       }
00196 
00197       fillchar = ' ';
00198 
00199       /* we just saw a format character.  See if what follows
00200        * is a width specifier:
00201        */
00202       width = 0;
00203 
00204       if (*fmt == '0')
00205         fillchar = '0';
00206 
00207       while (*fmt && *fmt >= '0' && *fmt <= '9') {
00208         width *= 10;
00209         width += (*fmt - '0');
00210         fmt++;
00211       }
00212 
00213       assert (*fmt);            /* check bogus fmt */
00214 
00215       sign = false;
00216 
00217       switch (*fmt) {
00218       case '%':
00219         {
00220           xputchar(*fmt);
00221           output_count ++;
00222           break;
00223         }
00224       case 's':
00225         {
00226           p = pend = va_arg(ap, char *);
00227 
00228           if (pend == 0)
00229             p = pend = "<null>";
00230 
00231           while (*pend)
00232             pend++;
00233         
00234           break;
00235         }
00236       case 'c':
00237         {
00238           long c;
00239           c = va_arg(ap, long);
00240           *(--p) = (char) c;
00241           break;
00242         }       
00243       case 'd':
00244         {
00245           long l;
00246           unsigned long ul;
00247 
00248           l = va_arg(ap, long);
00249         
00250           if (l == 0) {
00251             *(--p) = '0';
00252           }
00253           else {
00254             if (l < 0)
00255               sign = '-';
00256 
00257             ul = (l < 0) ? (unsigned) -l : (unsigned) l;
00258 
00259             if (l == LONG_MIN)
00260               ul = ((unsigned long) LONG_MAX) + 1ul;
00261 
00262             while(ul) {
00263               *(--p) = '0' + (ul % 10);
00264               ul = ul / 10;
00265             }
00266           }
00267           break;
00268         }
00269       case 'u':
00270         {
00271           unsigned long ul;
00272 
00273           ul = va_arg(ap, unsigned long);
00274         
00275           if (ul == 0) {
00276             *(--p) = '0';
00277           }
00278           else {
00279             while(ul) {
00280               *(--p) = '0' + (ul % 10);
00281               ul = ul / 10;
00282             }
00283           }
00284           break;
00285         }
00286       case 'x':
00287         {
00288           unsigned long ul;
00289           static char *hex_digits = "0123456789abcdef";
00290 
00291           ul = va_arg(ap, unsigned long);
00292         
00293           if (ul == 0) {
00294             *(--p) = '0';
00295           }
00296           else {
00297             while(ul) {
00298               *(--p) = hex_digits[ul % 16];
00299               ul = ul / 16;
00300             }
00301           }
00302           break;
00303         }
00304       default:
00305         {
00306           assert(false);
00307         }
00308       }
00309 
00310       len = pend - p;
00311       if (sign)
00312         len++;
00313 
00314       /* do padding with initial spaces for right justification: */
00315       if (width && rightAdjust && len < width) {
00316         while (len < width) {
00317           xputchar(fillchar);
00318           output_count ++;
00319           width--;
00320         }
00321       }
00322 
00323       if (sign)
00324         xputchar(sign);
00325 
00326       /* output the text */
00327       while (p != pend) {
00328         xputchar(*p++);
00329         output_count ++;
00330       }
00331 
00332       /* do padding with trailing spaces for left justification: */
00333       if (width && rightAdjust == false && len < width) {
00334         while (len < width) {
00335           xputchar(fillchar);
00336           output_count ++;
00337           width--;
00338         }
00339       }
00340     }
00341 
00342     va_end(ap);
00343 
00344     return output_count;
00345   }
00346 #endif
00347 
00348   /* This is _exactly_ like bsearch, except that if base == NULL, simply return
00349      NULL. Normally this should work anyway, but it seems Solaris has 'issues'
00350      with this -- thus, this wrapper function.
00351   */
00352   void*
00353   xbsearch(const void *key, const void *base, size_t nmemb,
00354            size_t size, int (*compar)(const void *, const void *))
00355   {
00356     /* FIX: Should we check for base==NULL and nmemb > 0? */
00357     if(base == NULL)
00358       return NULL;
00359     return bsearch(key, base, nmemb, size, compar);
00360   }
00361 
00362   std::string
00363   sgetenv(const char *var)
00364   {
00365     std::string s;
00366 
00367     const char *result = getenv(var);
00368 
00369     if (result)
00370       s = result;
00371 
00372     return s;
00373   }
00374 
00375 } /* namespace sherpa */

Generated on Fri May 18 07:59:18 2012 for BitC Compiler by  doxygen 1.4.7