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