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