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   size_t        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
109 #define FLAG_RESERVED2  0x00000020      /* reserved for future expansion */
110 #define FLAG_RESERVED1  0x00000040
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 '0': /* Deal with a zero flag */
1537         if (state == FLAG) {
1538           fld_s.flags |= FLAG_ZERO;
1539           continue;
1540         }
1541         /*FALLTHROUGH*/
1542       case '1':  case '2':  case '3':  case '4':  case '5':
1543       case '6':  case '7':  case '8':  case '9':
1544         if (state == FLAG) /* switch to the WIDTH state if needed? */
1545           state = WIDTH;
1546         else if (state != WIDTH && state != PREC)
1547           continue; /* don't process it any more */
1548
1549         /* convert number */
1550         if (state == WIDTH) {
1551           if (fld_s.width < WIDTH_MAX) /* prevent overflow */
1552             fld_s.width = fld_s.width * 10 + (*fmt - '0');
1553         } else {
1554           if (fld_s.prec < WIDTH_MAX) /* prevent overflow */
1555             fld_s.prec = fld_s.prec * 10 + (*fmt - '0');
1556         }
1557         continue;
1558
1559       case '.': /* We found a '.'; go to precision state */
1560         if (state <= DOT) {
1561           state = PREC;
1562           fld_s.prec = 0;
1563         }
1564         continue;
1565
1566       case '*': /* Grab an argument containing a width or precision */
1567         if (state <= WIDTH && fld_s.width <= 0) {
1568           fld_s.width = (short)va_arg(vp, int); /* Get argument */
1569
1570           state = DOT; /* '.' better be next */
1571
1572           if (fld_s.width < 0) { /* deal with negative width */
1573             fld_s.flags |= FLAG_MINUS;
1574             fld_s.width = -fld_s.width;
1575           }
1576         } else if (state == PREC && fld_s.prec <= 0) {
1577           fld_s.prec = (short)va_arg(vp, int); /* Get argument */
1578
1579           state = OPT; /* No more precision stuff */
1580
1581           if (fld_s.prec < 0) /* deal with negative precision */
1582             fld_s.prec = -1;
1583         }
1584         continue;
1585
1586       case 'h': /* it's a short */
1587         if (state <= OPT) {
1588           state = OPT;
1589           if (fld_s.flags & TYPE_SHORT) /* We support 'hh' */
1590             fld_s.flags |= TYPE_CHAR;
1591           else if (!(fld_s.flags & TYPE_MASK))
1592             fld_s.flags |= TYPE_SHORT;
1593         }
1594         continue;
1595
1596       case 'l': /* it's a long */
1597         if (state <= OPT) {
1598           state = OPT;
1599           if (fld_s.flags & TYPE_LONG) /* We support 'll' */
1600             fld_s.flags |= TYPE_QUAD | TYPE_LONGDOUBLE;
1601           else if (!(fld_s.flags & TYPE_MASK))
1602             fld_s.flags |= TYPE_LONG;
1603         }
1604         continue;
1605
1606       case 'q':  case 'L': /* it's a quad or long double */
1607         if (state <= OPT) {
1608           state = OPT;
1609           if (!(fld_s.flags & TYPE_MASK))
1610             fld_s.flags |= TYPE_QUAD | TYPE_LONGDOUBLE;
1611         }
1612         continue;
1613
1614       case 'j': /* it's an intmax_t */
1615         if (state <= OPT) {
1616           state = OPT;
1617           if (!(fld_s.flags & TYPE_MASK))
1618             fld_s.flags |= TYPE_INTMAX;
1619         }
1620         continue;
1621
1622       case 't': /* it's a ptrdiff_t */
1623         if (state <= OPT) {
1624           state = OPT;
1625           if (!(fld_s.flags & TYPE_MASK))
1626             fld_s.flags |= TYPE_PTRDIFF;
1627         }
1628         continue;
1629
1630       case 'z':  case 'Z': /* it's a size_t */
1631         if (state <= OPT) {
1632           state = OPT;
1633           if (!(fld_s.flags & TYPE_MASK))
1634             fld_s.flags |= TYPE_SIZE;
1635         }
1636         continue;
1637
1638       case 'T': /* it's a time_t */
1639         if (state <= OPT) {
1640           state = OPT;
1641           if (!(fld_s.flags & TYPE_MASK))
1642             fld_s.flags |= TYPE_TIME;
1643         }
1644         continue;
1645
1646       case 's': /* convert a string */
1647         fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1648                          TYPE_MASK);
1649         fld_s.flags |= ARG_PTR | CONV_STRING;
1650         break;
1651
1652       case 'd':  case 'i':
1653         fld_s.flags |= ARG_INT | CONV_INT;
1654         break;
1655
1656       case 'X': /* uppercase hexadecimal */
1657         fld_s.flags |= INFO_UPPERCASE;
1658         /*FALLTHROUGH*/
1659       case 'o':  case 'x': /* octal or hexadecimal */
1660         if (*fmt == 'o')
1661           fld_s.base = BASE_OCTAL;
1662         else
1663           fld_s.base = BASE_HEX;
1664         /*FALLTHROUGH*/
1665       case 'u': /* Unsigned int */
1666         fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE);
1667         fld_s.flags |= INFO_UNSIGNED | ARG_INT | CONV_INT;
1668         break;
1669
1670         /* Don't support floating point at this time; it's too complicated */
1671 /*        case 'E':  case 'G':  case 'A': */
1672 /*      fld_s.flags |= INFO_UPPERCASE; */
1673         /*FALLTHROUGH*/
1674 /*        case 'e':  case 'f':  case 'g':  case 'a': */
1675 /*      fld_s.flags |= ARG_FLOAT | CONV_FLOAT; */
1676 /*      break; */
1677
1678       case 'c': /* character */
1679         fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1680                           TYPE_MASK);
1681         fld_s.flags |= INFO_UNSIGNED | ARG_INT | TYPE_CHAR | CONV_CHAR;
1682         fld_s.prec = -1;
1683         break;
1684
1685       case 'p': /* display a pointer */
1686         fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | TYPE_MASK);
1687         fld_s.flags |= (FLAG_ALT | FLAG_ZERO | TYPE_POINTER | ARG_PTR |
1688                         CONV_INT | INFO_UNSIGNED);
1689         fld_s.prec = (SIZEOF_VOID_P * 2); /* number of characters */
1690         fld_s.base = BASE_HEX;
1691         break;
1692
1693       case 'n': /* write back a character count */
1694         if (fld_s.flags & TYPE_CHAR) /* eg, %hhn */
1695           *((char *)va_arg(vp, int *)) = TOTAL(buf_p);
1696         else if (fld_s.flags & TYPE_SHORT) /* eg, %hn */
1697           *((short *)va_arg(vp, int *)) = TOTAL(buf_p);
1698 #ifdef HAVE_LONG_LONG
1699         else if (fld_s.flags & TYPE_QUAD) /* eg, %qn */
1700           *((my_quad_t *)va_arg(vp, my_quad_t *)) = TOTAL(buf_p);
1701 #endif /* HAVE_LONG_LONG */
1702         else if (fld_s.flags & TYPE_LONG) /* eg, %ln */
1703           *((long *)va_arg(vp, long *)) = TOTAL(buf_p);
1704         else if (fld_s.flags & TYPE_INTMAX) /* eg, %jn */
1705           *((_large_t *)va_arg(vp, _large_t *)) = TOTAL(buf_p);
1706         else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %tn */
1707           *((ptrdiff_t *)va_arg(vp, ptrdiff_t *)) = TOTAL(buf_p);
1708         else if (fld_s.flags & TYPE_SIZE) /* eg, %zn */
1709           *((size_t *)va_arg(vp, size_t *)) = TOTAL(buf_p);
1710         else if (fld_s.flags & TYPE_TIME) /* eg, %Tn */
1711           *((time_t *)va_arg(vp, time_t *)) = TOTAL(buf_p);
1712         else /* eg, %n */
1713           *((int *)va_arg(vp, int *)) = TOTAL(buf_p);
1714         fld_s.flags = 0; /* no further processing required */
1715         break;
1716
1717       case 'm': /* write out a string describing an errno error */
1718         fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1719                           TYPE_MASK);
1720         fld_s.flags |= CONV_STRING;
1721         fld_s.value.v_ptr = (void *)strerror(errno);
1722         break;
1723
1724       case 'v': /* here's the infamous %v... */
1725         fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1726                          TYPE_MASK);
1727         fld_s.flags |= ARG_PTR | CONV_VARARGS;
1728         break;
1729
1730       case 'C': /* convert a client name... */
1731         fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1732                          TYPE_MASK);
1733         fld_s.flags |= ARG_PTR | CONV_CLIENT;
1734         break;
1735
1736       default: /* Unsupported, display a message and the entire format */
1737         adds(buf_p, -1, "(Unsupported: %");
1738         adds(buf_p, fmt - fstart + 1, fstart);
1739         addc(buf_p, ')');
1740         fld_s.flags = 0; /* no further processing required */
1741         break;
1742       } /* switch (*fmt) { */
1743
1744       break;
1745     } /* for (; *fmt; fmt++) { */
1746
1747     if (!*fmt) /* hit the end */
1748       break;
1749     else if (!(fld_s.flags & (ARG_MASK | CONV_MASK))) /* is it done? */
1750       continue;
1751
1752     if ((fld_s.flags & ARG_MASK) == ARG_INT) { /* grab an integer argument */
1753       if (fld_s.flags & INFO_UNSIGNED) { /* go direct if unsigned */
1754         if (fld_s.flags & TYPE_CHAR) /* eg, %hhu */
1755           fld_s.value.v_int = (unsigned char)va_arg(vp, unsigned int);
1756         else if (fld_s.flags & TYPE_SHORT) /* eg, %hu */
1757           fld_s.value.v_int = (short)va_arg(vp, unsigned int);
1758 #ifdef HAVE_LONG_LONG
1759         else if (fld_s.flags & TYPE_QUAD) /* eg, %qu */
1760           fld_s.value.v_int = va_arg(vp, _large_t);
1761 #endif
1762         else if (fld_s.flags & TYPE_LONG) /* eg, %lu */
1763           fld_s.value.v_int = va_arg(vp, unsigned long);
1764         else if (fld_s.flags & TYPE_INTMAX) /* eg, %ju */
1765           fld_s.value.v_int = va_arg(vp, _large_t);
1766         else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %tu */
1767           fld_s.value.v_int = va_arg(vp, ptrdiff_t);
1768         else if (fld_s.flags & TYPE_SIZE) /* eg, %zu */
1769           fld_s.value.v_int = va_arg(vp, size_t);
1770         else if (fld_s.flags & TYPE_TIME) /* eg, %Tu */
1771           fld_s.value.v_int = va_arg(vp, time_t);
1772         else if (fld_s.flags & TYPE_POINTER) /* eg, %p */
1773           fld_s.value.v_int = va_arg(vp, _pointer_t);
1774         else /* eg, %u */
1775           fld_s.value.v_int = va_arg(vp, unsigned int);
1776       } else {
1777         _large_t signed_int; /* temp. store the signed integer */
1778
1779         if (fld_s.flags & TYPE_CHAR) /* eg, %hhd */
1780           signed_int = (char)va_arg(vp, unsigned int);
1781         else if (fld_s.flags & TYPE_SHORT) /* eg, %hd */
1782           signed_int = (short)va_arg(vp, unsigned int);
1783 #ifdef HAVE_LONG_LONG
1784         else if (fld_s.flags & TYPE_QUAD) /* eg, %qd */
1785           signed_int = va_arg(vp, _large_t);
1786 #endif
1787         else if (fld_s.flags & TYPE_LONG) /* eg, %ld */
1788           signed_int = va_arg(vp, long);
1789         else if (fld_s.flags & TYPE_INTMAX) /* eg, %jd */
1790           signed_int = va_arg(vp, _large_t);
1791         else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %td */
1792           signed_int = va_arg(vp, ptrdiff_t);
1793         else if (fld_s.flags & TYPE_SIZE) /* eg, %zd */
1794           signed_int = va_arg(vp, size_t);
1795         else if (fld_s.flags & TYPE_TIME) /* eg, %Td */
1796           signed_int = va_arg(vp, time_t);
1797         else /* eg, %d */
1798           signed_int = va_arg(vp, int);
1799
1800         if (signed_int < 0) { /* Now figure out if it's negative... */
1801           fld_s.flags |= INFO_NEGATIVE;
1802           fld_s.value.v_int = -signed_int; /* negate safely (I hope) */
1803         } else
1804           fld_s.value.v_int = signed_int;
1805       }
1806     } else if ((fld_s.flags & ARG_MASK) == ARG_FLOAT) { /* extract a float */
1807       if (fld_s.flags & TYPE_LONGDOUBLE) /* eg, %Lf */
1808         fld_s.value.v_float = va_arg(vp, long double);
1809       else /* eg, %f */
1810         fld_s.value.v_float = va_arg(vp, double);
1811     } else if ((fld_s.flags & ARG_MASK) == ARG_PTR) { /* pointer argument */
1812       fld_s.value.v_ptr = va_arg(vp, void *);
1813     }
1814
1815     /* We've eaten the arguments, we have all the information we need for
1816      * the conversion.  Time to actually *do* the conversion
1817      */
1818     if ((fld_s.flags & CONV_MASK) == CONV_INT) {
1819       /* convert an integer */
1820       char intbuf[INTBUF_LEN], **table = 0, *tstr;
1821       int ibuf_loc = INTBUF_LEN, ilen, zlen = 0, plen = 0, elen = 0;
1822
1823       if (fld_s.base == BASE_OCTAL) /* select string table to use */
1824         table = octal;
1825       else if (fld_s.base == BASE_DECIMAL)
1826         table = decimal;
1827       else if (fld_s.base == BASE_HEX) { /* have to deal with upper case */
1828         table = (fld_s.flags & INFO_UPPERCASE) ? HEX : hex;
1829         if (fld_s.flags & FLAG_ALT)
1830           elen = 2; /* account for the length of 0x */
1831       }
1832
1833       if (fld_s.prec < 0) { /* default precision is 1 */
1834         if ((fld_s.flags & (FLAG_MINUS | FLAG_ZERO)) == FLAG_ZERO &&
1835             fld_s.width) {
1836           fld_s.prec = fld_s.width - elen;
1837           fld_s.width = 0;
1838         } else
1839           fld_s.prec = 1;
1840       }
1841
1842       /* If there's a sign flag, account for it */
1843       if (fld_s.flags & (FLAG_PLUS | FLAG_SPACE | INFO_NEGATIVE))
1844         elen++;
1845
1846       if (fld_s.base < 0) { /* non-binary base flagged by negative */
1847         fld_s.base = -fld_s.base; /* negate it... */
1848
1849         while (fld_s.value.v_int) { /* and convert it */
1850           tstr = table[fld_s.value.v_int % fld_s.base]; /* which string? */
1851           fld_s.value.v_int /= fld_s.base; /* next value */
1852
1853           ilen = 3; /* if we have to fill in zeros, here's how many */
1854
1855           while (*tstr) { /* add string to intbuf; note growing backwards */
1856             intbuf[--ibuf_loc] = *(tstr++);
1857             ilen--;
1858           }
1859
1860           if (fld_s.value.v_int > 0 && ilen) /* add zeros if needed */
1861             while (ilen--)
1862               intbuf[--ibuf_loc] = '0';
1863         }
1864       } else { /* optimize for powers of 2 */
1865         while (fld_s.value.v_int) { /* which string? */
1866           tstr = table[(fld_s.value.v_int & ((1 << fld_s.base) - 1))];
1867           fld_s.value.v_int >>= fld_s.base; /* next value */
1868
1869           ilen = 3; /* if we have to fill in zeros, here's how many */
1870
1871           while (*tstr) { /* add string to intbuf; note growing backwards */
1872             intbuf[--ibuf_loc] = *(tstr++);
1873             ilen--;
1874           }
1875
1876           if (fld_s.value.v_int > 0 && ilen) /* add zeros if needed */
1877             while (ilen--)
1878               intbuf[--ibuf_loc] = '0';
1879         }
1880       }
1881
1882       ilen = INTBUF_LEN - ibuf_loc; /* how many chars did we add? */
1883
1884       if (fld_s.prec > ilen) /* do we need any leading zeros? */
1885         zlen = fld_s.prec - ilen;
1886
1887       if (fld_s.base == BASE_OCTAL && zlen == 0 && fld_s.flags & FLAG_ALT)
1888         zlen++; /* factor in a leading zero for %#o */
1889
1890       if (fld_s.width > ilen + zlen + elen) /* calculate space padding */
1891         plen = fld_s.width - (ilen + zlen + elen);
1892
1893       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
1894         do_pad(buf_p, plen, spaces); /* pre-padding */
1895
1896       if (fld_s.flags & INFO_NEGATIVE) /* leading signs */
1897         addc(buf_p, '-');
1898       else if (fld_s.flags & FLAG_PLUS)
1899         addc(buf_p, '+');
1900       else if (fld_s.flags & FLAG_SPACE)
1901         addc(buf_p, ' ');
1902
1903       if ((fld_s.flags & FLAG_ALT) && fld_s.base == BASE_HEX) { /* hex 0x */
1904         addc(buf_p, '0');
1905         addc(buf_p, fld_s.flags & INFO_UPPERCASE ? 'X' : 'x');
1906       }
1907
1908       if (zlen > 0) /* leading zeros */
1909         do_pad(buf_p, zlen, zeros);
1910
1911       adds(buf_p, ilen, intbuf + ibuf_loc); /* add the integer string */
1912
1913       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
1914         do_pad(buf_p, plen, spaces); /* post-padding */
1915
1916       /* Don't support floating point at this time; it's too complicated */
1917 /*      } else if ((fld_s.flags & CONV_MASK) == CONV_FLOAT) { */
1918       /* convert a float */
1919     } else if ((fld_s.flags & CONV_MASK) == CONV_CHAR) {
1920       if (fld_s.width > 0 && !(fld_s.flags & FLAG_MINUS))
1921         do_pad(buf_p, fld_s.width - 1, spaces); /* pre-padding */
1922
1923       addc(buf_p, fld_s.value.v_int); /* add the character */
1924
1925       if (fld_s.width > 0 &&  (fld_s.flags & FLAG_MINUS))
1926         do_pad(buf_p, fld_s.width - 1, spaces); /* post-padding */
1927     } else if ((fld_s.flags & CONV_MASK) == CONV_STRING ||
1928                fld_s.value.v_ptr == 0) { /* spaces or null pointers */
1929       int slen, plen;
1930       char *str = fld_s.value.v_ptr;
1931
1932       if (!str) /* NULL pointers print "(null)" */
1933         str = "(null)";
1934
1935       slen = my_strnlen(str, fld_s.prec); /* str lengths and pad lengths */
1936       plen = (fld_s.width - slen <= 0 ? 0 : fld_s.width - slen);
1937
1938       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
1939         do_pad(buf_p, plen, spaces); /* pre-padding */
1940
1941       adds(buf_p, slen, str); /* add the string */
1942
1943       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
1944         do_pad(buf_p, plen, spaces); /* post-padding */
1945     } else if ((fld_s.flags & CONV_MASK) == CONV_VARARGS) {
1946       struct BufData buf_s = BUFDATA_INIT;
1947       struct VarData *vdata = fld_s.value.v_ptr;
1948       int plen, tlen;
1949
1950       buf_s.buf = buf_p->buf + buf_p->buf_loc;
1951       buf_s.buf_size = buf_p->buf_size - buf_p->buf_loc;
1952       buf_s.limit = fld_s.prec;
1953
1954       doprintf(dest, &buf_s, vdata->vd_format, vdata->vd_args);
1955
1956       plen = (fld_s.width - buf_s.buf_loc <= 0 ? 0 :
1957               fld_s.width - buf_s.buf_loc);
1958
1959       if (plen > 0) {
1960         if (fld_s.flags & FLAG_MINUS) { /* left aligned... */
1961           buf_p->buf_loc += buf_s.buf_loc; /* remember the modifications */
1962           buf_p->buf_overflow += buf_s.buf_overflow;
1963
1964           do_pad(buf_p, plen, spaces); /* and do the post-padding */
1965         } else { /* right aligned... */
1966           /* Ok, first, see if we'll have *anything* left after padding */
1967           if (plen > buf_s.buf_size) {
1968             /* nope, good, this is easy: everything overflowed buffer */
1969             do_pad(buf_p, plen, spaces);
1970
1971             buf_s.buf_overflow += buf_s.buf_loc; /* update buf counts */
1972             buf_s.buf_loc = 0;
1973             buf_p->buf_overflow += buf_s.buf_overflow;
1974           } else {
1975             /* first figure out how much we're going to save */
1976             tlen = SNP_MIN(buf_s.buf_loc, buf_s.buf_size - plen);
1977
1978             memmove(buf_s.buf + plen, buf_s.buf, tlen); /* save it... */
1979             do_pad(buf_p, plen, spaces); /* add spaces... */
1980
1981             buf_s.buf_overflow += buf_s.buf_loc - tlen; /* update buf counts */
1982             buf_s.buf_loc = tlen;
1983             buf_p->buf_overflow += buf_s.buf_overflow;
1984             buf_p->buf_loc += buf_s.buf_loc;
1985           }
1986         }
1987       } else {
1988         buf_p->buf_loc += buf_s.buf_loc; /* no padding, but remember mods */
1989         buf_p->buf_overflow += buf_s.buf_overflow;
1990       }
1991
1992       vdata->vd_chars = buf_s.buf_loc; /* return relevant data */
1993       vdata->vd_overflow = SNP_MAX(buf_s.buf_overflow, buf_s.overflow);
1994     } else if ((fld_s.flags & CONV_MASK) == CONV_CLIENT) {
1995       struct Client *cptr = fld_s.value.v_ptr;
1996       char *str1 = 0, *str2 = 0;
1997       int slen1 = 0, slen2 = 0, plen = 0;
1998
1999       if (dest && IsServer(dest)) {
2000         if (IsServer(cptr))
2001           str1 = cptr->yxx;
2002         else {
2003           str1 = cptr->user->server->yxx;
2004           str2 = cptr->yxx;
2005         }
2006       } else
2007         str1 = cptr->name;
2008
2009       slen1 = my_strnlen(str1, fld_s.prec);
2010       if (str2 && (fld_s.prec < 0 || fld_s.prec - slen1 > 0))
2011         slen2 = my_strnlen(str2, fld_s.prec < 0 ? -1 : fld_s.prec - slen1);
2012       plen = (fld_s.width - (slen1 + slen2) <= 0 ? 0 :
2013               fld_s.width - (slen1 + slen2));
2014
2015       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
2016         do_pad(buf_p, plen, spaces); /* pre-padding */
2017
2018       adds(buf_p, slen1, str1);
2019       if (str2)
2020         adds(buf_p, slen2, str2);
2021
2022       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
2023         do_pad(buf_p, plen, spaces); /* post-padding */
2024     }
2025   } /* for (; *fmt; fmt++) { */
2026 }
2027
2028 int
2029 ircd_snprintf(struct Client *dest, char *buf, size_t buf_len,
2030               const char *format, ...)
2031 {
2032   struct BufData buf_s = BUFDATA_INIT;
2033   va_list args;
2034
2035   if (!format)
2036     return 0;
2037
2038   buf_s.buf = buf; /* initialize buffer settings */
2039   buf_s.buf_size = buf_len - 1;
2040   buf_s.limit = -1;
2041
2042   va_start(args, format);
2043   doprintf(dest, &buf_s, format, args); /* fill the buffer */
2044   va_end(args);
2045
2046   buf_s.buf[buf_s.buf_loc] = '\0'; /* terminate buffer */
2047
2048   return TOTAL(&buf_s);
2049 }
2050
2051 int
2052 ircd_vsnprintf(struct Client *dest, char *buf, size_t buf_len,
2053                const char *format, va_list args)
2054 {
2055   struct BufData buf_s = BUFDATA_INIT;
2056
2057   if (!format)
2058     return 0;
2059
2060   buf_s.buf = buf; /* initialize buffer settings */
2061   buf_s.buf_size = buf_len - 1;
2062   buf_s.limit = -1;
2063
2064   doprintf(dest, &buf_s, format, args); /* fill the buffer */
2065
2066   buf_s.buf[buf_s.buf_loc] = '\0'; /* terminate buffer */
2067
2068   return TOTAL(&buf_s);
2069 }