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