added some debug information to ssl.c
[ircu2.10.12-pk.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 1642 2006-04-07 03:56:22Z entrope $
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
184 #define CONV_RESERVED7  0x08000000      /**< reserved for future expansion */
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 'H': /* convert a channel name... */
1782         fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1783                          FLAG_COLON | TYPE_MASK);
1784         fld_s.flags |= ARG_PTR | CONV_CHANNEL;
1785         break;
1786
1787       default: /* Unsupported, display a message and the entire format */
1788         adds(buf_p, -1, "(Unsupported: %");
1789         adds(buf_p, fmt - fstart + 1, fstart);
1790         addc(buf_p, ')');
1791         fld_s.flags = 0; /* no further processing required */
1792         break;
1793       } /* switch (*fmt) { */
1794
1795       break;
1796     } /* for (; *fmt; fmt++) { */
1797
1798     if (!*fmt) /* hit the end */
1799       break;
1800     else if (!(fld_s.flags & (ARG_MASK | CONV_MASK))) /* is it done? */
1801       continue;
1802
1803     if ((fld_s.flags & ARG_MASK) == ARG_INT) { /* grab an integer argument */
1804       if (fld_s.flags & INFO_UNSIGNED) { /* go direct if unsigned */
1805         if (fld_s.flags & TYPE_CHAR) /* eg, %hhu */
1806           fld_s.value.v_int = (unsigned char)va_arg(vp, unsigned int);
1807         else if (fld_s.flags & TYPE_SHORT) /* eg, %hu */
1808           fld_s.value.v_int = (unsigned short)va_arg(vp, unsigned int);
1809         else if (fld_s.flags & TYPE_QUAD) /* eg, %qu */
1810           fld_s.value.v_int = va_arg(vp, uint64_t);
1811         else if (fld_s.flags & TYPE_LONG) /* eg, %lu */
1812           fld_s.value.v_int = va_arg(vp, unsigned long);
1813         else if (fld_s.flags & TYPE_INTMAX) /* eg, %ju */
1814           fld_s.value.v_int = va_arg(vp, _large_t);
1815         else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %tu */
1816           fld_s.value.v_int = va_arg(vp, ptrdiff_t);
1817         else if (fld_s.flags & TYPE_SIZE) /* eg, %zu */
1818           fld_s.value.v_int = va_arg(vp, size_t);
1819         else if (fld_s.flags & TYPE_TIME) /* eg, %Tu */
1820           fld_s.value.v_int = va_arg(vp, time_t);
1821         else if (fld_s.flags & TYPE_POINTER) /* eg, %p */
1822           fld_s.value.v_int = va_arg(vp, _pointer_t);
1823         else /* eg, %u */
1824           fld_s.value.v_int = va_arg(vp, unsigned int);
1825       } else {
1826         _large_t signed_int; /* temp. store the signed integer */
1827
1828         if (fld_s.flags & TYPE_CHAR) /* eg, %hhd */
1829           signed_int = (char)va_arg(vp, unsigned int);
1830         else if (fld_s.flags & TYPE_SHORT) /* eg, %hd */
1831           signed_int = (short)va_arg(vp, unsigned int);
1832         else if (fld_s.flags & TYPE_QUAD) /* eg, %qd */
1833           signed_int = va_arg(vp, int64_t);
1834         else if (fld_s.flags & TYPE_LONG) /* eg, %ld */
1835           signed_int = va_arg(vp, long);
1836         else if (fld_s.flags & TYPE_INTMAX) /* eg, %jd */
1837           signed_int = va_arg(vp, _large_t);
1838         else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %td */
1839           signed_int = va_arg(vp, ptrdiff_t);
1840         else if (fld_s.flags & TYPE_SIZE) /* eg, %zd */
1841           signed_int = va_arg(vp, size_t);
1842         else if (fld_s.flags & TYPE_TIME) /* eg, %Td */
1843           signed_int = va_arg(vp, time_t);
1844         else /* eg, %d */
1845           signed_int = va_arg(vp, int);
1846
1847         if (signed_int < 0) { /* Now figure out if it's negative... */
1848           fld_s.flags |= INFO_NEGATIVE;
1849           fld_s.value.v_int = -signed_int; /* negate safely (I hope) */
1850         } else
1851           fld_s.value.v_int = signed_int;
1852       }
1853     } else if ((fld_s.flags & ARG_MASK) == ARG_FLOAT) { /* extract a float */
1854       if (fld_s.flags & TYPE_LONGDOUBLE) /* eg, %Lf */
1855         fld_s.value.v_float = va_arg(vp, long double);
1856       else /* eg, %f */
1857         fld_s.value.v_float = va_arg(vp, double);
1858     } else if ((fld_s.flags & ARG_MASK) == ARG_PTR) { /* pointer argument */
1859       fld_s.value.v_ptr = va_arg(vp, void *);
1860     }
1861
1862     /* We've eaten the arguments, we have all the information we need for
1863      * the conversion.  Time to actually *do* the conversion
1864      */
1865     if ((fld_s.flags & CONV_MASK) == CONV_INT) {
1866       /* convert an integer */
1867       char intbuf[INTBUF_LEN], **table = 0, *tstr;
1868       int ibuf_loc = INTBUF_LEN, ilen, zlen = 0, plen = 0, elen = 0;
1869
1870       if (fld_s.base == BASE_OCTAL) /* select string table to use */
1871         table = octal;
1872       else if (fld_s.base == BASE_DECIMAL)
1873         table = decimal;
1874       else if (fld_s.base == BASE_HEX) { /* have to deal with upper case */
1875         table = (fld_s.flags & INFO_UPPERCASE) ? HEX : hex;
1876         if (fld_s.flags & FLAG_ALT)
1877           elen = 2; /* account for the length of 0x */
1878       }
1879
1880       if (fld_s.prec < 0) { /* default precision is 1 */
1881         if ((fld_s.flags & (FLAG_MINUS | FLAG_ZERO)) == FLAG_ZERO &&
1882             fld_s.width) {
1883           fld_s.prec = fld_s.width - elen;
1884           fld_s.width = 0;
1885         } else
1886           fld_s.prec = 1;
1887       }
1888
1889       /* If there's a sign flag, account for it */
1890       if (fld_s.flags & (FLAG_PLUS | FLAG_SPACE | INFO_NEGATIVE))
1891         elen++;
1892
1893       if (fld_s.base < 0) { /* non-binary base flagged by negative */
1894         fld_s.base = -fld_s.base; /* negate it... */
1895
1896         while (fld_s.value.v_int) { /* and convert it */
1897           tstr = table[fld_s.value.v_int % fld_s.base]; /* which string? */
1898           fld_s.value.v_int /= fld_s.base; /* next value */
1899
1900           ilen = 3; /* if we have to fill in zeros, here's how many */
1901
1902           while (*tstr) { /* add string to intbuf; note growing backwards */
1903             intbuf[--ibuf_loc] = *(tstr++);
1904             ilen--;
1905           }
1906
1907           if (fld_s.value.v_int > 0 && ilen) /* add zeros if needed */
1908             while (ilen--)
1909               intbuf[--ibuf_loc] = '0';
1910         }
1911       } else { /* optimize for powers of 2 */
1912         while (fld_s.value.v_int) { /* which string? */
1913           tstr = table[(fld_s.value.v_int & ((1 << fld_s.base) - 1))];
1914           fld_s.value.v_int >>= fld_s.base; /* next value */
1915
1916           ilen = 3; /* if we have to fill in zeros, here's how many */
1917
1918           while (*tstr) { /* add string to intbuf; note growing backwards */
1919             intbuf[--ibuf_loc] = *(tstr++);
1920             ilen--;
1921           }
1922
1923           if (fld_s.value.v_int > 0 && ilen) /* add zeros if needed */
1924             while (ilen--)
1925               intbuf[--ibuf_loc] = '0';
1926         }
1927       }
1928
1929       ilen = INTBUF_LEN - ibuf_loc; /* how many chars did we add? */
1930
1931       if (fld_s.prec > ilen) /* do we need any leading zeros? */
1932         zlen = fld_s.prec - ilen;
1933
1934       if (fld_s.base == BASE_OCTAL && zlen == 0 && fld_s.flags & FLAG_ALT)
1935         zlen++; /* factor in a leading zero for %#o */
1936
1937       if (fld_s.width > ilen + zlen + elen) /* calculate space padding */
1938         plen = fld_s.width - (ilen + zlen + elen);
1939
1940       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
1941         do_pad(buf_p, plen, spaces); /* pre-padding */
1942
1943       if (fld_s.flags & INFO_NEGATIVE) /* leading signs */
1944         addc(buf_p, '-');
1945       else if (fld_s.flags & FLAG_PLUS)
1946         addc(buf_p, '+');
1947       else if (fld_s.flags & FLAG_SPACE)
1948         addc(buf_p, ' ');
1949
1950       if ((fld_s.flags & FLAG_ALT) && fld_s.base == BASE_HEX) { /* hex 0x */
1951         addc(buf_p, '0');
1952         addc(buf_p, fld_s.flags & INFO_UPPERCASE ? 'X' : 'x');
1953       }
1954
1955       if (zlen > 0) /* leading zeros */
1956         do_pad(buf_p, zlen, zeros);
1957
1958       adds(buf_p, ilen, intbuf + ibuf_loc); /* add the integer string */
1959
1960       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
1961         do_pad(buf_p, plen, spaces); /* post-padding */
1962
1963       /* Don't support floating point at this time; it's too complicated */
1964 /*      } else if ((fld_s.flags & CONV_MASK) == CONV_FLOAT) { */
1965       /* convert a float */
1966     } else if ((fld_s.flags & CONV_MASK) == CONV_CHAR) {
1967       if (fld_s.width > 0 && !(fld_s.flags & FLAG_MINUS))
1968         do_pad(buf_p, fld_s.width - 1, spaces); /* pre-padding */
1969
1970       addc(buf_p, fld_s.value.v_int); /* add the character */
1971
1972       if (fld_s.width > 0 &&  (fld_s.flags & FLAG_MINUS))
1973         do_pad(buf_p, fld_s.width - 1, spaces); /* post-padding */
1974     } else if ((fld_s.flags & CONV_MASK) == CONV_STRING ||
1975                fld_s.value.v_ptr == 0) { /* spaces or null pointers */
1976       int slen, plen;
1977       char *str = (char*) fld_s.value.v_ptr;
1978
1979       if (!str) /* NULL pointers print "(null)" */
1980         str = "(null)";
1981
1982       slen = my_strnlen(str, fld_s.prec); /* str lengths and pad lengths */
1983       plen = (fld_s.width - slen <= 0 ? 0 : fld_s.width - slen);
1984
1985       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
1986         do_pad(buf_p, plen, spaces); /* pre-padding */
1987
1988       adds(buf_p, slen, str); /* add the string */
1989
1990       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
1991         do_pad(buf_p, plen, spaces); /* post-padding */
1992     } else if ((fld_s.flags & CONV_MASK) == CONV_VARARGS) {
1993       struct BufData buf_s = BUFDATA_INIT;
1994       struct VarData *vdata = (struct VarData*) fld_s.value.v_ptr;
1995       int plen, tlen;
1996
1997       buf_s.buf = buf_p->buf + buf_p->buf_loc;
1998       buf_s.buf_size = buf_p->buf_size - buf_p->buf_loc;
1999       buf_s.limit = fld_s.prec;
2000
2001       doprintf(dest, &buf_s, vdata->vd_format, vdata->vd_args);
2002
2003       plen = (fld_s.width - buf_s.buf_loc <= 0 ? 0 :
2004               fld_s.width - buf_s.buf_loc);
2005
2006       if (plen > 0) {
2007         if (fld_s.flags & FLAG_MINUS) { /* left aligned... */
2008           buf_p->buf_loc += buf_s.buf_loc; /* remember the modifications */
2009           buf_p->buf_overflow += buf_s.buf_overflow;
2010
2011           do_pad(buf_p, plen, spaces); /* and do the post-padding */
2012         } else { /* right aligned... */
2013           /* Ok, first, see if we'll have *anything* left after padding */
2014           if (plen > buf_s.buf_size) {
2015             /* nope, good, this is easy: everything overflowed buffer */
2016             do_pad(buf_p, plen, spaces);
2017
2018             buf_s.buf_overflow += buf_s.buf_loc; /* update buf counts */
2019             buf_s.buf_loc = 0;
2020             buf_p->buf_overflow += buf_s.buf_overflow;
2021           } else {
2022             /* first figure out how much we're going to save */
2023             tlen = SNP_MIN(buf_s.buf_loc, buf_s.buf_size - plen);
2024
2025             memmove(buf_s.buf + plen, buf_s.buf, tlen); /* save it... */
2026             do_pad(buf_p, plen, spaces); /* add spaces... */
2027
2028             buf_s.buf_overflow += buf_s.buf_loc - tlen; /* update buf counts */
2029             buf_s.buf_loc = tlen;
2030             buf_p->buf_overflow += buf_s.buf_overflow;
2031             buf_p->buf_loc += buf_s.buf_loc;
2032           }
2033         }
2034       } else {
2035         buf_p->buf_loc += buf_s.buf_loc; /* no padding, but remember mods */
2036         buf_p->buf_overflow += buf_s.buf_overflow;
2037       }
2038
2039       vdata->vd_chars = buf_s.buf_loc; /* return relevant data */
2040       vdata->vd_overflow = SNP_MAX(buf_s.buf_overflow, buf_s.overflow);
2041     } else if ((fld_s.flags & CONV_MASK) == CONV_CLIENT) {
2042       struct Client *cptr = (struct Client*) fld_s.value.v_ptr;
2043       const char *str1 = 0, *str2 = 0, *str3 = 0;
2044       int slen1 = 0, slen2 = 0, slen3 = 0, elen = 0, plen = 0;
2045
2046       /* &me is used if it's not a definite server */
2047       if (dest && (IsServer(dest) || IsMe(dest))) {
2048         if (IsServer(cptr) || IsMe(cptr))
2049           str1 = cli_yxx(cptr);
2050         else {
2051           str1 = cli_yxx(cli_user(cptr)->server);
2052           str2 = cli_yxx(cptr);
2053         }
2054         fld_s.flags &= ~(FLAG_ALT | FLAG_COLON);
2055       } else {
2056         str1 = *cli_name(cptr) ? cli_name(cptr) : "*";
2057         if (!IsServer(cptr) && !IsMe(cptr) && fld_s.flags & FLAG_ALT) {
2058           assert(0 != cli_user(cptr));
2059           assert(0 != *(cli_name(cptr)));
2060           str2 = cli_user(cptr)->username;
2061           str3 = cli_user(cptr)->host;
2062         } else
2063           fld_s.flags &= ~FLAG_ALT;
2064       }
2065
2066       if (fld_s.flags & FLAG_COLON)
2067         elen++; /* account for : */
2068
2069       slen1 = my_strnlen(str1, fld_s.prec < 0 ? -1 : fld_s.prec - elen);
2070       if (fld_s.flags & FLAG_ALT)
2071         elen++; /* account for ! */
2072       if (str2 && (fld_s.prec < 0 || fld_s.prec - (slen1 + elen) > 0))
2073         slen2 = my_strnlen(str2, fld_s.prec < 0 ? -1 : fld_s.prec -
2074                            (slen1 + elen));
2075       if (fld_s.flags & FLAG_ALT)
2076         elen++; /* account for @ */
2077       if (str3 && (fld_s.prec < 0 || fld_s.prec - (slen1 + slen2 + elen) > 0))
2078         slen3 = my_strnlen(str3, fld_s.prec < 0 ? -1 : fld_s.prec -
2079                            (slen1 + slen2 + elen));
2080       plen = (fld_s.width - (slen1 + slen2 + slen3 + elen) <= 0 ? 0 :
2081               fld_s.width - (slen1 + slen2 + slen3 + elen));
2082
2083       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
2084         do_pad(buf_p, plen, spaces); /* pre-padding */
2085
2086       if (fld_s.flags & FLAG_COLON)
2087         addc(buf_p, ':');
2088       adds(buf_p, slen1, str1);
2089       if (fld_s.flags & FLAG_ALT)
2090         addc(buf_p, '!');
2091       if (str2)
2092         adds(buf_p, slen2, str2);
2093       if (fld_s.flags & FLAG_ALT)
2094         addc(buf_p, '@');
2095       if (str3)
2096         adds(buf_p, slen3, str3);
2097
2098       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
2099         do_pad(buf_p, plen, spaces); /* post-padding */
2100     } else if ((fld_s.flags & CONV_MASK) == CONV_CHANNEL) {
2101       struct Channel *chan = (struct Channel *)fld_s.value.v_ptr;
2102       char *str = chan->chname;
2103       int slen, plen;
2104
2105       slen = my_strnlen(str, fld_s.prec); /* str lengths and pad lengths */
2106       plen = (fld_s.width - slen <= 0 ? 0 : fld_s.width - slen);
2107
2108       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
2109         do_pad(buf_p, plen, spaces); /* pre-padding */
2110
2111       adds(buf_p, slen, str); /* add the string */
2112
2113       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
2114         do_pad(buf_p, plen, spaces); /* post-padding */
2115     }
2116   } /* for (; *fmt; fmt++) { */
2117 }
2118
2119 /* ircd_snprintf() has a big Doxygen comment in the header file. */
2120 int
2121 ircd_snprintf(struct Client *dest, char *buf, size_t buf_len,
2122               const char *format, ...)
2123 {
2124   struct BufData buf_s = BUFDATA_INIT;
2125   va_list args;
2126
2127   if (!format)
2128     return 0;
2129
2130   buf_s.buf = buf; /* initialize buffer settings */
2131   buf_s.buf_size = buf_len - 1;
2132   buf_s.limit = -1;
2133
2134   va_start(args, format);
2135   doprintf(dest, &buf_s, format, args); /* fill the buffer */
2136   va_end(args);
2137
2138   buf_s.buf[buf_s.buf_loc] = '\0'; /* terminate buffer */
2139
2140   return TOTAL(&buf_s);
2141 }
2142
2143 /** Like ircd_snprintf() but with a va_list argument list.
2144  * @param[in] dest Client receiving of message.
2145  * @param[out] buf Output buffer for formatted message.
2146  * @param[in] buf_len Number of bytes that can be written to \a buf.
2147  * @param[in] format Format string for message.
2148  * @param[in] args Variable-length argument list for format string.
2149  * @return Number of bytes that would be written to \a buf without truncation.
2150  */
2151 int
2152 ircd_vsnprintf(struct Client *dest, char *buf, size_t buf_len,
2153                const char *format, va_list args)
2154 {
2155   struct BufData buf_s = BUFDATA_INIT;
2156
2157   if (!format)
2158     return 0;
2159
2160   buf_s.buf = buf; /* initialize buffer settings */
2161   buf_s.buf_size = buf_len - 1;
2162   buf_s.limit = -1;
2163
2164   doprintf(dest, &buf_s, format, args); /* fill the buffer */
2165
2166   buf_s.buf[buf_s.buf_loc] = '\0'; /* terminate buffer */
2167
2168   return TOTAL(&buf_s);
2169 }