]> jfr.im git - irc/quakenet/snircd.git/blob - ircd/ircd_snprintf.c
merge 07 in
[irc/quakenet/snircd.git] / ircd / ircd_snprintf.c
1 /*
2 * IRC - Internet Relay Chat, ircd/ircd_snprintf.c
3 * Copyright (C) 2000 Kevin L. Mitchell <klmitch@mit.edu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 1, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /** @file
20 * @brief IRC-specific printf() clone implementation.
21 * @version $Id: ircd_snprintf.c,v 1.18.2.2 2006/04/07 03:51:48 entrope Exp $
22 */
23 #include "config.h"
24
25 #include "client.h"
26 #include "channel.h"
27 #include "ircd_log.h"
28 #include "ircd_snprintf.h"
29 #include "struct.h"
30
31 /* #include <assert.h> -- Now using assert in ircd_log.h */
32 #include <errno.h>
33 #include <stddef.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <time.h>
37
38 /* Inhibit complaints when we use GCC extensions */
39 #if defined(__GNUC__) && SIZEOF_LONG_LONG
40 # define EXTENSION __extension__
41 #else
42 /** Fallback (empty) definition of EXTENSION. */
43 # define EXTENSION
44 #endif
45
46 /* Find the largest type */
47 #if SIZEOF_LONG_LONG
48 EXTENSION typedef long long _large_t;
49 EXTENSION typedef unsigned long long _ularge_t;
50 # define SIZEOF__LARGE_T SIZEOF_LONG_LONG
51 /* Oh, if long long happens to be the size of void *, set _pointer_t, too */
52 # if SIZEOF_LONG_LONG == SIZEOF_VOID_P
53 typedef _ularge_t _pointer_t;
54 # define HAVE_POINTER_T
55 # endif
56 #else
57 /** Fallback definition of the largest integer type. */
58 typedef long _large_t;
59 /** Fallback definition of the largest unsigned integer type. */
60 typedef unsigned long _ularge_t;
61 /** Fallback definition of SIZEOF__LARGE_T. */
62 # define SIZEOF__LARGE_T SIZEOF_LONG
63 #endif
64
65 /* Select something for _pointer_t */
66 #ifndef HAVE_POINTER_T
67 # if SIZEOF_LONG == SIZEOF_VOID_P
68 /** Unsigned integer type large enough to hold a pointer. */
69 typedef unsigned long _pointer_t;
70 # elif SIZEOF_INT == SIZEOF_VOID_P
71 typedef unsigned int _pointer_t;
72 # else
73 # error Unable to find a suitable type for _pointer_t
74 # endif
75 #endif /* HAVE_POINTER_T */
76
77 /** rough length sufficient to hold an octal number, since those can be large */
78 #define INTBUF_LEN (SIZEOF__LARGE_T * 3)
79
80 /** Return minimum of \a i1 and \a i2. */
81 #define SNP_MIN(i1, i2) ((i1) < (i2) ? (i1) : (i2))
82 /** Return maximum of \a i1 and \a i2. */
83 #define SNP_MAX(i1, i2) ((i1) > (i2) ? (i1) : (i2))
84 /** Indicate total number of bytes "pseudo-output" in buffer. */
85 #define TOTAL(buf_p) ((buf_p)->buf_loc + \
86 SNP_MAX((buf_p)->buf_overflow, (buf_p)->overflow))
87
88 #define WIDTH_MAX 999 /**< keep from overflowing width */
89
90 /** data about the output buffer */
91 struct BufData {
92 char *buf; /**< pointer to buffer */
93 size_t buf_size; /**< maximum size of buffer */
94 size_t buf_overflow; /**< how much buffer has been overflowed */
95 size_t buf_loc; /**< where we are in the buffer */
96 short limit; /**< max # of chars to convert */
97 size_t overflow; /**< how much we overflowed the limit */
98 };
99
100 /** initializer for BufData */
101 #define BUFDATA_INIT { 0, 0, 0, 0, 0, 0 }
102
103 /** data about format fields */
104 struct FieldData {
105 unsigned int flags; /**< flags describing argument */
106 short base; /**< base for integer conversions */
107 short width; /**< width of field */
108 short prec; /**< precision of field */
109 union {
110 _ularge_t v_int; /**< an integer value */
111 long double v_float; /**< a floating point value -- NOT SUPPORTED */
112 void *v_ptr; /**< a pointer value */
113 } value; /**< value of a field */
114 };
115
116 /** initializer for FieldData */
117 #define FIELDDATA_INIT { 0, 0, 0, 0, { 0 } }
118
119 /* Specifier flags */
120 #define FLAG_MINUS 0x00000001 /**< found a '-' flag */
121 #define FLAG_PLUS 0x00000002 /**< found a '+' flag */
122 #define FLAG_SPACE 0x00000004 /**< found a ' ' flag */
123 #define FLAG_ALT 0x00000008 /**< found a '#' flag */
124 #define FLAG_ZERO 0x00000010 /**< found a '0' flag */
125 #define FLAG_COLON 0x00000020 /**< found a ':' flag */
126
127 #define FLAG_RESERVED1 0x00000040 /**< reserved for future expansion */
128 #define FLAG_RESERVED0 0x00000080 /**< reserved for future expansion */
129
130 /* integer types */
131 #define TYPE_CHAR 0x00000100 /**< number is a char */
132 #define TYPE_SHORT 0x00000200 /**< number is a short */
133 #define TYPE_LONG 0x00000400 /**< number is a long */
134 #define TYPE_QUAD 0x00000800 /**< number is a quad */
135
136 /* special integer types */
137 #define TYPE_INTMAX 0x00001000 /**< number is an intmax_t */
138 #define TYPE_PTRDIFF 0x00002000 /**< number is a ptrdiff_t */
139 #define TYPE_SIZE 0x00004000 /**< number is a size_t */
140 #define TYPE_TIME 0x00008000 /**< number is a time_t */
141 #define TYPE_POINTER 0x00010000 /**< number is a pointer_t */
142
143 /* floating point types */
144 #define TYPE_LONGDOUBLE 0x00020000 /**< number is a long double */
145
146 #define TYPE_RESERVED1 0x00040000 /**< reserved for future expansion */
147 #define TYPE_RESERVED0 0x00080000 /**< reserved for future expansion */
148
149 /** Mask to get just the type data */
150 #define TYPE_MASK (TYPE_CHAR | TYPE_SHORT | TYPE_LONG | TYPE_QUAD | \
151 TYPE_INTMAX | TYPE_PTRDIFF | TYPE_SIZE | TYPE_TIME | \
152 TYPE_POINTER | TYPE_LONGDOUBLE)
153
154 /* type of argument to extract */
155 #define ARG_INT 0x00100000 /**< argument is an integer */
156 #define ARG_FLOAT 0x00200000 /**< argument is a float */
157 #define ARG_PTR 0x00300000 /**< argument is a pointer */
158
159 #define ARG_RESERVED11 0x00400000 /**< reserved for future expansion */
160 #define ARG_RESERVED10 0x00500000 /**< reserved for future expansion */
161 #define ARG_RESERVED9 0x00600000 /**< reserved for future expansion */
162 #define ARG_RESERVED8 0x00700000 /**< reserved for future expansion */
163 #define ARG_RESERVED7 0x00800000 /**< reserved for future expansion */
164 #define ARG_RESERVED6 0x00900000 /**< reserved for future expansion */
165 #define ARG_RESERVED5 0x00a00000 /**< reserved for future expansion */
166 #define ARG_RESERVED4 0x00b00000 /**< reserved for future expansion */
167 #define ARG_RESERVED3 0x00c00000 /**< reserved for future expansion */
168 #define ARG_RESERVED2 0x00d00000 /**< reserved for future expansion */
169 #define ARG_RESERVED1 0x00e00000 /**< reserved for future expansion */
170 #define ARG_RESERVED0 0x00f00000 /**< reserved for future expansion */
171
172 /* Mask to get just the argument data */
173 #define ARG_MASK 0x00f00000 /**< masks off non-argument bits */
174
175 /* type of conversion to perform */
176 #define CONV_INT 0x01000000 /**< convert integers */
177 #define CONV_FLOAT 0x02000000 /**< convert floats */
178 #define CONV_CHAR 0x03000000 /**< convert chars */
179 #define CONV_STRING 0x04000000 /**< convert strings */
180 #define CONV_VARARGS 0x05000000 /**< convert a %v */
181 #define CONV_CLIENT 0x06000000 /**< convert a struct Client */
182 #define CONV_CHANNEL 0x07000000 /**< convert a struct Channel */
183 #define CONV_REAL 0x08000000 /**< convert a struct Client and show realhost */
184
185 #define CONV_RESERVED6 0x09000000 /**< reserved for future expansion */
186 #define CONV_RESERVED5 0x0a000000 /**< reserved for future expansion */
187 #define CONV_RESERVED4 0x0b000000 /**< reserved for future expansion */
188 #define CONV_RESERVED3 0x0c000000 /**< reserved for future expansion */
189 #define CONV_RESERVED2 0x0d000000 /**< reserved for future expansion */
190 #define CONV_RESERVED1 0x0e000000 /**< reserved for future expansion */
191 #define CONV_RESERVED0 0x0f000000 /**< reserved for future expansion */
192
193 /* Mask to get just the conversion data */
194 #define CONV_MASK 0x0f000000 /**< masks off non-conversion bits */
195
196 /* Value information flags */
197 #define INFO_RESERVED0 0x10000000 /**< reserved for future expansion */
198 #define INFO_UPPERCASE 0x20000000 /**< use uppercase characters */
199 #define INFO_UNSIGNED 0x40000000 /**< number is unsigned */
200 #define INFO_NEGATIVE 0x80000000 /**< number is negative */
201
202 #define BASE_OCTAL 9 /**< octal base; bits-per-char * 3 */
203 #define BASE_DECIMAL -1000 /**< decimal base; 10 ** 3 */
204 #define BASE_HEX 12 /**< hexadecimal base; bits-per-char * 3 */
205
206
207 /* padding... 1 2 3 4 5 */
208 /* 12345678901234567890123456789012345678901234567890 */
209 /** Predefined space padding. */
210 static char spaces[] = " ";
211 /** Predefined zero padding. */
212 static char zeros[] = "00000000000000000000000000000000000000000000000000";
213
214 /** Length of predefined padding strings. */
215 #define PAD_LENGTH (sizeof(spaces) - 1)
216
217 /*
218 * Note that these string tables have characters reversed. There is, of
219 * course, a reason for this; check out how they're built in doprintf.
220 */
221
222 /** string table for octal values */
223 static char *octal[] = {
224 "", "1", "2", "3", "4", "5", "6", "7",
225 "01", "11", "21", "31", "41", "51", "61", "71",
226 "02", "12", "22", "32", "42", "52", "62", "72",
227 "03", "13", "23", "33", "43", "53", "63", "73",
228 "04", "14", "24", "34", "44", "54", "64", "74",
229 "05", "15", "25", "35", "45", "55", "65", "75",
230 "06", "16", "26", "36", "46", "56", "66", "76",
231 "07", "17", "27", "37", "47", "57", "67", "77",
232 "001", "101", "201", "301", "401", "501", "601", "701",
233 "011", "111", "211", "311", "411", "511", "611", "711",
234 "021", "121", "221", "321", "421", "521", "621", "721",
235 "031", "131", "231", "331", "431", "531", "631", "731",
236 "041", "141", "241", "341", "441", "541", "641", "741",
237 "051", "151", "251", "351", "451", "551", "651", "751",
238 "061", "161", "261", "361", "461", "561", "661", "761",
239 "071", "171", "271", "371", "471", "571", "671", "771",
240 "002", "102", "202", "302", "402", "502", "602", "702",
241 "012", "112", "212", "312", "412", "512", "612", "712",
242 "022", "122", "222", "322", "422", "522", "622", "722",
243 "032", "132", "232", "332", "432", "532", "632", "732",
244 "042", "142", "242", "342", "442", "542", "642", "742",
245 "052", "152", "252", "352", "452", "552", "652", "752",
246 "062", "162", "262", "362", "462", "562", "662", "762",
247 "072", "172", "272", "372", "472", "572", "672", "772",
248 "003", "103", "203", "303", "403", "503", "603", "703",
249 "013", "113", "213", "313", "413", "513", "613", "713",
250 "023", "123", "223", "323", "423", "523", "623", "723",
251 "033", "133", "233", "333", "433", "533", "633", "733",
252 "043", "143", "243", "343", "443", "543", "643", "743",
253 "053", "153", "253", "353", "453", "553", "653", "753",
254 "063", "163", "263", "363", "463", "563", "663", "763",
255 "073", "173", "273", "373", "473", "573", "673", "773",
256 "004", "104", "204", "304", "404", "504", "604", "704",
257 "014", "114", "214", "314", "414", "514", "614", "714",
258 "024", "124", "224", "324", "424", "524", "624", "724",
259 "034", "134", "234", "334", "434", "534", "634", "734",
260 "044", "144", "244", "344", "444", "544", "644", "744",
261 "054", "154", "254", "354", "454", "554", "654", "754",
262 "064", "164", "264", "364", "464", "564", "664", "764",
263 "074", "174", "274", "374", "474", "574", "674", "774",
264 "005", "105", "205", "305", "405", "505", "605", "705",
265 "015", "115", "215", "315", "415", "515", "615", "715",
266 "025", "125", "225", "325", "425", "525", "625", "725",
267 "035", "135", "235", "335", "435", "535", "635", "735",
268 "045", "145", "245", "345", "445", "545", "645", "745",
269 "055", "155", "255", "355", "455", "555", "655", "755",
270 "065", "165", "265", "365", "465", "565", "665", "765",
271 "075", "175", "275", "375", "475", "575", "675", "775",
272 "006", "106", "206", "306", "406", "506", "606", "706",
273 "016", "116", "216", "316", "416", "516", "616", "716",
274 "026", "126", "226", "326", "426", "526", "626", "726",
275 "036", "136", "236", "336", "436", "536", "636", "736",
276 "046", "146", "246", "346", "446", "546", "646", "746",
277 "056", "156", "256", "356", "456", "556", "656", "756",
278 "066", "166", "266", "366", "466", "566", "666", "766",
279 "076", "176", "276", "376", "476", "576", "676", "776",
280 "007", "107", "207", "307", "407", "507", "607", "707",
281 "017", "117", "217", "317", "417", "517", "617", "717",
282 "027", "127", "227", "327", "427", "527", "627", "727",
283 "037", "137", "237", "337", "437", "537", "637", "737",
284 "047", "147", "247", "347", "447", "547", "647", "747",
285 "057", "157", "257", "357", "457", "557", "657", "757",
286 "067", "167", "267", "367", "467", "567", "667", "767",
287 "077", "177", "277", "377", "477", "577", "677", "777"
288 };
289
290 /** string table for decimal values */
291 static char *decimal[] = {
292 "", "1", "2", "3", "4", "5", "6", "7", "8", "9",
293 "01", "11", "21", "31", "41", "51", "61", "71", "81", "91",
294 "02", "12", "22", "32", "42", "52", "62", "72", "82", "92",
295 "03", "13", "23", "33", "43", "53", "63", "73", "83", "93",
296 "04", "14", "24", "34", "44", "54", "64", "74", "84", "94",
297 "05", "15", "25", "35", "45", "55", "65", "75", "85", "95",
298 "06", "16", "26", "36", "46", "56", "66", "76", "86", "96",
299 "07", "17", "27", "37", "47", "57", "67", "77", "87", "97",
300 "08", "18", "28", "38", "48", "58", "68", "78", "88", "98",
301 "09", "19", "29", "39", "49", "59", "69", "79", "89", "99",
302 "001", "101", "201", "301", "401", "501", "601", "701", "801", "901",
303 "011", "111", "211", "311", "411", "511", "611", "711", "811", "911",
304 "021", "121", "221", "321", "421", "521", "621", "721", "821", "921",
305 "031", "131", "231", "331", "431", "531", "631", "731", "831", "931",
306 "041", "141", "241", "341", "441", "541", "641", "741", "841", "941",
307 "051", "151", "251", "351", "451", "551", "651", "751", "851", "951",
308 "061", "161", "261", "361", "461", "561", "661", "761", "861", "961",
309 "071", "171", "271", "371", "471", "571", "671", "771", "871", "971",
310 "081", "181", "281", "381", "481", "581", "681", "781", "881", "981",
311 "091", "191", "291", "391", "491", "591", "691", "791", "891", "991",
312 "002", "102", "202", "302", "402", "502", "602", "702", "802", "902",
313 "012", "112", "212", "312", "412", "512", "612", "712", "812", "912",
314 "022", "122", "222", "322", "422", "522", "622", "722", "822", "922",
315 "032", "132", "232", "332", "432", "532", "632", "732", "832", "932",
316 "042", "142", "242", "342", "442", "542", "642", "742", "842", "942",
317 "052", "152", "252", "352", "452", "552", "652", "752", "852", "952",
318 "062", "162", "262", "362", "462", "562", "662", "762", "862", "962",
319 "072", "172", "272", "372", "472", "572", "672", "772", "872", "972",
320 "082", "182", "282", "382", "482", "582", "682", "782", "882", "982",
321 "092", "192", "292", "392", "492", "592", "692", "792", "892", "992",
322 "003", "103", "203", "303", "403", "503", "603", "703", "803", "903",
323 "013", "113", "213", "313", "413", "513", "613", "713", "813", "913",
324 "023", "123", "223", "323", "423", "523", "623", "723", "823", "923",
325 "033", "133", "233", "333", "433", "533", "633", "733", "833", "933",
326 "043", "143", "243", "343", "443", "543", "643", "743", "843", "943",
327 "053", "153", "253", "353", "453", "553", "653", "753", "853", "953",
328 "063", "163", "263", "363", "463", "563", "663", "763", "863", "963",
329 "073", "173", "273", "373", "473", "573", "673", "773", "873", "973",
330 "083", "183", "283", "383", "483", "583", "683", "783", "883", "983",
331 "093", "193", "293", "393", "493", "593", "693", "793", "893", "993",
332 "004", "104", "204", "304", "404", "504", "604", "704", "804", "904",
333 "014", "114", "214", "314", "414", "514", "614", "714", "814", "914",
334 "024", "124", "224", "324", "424", "524", "624", "724", "824", "924",
335 "034", "134", "234", "334", "434", "534", "634", "734", "834", "934",
336 "044", "144", "244", "344", "444", "544", "644", "744", "844", "944",
337 "054", "154", "254", "354", "454", "554", "654", "754", "854", "954",
338 "064", "164", "264", "364", "464", "564", "664", "764", "864", "964",
339 "074", "174", "274", "374", "474", "574", "674", "774", "874", "974",
340 "084", "184", "284", "384", "484", "584", "684", "784", "884", "984",
341 "094", "194", "294", "394", "494", "594", "694", "794", "894", "994",
342 "005", "105", "205", "305", "405", "505", "605", "705", "805", "905",
343 "015", "115", "215", "315", "415", "515", "615", "715", "815", "915",
344 "025", "125", "225", "325", "425", "525", "625", "725", "825", "925",
345 "035", "135", "235", "335", "435", "535", "635", "735", "835", "935",
346 "045", "145", "245", "345", "445", "545", "645", "745", "845", "945",
347 "055", "155", "255", "355", "455", "555", "655", "755", "855", "955",
348 "065", "165", "265", "365", "465", "565", "665", "765", "865", "965",
349 "075", "175", "275", "375", "475", "575", "675", "775", "875", "975",
350 "085", "185", "285", "385", "485", "585", "685", "785", "885", "985",
351 "095", "195", "295", "395", "495", "595", "695", "795", "895", "995",
352 "006", "106", "206", "306", "406", "506", "606", "706", "806", "906",
353 "016", "116", "216", "316", "416", "516", "616", "716", "816", "916",
354 "026", "126", "226", "326", "426", "526", "626", "726", "826", "926",
355 "036", "136", "236", "336", "436", "536", "636", "736", "836", "936",
356 "046", "146", "246", "346", "446", "546", "646", "746", "846", "946",
357 "056", "156", "256", "356", "456", "556", "656", "756", "856", "956",
358 "066", "166", "266", "366", "466", "566", "666", "766", "866", "966",
359 "076", "176", "276", "376", "476", "576", "676", "776", "876", "976",
360 "086", "186", "286", "386", "486", "586", "686", "786", "886", "986",
361 "096", "196", "296", "396", "496", "596", "696", "796", "896", "996",
362 "007", "107", "207", "307", "407", "507", "607", "707", "807", "907",
363 "017", "117", "217", "317", "417", "517", "617", "717", "817", "917",
364 "027", "127", "227", "327", "427", "527", "627", "727", "827", "927",
365 "037", "137", "237", "337", "437", "537", "637", "737", "837", "937",
366 "047", "147", "247", "347", "447", "547", "647", "747", "847", "947",
367 "057", "157", "257", "357", "457", "557", "657", "757", "857", "957",
368 "067", "167", "267", "367", "467", "567", "667", "767", "867", "967",
369 "077", "177", "277", "377", "477", "577", "677", "777", "877", "977",
370 "087", "187", "287", "387", "487", "587", "687", "787", "887", "987",
371 "097", "197", "297", "397", "497", "597", "697", "797", "897", "997",
372 "008", "108", "208", "308", "408", "508", "608", "708", "808", "908",
373 "018", "118", "218", "318", "418", "518", "618", "718", "818", "918",
374 "028", "128", "228", "328", "428", "528", "628", "728", "828", "928",
375 "038", "138", "238", "338", "438", "538", "638", "738", "838", "938",
376 "048", "148", "248", "348", "448", "548", "648", "748", "848", "948",
377 "058", "158", "258", "358", "458", "558", "658", "758", "858", "958",
378 "068", "168", "268", "368", "468", "568", "668", "768", "868", "968",
379 "078", "178", "278", "378", "478", "578", "678", "778", "878", "978",
380 "088", "188", "288", "388", "488", "588", "688", "788", "888", "988",
381 "098", "198", "298", "398", "498", "598", "698", "798", "898", "998",
382 "009", "109", "209", "309", "409", "509", "609", "709", "809", "909",
383 "019", "119", "219", "319", "419", "519", "619", "719", "819", "919",
384 "029", "129", "229", "329", "429", "529", "629", "729", "829", "929",
385 "039", "139", "239", "339", "439", "539", "639", "739", "839", "939",
386 "049", "149", "249", "349", "449", "549", "649", "749", "849", "949",
387 "059", "159", "259", "359", "459", "559", "659", "759", "859", "959",
388 "069", "169", "269", "369", "469", "569", "669", "769", "869", "969",
389 "079", "179", "279", "379", "479", "579", "679", "779", "879", "979",
390 "089", "189", "289", "389", "489", "589", "689", "789", "889", "989",
391 "099", "199", "299", "399", "499", "599", "699", "799", "899", "999"
392 };
393
394 /** string table for lower-case hexadecimal values */
395 static char *hex[] = {
396 "", "1", "2", "3", "4", "5", "6", "7",
397 "8", "9", "a", "b", "c", "d", "e", "f",
398 "01", "11", "21", "31", "41", "51", "61", "71",
399 "81", "91", "a1", "b1", "c1", "d1", "e1", "f1",
400 "02", "12", "22", "32", "42", "52", "62", "72",
401 "82", "92", "a2", "b2", "c2", "d2", "e2", "f2",
402 "03", "13", "23", "33", "43", "53", "63", "73",
403 "83", "93", "a3", "b3", "c3", "d3", "e3", "f3",
404 "04", "14", "24", "34", "44", "54", "64", "74",
405 "84", "94", "a4", "b4", "c4", "d4", "e4", "f4",
406 "05", "15", "25", "35", "45", "55", "65", "75",
407 "85", "95", "a5", "b5", "c5", "d5", "e5", "f5",
408 "06", "16", "26", "36", "46", "56", "66", "76",
409 "86", "96", "a6", "b6", "c6", "d6", "e6", "f6",
410 "07", "17", "27", "37", "47", "57", "67", "77",
411 "87", "97", "a7", "b7", "c7", "d7", "e7", "f7",
412 "08", "18", "28", "38", "48", "58", "68", "78",
413 "88", "98", "a8", "b8", "c8", "d8", "e8", "f8",
414 "09", "19", "29", "39", "49", "59", "69", "79",
415 "89", "99", "a9", "b9", "c9", "d9", "e9", "f9",
416 "0a", "1a", "2a", "3a", "4a", "5a", "6a", "7a",
417 "8a", "9a", "aa", "ba", "ca", "da", "ea", "fa",
418 "0b", "1b", "2b", "3b", "4b", "5b", "6b", "7b",
419 "8b", "9b", "ab", "bb", "cb", "db", "eb", "fb",
420 "0c", "1c", "2c", "3c", "4c", "5c", "6c", "7c",
421 "8c", "9c", "ac", "bc", "cc", "dc", "ec", "fc",
422 "0d", "1d", "2d", "3d", "4d", "5d", "6d", "7d",
423 "8d", "9d", "ad", "bd", "cd", "dd", "ed", "fd",
424 "0e", "1e", "2e", "3e", "4e", "5e", "6e", "7e",
425 "8e", "9e", "ae", "be", "ce", "de", "ee", "fe",
426 "0f", "1f", "2f", "3f", "4f", "5f", "6f", "7f",
427 "8f", "9f", "af", "bf", "cf", "df", "ef", "ff",
428 "001", "101", "201", "301", "401", "501", "601", "701",
429 "801", "901", "a01", "b01", "c01", "d01", "e01", "f01",
430 "011", "111", "211", "311", "411", "511", "611", "711",
431 "811", "911", "a11", "b11", "c11", "d11", "e11", "f11",
432 "021", "121", "221", "321", "421", "521", "621", "721",
433 "821", "921", "a21", "b21", "c21", "d21", "e21", "f21",
434 "031", "131", "231", "331", "431", "531", "631", "731",
435 "831", "931", "a31", "b31", "c31", "d31", "e31", "f31",
436 "041", "141", "241", "341", "441", "541", "641", "741",
437 "841", "941", "a41", "b41", "c41", "d41", "e41", "f41",
438 "051", "151", "251", "351", "451", "551", "651", "751",
439 "851", "951", "a51", "b51", "c51", "d51", "e51", "f51",
440 "061", "161", "261", "361", "461", "561", "661", "761",
441 "861", "961", "a61", "b61", "c61", "d61", "e61", "f61",
442 "071", "171", "271", "371", "471", "571", "671", "771",
443 "871", "971", "a71", "b71", "c71", "d71", "e71", "f71",
444 "081", "181", "281", "381", "481", "581", "681", "781",
445 "881", "981", "a81", "b81", "c81", "d81", "e81", "f81",
446 "091", "191", "291", "391", "491", "591", "691", "791",
447 "891", "991", "a91", "b91", "c91", "d91", "e91", "f91",
448 "0a1", "1a1", "2a1", "3a1", "4a1", "5a1", "6a1", "7a1",
449 "8a1", "9a1", "aa1", "ba1", "ca1", "da1", "ea1", "fa1",
450 "0b1", "1b1", "2b1", "3b1", "4b1", "5b1", "6b1", "7b1",
451 "8b1", "9b1", "ab1", "bb1", "cb1", "db1", "eb1", "fb1",
452 "0c1", "1c1", "2c1", "3c1", "4c1", "5c1", "6c1", "7c1",
453 "8c1", "9c1", "ac1", "bc1", "cc1", "dc1", "ec1", "fc1",
454 "0d1", "1d1", "2d1", "3d1", "4d1", "5d1", "6d1", "7d1",
455 "8d1", "9d1", "ad1", "bd1", "cd1", "dd1", "ed1", "fd1",
456 "0e1", "1e1", "2e1", "3e1", "4e1", "5e1", "6e1", "7e1",
457 "8e1", "9e1", "ae1", "be1", "ce1", "de1", "ee1", "fe1",
458 "0f1", "1f1", "2f1", "3f1", "4f1", "5f1", "6f1", "7f1",
459 "8f1", "9f1", "af1", "bf1", "cf1", "df1", "ef1", "ff1",
460 "002", "102", "202", "302", "402", "502", "602", "702",
461 "802", "902", "a02", "b02", "c02", "d02", "e02", "f02",
462 "012", "112", "212", "312", "412", "512", "612", "712",
463 "812", "912", "a12", "b12", "c12", "d12", "e12", "f12",
464 "022", "122", "222", "322", "422", "522", "622", "722",
465 "822", "922", "a22", "b22", "c22", "d22", "e22", "f22",
466 "032", "132", "232", "332", "432", "532", "632", "732",
467 "832", "932", "a32", "b32", "c32", "d32", "e32", "f32",
468 "042", "142", "242", "342", "442", "542", "642", "742",
469 "842", "942", "a42", "b42", "c42", "d42", "e42", "f42",
470 "052", "152", "252", "352", "452", "552", "652", "752",
471 "852", "952", "a52", "b52", "c52", "d52", "e52", "f52",
472 "062", "162", "262", "362", "462", "562", "662", "762",
473 "862", "962", "a62", "b62", "c62", "d62", "e62", "f62",
474 "072", "172", "272", "372", "472", "572", "672", "772",
475 "872", "972", "a72", "b72", "c72", "d72", "e72", "f72",
476 "082", "182", "282", "382", "482", "582", "682", "782",
477 "882", "982", "a82", "b82", "c82", "d82", "e82", "f82",
478 "092", "192", "292", "392", "492", "592", "692", "792",
479 "892", "992", "a92", "b92", "c92", "d92", "e92", "f92",
480 "0a2", "1a2", "2a2", "3a2", "4a2", "5a2", "6a2", "7a2",
481 "8a2", "9a2", "aa2", "ba2", "ca2", "da2", "ea2", "fa2",
482 "0b2", "1b2", "2b2", "3b2", "4b2", "5b2", "6b2", "7b2",
483 "8b2", "9b2", "ab2", "bb2", "cb2", "db2", "eb2", "fb2",
484 "0c2", "1c2", "2c2", "3c2", "4c2", "5c2", "6c2", "7c2",
485 "8c2", "9c2", "ac2", "bc2", "cc2", "dc2", "ec2", "fc2",
486 "0d2", "1d2", "2d2", "3d2", "4d2", "5d2", "6d2", "7d2",
487 "8d2", "9d2", "ad2", "bd2", "cd2", "dd2", "ed2", "fd2",
488 "0e2", "1e2", "2e2", "3e2", "4e2", "5e2", "6e2", "7e2",
489 "8e2", "9e2", "ae2", "be2", "ce2", "de2", "ee2", "fe2",
490 "0f2", "1f2", "2f2", "3f2", "4f2", "5f2", "6f2", "7f2",
491 "8f2", "9f2", "af2", "bf2", "cf2", "df2", "ef2", "ff2",
492 "003", "103", "203", "303", "403", "503", "603", "703",
493 "803", "903", "a03", "b03", "c03", "d03", "e03", "f03",
494 "013", "113", "213", "313", "413", "513", "613", "713",
495 "813", "913", "a13", "b13", "c13", "d13", "e13", "f13",
496 "023", "123", "223", "323", "423", "523", "623", "723",
497 "823", "923", "a23", "b23", "c23", "d23", "e23", "f23",
498 "033", "133", "233", "333", "433", "533", "633", "733",
499 "833", "933", "a33", "b33", "c33", "d33", "e33", "f33",
500 "043", "143", "243", "343", "443", "543", "643", "743",
501 "843", "943", "a43", "b43", "c43", "d43", "e43", "f43",
502 "053", "153", "253", "353", "453", "553", "653", "753",
503 "853", "953", "a53", "b53", "c53", "d53", "e53", "f53",
504 "063", "163", "263", "363", "463", "563", "663", "763",
505 "863", "963", "a63", "b63", "c63", "d63", "e63", "f63",
506 "073", "173", "273", "373", "473", "573", "673", "773",
507 "873", "973", "a73", "b73", "c73", "d73", "e73", "f73",
508 "083", "183", "283", "383", "483", "583", "683", "783",
509 "883", "983", "a83", "b83", "c83", "d83", "e83", "f83",
510 "093", "193", "293", "393", "493", "593", "693", "793",
511 "893", "993", "a93", "b93", "c93", "d93", "e93", "f93",
512 "0a3", "1a3", "2a3", "3a3", "4a3", "5a3", "6a3", "7a3",
513 "8a3", "9a3", "aa3", "ba3", "ca3", "da3", "ea3", "fa3",
514 "0b3", "1b3", "2b3", "3b3", "4b3", "5b3", "6b3", "7b3",
515 "8b3", "9b3", "ab3", "bb3", "cb3", "db3", "eb3", "fb3",
516 "0c3", "1c3", "2c3", "3c3", "4c3", "5c3", "6c3", "7c3",
517 "8c3", "9c3", "ac3", "bc3", "cc3", "dc3", "ec3", "fc3",
518 "0d3", "1d3", "2d3", "3d3", "4d3", "5d3", "6d3", "7d3",
519 "8d3", "9d3", "ad3", "bd3", "cd3", "dd3", "ed3", "fd3",
520 "0e3", "1e3", "2e3", "3e3", "4e3", "5e3", "6e3", "7e3",
521 "8e3", "9e3", "ae3", "be3", "ce3", "de3", "ee3", "fe3",
522 "0f3", "1f3", "2f3", "3f3", "4f3", "5f3", "6f3", "7f3",
523 "8f3", "9f3", "af3", "bf3", "cf3", "df3", "ef3", "ff3",
524 "004", "104", "204", "304", "404", "504", "604", "704",
525 "804", "904", "a04", "b04", "c04", "d04", "e04", "f04",
526 "014", "114", "214", "314", "414", "514", "614", "714",
527 "814", "914", "a14", "b14", "c14", "d14", "e14", "f14",
528 "024", "124", "224", "324", "424", "524", "624", "724",
529 "824", "924", "a24", "b24", "c24", "d24", "e24", "f24",
530 "034", "134", "234", "334", "434", "534", "634", "734",
531 "834", "934", "a34", "b34", "c34", "d34", "e34", "f34",
532 "044", "144", "244", "344", "444", "544", "644", "744",
533 "844", "944", "a44", "b44", "c44", "d44", "e44", "f44",
534 "054", "154", "254", "354", "454", "554", "654", "754",
535 "854", "954", "a54", "b54", "c54", "d54", "e54", "f54",
536 "064", "164", "264", "364", "464", "564", "664", "764",
537 "864", "964", "a64", "b64", "c64", "d64", "e64", "f64",
538 "074", "174", "274", "374", "474", "574", "674", "774",
539 "874", "974", "a74", "b74", "c74", "d74", "e74", "f74",
540 "084", "184", "284", "384", "484", "584", "684", "784",
541 "884", "984", "a84", "b84", "c84", "d84", "e84", "f84",
542 "094", "194", "294", "394", "494", "594", "694", "794",
543 "894", "994", "a94", "b94", "c94", "d94", "e94", "f94",
544 "0a4", "1a4", "2a4", "3a4", "4a4", "5a4", "6a4", "7a4",
545 "8a4", "9a4", "aa4", "ba4", "ca4", "da4", "ea4", "fa4",
546 "0b4", "1b4", "2b4", "3b4", "4b4", "5b4", "6b4", "7b4",
547 "8b4", "9b4", "ab4", "bb4", "cb4", "db4", "eb4", "fb4",
548 "0c4", "1c4", "2c4", "3c4", "4c4", "5c4", "6c4", "7c4",
549 "8c4", "9c4", "ac4", "bc4", "cc4", "dc4", "ec4", "fc4",
550 "0d4", "1d4", "2d4", "3d4", "4d4", "5d4", "6d4", "7d4",
551 "8d4", "9d4", "ad4", "bd4", "cd4", "dd4", "ed4", "fd4",
552 "0e4", "1e4", "2e4", "3e4", "4e4", "5e4", "6e4", "7e4",
553 "8e4", "9e4", "ae4", "be4", "ce4", "de4", "ee4", "fe4",
554 "0f4", "1f4", "2f4", "3f4", "4f4", "5f4", "6f4", "7f4",
555 "8f4", "9f4", "af4", "bf4", "cf4", "df4", "ef4", "ff4",
556 "005", "105", "205", "305", "405", "505", "605", "705",
557 "805", "905", "a05", "b05", "c05", "d05", "e05", "f05",
558 "015", "115", "215", "315", "415", "515", "615", "715",
559 "815", "915", "a15", "b15", "c15", "d15", "e15", "f15",
560 "025", "125", "225", "325", "425", "525", "625", "725",
561 "825", "925", "a25", "b25", "c25", "d25", "e25", "f25",
562 "035", "135", "235", "335", "435", "535", "635", "735",
563 "835", "935", "a35", "b35", "c35", "d35", "e35", "f35",
564 "045", "145", "245", "345", "445", "545", "645", "745",
565 "845", "945", "a45", "b45", "c45", "d45", "e45", "f45",
566 "055", "155", "255", "355", "455", "555", "655", "755",
567 "855", "955", "a55", "b55", "c55", "d55", "e55", "f55",
568 "065", "165", "265", "365", "465", "565", "665", "765",
569 "865", "965", "a65", "b65", "c65", "d65", "e65", "f65",
570 "075", "175", "275", "375", "475", "575", "675", "775",
571 "875", "975", "a75", "b75", "c75", "d75", "e75", "f75",
572 "085", "185", "285", "385", "485", "585", "685", "785",
573 "885", "985", "a85", "b85", "c85", "d85", "e85", "f85",
574 "095", "195", "295", "395", "495", "595", "695", "795",
575 "895", "995", "a95", "b95", "c95", "d95", "e95", "f95",
576 "0a5", "1a5", "2a5", "3a5", "4a5", "5a5", "6a5", "7a5",
577 "8a5", "9a5", "aa5", "ba5", "ca5", "da5", "ea5", "fa5",
578 "0b5", "1b5", "2b5", "3b5", "4b5", "5b5", "6b5", "7b5",
579 "8b5", "9b5", "ab5", "bb5", "cb5", "db5", "eb5", "fb5",
580 "0c5", "1c5", "2c5", "3c5", "4c5", "5c5", "6c5", "7c5",
581 "8c5", "9c5", "ac5", "bc5", "cc5", "dc5", "ec5", "fc5",
582 "0d5", "1d5", "2d5", "3d5", "4d5", "5d5", "6d5", "7d5",
583 "8d5", "9d5", "ad5", "bd5", "cd5", "dd5", "ed5", "fd5",
584 "0e5", "1e5", "2e5", "3e5", "4e5", "5e5", "6e5", "7e5",
585 "8e5", "9e5", "ae5", "be5", "ce5", "de5", "ee5", "fe5",
586 "0f5", "1f5", "2f5", "3f5", "4f5", "5f5", "6f5", "7f5",
587 "8f5", "9f5", "af5", "bf5", "cf5", "df5", "ef5", "ff5",
588 "006", "106", "206", "306", "406", "506", "606", "706",
589 "806", "906", "a06", "b06", "c06", "d06", "e06", "f06",
590 "016", "116", "216", "316", "416", "516", "616", "716",
591 "816", "916", "a16", "b16", "c16", "d16", "e16", "f16",
592 "026", "126", "226", "326", "426", "526", "626", "726",
593 "826", "926", "a26", "b26", "c26", "d26", "e26", "f26",
594 "036", "136", "236", "336", "436", "536", "636", "736",
595 "836", "936", "a36", "b36", "c36", "d36", "e36", "f36",
596 "046", "146", "246", "346", "446", "546", "646", "746",
597 "846", "946", "a46", "b46", "c46", "d46", "e46", "f46",
598 "056", "156", "256", "356", "456", "556", "656", "756",
599 "856", "956", "a56", "b56", "c56", "d56", "e56", "f56",
600 "066", "166", "266", "366", "466", "566", "666", "766",
601 "866", "966", "a66", "b66", "c66", "d66", "e66", "f66",
602 "076", "176", "276", "376", "476", "576", "676", "776",
603 "876", "976", "a76", "b76", "c76", "d76", "e76", "f76",
604 "086", "186", "286", "386", "486", "586", "686", "786",
605 "886", "986", "a86", "b86", "c86", "d86", "e86", "f86",
606 "096", "196", "296", "396", "496", "596", "696", "796",
607 "896", "996", "a96", "b96", "c96", "d96", "e96", "f96",
608 "0a6", "1a6", "2a6", "3a6", "4a6", "5a6", "6a6", "7a6",
609 "8a6", "9a6", "aa6", "ba6", "ca6", "da6", "ea6", "fa6",
610 "0b6", "1b6", "2b6", "3b6", "4b6", "5b6", "6b6", "7b6",
611 "8b6", "9b6", "ab6", "bb6", "cb6", "db6", "eb6", "fb6",
612 "0c6", "1c6", "2c6", "3c6", "4c6", "5c6", "6c6", "7c6",
613 "8c6", "9c6", "ac6", "bc6", "cc6", "dc6", "ec6", "fc6",
614 "0d6", "1d6", "2d6", "3d6", "4d6", "5d6", "6d6", "7d6",
615 "8d6", "9d6", "ad6", "bd6", "cd6", "dd6", "ed6", "fd6",
616 "0e6", "1e6", "2e6", "3e6", "4e6", "5e6", "6e6", "7e6",
617 "8e6", "9e6", "ae6", "be6", "ce6", "de6", "ee6", "fe6",
618 "0f6", "1f6", "2f6", "3f6", "4f6", "5f6", "6f6", "7f6",
619 "8f6", "9f6", "af6", "bf6", "cf6", "df6", "ef6", "ff6",
620 "007", "107", "207", "307", "407", "507", "607", "707",
621 "807", "907", "a07", "b07", "c07", "d07", "e07", "f07",
622 "017", "117", "217", "317", "417", "517", "617", "717",
623 "817", "917", "a17", "b17", "c17", "d17", "e17", "f17",
624 "027", "127", "227", "327", "427", "527", "627", "727",
625 "827", "927", "a27", "b27", "c27", "d27", "e27", "f27",
626 "037", "137", "237", "337", "437", "537", "637", "737",
627 "837", "937", "a37", "b37", "c37", "d37", "e37", "f37",
628 "047", "147", "247", "347", "447", "547", "647", "747",
629 "847", "947", "a47", "b47", "c47", "d47", "e47", "f47",
630 "057", "157", "257", "357", "457", "557", "657", "757",
631 "857", "957", "a57", "b57", "c57", "d57", "e57", "f57",
632 "067", "167", "267", "367", "467", "567", "667", "767",
633 "867", "967", "a67", "b67", "c67", "d67", "e67", "f67",
634 "077", "177", "277", "377", "477", "577", "677", "777",
635 "877", "977", "a77", "b77", "c77", "d77", "e77", "f77",
636 "087", "187", "287", "387", "487", "587", "687", "787",
637 "887", "987", "a87", "b87", "c87", "d87", "e87", "f87",
638 "097", "197", "297", "397", "497", "597", "697", "797",
639 "897", "997", "a97", "b97", "c97", "d97", "e97", "f97",
640 "0a7", "1a7", "2a7", "3a7", "4a7", "5a7", "6a7", "7a7",
641 "8a7", "9a7", "aa7", "ba7", "ca7", "da7", "ea7", "fa7",
642 "0b7", "1b7", "2b7", "3b7", "4b7", "5b7", "6b7", "7b7",
643 "8b7", "9b7", "ab7", "bb7", "cb7", "db7", "eb7", "fb7",
644 "0c7", "1c7", "2c7", "3c7", "4c7", "5c7", "6c7", "7c7",
645 "8c7", "9c7", "ac7", "bc7", "cc7", "dc7", "ec7", "fc7",
646 "0d7", "1d7", "2d7", "3d7", "4d7", "5d7", "6d7", "7d7",
647 "8d7", "9d7", "ad7", "bd7", "cd7", "dd7", "ed7", "fd7",
648 "0e7", "1e7", "2e7", "3e7", "4e7", "5e7", "6e7", "7e7",
649 "8e7", "9e7", "ae7", "be7", "ce7", "de7", "ee7", "fe7",
650 "0f7", "1f7", "2f7", "3f7", "4f7", "5f7", "6f7", "7f7",
651 "8f7", "9f7", "af7", "bf7", "cf7", "df7", "ef7", "ff7",
652 "008", "108", "208", "308", "408", "508", "608", "708",
653 "808", "908", "a08", "b08", "c08", "d08", "e08", "f08",
654 "018", "118", "218", "318", "418", "518", "618", "718",
655 "818", "918", "a18", "b18", "c18", "d18", "e18", "f18",
656 "028", "128", "228", "328", "428", "528", "628", "728",
657 "828", "928", "a28", "b28", "c28", "d28", "e28", "f28",
658 "038", "138", "238", "338", "438", "538", "638", "738",
659 "838", "938", "a38", "b38", "c38", "d38", "e38", "f38",
660 "048", "148", "248", "348", "448", "548", "648", "748",
661 "848", "948", "a48", "b48", "c48", "d48", "e48", "f48",
662 "058", "158", "258", "358", "458", "558", "658", "758",
663 "858", "958", "a58", "b58", "c58", "d58", "e58", "f58",
664 "068", "168", "268", "368", "468", "568", "668", "768",
665 "868", "968", "a68", "b68", "c68", "d68", "e68", "f68",
666 "078", "178", "278", "378", "478", "578", "678", "778",
667 "878", "978", "a78", "b78", "c78", "d78", "e78", "f78",
668 "088", "188", "288", "388", "488", "588", "688", "788",
669 "888", "988", "a88", "b88", "c88", "d88", "e88", "f88",
670 "098", "198", "298", "398", "498", "598", "698", "798",
671 "898", "998", "a98", "b98", "c98", "d98", "e98", "f98",
672 "0a8", "1a8", "2a8", "3a8", "4a8", "5a8", "6a8", "7a8",
673 "8a8", "9a8", "aa8", "ba8", "ca8", "da8", "ea8", "fa8",
674 "0b8", "1b8", "2b8", "3b8", "4b8", "5b8", "6b8", "7b8",
675 "8b8", "9b8", "ab8", "bb8", "cb8", "db8", "eb8", "fb8",
676 "0c8", "1c8", "2c8", "3c8", "4c8", "5c8", "6c8", "7c8",
677 "8c8", "9c8", "ac8", "bc8", "cc8", "dc8", "ec8", "fc8",
678 "0d8", "1d8", "2d8", "3d8", "4d8", "5d8", "6d8", "7d8",
679 "8d8", "9d8", "ad8", "bd8", "cd8", "dd8", "ed8", "fd8",
680 "0e8", "1e8", "2e8", "3e8", "4e8", "5e8", "6e8", "7e8",
681 "8e8", "9e8", "ae8", "be8", "ce8", "de8", "ee8", "fe8",
682 "0f8", "1f8", "2f8", "3f8", "4f8", "5f8", "6f8", "7f8",
683 "8f8", "9f8", "af8", "bf8", "cf8", "df8", "ef8", "ff8",
684 "009", "109", "209", "309", "409", "509", "609", "709",
685 "809", "909", "a09", "b09", "c09", "d09", "e09", "f09",
686 "019", "119", "219", "319", "419", "519", "619", "719",
687 "819", "919", "a19", "b19", "c19", "d19", "e19", "f19",
688 "029", "129", "229", "329", "429", "529", "629", "729",
689 "829", "929", "a29", "b29", "c29", "d29", "e29", "f29",
690 "039", "139", "239", "339", "439", "539", "639", "739",
691 "839", "939", "a39", "b39", "c39", "d39", "e39", "f39",
692 "049", "149", "249", "349", "449", "549", "649", "749",
693 "849", "949", "a49", "b49", "c49", "d49", "e49", "f49",
694 "059", "159", "259", "359", "459", "559", "659", "759",
695 "859", "959", "a59", "b59", "c59", "d59", "e59", "f59",
696 "069", "169", "269", "369", "469", "569", "669", "769",
697 "869", "969", "a69", "b69", "c69", "d69", "e69", "f69",
698 "079", "179", "279", "379", "479", "579", "679", "779",
699 "879", "979", "a79", "b79", "c79", "d79", "e79", "f79",
700 "089", "189", "289", "389", "489", "589", "689", "789",
701 "889", "989", "a89", "b89", "c89", "d89", "e89", "f89",
702 "099", "199", "299", "399", "499", "599", "699", "799",
703 "899", "999", "a99", "b99", "c99", "d99", "e99", "f99",
704 "0a9", "1a9", "2a9", "3a9", "4a9", "5a9", "6a9", "7a9",
705 "8a9", "9a9", "aa9", "ba9", "ca9", "da9", "ea9", "fa9",
706 "0b9", "1b9", "2b9", "3b9", "4b9", "5b9", "6b9", "7b9",
707 "8b9", "9b9", "ab9", "bb9", "cb9", "db9", "eb9", "fb9",
708 "0c9", "1c9", "2c9", "3c9", "4c9", "5c9", "6c9", "7c9",
709 "8c9", "9c9", "ac9", "bc9", "cc9", "dc9", "ec9", "fc9",
710 "0d9", "1d9", "2d9", "3d9", "4d9", "5d9", "6d9", "7d9",
711 "8d9", "9d9", "ad9", "bd9", "cd9", "dd9", "ed9", "fd9",
712 "0e9", "1e9", "2e9", "3e9", "4e9", "5e9", "6e9", "7e9",
713 "8e9", "9e9", "ae9", "be9", "ce9", "de9", "ee9", "fe9",
714 "0f9", "1f9", "2f9", "3f9", "4f9", "5f9", "6f9", "7f9",
715 "8f9", "9f9", "af9", "bf9", "cf9", "df9", "ef9", "ff9",
716 "00a", "10a", "20a", "30a", "40a", "50a", "60a", "70a",
717 "80a", "90a", "a0a", "b0a", "c0a", "d0a", "e0a", "f0a",
718 "01a", "11a", "21a", "31a", "41a", "51a", "61a", "71a",
719 "81a", "91a", "a1a", "b1a", "c1a", "d1a", "e1a", "f1a",
720 "02a", "12a", "22a", "32a", "42a", "52a", "62a", "72a",
721 "82a", "92a", "a2a", "b2a", "c2a", "d2a", "e2a", "f2a",
722 "03a", "13a", "23a", "33a", "43a", "53a", "63a", "73a",
723 "83a", "93a", "a3a", "b3a", "c3a", "d3a", "e3a", "f3a",
724 "04a", "14a", "24a", "34a", "44a", "54a", "64a", "74a",
725 "84a", "94a", "a4a", "b4a", "c4a", "d4a", "e4a", "f4a",
726 "05a", "15a", "25a", "35a", "45a", "55a", "65a", "75a",
727 "85a", "95a", "a5a", "b5a", "c5a", "d5a", "e5a", "f5a",
728 "06a", "16a", "26a", "36a", "46a", "56a", "66a", "76a",
729 "86a", "96a", "a6a", "b6a", "c6a", "d6a", "e6a", "f6a",
730 "07a", "17a", "27a", "37a", "47a", "57a", "67a", "77a",
731 "87a", "97a", "a7a", "b7a", "c7a", "d7a", "e7a", "f7a",
732 "08a", "18a", "28a", "38a", "48a", "58a", "68a", "78a",
733 "88a", "98a", "a8a", "b8a", "c8a", "d8a", "e8a", "f8a",
734 "09a", "19a", "29a", "39a", "49a", "59a", "69a", "79a",
735 "89a", "99a", "a9a", "b9a", "c9a", "d9a", "e9a", "f9a",
736 "0aa", "1aa", "2aa", "3aa", "4aa", "5aa", "6aa", "7aa",
737 "8aa", "9aa", "aaa", "baa", "caa", "daa", "eaa", "faa",
738 "0ba", "1ba", "2ba", "3ba", "4ba", "5ba", "6ba", "7ba",
739 "8ba", "9ba", "aba", "bba", "cba", "dba", "eba", "fba",
740 "0ca", "1ca", "2ca", "3ca", "4ca", "5ca", "6ca", "7ca",
741 "8ca", "9ca", "aca", "bca", "cca", "dca", "eca", "fca",
742 "0da", "1da", "2da", "3da", "4da", "5da", "6da", "7da",
743 "8da", "9da", "ada", "bda", "cda", "dda", "eda", "fda",
744 "0ea", "1ea", "2ea", "3ea", "4ea", "5ea", "6ea", "7ea",
745 "8ea", "9ea", "aea", "bea", "cea", "dea", "eea", "fea",
746 "0fa", "1fa", "2fa", "3fa", "4fa", "5fa", "6fa", "7fa",
747 "8fa", "9fa", "afa", "bfa", "cfa", "dfa", "efa", "ffa",
748 "00b", "10b", "20b", "30b", "40b", "50b", "60b", "70b",
749 "80b", "90b", "a0b", "b0b", "c0b", "d0b", "e0b", "f0b",
750 "01b", "11b", "21b", "31b", "41b", "51b", "61b", "71b",
751 "81b", "91b", "a1b", "b1b", "c1b", "d1b", "e1b", "f1b",
752 "02b", "12b", "22b", "32b", "42b", "52b", "62b", "72b",
753 "82b", "92b", "a2b", "b2b", "c2b", "d2b", "e2b", "f2b",
754 "03b", "13b", "23b", "33b", "43b", "53b", "63b", "73b",
755 "83b", "93b", "a3b", "b3b", "c3b", "d3b", "e3b", "f3b",
756 "04b", "14b", "24b", "34b", "44b", "54b", "64b", "74b",
757 "84b", "94b", "a4b", "b4b", "c4b", "d4b", "e4b", "f4b",
758 "05b", "15b", "25b", "35b", "45b", "55b", "65b", "75b",
759 "85b", "95b", "a5b", "b5b", "c5b", "d5b", "e5b", "f5b",
760 "06b", "16b", "26b", "36b", "46b", "56b", "66b", "76b",
761 "86b", "96b", "a6b", "b6b", "c6b", "d6b", "e6b", "f6b",
762 "07b", "17b", "27b", "37b", "47b", "57b", "67b", "77b",
763 "87b", "97b", "a7b", "b7b", "c7b", "d7b", "e7b", "f7b",
764 "08b", "18b", "28b", "38b", "48b", "58b", "68b", "78b",
765 "88b", "98b", "a8b", "b8b", "c8b", "d8b", "e8b", "f8b",
766 "09b", "19b", "29b", "39b", "49b", "59b", "69b", "79b",
767 "89b", "99b", "a9b", "b9b", "c9b", "d9b", "e9b", "f9b",
768 "0ab", "1ab", "2ab", "3ab", "4ab", "5ab", "6ab", "7ab",
769 "8ab", "9ab", "aab", "bab", "cab", "dab", "eab", "fab",
770 "0bb", "1bb", "2bb", "3bb", "4bb", "5bb", "6bb", "7bb",
771 "8bb", "9bb", "abb", "bbb", "cbb", "dbb", "ebb", "fbb",
772 "0cb", "1cb", "2cb", "3cb", "4cb", "5cb", "6cb", "7cb",
773 "8cb", "9cb", "acb", "bcb", "ccb", "dcb", "ecb", "fcb",
774 "0db", "1db", "2db", "3db", "4db", "5db", "6db", "7db",
775 "8db", "9db", "adb", "bdb", "cdb", "ddb", "edb", "fdb",
776 "0eb", "1eb", "2eb", "3eb", "4eb", "5eb", "6eb", "7eb",
777 "8eb", "9eb", "aeb", "beb", "ceb", "deb", "eeb", "feb",
778 "0fb", "1fb", "2fb", "3fb", "4fb", "5fb", "6fb", "7fb",
779 "8fb", "9fb", "afb", "bfb", "cfb", "dfb", "efb", "ffb",
780 "00c", "10c", "20c", "30c", "40c", "50c", "60c", "70c",
781 "80c", "90c", "a0c", "b0c", "c0c", "d0c", "e0c", "f0c",
782 "01c", "11c", "21c", "31c", "41c", "51c", "61c", "71c",
783 "81c", "91c", "a1c", "b1c", "c1c", "d1c", "e1c", "f1c",
784 "02c", "12c", "22c", "32c", "42c", "52c", "62c", "72c",
785 "82c", "92c", "a2c", "b2c", "c2c", "d2c", "e2c", "f2c",
786 "03c", "13c", "23c", "33c", "43c", "53c", "63c", "73c",
787 "83c", "93c", "a3c", "b3c", "c3c", "d3c", "e3c", "f3c",
788 "04c", "14c", "24c", "34c", "44c", "54c", "64c", "74c",
789 "84c", "94c", "a4c", "b4c", "c4c", "d4c", "e4c", "f4c",
790 "05c", "15c", "25c", "35c", "45c", "55c", "65c", "75c",
791 "85c", "95c", "a5c", "b5c", "c5c", "d5c", "e5c", "f5c",
792 "06c", "16c", "26c", "36c", "46c", "56c", "66c", "76c",
793 "86c", "96c", "a6c", "b6c", "c6c", "d6c", "e6c", "f6c",
794 "07c", "17c", "27c", "37c", "47c", "57c", "67c", "77c",
795 "87c", "97c", "a7c", "b7c", "c7c", "d7c", "e7c", "f7c",
796 "08c", "18c", "28c", "38c", "48c", "58c", "68c", "78c",
797 "88c", "98c", "a8c", "b8c", "c8c", "d8c", "e8c", "f8c",
798 "09c", "19c", "29c", "39c", "49c", "59c", "69c", "79c",
799 "89c", "99c", "a9c", "b9c", "c9c", "d9c", "e9c", "f9c",
800 "0ac", "1ac", "2ac", "3ac", "4ac", "5ac", "6ac", "7ac",
801 "8ac", "9ac", "aac", "bac", "cac", "dac", "eac", "fac",
802 "0bc", "1bc", "2bc", "3bc", "4bc", "5bc", "6bc", "7bc",
803 "8bc", "9bc", "abc", "bbc", "cbc", "dbc", "ebc", "fbc",
804 "0cc", "1cc", "2cc", "3cc", "4cc", "5cc", "6cc", "7cc",
805 "8cc", "9cc", "acc", "bcc", "ccc", "dcc", "ecc", "fcc",
806 "0dc", "1dc", "2dc", "3dc", "4dc", "5dc", "6dc", "7dc",
807 "8dc", "9dc", "adc", "bdc", "cdc", "ddc", "edc", "fdc",
808 "0ec", "1ec", "2ec", "3ec", "4ec", "5ec", "6ec", "7ec",
809 "8ec", "9ec", "aec", "bec", "cec", "dec", "eec", "fec",
810 "0fc", "1fc", "2fc", "3fc", "4fc", "5fc", "6fc", "7fc",
811 "8fc", "9fc", "afc", "bfc", "cfc", "dfc", "efc", "ffc",
812 "00d", "10d", "20d", "30d", "40d", "50d", "60d", "70d",
813 "80d", "90d", "a0d", "b0d", "c0d", "d0d", "e0d", "f0d",
814 "01d", "11d", "21d", "31d", "41d", "51d", "61d", "71d",
815 "81d", "91d", "a1d", "b1d", "c1d", "d1d", "e1d", "f1d",
816 "02d", "12d", "22d", "32d", "42d", "52d", "62d", "72d",
817 "82d", "92d", "a2d", "b2d", "c2d", "d2d", "e2d", "f2d",
818 "03d", "13d", "23d", "33d", "43d", "53d", "63d", "73d",
819 "83d", "93d", "a3d", "b3d", "c3d", "d3d", "e3d", "f3d",
820 "04d", "14d", "24d", "34d", "44d", "54d", "64d", "74d",
821 "84d", "94d", "a4d", "b4d", "c4d", "d4d", "e4d", "f4d",
822 "05d", "15d", "25d", "35d", "45d", "55d", "65d", "75d",
823 "85d", "95d", "a5d", "b5d", "c5d", "d5d", "e5d", "f5d",
824 "06d", "16d", "26d", "36d", "46d", "56d", "66d", "76d",
825 "86d", "96d", "a6d", "b6d", "c6d", "d6d", "e6d", "f6d",
826 "07d", "17d", "27d", "37d", "47d", "57d", "67d", "77d",
827 "87d", "97d", "a7d", "b7d", "c7d", "d7d", "e7d", "f7d",
828 "08d", "18d", "28d", "38d", "48d", "58d", "68d", "78d",
829 "88d", "98d", "a8d", "b8d", "c8d", "d8d", "e8d", "f8d",
830 "09d", "19d", "29d", "39d", "49d", "59d", "69d", "79d",
831 "89d", "99d", "a9d", "b9d", "c9d", "d9d", "e9d", "f9d",
832 "0ad", "1ad", "2ad", "3ad", "4ad", "5ad", "6ad", "7ad",
833 "8ad", "9ad", "aad", "bad", "cad", "dad", "ead", "fad",
834 "0bd", "1bd", "2bd", "3bd", "4bd", "5bd", "6bd", "7bd",
835 "8bd", "9bd", "abd", "bbd", "cbd", "dbd", "ebd", "fbd",
836 "0cd", "1cd", "2cd", "3cd", "4cd", "5cd", "6cd", "7cd",
837 "8cd", "9cd", "acd", "bcd", "ccd", "dcd", "ecd", "fcd",
838 "0dd", "1dd", "2dd", "3dd", "4dd", "5dd", "6dd", "7dd",
839 "8dd", "9dd", "add", "bdd", "cdd", "ddd", "edd", "fdd",
840 "0ed", "1ed", "2ed", "3ed", "4ed", "5ed", "6ed", "7ed",
841 "8ed", "9ed", "aed", "bed", "ced", "ded", "eed", "fed",
842 "0fd", "1fd", "2fd", "3fd", "4fd", "5fd", "6fd", "7fd",
843 "8fd", "9fd", "afd", "bfd", "cfd", "dfd", "efd", "ffd",
844 "00e", "10e", "20e", "30e", "40e", "50e", "60e", "70e",
845 "80e", "90e", "a0e", "b0e", "c0e", "d0e", "e0e", "f0e",
846 "01e", "11e", "21e", "31e", "41e", "51e", "61e", "71e",
847 "81e", "91e", "a1e", "b1e", "c1e", "d1e", "e1e", "f1e",
848 "02e", "12e", "22e", "32e", "42e", "52e", "62e", "72e",
849 "82e", "92e", "a2e", "b2e", "c2e", "d2e", "e2e", "f2e",
850 "03e", "13e", "23e", "33e", "43e", "53e", "63e", "73e",
851 "83e", "93e", "a3e", "b3e", "c3e", "d3e", "e3e", "f3e",
852 "04e", "14e", "24e", "34e", "44e", "54e", "64e", "74e",
853 "84e", "94e", "a4e", "b4e", "c4e", "d4e", "e4e", "f4e",
854 "05e", "15e", "25e", "35e", "45e", "55e", "65e", "75e",
855 "85e", "95e", "a5e", "b5e", "c5e", "d5e", "e5e", "f5e",
856 "06e", "16e", "26e", "36e", "46e", "56e", "66e", "76e",
857 "86e", "96e", "a6e", "b6e", "c6e", "d6e", "e6e", "f6e",
858 "07e", "17e", "27e", "37e", "47e", "57e", "67e", "77e",
859 "87e", "97e", "a7e", "b7e", "c7e", "d7e", "e7e", "f7e",
860 "08e", "18e", "28e", "38e", "48e", "58e", "68e", "78e",
861 "88e", "98e", "a8e", "b8e", "c8e", "d8e", "e8e", "f8e",
862 "09e", "19e", "29e", "39e", "49e", "59e", "69e", "79e",
863 "89e", "99e", "a9e", "b9e", "c9e", "d9e", "e9e", "f9e",
864 "0ae", "1ae", "2ae", "3ae", "4ae", "5ae", "6ae", "7ae",
865 "8ae", "9ae", "aae", "bae", "cae", "dae", "eae", "fae",
866 "0be", "1be", "2be", "3be", "4be", "5be", "6be", "7be",
867 "8be", "9be", "abe", "bbe", "cbe", "dbe", "ebe", "fbe",
868 "0ce", "1ce", "2ce", "3ce", "4ce", "5ce", "6ce", "7ce",
869 "8ce", "9ce", "ace", "bce", "cce", "dce", "ece", "fce",
870 "0de", "1de", "2de", "3de", "4de", "5de", "6de", "7de",
871 "8de", "9de", "ade", "bde", "cde", "dde", "ede", "fde",
872 "0ee", "1ee", "2ee", "3ee", "4ee", "5ee", "6ee", "7ee",
873 "8ee", "9ee", "aee", "bee", "cee", "dee", "eee", "fee",
874 "0fe", "1fe", "2fe", "3fe", "4fe", "5fe", "6fe", "7fe",
875 "8fe", "9fe", "afe", "bfe", "cfe", "dfe", "efe", "ffe",
876 "00f", "10f", "20f", "30f", "40f", "50f", "60f", "70f",
877 "80f", "90f", "a0f", "b0f", "c0f", "d0f", "e0f", "f0f",
878 "01f", "11f", "21f", "31f", "41f", "51f", "61f", "71f",
879 "81f", "91f", "a1f", "b1f", "c1f", "d1f", "e1f", "f1f",
880 "02f", "12f", "22f", "32f", "42f", "52f", "62f", "72f",
881 "82f", "92f", "a2f", "b2f", "c2f", "d2f", "e2f", "f2f",
882 "03f", "13f", "23f", "33f", "43f", "53f", "63f", "73f",
883 "83f", "93f", "a3f", "b3f", "c3f", "d3f", "e3f", "f3f",
884 "04f", "14f", "24f", "34f", "44f", "54f", "64f", "74f",
885 "84f", "94f", "a4f", "b4f", "c4f", "d4f", "e4f", "f4f",
886 "05f", "15f", "25f", "35f", "45f", "55f", "65f", "75f",
887 "85f", "95f", "a5f", "b5f", "c5f", "d5f", "e5f", "f5f",
888 "06f", "16f", "26f", "36f", "46f", "56f", "66f", "76f",
889 "86f", "96f", "a6f", "b6f", "c6f", "d6f", "e6f", "f6f",
890 "07f", "17f", "27f", "37f", "47f", "57f", "67f", "77f",
891 "87f", "97f", "a7f", "b7f", "c7f", "d7f", "e7f", "f7f",
892 "08f", "18f", "28f", "38f", "48f", "58f", "68f", "78f",
893 "88f", "98f", "a8f", "b8f", "c8f", "d8f", "e8f", "f8f",
894 "09f", "19f", "29f", "39f", "49f", "59f", "69f", "79f",
895 "89f", "99f", "a9f", "b9f", "c9f", "d9f", "e9f", "f9f",
896 "0af", "1af", "2af", "3af", "4af", "5af", "6af", "7af",
897 "8af", "9af", "aaf", "baf", "caf", "daf", "eaf", "faf",
898 "0bf", "1bf", "2bf", "3bf", "4bf", "5bf", "6bf", "7bf",
899 "8bf", "9bf", "abf", "bbf", "cbf", "dbf", "ebf", "fbf",
900 "0cf", "1cf", "2cf", "3cf", "4cf", "5cf", "6cf", "7cf",
901 "8cf", "9cf", "acf", "bcf", "ccf", "dcf", "ecf", "fcf",
902 "0df", "1df", "2df", "3df", "4df", "5df", "6df", "7df",
903 "8df", "9df", "adf", "bdf", "cdf", "ddf", "edf", "fdf",
904 "0ef", "1ef", "2ef", "3ef", "4ef", "5ef", "6ef", "7ef",
905 "8ef", "9ef", "aef", "bef", "cef", "def", "eef", "fef",
906 "0ff", "1ff", "2ff", "3ff", "4ff", "5ff", "6ff", "7ff",
907 "8ff", "9ff", "aff", "bff", "cff", "dff", "eff", "fff"
908 };
909
910 /** string table for upper-case hexadecimal values */
911 static char *HEX[] = {
912 "", "1", "2", "3", "4", "5", "6", "7",
913 "8", "9", "A", "B", "C", "D", "E", "F",
914 "01", "11", "21", "31", "41", "51", "61", "71",
915 "81", "91", "A1", "B1", "C1", "D1", "E1", "F1",
916 "02", "12", "22", "32", "42", "52", "62", "72",
917 "82", "92", "A2", "B2", "C2", "D2", "E2", "F2",
918 "03", "13", "23", "33", "43", "53", "63", "73",
919 "83", "93", "A3", "B3", "C3", "D3", "E3", "F3",
920 "04", "14", "24", "34", "44", "54", "64", "74",
921 "84", "94", "A4", "B4", "C4", "D4", "E4", "F4",
922 "05", "15", "25", "35", "45", "55", "65", "75",
923 "85", "95", "A5", "B5", "C5", "D5", "E5", "F5",
924 "06", "16", "26", "36", "46", "56", "66", "76",
925 "86", "96", "A6", "B6", "C6", "D6", "E6", "F6",
926 "07", "17", "27", "37", "47", "57", "67", "77",
927 "87", "97", "A7", "B7", "C7", "D7", "E7", "F7",
928 "08", "18", "28", "38", "48", "58", "68", "78",
929 "88", "98", "A8", "B8", "C8", "D8", "E8", "F8",
930 "09", "19", "29", "39", "49", "59", "69", "79",
931 "89", "99", "A9", "B9", "C9", "D9", "E9", "F9",
932 "0A", "1A", "2A", "3A", "4A", "5A", "6A", "7A",
933 "8A", "9A", "AA", "BA", "CA", "DA", "EA", "FA",
934 "0B", "1B", "2B", "3B", "4B", "5B", "6B", "7B",
935 "8B", "9B", "AB", "BB", "CB", "DB", "EB", "FB",
936 "0C", "1C", "2C", "3C", "4C", "5C", "6C", "7C",
937 "8C", "9C", "AC", "BC", "CC", "DC", "EC", "FC",
938 "0D", "1D", "2D", "3D", "4D", "5D", "6D", "7D",
939 "8D", "9D", "AD", "BD", "CD", "DD", "ED", "FD",
940 "0E", "1E", "2E", "3E", "4E", "5E", "6E", "7E",
941 "8E", "9E", "AE", "BE", "CE", "DE", "EE", "FE",
942 "0F", "1F", "2F", "3F", "4F", "5F", "6F", "7F",
943 "8F", "9F", "AF", "BF", "CF", "DF", "EF", "FF",
944 "001", "101", "201", "301", "401", "501", "601", "701",
945 "801", "901", "A01", "B01", "C01", "D01", "E01", "F01",
946 "011", "111", "211", "311", "411", "511", "611", "711",
947 "811", "911", "A11", "B11", "C11", "D11", "E11", "F11",
948 "021", "121", "221", "321", "421", "521", "621", "721",
949 "821", "921", "A21", "B21", "C21", "D21", "E21", "F21",
950 "031", "131", "231", "331", "431", "531", "631", "731",
951 "831", "931", "A31", "B31", "C31", "D31", "E31", "F31",
952 "041", "141", "241", "341", "441", "541", "641", "741",
953 "841", "941", "A41", "B41", "C41", "D41", "E41", "F41",
954 "051", "151", "251", "351", "451", "551", "651", "751",
955 "851", "951", "A51", "B51", "C51", "D51", "E51", "F51",
956 "061", "161", "261", "361", "461", "561", "661", "761",
957 "861", "961", "A61", "B61", "C61", "D61", "E61", "F61",
958 "071", "171", "271", "371", "471", "571", "671", "771",
959 "871", "971", "A71", "B71", "C71", "D71", "E71", "F71",
960 "081", "181", "281", "381", "481", "581", "681", "781",
961 "881", "981", "A81", "B81", "C81", "D81", "E81", "F81",
962 "091", "191", "291", "391", "491", "591", "691", "791",
963 "891", "991", "A91", "B91", "C91", "D91", "E91", "F91",
964 "0A1", "1A1", "2A1", "3A1", "4A1", "5A1", "6A1", "7A1",
965 "8A1", "9A1", "AA1", "BA1", "CA1", "DA1", "EA1", "FA1",
966 "0B1", "1B1", "2B1", "3B1", "4B1", "5B1", "6B1", "7B1",
967 "8B1", "9B1", "AB1", "BB1", "CB1", "DB1", "EB1", "FB1",
968 "0C1", "1C1", "2C1", "3C1", "4C1", "5C1", "6C1", "7C1",
969 "8C1", "9C1", "AC1", "BC1", "CC1", "DC1", "EC1", "FC1",
970 "0D1", "1D1", "2D1", "3D1", "4D1", "5D1", "6D1", "7D1",
971 "8D1", "9D1", "AD1", "BD1", "CD1", "DD1", "ED1", "FD1",
972 "0E1", "1E1", "2E1", "3E1", "4E1", "5E1", "6E1", "7E1",
973 "8E1", "9E1", "AE1", "BE1", "CE1", "DE1", "EE1", "FE1",
974 "0F1", "1F1", "2F1", "3F1", "4F1", "5F1", "6F1", "7F1",
975 "8F1", "9F1", "AF1", "BF1", "CF1", "DF1", "EF1", "FF1",
976 "002", "102", "202", "302", "402", "502", "602", "702",
977 "802", "902", "A02", "B02", "C02", "D02", "E02", "F02",
978 "012", "112", "212", "312", "412", "512", "612", "712",
979 "812", "912", "A12", "B12", "C12", "D12", "E12", "F12",
980 "022", "122", "222", "322", "422", "522", "622", "722",
981 "822", "922", "A22", "B22", "C22", "D22", "E22", "F22",
982 "032", "132", "232", "332", "432", "532", "632", "732",
983 "832", "932", "A32", "B32", "C32", "D32", "E32", "F32",
984 "042", "142", "242", "342", "442", "542", "642", "742",
985 "842", "942", "A42", "B42", "C42", "D42", "E42", "F42",
986 "052", "152", "252", "352", "452", "552", "652", "752",
987 "852", "952", "A52", "B52", "C52", "D52", "E52", "F52",
988 "062", "162", "262", "362", "462", "562", "662", "762",
989 "862", "962", "A62", "B62", "C62", "D62", "E62", "F62",
990 "072", "172", "272", "372", "472", "572", "672", "772",
991 "872", "972", "A72", "B72", "C72", "D72", "E72", "F72",
992 "082", "182", "282", "382", "482", "582", "682", "782",
993 "882", "982", "A82", "B82", "C82", "D82", "E82", "F82",
994 "092", "192", "292", "392", "492", "592", "692", "792",
995 "892", "992", "A92", "B92", "C92", "D92", "E92", "F92",
996 "0A2", "1A2", "2A2", "3A2", "4A2", "5A2", "6A2", "7A2",
997 "8A2", "9A2", "AA2", "BA2", "CA2", "DA2", "EA2", "FA2",
998 "0B2", "1B2", "2B2", "3B2", "4B2", "5B2", "6B2", "7B2",
999 "8B2", "9B2", "AB2", "BB2", "CB2", "DB2", "EB2", "FB2",
1000 "0C2", "1C2", "2C2", "3C2", "4C2", "5C2", "6C2", "7C2",
1001 "8C2", "9C2", "AC2", "BC2", "CC2", "DC2", "EC2", "FC2",
1002 "0D2", "1D2", "2D2", "3D2", "4D2", "5D2", "6D2", "7D2",
1003 "8D2", "9D2", "AD2", "BD2", "CD2", "DD2", "ED2", "FD2",
1004 "0E2", "1E2", "2E2", "3E2", "4E2", "5E2", "6E2", "7E2",
1005 "8E2", "9E2", "AE2", "BE2", "CE2", "DE2", "EE2", "FE2",
1006 "0F2", "1F2", "2F2", "3F2", "4F2", "5F2", "6F2", "7F2",
1007 "8F2", "9F2", "AF2", "BF2", "CF2", "DF2", "EF2", "FF2",
1008 "003", "103", "203", "303", "403", "503", "603", "703",
1009 "803", "903", "A03", "B03", "C03", "D03", "E03", "F03",
1010 "013", "113", "213", "313", "413", "513", "613", "713",
1011 "813", "913", "A13", "B13", "C13", "D13", "E13", "F13",
1012 "023", "123", "223", "323", "423", "523", "623", "723",
1013 "823", "923", "A23", "B23", "C23", "D23", "E23", "F23",
1014 "033", "133", "233", "333", "433", "533", "633", "733",
1015 "833", "933", "A33", "B33", "C33", "D33", "E33", "F33",
1016 "043", "143", "243", "343", "443", "543", "643", "743",
1017 "843", "943", "A43", "B43", "C43", "D43", "E43", "F43",
1018 "053", "153", "253", "353", "453", "553", "653", "753",
1019 "853", "953", "A53", "B53", "C53", "D53", "E53", "F53",
1020 "063", "163", "263", "363", "463", "563", "663", "763",
1021 "863", "963", "A63", "B63", "C63", "D63", "E63", "F63",
1022 "073", "173", "273", "373", "473", "573", "673", "773",
1023 "873", "973", "A73", "B73", "C73", "D73", "E73", "F73",
1024 "083", "183", "283", "383", "483", "583", "683", "783",
1025 "883", "983", "A83", "B83", "C83", "D83", "E83", "F83",
1026 "093", "193", "293", "393", "493", "593", "693", "793",
1027 "893", "993", "A93", "B93", "C93", "D93", "E93", "F93",
1028 "0A3", "1A3", "2A3", "3A3", "4A3", "5A3", "6A3", "7A3",
1029 "8A3", "9A3", "AA3", "BA3", "CA3", "DA3", "EA3", "FA3",
1030 "0B3", "1B3", "2B3", "3B3", "4B3", "5B3", "6B3", "7B3",
1031 "8B3", "9B3", "AB3", "BB3", "CB3", "DB3", "EB3", "FB3",
1032 "0C3", "1C3", "2C3", "3C3", "4C3", "5C3", "6C3", "7C3",
1033 "8C3", "9C3", "AC3", "BC3", "CC3", "DC3", "EC3", "FC3",
1034 "0D3", "1D3", "2D3", "3D3", "4D3", "5D3", "6D3", "7D3",
1035 "8D3", "9D3", "AD3", "BD3", "CD3", "DD3", "ED3", "FD3",
1036 "0E3", "1E3", "2E3", "3E3", "4E3", "5E3", "6E3", "7E3",
1037 "8E3", "9E3", "AE3", "BE3", "CE3", "DE3", "EE3", "FE3",
1038 "0F3", "1F3", "2F3", "3F3", "4F3", "5F3", "6F3", "7F3",
1039 "8F3", "9F3", "AF3", "BF3", "CF3", "DF3", "EF3", "FF3",
1040 "004", "104", "204", "304", "404", "504", "604", "704",
1041 "804", "904", "A04", "B04", "C04", "D04", "E04", "F04",
1042 "014", "114", "214", "314", "414", "514", "614", "714",
1043 "814", "914", "A14", "B14", "C14", "D14", "E14", "F14",
1044 "024", "124", "224", "324", "424", "524", "624", "724",
1045 "824", "924", "A24", "B24", "C24", "D24", "E24", "F24",
1046 "034", "134", "234", "334", "434", "534", "634", "734",
1047 "834", "934", "A34", "B34", "C34", "D34", "E34", "F34",
1048 "044", "144", "244", "344", "444", "544", "644", "744",
1049 "844", "944", "A44", "B44", "C44", "D44", "E44", "F44",
1050 "054", "154", "254", "354", "454", "554", "654", "754",
1051 "854", "954", "A54", "B54", "C54", "D54", "E54", "F54",
1052 "064", "164", "264", "364", "464", "564", "664", "764",
1053 "864", "964", "A64", "B64", "C64", "D64", "E64", "F64",
1054 "074", "174", "274", "374", "474", "574", "674", "774",
1055 "874", "974", "A74", "B74", "C74", "D74", "E74", "F74",
1056 "084", "184", "284", "384", "484", "584", "684", "784",
1057 "884", "984", "A84", "B84", "C84", "D84", "E84", "F84",
1058 "094", "194", "294", "394", "494", "594", "694", "794",
1059 "894", "994", "A94", "B94", "C94", "D94", "E94", "F94",
1060 "0A4", "1A4", "2A4", "3A4", "4A4", "5A4", "6A4", "7A4",
1061 "8A4", "9A4", "AA4", "BA4", "CA4", "DA4", "EA4", "FA4",
1062 "0B4", "1B4", "2B4", "3B4", "4B4", "5B4", "6B4", "7B4",
1063 "8B4", "9B4", "AB4", "BB4", "CB4", "DB4", "EB4", "FB4",
1064 "0C4", "1C4", "2C4", "3C4", "4C4", "5C4", "6C4", "7C4",
1065 "8C4", "9C4", "AC4", "BC4", "CC4", "DC4", "EC4", "FC4",
1066 "0D4", "1D4", "2D4", "3D4", "4D4", "5D4", "6D4", "7D4",
1067 "8D4", "9D4", "AD4", "BD4", "CD4", "DD4", "ED4", "FD4",
1068 "0E4", "1E4", "2E4", "3E4", "4E4", "5E4", "6E4", "7E4",
1069 "8E4", "9E4", "AE4", "BE4", "CE4", "DE4", "EE4", "FE4",
1070 "0F4", "1F4", "2F4", "3F4", "4F4", "5F4", "6F4", "7F4",
1071 "8F4", "9F4", "AF4", "BF4", "CF4", "DF4", "EF4", "FF4",
1072 "005", "105", "205", "305", "405", "505", "605", "705",
1073 "805", "905", "A05", "B05", "C05", "D05", "E05", "F05",
1074 "015", "115", "215", "315", "415", "515", "615", "715",
1075 "815", "915", "A15", "B15", "C15", "D15", "E15", "F15",
1076 "025", "125", "225", "325", "425", "525", "625", "725",
1077 "825", "925", "A25", "B25", "C25", "D25", "E25", "F25",
1078 "035", "135", "235", "335", "435", "535", "635", "735",
1079 "835", "935", "A35", "B35", "C35", "D35", "E35", "F35",
1080 "045", "145", "245", "345", "445", "545", "645", "745",
1081 "845", "945", "A45", "B45", "C45", "D45", "E45", "F45",
1082 "055", "155", "255", "355", "455", "555", "655", "755",
1083 "855", "955", "A55", "B55", "C55", "D55", "E55", "F55",
1084 "065", "165", "265", "365", "465", "565", "665", "765",
1085 "865", "965", "A65", "B65", "C65", "D65", "E65", "F65",
1086 "075", "175", "275", "375", "475", "575", "675", "775",
1087 "875", "975", "A75", "B75", "C75", "D75", "E75", "F75",
1088 "085", "185", "285", "385", "485", "585", "685", "785",
1089 "885", "985", "A85", "B85", "C85", "D85", "E85", "F85",
1090 "095", "195", "295", "395", "495", "595", "695", "795",
1091 "895", "995", "A95", "B95", "C95", "D95", "E95", "F95",
1092 "0A5", "1A5", "2A5", "3A5", "4A5", "5A5", "6A5", "7A5",
1093 "8A5", "9A5", "AA5", "BA5", "CA5", "DA5", "EA5", "FA5",
1094 "0B5", "1B5", "2B5", "3B5", "4B5", "5B5", "6B5", "7B5",
1095 "8B5", "9B5", "AB5", "BB5", "CB5", "DB5", "EB5", "FB5",
1096 "0C5", "1C5", "2C5", "3C5", "4C5", "5C5", "6C5", "7C5",
1097 "8C5", "9C5", "AC5", "BC5", "CC5", "DC5", "EC5", "FC5",
1098 "0D5", "1D5", "2D5", "3D5", "4D5", "5D5", "6D5", "7D5",
1099 "8D5", "9D5", "AD5", "BD5", "CD5", "DD5", "ED5", "FD5",
1100 "0E5", "1E5", "2E5", "3E5", "4E5", "5E5", "6E5", "7E5",
1101 "8E5", "9E5", "AE5", "BE5", "CE5", "DE5", "EE5", "FE5",
1102 "0F5", "1F5", "2F5", "3F5", "4F5", "5F5", "6F5", "7F5",
1103 "8F5", "9F5", "AF5", "BF5", "CF5", "DF5", "EF5", "FF5",
1104 "006", "106", "206", "306", "406", "506", "606", "706",
1105 "806", "906", "A06", "B06", "C06", "D06", "E06", "F06",
1106 "016", "116", "216", "316", "416", "516", "616", "716",
1107 "816", "916", "A16", "B16", "C16", "D16", "E16", "F16",
1108 "026", "126", "226", "326", "426", "526", "626", "726",
1109 "826", "926", "A26", "B26", "C26", "D26", "E26", "F26",
1110 "036", "136", "236", "336", "436", "536", "636", "736",
1111 "836", "936", "A36", "B36", "C36", "D36", "E36", "F36",
1112 "046", "146", "246", "346", "446", "546", "646", "746",
1113 "846", "946", "A46", "B46", "C46", "D46", "E46", "F46",
1114 "056", "156", "256", "356", "456", "556", "656", "756",
1115 "856", "956", "A56", "B56", "C56", "D56", "E56", "F56",
1116 "066", "166", "266", "366", "466", "566", "666", "766",
1117 "866", "966", "A66", "B66", "C66", "D66", "E66", "F66",
1118 "076", "176", "276", "376", "476", "576", "676", "776",
1119 "876", "976", "A76", "B76", "C76", "D76", "E76", "F76",
1120 "086", "186", "286", "386", "486", "586", "686", "786",
1121 "886", "986", "A86", "B86", "C86", "D86", "E86", "F86",
1122 "096", "196", "296", "396", "496", "596", "696", "796",
1123 "896", "996", "A96", "B96", "C96", "D96", "E96", "F96",
1124 "0A6", "1A6", "2A6", "3A6", "4A6", "5A6", "6A6", "7A6",
1125 "8A6", "9A6", "AA6", "BA6", "CA6", "DA6", "EA6", "FA6",
1126 "0B6", "1B6", "2B6", "3B6", "4B6", "5B6", "6B6", "7B6",
1127 "8B6", "9B6", "AB6", "BB6", "CB6", "DB6", "EB6", "FB6",
1128 "0C6", "1C6", "2C6", "3C6", "4C6", "5C6", "6C6", "7C6",
1129 "8C6", "9C6", "AC6", "BC6", "CC6", "DC6", "EC6", "FC6",
1130 "0D6", "1D6", "2D6", "3D6", "4D6", "5D6", "6D6", "7D6",
1131 "8D6", "9D6", "AD6", "BD6", "CD6", "DD6", "ED6", "FD6",
1132 "0E6", "1E6", "2E6", "3E6", "4E6", "5E6", "6E6", "7E6",
1133 "8E6", "9E6", "AE6", "BE6", "CE6", "DE6", "EE6", "FE6",
1134 "0F6", "1F6", "2F6", "3F6", "4F6", "5F6", "6F6", "7F6",
1135 "8F6", "9F6", "AF6", "BF6", "CF6", "DF6", "EF6", "FF6",
1136 "007", "107", "207", "307", "407", "507", "607", "707",
1137 "807", "907", "A07", "B07", "C07", "D07", "E07", "F07",
1138 "017", "117", "217", "317", "417", "517", "617", "717",
1139 "817", "917", "A17", "B17", "C17", "D17", "E17", "F17",
1140 "027", "127", "227", "327", "427", "527", "627", "727",
1141 "827", "927", "A27", "B27", "C27", "D27", "E27", "F27",
1142 "037", "137", "237", "337", "437", "537", "637", "737",
1143 "837", "937", "A37", "B37", "C37", "D37", "E37", "F37",
1144 "047", "147", "247", "347", "447", "547", "647", "747",
1145 "847", "947", "A47", "B47", "C47", "D47", "E47", "F47",
1146 "057", "157", "257", "357", "457", "557", "657", "757",
1147 "857", "957", "A57", "B57", "C57", "D57", "E57", "F57",
1148 "067", "167", "267", "367", "467", "567", "667", "767",
1149 "867", "967", "A67", "B67", "C67", "D67", "E67", "F67",
1150 "077", "177", "277", "377", "477", "577", "677", "777",
1151 "877", "977", "A77", "B77", "C77", "D77", "E77", "F77",
1152 "087", "187", "287", "387", "487", "587", "687", "787",
1153 "887", "987", "A87", "B87", "C87", "D87", "E87", "F87",
1154 "097", "197", "297", "397", "497", "597", "697", "797",
1155 "897", "997", "A97", "B97", "C97", "D97", "E97", "F97",
1156 "0A7", "1A7", "2A7", "3A7", "4A7", "5A7", "6A7", "7A7",
1157 "8A7", "9A7", "AA7", "BA7", "CA7", "DA7", "EA7", "FA7",
1158 "0B7", "1B7", "2B7", "3B7", "4B7", "5B7", "6B7", "7B7",
1159 "8B7", "9B7", "AB7", "BB7", "CB7", "DB7", "EB7", "FB7",
1160 "0C7", "1C7", "2C7", "3C7", "4C7", "5C7", "6C7", "7C7",
1161 "8C7", "9C7", "AC7", "BC7", "CC7", "DC7", "EC7", "FC7",
1162 "0D7", "1D7", "2D7", "3D7", "4D7", "5D7", "6D7", "7D7",
1163 "8D7", "9D7", "AD7", "BD7", "CD7", "DD7", "ED7", "FD7",
1164 "0E7", "1E7", "2E7", "3E7", "4E7", "5E7", "6E7", "7E7",
1165 "8E7", "9E7", "AE7", "BE7", "CE7", "DE7", "EE7", "FE7",
1166 "0F7", "1F7", "2F7", "3F7", "4F7", "5F7", "6F7", "7F7",
1167 "8F7", "9F7", "AF7", "BF7", "CF7", "DF7", "EF7", "FF7",
1168 "008", "108", "208", "308", "408", "508", "608", "708",
1169 "808", "908", "A08", "B08", "C08", "D08", "E08", "F08",
1170 "018", "118", "218", "318", "418", "518", "618", "718",
1171 "818", "918", "A18", "B18", "C18", "D18", "E18", "F18",
1172 "028", "128", "228", "328", "428", "528", "628", "728",
1173 "828", "928", "A28", "B28", "C28", "D28", "E28", "F28",
1174 "038", "138", "238", "338", "438", "538", "638", "738",
1175 "838", "938", "A38", "B38", "C38", "D38", "E38", "F38",
1176 "048", "148", "248", "348", "448", "548", "648", "748",
1177 "848", "948", "A48", "B48", "C48", "D48", "E48", "F48",
1178 "058", "158", "258", "358", "458", "558", "658", "758",
1179 "858", "958", "A58", "B58", "C58", "D58", "E58", "F58",
1180 "068", "168", "268", "368", "468", "568", "668", "768",
1181 "868", "968", "A68", "B68", "C68", "D68", "E68", "F68",
1182 "078", "178", "278", "378", "478", "578", "678", "778",
1183 "878", "978", "A78", "B78", "C78", "D78", "E78", "F78",
1184 "088", "188", "288", "388", "488", "588", "688", "788",
1185 "888", "988", "A88", "B88", "C88", "D88", "E88", "F88",
1186 "098", "198", "298", "398", "498", "598", "698", "798",
1187 "898", "998", "A98", "B98", "C98", "D98", "E98", "F98",
1188 "0A8", "1A8", "2A8", "3A8", "4A8", "5A8", "6A8", "7A8",
1189 "8A8", "9A8", "AA8", "BA8", "CA8", "DA8", "EA8", "FA8",
1190 "0B8", "1B8", "2B8", "3B8", "4B8", "5B8", "6B8", "7B8",
1191 "8B8", "9B8", "AB8", "BB8", "CB8", "DB8", "EB8", "FB8",
1192 "0C8", "1C8", "2C8", "3C8", "4C8", "5C8", "6C8", "7C8",
1193 "8C8", "9C8", "AC8", "BC8", "CC8", "DC8", "EC8", "FC8",
1194 "0D8", "1D8", "2D8", "3D8", "4D8", "5D8", "6D8", "7D8",
1195 "8D8", "9D8", "AD8", "BD8", "CD8", "DD8", "ED8", "FD8",
1196 "0E8", "1E8", "2E8", "3E8", "4E8", "5E8", "6E8", "7E8",
1197 "8E8", "9E8", "AE8", "BE8", "CE8", "DE8", "EE8", "FE8",
1198 "0F8", "1F8", "2F8", "3F8", "4F8", "5F8", "6F8", "7F8",
1199 "8F8", "9F8", "AF8", "BF8", "CF8", "DF8", "EF8", "FF8",
1200 "009", "109", "209", "309", "409", "509", "609", "709",
1201 "809", "909", "A09", "B09", "C09", "D09", "E09", "F09",
1202 "019", "119", "219", "319", "419", "519", "619", "719",
1203 "819", "919", "A19", "B19", "C19", "D19", "E19", "F19",
1204 "029", "129", "229", "329", "429", "529", "629", "729",
1205 "829", "929", "A29", "B29", "C29", "D29", "E29", "F29",
1206 "039", "139", "239", "339", "439", "539", "639", "739",
1207 "839", "939", "A39", "B39", "C39", "D39", "E39", "F39",
1208 "049", "149", "249", "349", "449", "549", "649", "749",
1209 "849", "949", "A49", "B49", "C49", "D49", "E49", "F49",
1210 "059", "159", "259", "359", "459", "559", "659", "759",
1211 "859", "959", "A59", "B59", "C59", "D59", "E59", "F59",
1212 "069", "169", "269", "369", "469", "569", "669", "769",
1213 "869", "969", "A69", "B69", "C69", "D69", "E69", "F69",
1214 "079", "179", "279", "379", "479", "579", "679", "779",
1215 "879", "979", "A79", "B79", "C79", "D79", "E79", "F79",
1216 "089", "189", "289", "389", "489", "589", "689", "789",
1217 "889", "989", "A89", "B89", "C89", "D89", "E89", "F89",
1218 "099", "199", "299", "399", "499", "599", "699", "799",
1219 "899", "999", "A99", "B99", "C99", "D99", "E99", "F99",
1220 "0A9", "1A9", "2A9", "3A9", "4A9", "5A9", "6A9", "7A9",
1221 "8A9", "9A9", "AA9", "BA9", "CA9", "DA9", "EA9", "FA9",
1222 "0B9", "1B9", "2B9", "3B9", "4B9", "5B9", "6B9", "7B9",
1223 "8B9", "9B9", "AB9", "BB9", "CB9", "DB9", "EB9", "FB9",
1224 "0C9", "1C9", "2C9", "3C9", "4C9", "5C9", "6C9", "7C9",
1225 "8C9", "9C9", "AC9", "BC9", "CC9", "DC9", "EC9", "FC9",
1226 "0D9", "1D9", "2D9", "3D9", "4D9", "5D9", "6D9", "7D9",
1227 "8D9", "9D9", "AD9", "BD9", "CD9", "DD9", "ED9", "FD9",
1228 "0E9", "1E9", "2E9", "3E9", "4E9", "5E9", "6E9", "7E9",
1229 "8E9", "9E9", "AE9", "BE9", "CE9", "DE9", "EE9", "FE9",
1230 "0F9", "1F9", "2F9", "3F9", "4F9", "5F9", "6F9", "7F9",
1231 "8F9", "9F9", "AF9", "BF9", "CF9", "DF9", "EF9", "FF9",
1232 "00A", "10A", "20A", "30A", "40A", "50A", "60A", "70A",
1233 "80A", "90A", "A0A", "B0A", "C0A", "D0A", "E0A", "F0A",
1234 "01A", "11A", "21A", "31A", "41A", "51A", "61A", "71A",
1235 "81A", "91A", "A1A", "B1A", "C1A", "D1A", "E1A", "F1A",
1236 "02A", "12A", "22A", "32A", "42A", "52A", "62A", "72A",
1237 "82A", "92A", "A2A", "B2A", "C2A", "D2A", "E2A", "F2A",
1238 "03A", "13A", "23A", "33A", "43A", "53A", "63A", "73A",
1239 "83A", "93A", "A3A", "B3A", "C3A", "D3A", "E3A", "F3A",
1240 "04A", "14A", "24A", "34A", "44A", "54A", "64A", "74A",
1241 "84A", "94A", "A4A", "B4A", "C4A", "D4A", "E4A", "F4A",
1242 "05A", "15A", "25A", "35A", "45A", "55A", "65A", "75A",
1243 "85A", "95A", "A5A", "B5A", "C5A", "D5A", "E5A", "F5A",
1244 "06A", "16A", "26A", "36A", "46A", "56A", "66A", "76A",
1245 "86A", "96A", "A6A", "B6A", "C6A", "D6A", "E6A", "F6A",
1246 "07A", "17A", "27A", "37A", "47A", "57A", "67A", "77A",
1247 "87A", "97A", "A7A", "B7A", "C7A", "D7A", "E7A", "F7A",
1248 "08A", "18A", "28A", "38A", "48A", "58A", "68A", "78A",
1249 "88A", "98A", "A8A", "B8A", "C8A", "D8A", "E8A", "F8A",
1250 "09A", "19A", "29A", "39A", "49A", "59A", "69A", "79A",
1251 "89A", "99A", "A9A", "B9A", "C9A", "D9A", "E9A", "F9A",
1252 "0AA", "1AA", "2AA", "3AA", "4AA", "5AA", "6AA", "7AA",
1253 "8AA", "9AA", "AAA", "BAA", "CAA", "DAA", "EAA", "FAA",
1254 "0BA", "1BA", "2BA", "3BA", "4BA", "5BA", "6BA", "7BA",
1255 "8BA", "9BA", "ABA", "BBA", "CBA", "DBA", "EBA", "FBA",
1256 "0CA", "1CA", "2CA", "3CA", "4CA", "5CA", "6CA", "7CA",
1257 "8CA", "9CA", "ACA", "BCA", "CCA", "DCA", "ECA", "FCA",
1258 "0DA", "1DA", "2DA", "3DA", "4DA", "5DA", "6DA", "7DA",
1259 "8DA", "9DA", "ADA", "BDA", "CDA", "DDA", "EDA", "FDA",
1260 "0EA", "1EA", "2EA", "3EA", "4EA", "5EA", "6EA", "7EA",
1261 "8EA", "9EA", "AEA", "BEA", "CEA", "DEA", "EEA", "FEA",
1262 "0FA", "1FA", "2FA", "3FA", "4FA", "5FA", "6FA", "7FA",
1263 "8FA", "9FA", "AFA", "BFA", "CFA", "DFA", "EFA", "FFA",
1264 "00B", "10B", "20B", "30B", "40B", "50B", "60B", "70B",
1265 "80B", "90B", "A0B", "B0B", "C0B", "D0B", "E0B", "F0B",
1266 "01B", "11B", "21B", "31B", "41B", "51B", "61B", "71B",
1267 "81B", "91B", "A1B", "B1B", "C1B", "D1B", "E1B", "F1B",
1268 "02B", "12B", "22B", "32B", "42B", "52B", "62B", "72B",
1269 "82B", "92B", "A2B", "B2B", "C2B", "D2B", "E2B", "F2B",
1270 "03B", "13B", "23B", "33B", "43B", "53B", "63B", "73B",
1271 "83B", "93B", "A3B", "B3B", "C3B", "D3B", "E3B", "F3B",
1272 "04B", "14B", "24B", "34B", "44B", "54B", "64B", "74B",
1273 "84B", "94B", "A4B", "B4B", "C4B", "D4B", "E4B", "F4B",
1274 "05B", "15B", "25B", "35B", "45B", "55B", "65B", "75B",
1275 "85B", "95B", "A5B", "B5B", "C5B", "D5B", "E5B", "F5B",
1276 "06B", "16B", "26B", "36B", "46B", "56B", "66B", "76B",
1277 "86B", "96B", "A6B", "B6B", "C6B", "D6B", "E6B", "F6B",
1278 "07B", "17B", "27B", "37B", "47B", "57B", "67B", "77B",
1279 "87B", "97B", "A7B", "B7B", "C7B", "D7B", "E7B", "F7B",
1280 "08B", "18B", "28B", "38B", "48B", "58B", "68B", "78B",
1281 "88B", "98B", "A8B", "B8B", "C8B", "D8B", "E8B", "F8B",
1282 "09B", "19B", "29B", "39B", "49B", "59B", "69B", "79B",
1283 "89B", "99B", "A9B", "B9B", "C9B", "D9B", "E9B", "F9B",
1284 "0AB", "1AB", "2AB", "3AB", "4AB", "5AB", "6AB", "7AB",
1285 "8AB", "9AB", "AAB", "BAB", "CAB", "DAB", "EAB", "FAB",
1286 "0BB", "1BB", "2BB", "3BB", "4BB", "5BB", "6BB", "7BB",
1287 "8BB", "9BB", "ABB", "BBB", "CBB", "DBB", "EBB", "FBB",
1288 "0CB", "1CB", "2CB", "3CB", "4CB", "5CB", "6CB", "7CB",
1289 "8CB", "9CB", "ACB", "BCB", "CCB", "DCB", "ECB", "FCB",
1290 "0DB", "1DB", "2DB", "3DB", "4DB", "5DB", "6DB", "7DB",
1291 "8DB", "9DB", "ADB", "BDB", "CDB", "DDB", "EDB", "FDB",
1292 "0EB", "1EB", "2EB", "3EB", "4EB", "5EB", "6EB", "7EB",
1293 "8EB", "9EB", "AEB", "BEB", "CEB", "DEB", "EEB", "FEB",
1294 "0FB", "1FB", "2FB", "3FB", "4FB", "5FB", "6FB", "7FB",
1295 "8FB", "9FB", "AFB", "BFB", "CFB", "DFB", "EFB", "FFB",
1296 "00C", "10C", "20C", "30C", "40C", "50C", "60C", "70C",
1297 "80C", "90C", "A0C", "B0C", "C0C", "D0C", "E0C", "F0C",
1298 "01C", "11C", "21C", "31C", "41C", "51C", "61C", "71C",
1299 "81C", "91C", "A1C", "B1C", "C1C", "D1C", "E1C", "F1C",
1300 "02C", "12C", "22C", "32C", "42C", "52C", "62C", "72C",
1301 "82C", "92C", "A2C", "B2C", "C2C", "D2C", "E2C", "F2C",
1302 "03C", "13C", "23C", "33C", "43C", "53C", "63C", "73C",
1303 "83C", "93C", "A3C", "B3C", "C3C", "D3C", "E3C", "F3C",
1304 "04C", "14C", "24C", "34C", "44C", "54C", "64C", "74C",
1305 "84C", "94C", "A4C", "B4C", "C4C", "D4C", "E4C", "F4C",
1306 "05C", "15C", "25C", "35C", "45C", "55C", "65C", "75C",
1307 "85C", "95C", "A5C", "B5C", "C5C", "D5C", "E5C", "F5C",
1308 "06C", "16C", "26C", "36C", "46C", "56C", "66C", "76C",
1309 "86C", "96C", "A6C", "B6C", "C6C", "D6C", "E6C", "F6C",
1310 "07C", "17C", "27C", "37C", "47C", "57C", "67C", "77C",
1311 "87C", "97C", "A7C", "B7C", "C7C", "D7C", "E7C", "F7C",
1312 "08C", "18C", "28C", "38C", "48C", "58C", "68C", "78C",
1313 "88C", "98C", "A8C", "B8C", "C8C", "D8C", "E8C", "F8C",
1314 "09C", "19C", "29C", "39C", "49C", "59C", "69C", "79C",
1315 "89C", "99C", "A9C", "B9C", "C9C", "D9C", "E9C", "F9C",
1316 "0AC", "1AC", "2AC", "3AC", "4AC", "5AC", "6AC", "7AC",
1317 "8AC", "9AC", "AAC", "BAC", "CAC", "DAC", "EAC", "FAC",
1318 "0BC", "1BC", "2BC", "3BC", "4BC", "5BC", "6BC", "7BC",
1319 "8BC", "9BC", "ABC", "BBC", "CBC", "DBC", "EBC", "FBC",
1320 "0CC", "1CC", "2CC", "3CC", "4CC", "5CC", "6CC", "7CC",
1321 "8CC", "9CC", "ACC", "BCC", "CCC", "DCC", "ECC", "FCC",
1322 "0DC", "1DC", "2DC", "3DC", "4DC", "5DC", "6DC", "7DC",
1323 "8DC", "9DC", "ADC", "BDC", "CDC", "DDC", "EDC", "FDC",
1324 "0EC", "1EC", "2EC", "3EC", "4EC", "5EC", "6EC", "7EC",
1325 "8EC", "9EC", "AEC", "BEC", "CEC", "DEC", "EEC", "FEC",
1326 "0FC", "1FC", "2FC", "3FC", "4FC", "5FC", "6FC", "7FC",
1327 "8FC", "9FC", "AFC", "BFC", "CFC", "DFC", "EFC", "FFC",
1328 "00D", "10D", "20D", "30D", "40D", "50D", "60D", "70D",
1329 "80D", "90D", "A0D", "B0D", "C0D", "D0D", "E0D", "F0D",
1330 "01D", "11D", "21D", "31D", "41D", "51D", "61D", "71D",
1331 "81D", "91D", "A1D", "B1D", "C1D", "D1D", "E1D", "F1D",
1332 "02D", "12D", "22D", "32D", "42D", "52D", "62D", "72D",
1333 "82D", "92D", "A2D", "B2D", "C2D", "D2D", "E2D", "F2D",
1334 "03D", "13D", "23D", "33D", "43D", "53D", "63D", "73D",
1335 "83D", "93D", "A3D", "B3D", "C3D", "D3D", "E3D", "F3D",
1336 "04D", "14D", "24D", "34D", "44D", "54D", "64D", "74D",
1337 "84D", "94D", "A4D", "B4D", "C4D", "D4D", "E4D", "F4D",
1338 "05D", "15D", "25D", "35D", "45D", "55D", "65D", "75D",
1339 "85D", "95D", "A5D", "B5D", "C5D", "D5D", "E5D", "F5D",
1340 "06D", "16D", "26D", "36D", "46D", "56D", "66D", "76D",
1341 "86D", "96D", "A6D", "B6D", "C6D", "D6D", "E6D", "F6D",
1342 "07D", "17D", "27D", "37D", "47D", "57D", "67D", "77D",
1343 "87D", "97D", "A7D", "B7D", "C7D", "D7D", "E7D", "F7D",
1344 "08D", "18D", "28D", "38D", "48D", "58D", "68D", "78D",
1345 "88D", "98D", "A8D", "B8D", "C8D", "D8D", "E8D", "F8D",
1346 "09D", "19D", "29D", "39D", "49D", "59D", "69D", "79D",
1347 "89D", "99D", "A9D", "B9D", "C9D", "D9D", "E9D", "F9D",
1348 "0AD", "1AD", "2AD", "3AD", "4AD", "5AD", "6AD", "7AD",
1349 "8AD", "9AD", "AAD", "BAD", "CAD", "DAD", "EAD", "FAD",
1350 "0BD", "1BD", "2BD", "3BD", "4BD", "5BD", "6BD", "7BD",
1351 "8BD", "9BD", "ABD", "BBD", "CBD", "DBD", "EBD", "FBD",
1352 "0CD", "1CD", "2CD", "3CD", "4CD", "5CD", "6CD", "7CD",
1353 "8CD", "9CD", "ACD", "BCD", "CCD", "DCD", "ECD", "FCD",
1354 "0DD", "1DD", "2DD", "3DD", "4DD", "5DD", "6DD", "7DD",
1355 "8DD", "9DD", "ADD", "BDD", "CDD", "DDD", "EDD", "FDD",
1356 "0ED", "1ED", "2ED", "3ED", "4ED", "5ED", "6ED", "7ED",
1357 "8ED", "9ED", "AED", "BED", "CED", "DED", "EED", "FED",
1358 "0FD", "1FD", "2FD", "3FD", "4FD", "5FD", "6FD", "7FD",
1359 "8FD", "9FD", "AFD", "BFD", "CFD", "DFD", "EFD", "FFD",
1360 "00E", "10E", "20E", "30E", "40E", "50E", "60E", "70E",
1361 "80E", "90E", "A0E", "B0E", "C0E", "D0E", "E0E", "F0E",
1362 "01E", "11E", "21E", "31E", "41E", "51E", "61E", "71E",
1363 "81E", "91E", "A1E", "B1E", "C1E", "D1E", "E1E", "F1E",
1364 "02E", "12E", "22E", "32E", "42E", "52E", "62E", "72E",
1365 "82E", "92E", "A2E", "B2E", "C2E", "D2E", "E2E", "F2E",
1366 "03E", "13E", "23E", "33E", "43E", "53E", "63E", "73E",
1367 "83E", "93E", "A3E", "B3E", "C3E", "D3E", "E3E", "F3E",
1368 "04E", "14E", "24E", "34E", "44E", "54E", "64E", "74E",
1369 "84E", "94E", "A4E", "B4E", "C4E", "D4E", "E4E", "F4E",
1370 "05E", "15E", "25E", "35E", "45E", "55E", "65E", "75E",
1371 "85E", "95E", "A5E", "B5E", "C5E", "D5E", "E5E", "F5E",
1372 "06E", "16E", "26E", "36E", "46E", "56E", "66E", "76E",
1373 "86E", "96E", "A6E", "B6E", "C6E", "D6E", "E6E", "F6E",
1374 "07E", "17E", "27E", "37E", "47E", "57E", "67E", "77E",
1375 "87E", "97E", "A7E", "B7E", "C7E", "D7E", "E7E", "F7E",
1376 "08E", "18E", "28E", "38E", "48E", "58E", "68E", "78E",
1377 "88E", "98E", "A8E", "B8E", "C8E", "D8E", "E8E", "F8E",
1378 "09E", "19E", "29E", "39E", "49E", "59E", "69E", "79E",
1379 "89E", "99E", "A9E", "B9E", "C9E", "D9E", "E9E", "F9E",
1380 "0AE", "1AE", "2AE", "3AE", "4AE", "5AE", "6AE", "7AE",
1381 "8AE", "9AE", "AAE", "BAE", "CAE", "DAE", "EAE", "FAE",
1382 "0BE", "1BE", "2BE", "3BE", "4BE", "5BE", "6BE", "7BE",
1383 "8BE", "9BE", "ABE", "BBE", "CBE", "DBE", "EBE", "FBE",
1384 "0CE", "1CE", "2CE", "3CE", "4CE", "5CE", "6CE", "7CE",
1385 "8CE", "9CE", "ACE", "BCE", "CCE", "DCE", "ECE", "FCE",
1386 "0DE", "1DE", "2DE", "3DE", "4DE", "5DE", "6DE", "7DE",
1387 "8DE", "9DE", "ADE", "BDE", "CDE", "DDE", "EDE", "FDE",
1388 "0EE", "1EE", "2EE", "3EE", "4EE", "5EE", "6EE", "7EE",
1389 "8EE", "9EE", "AEE", "BEE", "CEE", "DEE", "EEE", "FEE",
1390 "0FE", "1FE", "2FE", "3FE", "4FE", "5FE", "6FE", "7FE",
1391 "8FE", "9FE", "AFE", "BFE", "CFE", "DFE", "EFE", "FFE",
1392 "00F", "10F", "20F", "30F", "40F", "50F", "60F", "70F",
1393 "80F", "90F", "A0F", "B0F", "C0F", "D0F", "E0F", "F0F",
1394 "01F", "11F", "21F", "31F", "41F", "51F", "61F", "71F",
1395 "81F", "91F", "A1F", "B1F", "C1F", "D1F", "E1F", "F1F",
1396 "02F", "12F", "22F", "32F", "42F", "52F", "62F", "72F",
1397 "82F", "92F", "A2F", "B2F", "C2F", "D2F", "E2F", "F2F",
1398 "03F", "13F", "23F", "33F", "43F", "53F", "63F", "73F",
1399 "83F", "93F", "A3F", "B3F", "C3F", "D3F", "E3F", "F3F",
1400 "04F", "14F", "24F", "34F", "44F", "54F", "64F", "74F",
1401 "84F", "94F", "A4F", "B4F", "C4F", "D4F", "E4F", "F4F",
1402 "05F", "15F", "25F", "35F", "45F", "55F", "65F", "75F",
1403 "85F", "95F", "A5F", "B5F", "C5F", "D5F", "E5F", "F5F",
1404 "06F", "16F", "26F", "36F", "46F", "56F", "66F", "76F",
1405 "86F", "96F", "A6F", "B6F", "C6F", "D6F", "E6F", "F6F",
1406 "07F", "17F", "27F", "37F", "47F", "57F", "67F", "77F",
1407 "87F", "97F", "A7F", "B7F", "C7F", "D7F", "E7F", "F7F",
1408 "08F", "18F", "28F", "38F", "48F", "58F", "68F", "78F",
1409 "88F", "98F", "A8F", "B8F", "C8F", "D8F", "E8F", "F8F",
1410 "09F", "19F", "29F", "39F", "49F", "59F", "69F", "79F",
1411 "89F", "99F", "A9F", "B9F", "C9F", "D9F", "E9F", "F9F",
1412 "0AF", "1AF", "2AF", "3AF", "4AF", "5AF", "6AF", "7AF",
1413 "8AF", "9AF", "AAF", "BAF", "CAF", "DAF", "EAF", "FAF",
1414 "0BF", "1BF", "2BF", "3BF", "4BF", "5BF", "6BF", "7BF",
1415 "8BF", "9BF", "ABF", "BBF", "CBF", "DBF", "EBF", "FBF",
1416 "0CF", "1CF", "2CF", "3CF", "4CF", "5CF", "6CF", "7CF",
1417 "8CF", "9CF", "ACF", "BCF", "CCF", "DCF", "ECF", "FCF",
1418 "0DF", "1DF", "2DF", "3DF", "4DF", "5DF", "6DF", "7DF",
1419 "8DF", "9DF", "ADF", "BDF", "CDF", "DDF", "EDF", "FDF",
1420 "0EF", "1EF", "2EF", "3EF", "4EF", "5EF", "6EF", "7EF",
1421 "8EF", "9EF", "AEF", "BEF", "CEF", "DEF", "EEF", "FEF",
1422 "0FF", "1FF", "2FF", "3FF", "4FF", "5FF", "6FF", "7FF",
1423 "8FF", "9FF", "AFF", "BFF", "CFF", "DFF", "EFF", "FFF"
1424 };
1425
1426 /** Append a single character to an output buffer.
1427 * @param[in,out] buf_p Buffer to append to.
1428 * @param[in] c Character to append.
1429 */
1430 static void
1431 addc(struct BufData *buf_p, int c)
1432 {
1433 int overflow = 0;
1434
1435 if (buf_p->limit == 0) { /* We've gone past the limit... */
1436 buf_p->overflow++;
1437 overflow++;
1438 } else if (buf_p->limit > 0) /* update the limit */
1439 buf_p->limit--;
1440
1441 if (buf_p->buf_loc >= buf_p->buf_size) { /* We've gone past buffer */
1442 buf_p->buf_overflow++;
1443 overflow++;
1444 }
1445
1446 if (!overflow) /* add the character to the buffer */
1447 buf_p->buf[buf_p->buf_loc++] = c;
1448 }
1449
1450 /** Append a string to an output buffer.
1451 * @param[in,out] buf_p Buffer to append to.
1452 * @param[in] s_len Length of string to append.
1453 * @param[in] s String to append.
1454 */
1455 static void
1456 adds(struct BufData *buf_p, int s_len, const char *s)
1457 {
1458 int overflow = 0;
1459
1460 /* while the string exists and has non-zero length */
1461 while (s_len && *s)
1462 {
1463 /* poor man's inlining; see addc(), above */
1464 if (buf_p->limit == 0) { /* We've gone past the limit... */
1465 buf_p->overflow++;
1466 overflow++;
1467 } else if (buf_p->limit > 0) /* update the limit */
1468 buf_p->limit--;
1469
1470 if (buf_p->buf_loc >= buf_p->buf_size) { /* We've gone past buffer */
1471 buf_p->buf_overflow++;
1472 overflow++;
1473 }
1474
1475 if (!overflow) /* add the character to the buffer */
1476 buf_p->buf[buf_p->buf_loc++] = *s;
1477
1478 s++; /* advance to next character */
1479 if (s_len > 0) /* update string length left to copy */
1480 s_len--;
1481 }
1482 }
1483
1484 /** Add certain padding to an output buffer.
1485 * @param[in,out] buf_p Buffer to append to.
1486 * @param[in] padlen Length of padding to add.
1487 * @param[in] pad Padding string (at least PAD_LENGTH bytes long).
1488 */
1489 static void
1490 do_pad(struct BufData *buf_p, int padlen, char *pad)
1491 {
1492 /* do chunks of PAD_LENGTH first */
1493 for (; padlen > PAD_LENGTH; padlen -= PAD_LENGTH)
1494 adds(buf_p, PAD_LENGTH, pad);
1495
1496 /* add any left-over padding */
1497 adds(buf_p, padlen, pad);
1498 }
1499
1500 /** Return length of string, up to a maximum.
1501 * @param[in] str String to find length for.
1502 * @param[in] maxlen Maximum value to return.
1503 * @return Minimum of \a maxlen and length of \a str.
1504 */
1505 static int
1506 my_strnlen(const char *str, int maxlen)
1507 {
1508 int len = 0;
1509
1510 while (*str++ && maxlen--)
1511 len++;
1512
1513 return len;
1514 }
1515
1516 /** Workhorse printing function.
1517 * @param[in] dest Client to format the message.
1518 * @param[in,out] buf_p Description of output buffer.
1519 * @param[in] fmt Message format string.
1520 * @param[in] vp Variable-length argument list for format string.
1521 */
1522 static void
1523 doprintf(struct Client *dest, struct BufData *buf_p, const char *fmt,
1524 va_list vp)
1525 {
1526 enum {
1527 FLAG, /* Gathering flags */
1528 WIDTH, /* Gathering field width */
1529 DOT, /* Found a dot */
1530 PREC, /* Gathering field precision */
1531 OPT, /* Gathering field options (l, h, q, etc.) */
1532 SPEC /* Looking for field specifier */
1533 } state = FLAG;
1534 struct FieldData fld_s = FIELDDATA_INIT;
1535 const char *fstart = 0;
1536
1537 for (; *fmt; fmt++) {
1538 /* If it's not %, or if it's %%, append it to the string */
1539 if (*fmt != '%' || (*fmt == '%' && *++fmt == '%')) {
1540 addc(buf_p, *fmt); /* add the character to the string */
1541
1542 continue; /* go to the next character */
1543 }
1544
1545 state = FLAG; /* initialize our field data */
1546 fld_s.flags = 0;
1547 fld_s.base = BASE_DECIMAL;
1548 fld_s.width = 0;
1549 fld_s.prec = -1;
1550 fstart = fmt;
1551
1552 for (; *fmt; fmt++) {
1553 switch (*fmt) {
1554 case '-': /* Deal with a minus flag */
1555 if (state == FLAG)
1556 fld_s.flags |= FLAG_MINUS;
1557 else if (state == PREC) { /* precisions may not be negative */
1558 fld_s.prec = -1;
1559 state = OPT; /* prohibit further precision wrangling */
1560 }
1561 continue;
1562
1563 case '+': /* Deal with a plus flag */
1564 if (state == FLAG)
1565 fld_s.flags |= FLAG_PLUS;
1566 continue;
1567
1568 case ' ': /* Deal with a space flag */
1569 if (state == FLAG)
1570 fld_s.flags |= FLAG_SPACE;
1571 continue;
1572
1573 case '#': /* Deal with the so-called "alternate" flag */
1574 if (state == FLAG)
1575 fld_s.flags |= FLAG_ALT;
1576 continue;
1577
1578 case ':': /* Deal with the colon flag */
1579 if (state == FLAG)
1580 fld_s.flags |= FLAG_COLON;
1581 continue;
1582
1583 case '0': /* Deal with a zero flag */
1584 if (state == FLAG) {
1585 fld_s.flags |= FLAG_ZERO;
1586 continue;
1587 }
1588 /*FALLTHROUGH*/
1589 case '1': case '2': case '3': case '4': case '5':
1590 case '6': case '7': case '8': case '9':
1591 if (state == FLAG) /* switch to the WIDTH state if needed? */
1592 state = WIDTH;
1593 else if (state != WIDTH && state != PREC)
1594 continue; /* don't process it any more */
1595
1596 /* convert number */
1597 if (state == WIDTH) {
1598 if (fld_s.width < WIDTH_MAX) /* prevent overflow */
1599 fld_s.width = fld_s.width * 10 + (*fmt - '0');
1600 } else {
1601 if (fld_s.prec < WIDTH_MAX) /* prevent overflow */
1602 fld_s.prec = fld_s.prec * 10 + (*fmt - '0');
1603 }
1604 continue;
1605
1606 case '.': /* We found a '.'; go to precision state */
1607 if (state <= DOT) {
1608 state = PREC;
1609 fld_s.prec = 0;
1610 }
1611 continue;
1612
1613 case '*': /* Grab an argument containing a width or precision */
1614 if (state <= WIDTH && fld_s.width <= 0) {
1615 fld_s.width = (short)va_arg(vp, int); /* Get argument */
1616
1617 state = DOT; /* '.' better be next */
1618
1619 if (fld_s.width < 0) { /* deal with negative width */
1620 fld_s.flags |= FLAG_MINUS;
1621 fld_s.width = -fld_s.width;
1622 }
1623 } else if (state == PREC && fld_s.prec <= 0) {
1624 fld_s.prec = (short)va_arg(vp, int); /* Get argument */
1625
1626 state = OPT; /* No more precision stuff */
1627
1628 if (fld_s.prec < 0) /* deal with negative precision */
1629 fld_s.prec = -1;
1630 }
1631 continue;
1632
1633 case 'h': /* it's a short */
1634 if (state <= OPT) {
1635 state = OPT;
1636 if (fld_s.flags & TYPE_SHORT) /* We support 'hh' */
1637 fld_s.flags |= TYPE_CHAR;
1638 else if (!(fld_s.flags & TYPE_MASK))
1639 fld_s.flags |= TYPE_SHORT;
1640 }
1641 continue;
1642
1643 case 'l': /* it's a long */
1644 if (state <= OPT) {
1645 state = OPT;
1646 if (fld_s.flags & TYPE_LONG) /* We support 'll' */
1647 fld_s.flags |= TYPE_QUAD | TYPE_LONGDOUBLE;
1648 else if (!(fld_s.flags & TYPE_MASK))
1649 fld_s.flags |= TYPE_LONG;
1650 }
1651 continue;
1652
1653 case 'q': case 'L': /* it's a quad or long double */
1654 if (state <= OPT) {
1655 state = OPT;
1656 if (!(fld_s.flags & TYPE_MASK))
1657 fld_s.flags |= TYPE_QUAD | TYPE_LONGDOUBLE;
1658 }
1659 continue;
1660
1661 case 'j': /* it's an intmax_t */
1662 if (state <= OPT) {
1663 state = OPT;
1664 if (!(fld_s.flags & TYPE_MASK))
1665 fld_s.flags |= TYPE_INTMAX;
1666 }
1667 continue;
1668
1669 case 't': /* it's a ptrdiff_t */
1670 if (state <= OPT) {
1671 state = OPT;
1672 if (!(fld_s.flags & TYPE_MASK))
1673 fld_s.flags |= TYPE_PTRDIFF;
1674 }
1675 continue;
1676
1677 case 'z': case 'Z': /* it's a size_t */
1678 if (state <= OPT) {
1679 state = OPT;
1680 if (!(fld_s.flags & TYPE_MASK))
1681 fld_s.flags |= TYPE_SIZE;
1682 }
1683 continue;
1684
1685 case 'T': /* it's a time_t */
1686 if (state <= OPT) {
1687 state = OPT;
1688 if (!(fld_s.flags & TYPE_MASK))
1689 fld_s.flags |= TYPE_TIME;
1690 }
1691 continue;
1692
1693 case 's': /* convert a string */
1694 fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1695 FLAG_COLON | TYPE_MASK);
1696 fld_s.flags |= ARG_PTR | CONV_STRING;
1697 break;
1698
1699 case 'd': case 'i':
1700 fld_s.flags &= ~(FLAG_COLON);
1701 fld_s.flags |= ARG_INT | CONV_INT;
1702 break;
1703
1704 case 'X': /* uppercase hexadecimal */
1705 fld_s.flags |= INFO_UPPERCASE;
1706 /*FALLTHROUGH*/
1707 case 'o': case 'x': /* octal or hexadecimal */
1708 if (*fmt == 'o')
1709 fld_s.base = BASE_OCTAL;
1710 else
1711 fld_s.base = BASE_HEX;
1712 /*FALLTHROUGH*/
1713 case 'u': /* Unsigned int */
1714 fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_COLON);
1715 fld_s.flags |= INFO_UNSIGNED | ARG_INT | CONV_INT;
1716 break;
1717
1718 /* Don't support floating point at this time; it's too complicated */
1719 /* case 'E': case 'G': case 'A': */
1720 /* fld_s.flags |= INFO_UPPERCASE; */
1721 /*FALLTHROUGH*/
1722 /* case 'e': case 'f': case 'g': case 'a': */
1723 /* fld_s.flags |= ARG_FLOAT | CONV_FLOAT; */
1724 /* break; */
1725
1726 case 'c': /* character */
1727 fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1728 FLAG_COLON | TYPE_MASK);
1729 fld_s.flags |= INFO_UNSIGNED | ARG_INT | TYPE_CHAR | CONV_CHAR;
1730 fld_s.prec = -1;
1731 break;
1732
1733 case 'p': /* display a pointer */
1734 fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_COLON | TYPE_MASK);
1735 fld_s.flags |= (FLAG_ALT | FLAG_ZERO | TYPE_POINTER | ARG_PTR |
1736 CONV_INT | INFO_UNSIGNED);
1737 fld_s.prec = (SIZEOF_VOID_P * 2); /* number of characters */
1738 fld_s.base = BASE_HEX;
1739 break;
1740
1741 case 'n': /* write back a character count */
1742 if (fld_s.flags & TYPE_CHAR) /* eg, %hhn */
1743 *((char *)va_arg(vp, int *)) = TOTAL(buf_p);
1744 else if (fld_s.flags & TYPE_SHORT) /* eg, %hn */
1745 *((short *)va_arg(vp, int *)) = TOTAL(buf_p);
1746 else if (fld_s.flags & TYPE_QUAD) /* eg, %qn */
1747 *((int64_t *)va_arg(vp, int64_t *)) = TOTAL(buf_p);
1748 else if (fld_s.flags & TYPE_LONG) /* eg, %ln */
1749 *((long *)va_arg(vp, long *)) = TOTAL(buf_p);
1750 else if (fld_s.flags & TYPE_INTMAX) /* eg, %jn */
1751 *((_large_t *)va_arg(vp, _large_t *)) = TOTAL(buf_p);
1752 else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %tn */
1753 *((ptrdiff_t *)va_arg(vp, ptrdiff_t *)) = TOTAL(buf_p);
1754 else if (fld_s.flags & TYPE_SIZE) /* eg, %zn */
1755 *((size_t *)va_arg(vp, size_t *)) = TOTAL(buf_p);
1756 else if (fld_s.flags & TYPE_TIME) /* eg, %Tn */
1757 *((time_t *)va_arg(vp, time_t *)) = TOTAL(buf_p);
1758 else /* eg, %n */
1759 *((int *)va_arg(vp, int *)) = TOTAL(buf_p);
1760 fld_s.flags = 0; /* no further processing required */
1761 break;
1762
1763 case 'm': /* write out a string describing an errno error */
1764 fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1765 FLAG_COLON | TYPE_MASK);
1766 fld_s.flags |= CONV_STRING;
1767 fld_s.value.v_ptr = (void *)strerror(errno);
1768 break;
1769
1770 case 'v': /* here's the infamous %v... */
1771 fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1772 FLAG_COLON | TYPE_MASK);
1773 fld_s.flags |= ARG_PTR | CONV_VARARGS;
1774 break;
1775
1776 case 'C': /* convert a client name... */
1777 fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ZERO | TYPE_MASK);
1778 fld_s.flags |= ARG_PTR | CONV_CLIENT;
1779 break;
1780
1781 case 'R': /* convert a client name... */
1782 fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ZERO | TYPE_MASK);
1783 fld_s.flags |= ARG_PTR | CONV_REAL;
1784 break;
1785
1786 case 'H': /* convert a channel name... */
1787 fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1788 FLAG_COLON | TYPE_MASK);
1789 fld_s.flags |= ARG_PTR | CONV_CHANNEL;
1790 break;
1791
1792 default: /* Unsupported, display a message and the entire format */
1793 adds(buf_p, -1, "(Unsupported: %");
1794 adds(buf_p, fmt - fstart + 1, fstart);
1795 addc(buf_p, ')');
1796 fld_s.flags = 0; /* no further processing required */
1797 break;
1798 } /* switch (*fmt) { */
1799
1800 break;
1801 } /* for (; *fmt; fmt++) { */
1802
1803 if (!*fmt) /* hit the end */
1804 break;
1805 else if (!(fld_s.flags & (ARG_MASK | CONV_MASK))) /* is it done? */
1806 continue;
1807
1808 if ((fld_s.flags & ARG_MASK) == ARG_INT) { /* grab an integer argument */
1809 if (fld_s.flags & INFO_UNSIGNED) { /* go direct if unsigned */
1810 if (fld_s.flags & TYPE_CHAR) /* eg, %hhu */
1811 fld_s.value.v_int = (unsigned char)va_arg(vp, unsigned int);
1812 else if (fld_s.flags & TYPE_SHORT) /* eg, %hu */
1813 fld_s.value.v_int = (unsigned short)va_arg(vp, unsigned int);
1814 else if (fld_s.flags & TYPE_QUAD) /* eg, %qu */
1815 fld_s.value.v_int = va_arg(vp, uint64_t);
1816 else if (fld_s.flags & TYPE_LONG) /* eg, %lu */
1817 fld_s.value.v_int = va_arg(vp, unsigned long);
1818 else if (fld_s.flags & TYPE_INTMAX) /* eg, %ju */
1819 fld_s.value.v_int = va_arg(vp, _large_t);
1820 else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %tu */
1821 fld_s.value.v_int = va_arg(vp, ptrdiff_t);
1822 else if (fld_s.flags & TYPE_SIZE) /* eg, %zu */
1823 fld_s.value.v_int = va_arg(vp, size_t);
1824 else if (fld_s.flags & TYPE_TIME) /* eg, %Tu */
1825 fld_s.value.v_int = va_arg(vp, time_t);
1826 else if (fld_s.flags & TYPE_POINTER) /* eg, %p */
1827 fld_s.value.v_int = va_arg(vp, _pointer_t);
1828 else /* eg, %u */
1829 fld_s.value.v_int = va_arg(vp, unsigned int);
1830 } else {
1831 _large_t signed_int; /* temp. store the signed integer */
1832
1833 if (fld_s.flags & TYPE_CHAR) /* eg, %hhd */
1834 signed_int = (char)va_arg(vp, unsigned int);
1835 else if (fld_s.flags & TYPE_SHORT) /* eg, %hd */
1836 signed_int = (short)va_arg(vp, unsigned int);
1837 else if (fld_s.flags & TYPE_QUAD) /* eg, %qd */
1838 signed_int = va_arg(vp, int64_t);
1839 else if (fld_s.flags & TYPE_LONG) /* eg, %ld */
1840 signed_int = va_arg(vp, long);
1841 else if (fld_s.flags & TYPE_INTMAX) /* eg, %jd */
1842 signed_int = va_arg(vp, _large_t);
1843 else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %td */
1844 signed_int = va_arg(vp, ptrdiff_t);
1845 else if (fld_s.flags & TYPE_SIZE) /* eg, %zd */
1846 signed_int = va_arg(vp, size_t);
1847 else if (fld_s.flags & TYPE_TIME) /* eg, %Td */
1848 signed_int = va_arg(vp, time_t);
1849 else /* eg, %d */
1850 signed_int = va_arg(vp, int);
1851
1852 if (signed_int < 0) { /* Now figure out if it's negative... */
1853 fld_s.flags |= INFO_NEGATIVE;
1854 fld_s.value.v_int = -signed_int; /* negate safely (I hope) */
1855 } else
1856 fld_s.value.v_int = signed_int;
1857 }
1858 } else if ((fld_s.flags & ARG_MASK) == ARG_FLOAT) { /* extract a float */
1859 if (fld_s.flags & TYPE_LONGDOUBLE) /* eg, %Lf */
1860 fld_s.value.v_float = va_arg(vp, long double);
1861 else /* eg, %f */
1862 fld_s.value.v_float = va_arg(vp, double);
1863 } else if ((fld_s.flags & ARG_MASK) == ARG_PTR) { /* pointer argument */
1864 fld_s.value.v_ptr = va_arg(vp, void *);
1865 }
1866
1867 /* We've eaten the arguments, we have all the information we need for
1868 * the conversion. Time to actually *do* the conversion
1869 */
1870 if ((fld_s.flags & CONV_MASK) == CONV_INT) {
1871 /* convert an integer */
1872 char intbuf[INTBUF_LEN], **table = 0, *tstr;
1873 int ibuf_loc = INTBUF_LEN, ilen, zlen = 0, plen = 0, elen = 0;
1874
1875 if (fld_s.base == BASE_OCTAL) /* select string table to use */
1876 table = octal;
1877 else if (fld_s.base == BASE_DECIMAL)
1878 table = decimal;
1879 else if (fld_s.base == BASE_HEX) { /* have to deal with upper case */
1880 table = (fld_s.flags & INFO_UPPERCASE) ? HEX : hex;
1881 if (fld_s.flags & FLAG_ALT)
1882 elen = 2; /* account for the length of 0x */
1883 }
1884
1885 if (fld_s.prec < 0) { /* default precision is 1 */
1886 if ((fld_s.flags & (FLAG_MINUS | FLAG_ZERO)) == FLAG_ZERO &&
1887 fld_s.width) {
1888 fld_s.prec = fld_s.width - elen;
1889 fld_s.width = 0;
1890 } else
1891 fld_s.prec = 1;
1892 }
1893
1894 /* If there's a sign flag, account for it */
1895 if (fld_s.flags & (FLAG_PLUS | FLAG_SPACE | INFO_NEGATIVE))
1896 elen++;
1897
1898 if (fld_s.base < 0) { /* non-binary base flagged by negative */
1899 fld_s.base = -fld_s.base; /* negate it... */
1900
1901 while (fld_s.value.v_int) { /* and convert it */
1902 tstr = table[fld_s.value.v_int % fld_s.base]; /* which string? */
1903 fld_s.value.v_int /= fld_s.base; /* next value */
1904
1905 ilen = 3; /* if we have to fill in zeros, here's how many */
1906
1907 while (*tstr) { /* add string to intbuf; note growing backwards */
1908 intbuf[--ibuf_loc] = *(tstr++);
1909 ilen--;
1910 }
1911
1912 if (fld_s.value.v_int > 0 && ilen) /* add zeros if needed */
1913 while (ilen--)
1914 intbuf[--ibuf_loc] = '0';
1915 }
1916 } else { /* optimize for powers of 2 */
1917 while (fld_s.value.v_int) { /* which string? */
1918 tstr = table[(fld_s.value.v_int & ((1 << fld_s.base) - 1))];
1919 fld_s.value.v_int >>= fld_s.base; /* next value */
1920
1921 ilen = 3; /* if we have to fill in zeros, here's how many */
1922
1923 while (*tstr) { /* add string to intbuf; note growing backwards */
1924 intbuf[--ibuf_loc] = *(tstr++);
1925 ilen--;
1926 }
1927
1928 if (fld_s.value.v_int > 0 && ilen) /* add zeros if needed */
1929 while (ilen--)
1930 intbuf[--ibuf_loc] = '0';
1931 }
1932 }
1933
1934 ilen = INTBUF_LEN - ibuf_loc; /* how many chars did we add? */
1935
1936 if (fld_s.prec > ilen) /* do we need any leading zeros? */
1937 zlen = fld_s.prec - ilen;
1938
1939 if (fld_s.base == BASE_OCTAL && zlen == 0 && fld_s.flags & FLAG_ALT)
1940 zlen++; /* factor in a leading zero for %#o */
1941
1942 if (fld_s.width > ilen + zlen + elen) /* calculate space padding */
1943 plen = fld_s.width - (ilen + zlen + elen);
1944
1945 if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
1946 do_pad(buf_p, plen, spaces); /* pre-padding */
1947
1948 if (fld_s.flags & INFO_NEGATIVE) /* leading signs */
1949 addc(buf_p, '-');
1950 else if (fld_s.flags & FLAG_PLUS)
1951 addc(buf_p, '+');
1952 else if (fld_s.flags & FLAG_SPACE)
1953 addc(buf_p, ' ');
1954
1955 if ((fld_s.flags & FLAG_ALT) && fld_s.base == BASE_HEX) { /* hex 0x */
1956 addc(buf_p, '0');
1957 addc(buf_p, fld_s.flags & INFO_UPPERCASE ? 'X' : 'x');
1958 }
1959
1960 if (zlen > 0) /* leading zeros */
1961 do_pad(buf_p, zlen, zeros);
1962
1963 adds(buf_p, ilen, intbuf + ibuf_loc); /* add the integer string */
1964
1965 if (plen > 0 && (fld_s.flags & FLAG_MINUS))
1966 do_pad(buf_p, plen, spaces); /* post-padding */
1967
1968 /* Don't support floating point at this time; it's too complicated */
1969 /* } else if ((fld_s.flags & CONV_MASK) == CONV_FLOAT) { */
1970 /* convert a float */
1971 } else if ((fld_s.flags & CONV_MASK) == CONV_CHAR) {
1972 if (fld_s.width > 0 && !(fld_s.flags & FLAG_MINUS))
1973 do_pad(buf_p, fld_s.width - 1, spaces); /* pre-padding */
1974
1975 addc(buf_p, fld_s.value.v_int); /* add the character */
1976
1977 if (fld_s.width > 0 && (fld_s.flags & FLAG_MINUS))
1978 do_pad(buf_p, fld_s.width - 1, spaces); /* post-padding */
1979 } else if ((fld_s.flags & CONV_MASK) == CONV_STRING ||
1980 fld_s.value.v_ptr == 0) { /* spaces or null pointers */
1981 int slen, plen;
1982 char *str = (char*) fld_s.value.v_ptr;
1983
1984 if (!str) /* NULL pointers print "(null)" */
1985 str = "(null)";
1986
1987 slen = my_strnlen(str, fld_s.prec); /* str lengths and pad lengths */
1988 plen = (fld_s.width - slen <= 0 ? 0 : fld_s.width - slen);
1989
1990 if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
1991 do_pad(buf_p, plen, spaces); /* pre-padding */
1992
1993 adds(buf_p, slen, str); /* add the string */
1994
1995 if (plen > 0 && (fld_s.flags & FLAG_MINUS))
1996 do_pad(buf_p, plen, spaces); /* post-padding */
1997 } else if ((fld_s.flags & CONV_MASK) == CONV_VARARGS) {
1998 struct BufData buf_s = BUFDATA_INIT;
1999 struct VarData *vdata = (struct VarData*) fld_s.value.v_ptr;
2000 int plen, tlen;
2001
2002 buf_s.buf = buf_p->buf + buf_p->buf_loc;
2003 buf_s.buf_size = buf_p->buf_size - buf_p->buf_loc;
2004 buf_s.limit = fld_s.prec;
2005
2006 doprintf(dest, &buf_s, vdata->vd_format, vdata->vd_args);
2007
2008 plen = (fld_s.width - buf_s.buf_loc <= 0 ? 0 :
2009 fld_s.width - buf_s.buf_loc);
2010
2011 if (plen > 0) {
2012 if (fld_s.flags & FLAG_MINUS) { /* left aligned... */
2013 buf_p->buf_loc += buf_s.buf_loc; /* remember the modifications */
2014 buf_p->buf_overflow += buf_s.buf_overflow;
2015
2016 do_pad(buf_p, plen, spaces); /* and do the post-padding */
2017 } else { /* right aligned... */
2018 /* Ok, first, see if we'll have *anything* left after padding */
2019 if (plen > buf_s.buf_size) {
2020 /* nope, good, this is easy: everything overflowed buffer */
2021 do_pad(buf_p, plen, spaces);
2022
2023 buf_s.buf_overflow += buf_s.buf_loc; /* update buf counts */
2024 buf_s.buf_loc = 0;
2025 buf_p->buf_overflow += buf_s.buf_overflow;
2026 } else {
2027 /* first figure out how much we're going to save */
2028 tlen = SNP_MIN(buf_s.buf_loc, buf_s.buf_size - plen);
2029
2030 memmove(buf_s.buf + plen, buf_s.buf, tlen); /* save it... */
2031 do_pad(buf_p, plen, spaces); /* add spaces... */
2032
2033 buf_s.buf_overflow += buf_s.buf_loc - tlen; /* update buf counts */
2034 buf_s.buf_loc = tlen;
2035 buf_p->buf_overflow += buf_s.buf_overflow;
2036 buf_p->buf_loc += buf_s.buf_loc;
2037 }
2038 }
2039 } else {
2040 buf_p->buf_loc += buf_s.buf_loc; /* no padding, but remember mods */
2041 buf_p->buf_overflow += buf_s.buf_overflow;
2042 }
2043
2044 vdata->vd_chars = buf_s.buf_loc; /* return relevant data */
2045 vdata->vd_overflow = SNP_MAX(buf_s.buf_overflow, buf_s.overflow);
2046 } else if (((fld_s.flags & CONV_MASK) == CONV_CLIENT) ||
2047 ((fld_s.flags & CONV_MASK) == CONV_REAL)) {
2048 struct Client *cptr = (struct Client*) fld_s.value.v_ptr;
2049 const char *str1 = 0, *str2 = 0, *str3 = 0;
2050 int slen1 = 0, slen2 = 0, slen3 = 0, elen = 0, plen = 0;
2051
2052 /* &me is used if it's not a definite server */
2053 if (dest && (IsServer(dest) || IsMe(dest))) {
2054 if (IsServer(cptr) || IsMe(cptr))
2055 str1 = cli_yxx(cptr);
2056 else {
2057 str1 = cli_yxx(cli_user(cptr)->server);
2058 str2 = cli_yxx(cptr);
2059 }
2060 fld_s.flags &= ~(FLAG_ALT | FLAG_COLON);
2061 } else {
2062 str1 = *cli_name(cptr) ? cli_name(cptr) : "*";
2063 if (!IsServer(cptr) && !IsMe(cptr) && fld_s.flags & FLAG_ALT) {
2064 assert(0 != cli_user(cptr));
2065 assert(0 != *(cli_name(cptr)));
2066 if ((fld_s.flags & CONV_MASK) == CONV_REAL) {
2067 str2 = cli_user(cptr)->realusername;
2068 str3 = cli_user(cptr)->realhost;
2069 } else {
2070 str2 = cli_user(cptr)->username;
2071 str3 = cli_user(cptr)->host;
2072 }
2073 } else
2074 fld_s.flags &= ~FLAG_ALT;
2075 }
2076
2077 if (fld_s.flags & FLAG_COLON)
2078 elen++; /* account for : */
2079
2080 slen1 = my_strnlen(str1, fld_s.prec < 0 ? -1 : fld_s.prec - elen);
2081 if (fld_s.flags & FLAG_ALT)
2082 elen++; /* account for ! */
2083 if (str2 && (fld_s.prec < 0 || fld_s.prec - (slen1 + elen) > 0))
2084 slen2 = my_strnlen(str2, fld_s.prec < 0 ? -1 : fld_s.prec -
2085 (slen1 + elen));
2086 if (fld_s.flags & FLAG_ALT)
2087 elen++; /* account for @ */
2088 if (str3 && (fld_s.prec < 0 || fld_s.prec - (slen1 + slen2 + elen) > 0))
2089 slen3 = my_strnlen(str3, fld_s.prec < 0 ? -1 : fld_s.prec -
2090 (slen1 + slen2 + elen));
2091 plen = (fld_s.width - (slen1 + slen2 + slen3 + elen) <= 0 ? 0 :
2092 fld_s.width - (slen1 + slen2 + slen3 + elen));
2093
2094 if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
2095 do_pad(buf_p, plen, spaces); /* pre-padding */
2096
2097 if (fld_s.flags & FLAG_COLON)
2098 addc(buf_p, ':');
2099 adds(buf_p, slen1, str1);
2100 if (fld_s.flags & FLAG_ALT)
2101 addc(buf_p, '!');
2102 if (str2)
2103 adds(buf_p, slen2, str2);
2104 if (fld_s.flags & FLAG_ALT)
2105 addc(buf_p, '@');
2106 if (str3)
2107 adds(buf_p, slen3, str3);
2108
2109 if (plen > 0 && (fld_s.flags & FLAG_MINUS))
2110 do_pad(buf_p, plen, spaces); /* post-padding */
2111 } else if ((fld_s.flags & CONV_MASK) == CONV_CHANNEL) {
2112 struct Channel *chan = (struct Channel *)fld_s.value.v_ptr;
2113 char *str = chan->chname;
2114 int slen, plen;
2115
2116 slen = my_strnlen(str, fld_s.prec); /* str lengths and pad lengths */
2117 plen = (fld_s.width - slen <= 0 ? 0 : fld_s.width - slen);
2118
2119 if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
2120 do_pad(buf_p, plen, spaces); /* pre-padding */
2121
2122 adds(buf_p, slen, str); /* add the string */
2123
2124 if (plen > 0 && (fld_s.flags & FLAG_MINUS))
2125 do_pad(buf_p, plen, spaces); /* post-padding */
2126 }
2127 } /* for (; *fmt; fmt++) { */
2128 }
2129
2130 /* ircd_snprintf() has a big Doxygen comment in the header file. */
2131 int
2132 ircd_snprintf(struct Client *dest, char *buf, size_t buf_len,
2133 const char *format, ...)
2134 {
2135 struct BufData buf_s = BUFDATA_INIT;
2136 va_list args;
2137
2138 if (!format)
2139 return 0;
2140
2141 buf_s.buf = buf; /* initialize buffer settings */
2142 buf_s.buf_size = buf_len - 1;
2143 buf_s.limit = -1;
2144
2145 va_start(args, format);
2146 doprintf(dest, &buf_s, format, args); /* fill the buffer */
2147 va_end(args);
2148
2149 buf_s.buf[buf_s.buf_loc] = '\0'; /* terminate buffer */
2150
2151 return TOTAL(&buf_s);
2152 }
2153
2154 /** Like ircd_snprintf() but with a va_list argument list.
2155 * @param[in] dest Client receiving of message.
2156 * @param[out] buf Output buffer for formatted message.
2157 * @param[in] buf_len Number of bytes that can be written to \a buf.
2158 * @param[in] format Format string for message.
2159 * @param[in] args Variable-length argument list for format string.
2160 * @return Number of bytes that would be written to \a buf without truncation.
2161 */
2162 int
2163 ircd_vsnprintf(struct Client *dest, char *buf, size_t buf_len,
2164 const char *format, va_list args)
2165 {
2166 struct BufData buf_s = BUFDATA_INIT;
2167
2168 if (!format)
2169 return 0;
2170
2171 buf_s.buf = buf; /* initialize buffer settings */
2172 buf_s.buf_size = buf_len - 1;
2173 buf_s.limit = -1;
2174
2175 doprintf(dest, &buf_s, format, args); /* fill the buffer */
2176
2177 buf_s.buf[buf_s.buf_loc] = '\0'; /* terminate buffer */
2178
2179 return TOTAL(&buf_s);
2180 }