1 #! /usr/bin/env node 2 3 /* 4 * Copyright (c) 2012 Joyent, Inc. All rights reserved. 5 */ 6 7 var util = require('util'); 8 var fs = require('fs'); 9 var mod_getopt = require('posix-getopt'); 10 11 var prologue = 12 '/*\n' + 13 ' * STOP!\n' + 14 ' *\n' + 15 ' * Do not edit this file. It is automatically generated by generrno.\n' + 16 ' */\n\n'; 17 18 var guard_prologue = 19 '#ifndef\t_V8PLUS_ERRNO_H\n' + 20 '#define\t_V8PLUS_ERRNO_H\n\n' + 21 '#ifdef\t__cplusplus\n' + 22 'extern "C" {\n' + 23 '#endif\t/* __cplusplus */\n'; 24 25 var decl_prologue = 26 '#define\tV8PLUS_ERRNO_BASE\t%s\n\n' + 27 'typedef enum _v8plus_errno {\n' + 28 '\tV8PLUSERR_NOERROR = 0,\n' + 29 '\tV8PLUSERR_%s = V8PLUS_ERRNO_BASE + 1,\n'; 30 31 var decl_one = 32 '\tV8PLUSERR_%s,\n'; 33 34 var decl_epilogue = 35 '} v8plus_errno_t;\n'; 36 37 var guard_epilogue = 38 '#ifdef\t__cplusplus\n' + 39 '}\n' + 40 '#endif\t/* __cplusplus */\n\n' + 41 '#endif\t/* _V8PLUS_ERRNO_H */\n'; 42 43 var include = 44 '#include "v8plus_errno.h"\n\n'; 45 46 var func_prologue = 47 'const char *\n' + 48 'v8plus_%s(v8plus_errno_t e)\n' + 49 '{\n' + 50 '\tswitch (e) {\n'; 51 52 var generic_case = 53 '\tcase V8PLUSERR_%s:\n' + 54 '\t\treturn ("%s");\n'; 55 56 var errname_case = 57 '\tcase V8PLUSERR_%s:\n' + 58 '\t\treturn ("V8PLUSERR_%s");\n'; 59 60 var func_epilogue = 61 '\tdefault:\n' + 62 '\t\treturn ("%s");\n' + 63 '\t}\n' + 64 '}\n'; 65 66 var BUILTIN_ERRORS = [ 67 { 68 code: 'NOMEM', 69 msg: 'out of memory', 70 exception: 'Error' 71 }, 72 { 73 code: 'YOUSUCK', 74 msg: 'programmer error', 75 exception: 'Error' 76 }, 77 { 78 code: 'UNKNOWN', 79 msg: 'unknown error', 80 exception: 'Error' 81 }, 82 { 83 code: 'MISSINGARG', 84 msg: 'missing argument is required', 85 exception: 'TypeError' 86 }, 87 { 88 code: 'BADARG', 89 msg: 'argument is of incorrect type', 90 exception: 'TypeError' 91 }, 92 { 93 code: 'EXTRAARG', 94 msg: 'superfluous argument(s) detected', 95 exception: 'TypeError' 96 }, 97 { 98 code: 'BADF', 99 msg: 'bad file descriptor', 100 exception: 'Error' 101 } 102 ]; 103 104 function 105 usage() 106 { 107 console.log(process.argv[0] + ' ' + process.argv[1] + 108 ' {-c|-h} [-o <output>] <input>\n'); 109 process.exit(1); 110 } 111 112 function 113 parse_arguments(argv) 114 { 115 var opt_c = 0; 116 var opt_h = 0; 117 var option; 118 var obj = {}; 119 var parser = new mod_getopt.BasicParser('cho:', argv); 120 var defs; 121 122 while ((option = parser.getopt()) !== undefined && !option.error) { 123 switch (option.option) { 124 case 'c': 125 opt_c++; 126 obj.action = 'c'; 127 break; 128 case 'h': 129 opt_h++; 130 obj.action = 'h'; 131 break; 132 case 'o': 133 obj.output = option.optarg; 134 break; 135 default: 136 usage(); 137 break; 138 } 139 } 140 141 obj.input = argv[parser.optind()]; 142 143 if (opt_c + opt_h != 1) 144 usage(); 145 146 if (!obj.input) 147 usage(); 148 149 defs = fs.readFileSync(obj.input); 150 obj.defs = JSON.parse(defs); 151 152 BUILTIN_ERRORS.forEach(function _prepend_err(e) { 153 obj.defs.errors.unshift(e); 154 }); 155 156 return (obj); 157 } 158 159 function 160 write(output, str) 161 { 162 if (!output) 163 process.stdout.write(str); 164 else 165 fs.writeFileSync(output, str) 166 } 167 168 function 169 write_c(defs, output) 170 { 171 var out = ''; 172 173 out += prologue; 174 out += include; 175 176 out += util.format(func_prologue, 'strerror'); 177 defs.errors.forEach(function _append_str(e) { 178 out += util.format(generic_case, e.code, e.msg); 179 }); 180 out += util.format(func_epilogue, 'unknown v8+ error code'); 181 out += '\n'; 182 183 out += util.format(func_prologue, 'errname'); 184 defs.errors.forEach(function _append_name(e) { 185 out += util.format(errname_case, e.code, e.code); 186 }); 187 out += util.format(func_epilogue, 'unknown v8+ error code'); 188 out += '\n'; 189 190 out += util.format(func_prologue, 'excptype'); 191 defs.errors.forEach(function _append_excp(e) { 192 out += util.format(generic_case, e.code, e.exception); 193 }); 194 out += util.format(func_epilogue, 'Error'); 195 196 write(output, out); 197 } 198 199 function 200 write_header(defs, output) 201 { 202 var out = ''; 203 204 out += prologue; 205 out += guard_prologue; 206 out += util.format(decl_prologue, defs.error_base, defs.errors[0].code); 207 defs.errors.forEach(function _spew_decl(e, i) { 208 if (i > 0) 209 out += util.format(decl_one, e.code); 210 }); 211 out += decl_epilogue; 212 out += guard_epilogue; 213 214 write(output, out); 215 } 216 217 var action = parse_arguments(process.argv); 218 219 switch (action.action) { 220 case 'c': 221 write_c(action.defs, action.output); 222 break; 223 case 'h': 224 write_header(action.defs, action.output); 225 break; 226 default: 227 usage(); 228 break; 229 }