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