• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

ink_sprintf.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /*****************************************************************************
00025 
00026   ink_sprintf.cc
00027 
00028   This file implements some Inktomi variants of sprintf, to do bounds
00029   checking and length counting.
00030 
00031 
00032   ****************************************************************************/
00033 
00034 #include "ink_sprintf.h"
00035 
00036 #define NUL '\0'
00037 
00038 //////////////////////////////////////////////////////////////////////////////
00039 //
00040 //      int ink_bsprintf(char *buffer, char *format, ...)
00041 //      int ink_bvsprintf(char *buffer, char *format, va_list ap)
00042 //
00043 //      This is a very simplified version of sprintf that has the following
00044 //      behavior:
00045 //
00046 //      (1) the length in output characters is returned, including final NUL
00047 //      (2) buffer can be NULL, for just counting the output chars
00048 //      (3) only %s and %d are supported, with no field modifiers
00049 //
00050 //////////////////////////////////////////////////////////////////////////////
00051 
00052 int
00053 ink_bsprintf(char *buffer, const char *format, ...)
00054 {
00055   int l;
00056 
00057   va_list ap;
00058   va_start(ap, format);
00059   l = ink_bvsprintf(buffer, format, ap);
00060   va_end(ap);
00061 
00062   return (l);
00063 }
00064 
00065 
00066 int
00067 ink_bvsprintf(char *buffer, const char *format, va_list ap)
00068 {
00069   int d_val;
00070   const char *s;
00071   char *d, *p, *s_val, d_buffer[32];
00072   va_list ap_local;
00073   va_copy(ap_local, ap);
00074 
00075   s = format;
00076   d = buffer;
00077 
00078   while (*s) {
00079     /////////////////////////////
00080     // handle non-% characters //
00081     /////////////////////////////
00082 
00083     if (buffer)                 // if have output buffer
00084       while (*s && (*s != '%')) {
00085         *d++ = *s++;
00086       }                         //   really copy, else
00087     else
00088       while (*s && (*s != '%')) {
00089         d++;
00090         s++;
00091       }                         //   pass over string
00092 
00093     ///////////////////////////
00094     // handle NUL characters //
00095     ///////////////////////////
00096 
00097     if (*s == NUL)
00098       break;                    // end of string
00099 
00100     /////////////////////////
00101     // handle % characters //
00102     /////////////////////////
00103 
00104     ++s;                        // consume % character
00105 
00106     switch (*s)                 // dispatch on flag
00107     {
00108     case 's':                  // %s pattern
00109       ++s;                      // consume 's'
00110       s_val = va_arg(ap_local, char *);       // grab string argument
00111       p = s_val;                // temporary pointer
00112       if (buffer)               // if have output buffer
00113         while (*p) {
00114           *d++ = *p++;
00115         }                       //   copy value
00116       else                      // else
00117         while (*p) {
00118           d++;
00119           p++;
00120         }                       //   pass over value
00121       break;
00122     case 'd':                  // %d pattern
00123       ++s;                      // consume 'd'
00124       d_val = va_arg(ap_local, int);  // grab integer argument
00125       snprintf(d_buffer, sizeof(d_buffer), "%d", d_val);        // stringify integer
00126       p = d_buffer;             // temporary pointer
00127       if (buffer)               // if have output buffer
00128         while (*p) {
00129           *d++ = *p++;
00130         }                       //   copy value
00131       else                      // else
00132         while (*p) {
00133           d++;
00134           p++;
00135         }                       //   pass over value
00136       break;
00137     default:                   // something else
00138       if (buffer)
00139         *d = *s;                // copy unknown character
00140       ++d;
00141       ++s;
00142       break;
00143     }
00144   }
00145 
00146   if (buffer)
00147     *d = NUL;
00148   ++d;
00149 
00150   va_end(ap_local);
00151   return (int) (d - buffer);
00152 }

Generated by  doxygen 1.7.1