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 }