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