Changeset 439 for EcnlProtoTool/trunk/prototool
- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- Location:
- EcnlProtoTool/trunk/prototool
- Files:
-
- 2 added
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/prototool/.cproject
r427 r439 81 81 <listOptionValue builtIn="false" value=""${workspace_loc:/musl-1.1.18/include}""/> 82 82 <listOptionValue builtIn="false" value=""${workspace_loc:}/onigmo-6.1.3/src""/> 83 <listOptionValue builtIn="false" value=""${workspace_loc:/mruby- 1.3.0/include}""/>83 <listOptionValue builtIn="false" value=""${workspace_loc:/mruby-2.1.1/include}""/> 84 84 <listOptionValue builtIn="false" value=""${workspace_loc:/mbed_api/src}""/> 85 85 <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src}""/> … … 88 88 </option> 89 89 <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.165293534" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols"> 90 <listOptionValue builtIn="false" value="MRB_ GC_STRESS"/>90 <listOptionValue builtIn="false" value="MRB_USE_CUSTOM_RO_DATA_P"/> 91 91 <listOptionValue builtIn="false" value="MRB_ENABLE_DEBUG_HOOK"/> 92 <listOptionValue builtIn="false" value="MRB_CONSTRAINED_BASELINE_PROFILE"/> 92 93 <listOptionValue builtIn="false" value="_DEFAULT_SOURCE"/> 93 94 </option> … … 149 150 <listOptionValue builtIn="false" value=""${workspace_loc:/onigmo-6.1.3/Debug}""/> 150 151 <listOptionValue builtIn="false" value=""${workspace_loc:/mbed_api/Debug}""/> 151 <listOptionValue builtIn="false" value=""${workspace_loc:/mruby- 1.3.0/build/arm-none-eabi/lib}""/>152 <listOptionValue builtIn="false" value=""${workspace_loc:/mruby-2.1.1/build/arm-none-eabi/lib}""/> 152 153 <listOptionValue builtIn="false" value=""${TCINSTALL}/lib/gcc/arm-none-eabi/${GCC_VERSION}/thumb/v7-ar/fpv3/hard""/> 153 154 <listOptionValue builtIn="false" value=""${TCINSTALL}/arm-none-eabi/lib/thumb/v7-ar/fpv3/hard""/> … … 165 166 <listOptionValue builtIn="false" value=""${workspace_loc:/onigmo-6.1.3/Debug}/libonigmo.a""/> 166 167 <listOptionValue builtIn="false" value=""${workspace_loc:/mbed_api/Debug}/libmbed_api.a""/> 167 <listOptionValue builtIn="false" value=""${workspace_loc:/mruby- 1.3.0}/build/arm-none-eabi/lib/libmruby.a""/>168 <listOptionValue builtIn="false" value=""${workspace_loc:/mruby-2.1.1}/build/arm-none-eabi/lib/libmruby.a""/> 168 169 <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/lib}/libmrbcode.a""/> 169 170 </option> -
EcnlProtoTool/trunk/prototool/.project
r424 r439 6 6 <project>curl-7.57.0</project> 7 7 <project>mbed_api</project> 8 <project>mruby- 1.3.0</project>8 <project>mruby-2.1.1</project> 9 9 <project>ntshell</project> 10 10 <project>onigmo-6.1.3</project> -
EcnlProtoTool/trunk/prototool/debug_setting.txt
r438 r439 1 2 -f interface/cmsis-dap.cfg -f target/renesas_rza1h_swd.cfg 3 1 4 add-symbol-file ../ntshell/Debug/ntshell.elf 0x18004000 -
EcnlProtoTool/trunk/prototool/lib/makefile.mrbc
r331 r439 2 2 CC=arm-none-eabi-gcc 3 3 AR=arm-none-eabi-ar 4 MRBC=../../mruby- 1.3.0/bin/mrbc4 MRBC=../../mruby-2.1.1/bin/mrbc 5 5 6 CFLAGS=-mcpu=cortex-a9 -march=armv7-a -mlittle-endian -marm -mthumb-interwork -mfloat-abi=hard -mfpu=vfpv3 -I../../mruby- 1.3.0/include6 CFLAGS=-mcpu=cortex-a9 -march=armv7-a -mlittle-endian -marm -mthumb-interwork -mfloat-abi=hard -mfpu=vfpv3 -I../../mruby-2.1.1/include 7 7 COBJS=echo_server.o echo_client.o 8 8 CSRCS=$(foreach file,$(COBJS),$(file:.o=.c)) -
EcnlProtoTool/trunk/prototool/src/apibreak.c
r321 r439 4 4 */ 5 5 6 #include <stdlib.h>7 6 #include <string.h> 8 9 #include "mruby.h" 10 #include "mruby/irep.h" 7 #include <mruby.h> 8 #include <mruby/irep.h> 11 9 #include "mrdb.h" 12 #include "mruby/debug.h"13 #include "mruby/opcode.h"14 #include "mruby/class.h"15 #include "mruby/proc.h"16 #include "mruby/variable.h"10 #include <mruby/debug.h> 11 #include <mruby/opcode.h> 12 #include <mruby/class.h> 13 #include <mruby/proc.h> 14 #include <mruby/variable.h> 17 15 #include "mrdberror.h" 18 16 #include "apibreak.h" … … 25 23 check_lineno(mrb_irep_debug_info_file *info_file, uint16_t lineno) 26 24 { 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 25 uint32_t count = info_file->line_entry_count; 26 uint16_t l_idx; 27 28 if (info_file->line_type == mrb_debug_line_ary) { 29 for (l_idx = 0; l_idx < count; ++l_idx) { 30 if (lineno == info_file->lines.ary[l_idx]) { 31 return lineno; 32 } 33 } 34 } 35 else { 36 for (l_idx = 0; l_idx < count; ++l_idx) { 37 if (lineno == info_file->lines.flat_map[l_idx].line) { 38 return lineno; 39 } 40 } 41 } 42 43 return 0; 46 44 } 47 45 … … 49 47 get_break_index(mrb_debug_context *dbg, uint32_t bpno) 50 48 { 51 52 53 54 55 for (i = 0; i < dbg->bpnum; i++) {56 57 58 59 60 61 62 63 64 65 66 67 49 uint32_t i; 50 int32_t index; 51 char hit = FALSE; 52 53 for(i = 0 ; i < dbg->bpnum; i++) { 54 if (dbg->bp[i].bpno == bpno) { 55 hit = TRUE; 56 index = i; 57 break; 58 } 59 } 60 61 if (hit == FALSE) { 62 return MRB_DEBUG_BREAK_INVALID_NO; 63 } 64 65 return index; 68 66 } 69 67 … … 71 69 free_breakpoint(mrb_state *mrb, mrb_debug_breakpoint *bp) 72 70 { 73 switch(bp->type) {74 75 76 77 78 79 80 81 82 83 84 85 71 switch(bp->type) { 72 case MRB_DEBUG_BPTYPE_LINE: 73 mrb_free(mrb, (void*)bp->point.linepoint.file); 74 break; 75 case MRB_DEBUG_BPTYPE_METHOD: 76 mrb_free(mrb, (void*)bp->point.methodpoint.method_name); 77 if (bp->point.methodpoint.class_name != NULL) { 78 mrb_free(mrb, (void*)bp->point.methodpoint.class_name); 79 } 80 break; 81 default: 82 break; 83 } 86 84 } 87 85 88 86 static uint16_t 89 check_file_lineno(struct mrb_irep *irep, const char *file, uint16_t lineno) 90 { 91 mrb_irep_debug_info_file *info_file; 92 uint16_t result = 0; 93 uint16_t f_idx; 94 uint16_t fix_lineno; 95 uint16_t i; 96 97 for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { 98 info_file = irep->debug_info->files[f_idx]; 99 if (!strcmp(info_file->filename, file)) { 100 result = MRB_DEBUG_BP_FILE_OK; 101 102 fix_lineno = check_lineno(info_file, lineno); 103 if (fix_lineno != 0) { 104 return result | MRB_DEBUG_BP_LINENO_OK; 105 } 106 } 107 for (i = 0; i < irep->rlen; ++i) { 108 result |= check_file_lineno(irep->reps[i], file, lineno); 109 if (result == (MRB_DEBUG_BP_FILE_OK | MRB_DEBUG_BP_LINENO_OK)) { 110 return result; 111 } 112 } 113 } 114 return result; 115 } 116 117 static const char* 118 get_class_name(mrb_state *mrb, struct RClass *class_obj) 119 { 120 struct RClass *outer; 121 mrb_sym class_sym; 122 123 outer = mrb_class_outer_module(mrb, class_obj); 124 class_sym = mrb_class_sym(mrb, class_obj, outer); 125 return mrb_sym2name(mrb, class_sym); 87 check_file_lineno(mrb_state *mrb, struct mrb_irep *irep, const char *file, uint16_t lineno) 88 { 89 mrb_irep_debug_info_file *info_file; 90 uint16_t result = 0; 91 uint16_t f_idx; 92 uint16_t fix_lineno; 93 uint16_t i; 94 95 for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { 96 const char *filename; 97 info_file = irep->debug_info->files[f_idx]; 98 filename = mrb_sym_name_len(mrb, info_file->filename_sym, NULL); 99 if (!strcmp(filename, file)) { 100 result = MRB_DEBUG_BP_FILE_OK; 101 102 fix_lineno = check_lineno(info_file, lineno); 103 if (fix_lineno != 0) { 104 return result | MRB_DEBUG_BP_LINENO_OK; 105 } 106 } 107 for (i=0; i < irep->rlen; ++i) { 108 result |= check_file_lineno(mrb, irep->reps[i], file, lineno); 109 if (result == (MRB_DEBUG_BP_FILE_OK | MRB_DEBUG_BP_LINENO_OK)) { 110 return result; 111 } 112 } 113 } 114 return result; 126 115 } 127 116 … … 129 118 compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *class_obj, mrb_sym method_sym, mrb_bool* isCfunc) 130 119 { 131 132 133 struct RProc*m;134 135 136 137 138 139 140 method_name = mrb_sym2name(mrb, method_sym);141 142 143 144 class_name = get_class_name(mrb, class_obj);145 146 147 148 149 150 151 152 if (m == NULL) {153 154 155 if (MRB_PROC_CFUNC_P(m)) {156 157 158 159 160 161 162 163 164 165 166 167 if (m == NULL) {168 169 170 171 class_name = get_class_name(mrb, class_obj);172 sn = get_class_name(mrb, sc);173 174 175 176 177 178 120 const char* class_name; 121 const char* method_name; 122 mrb_method_t m; 123 struct RClass* sc; 124 const char* sn; 125 mrb_sym ssym; 126 mrb_debug_methodpoint *method_p; 127 mrb_bool is_defined; 128 129 method_name = mrb_sym_name(mrb, method_sym); 130 131 method_p = &bp->point.methodpoint; 132 if (strcmp(method_p->method_name, method_name) == 0) { 133 class_name = mrb_class_name(mrb, class_obj); 134 if (class_name == NULL) { 135 if (method_p->class_name == NULL) { 136 return bp->bpno; 137 } 138 } 139 else if (method_p->class_name != NULL) { 140 m = mrb_method_search_vm(mrb, &class_obj, method_sym); 141 if (MRB_METHOD_UNDEF_P(m)) { 142 return MRB_DEBUG_OK; 143 } 144 if (MRB_METHOD_CFUNC_P(m)) { 145 *isCfunc = TRUE; 146 } 147 148 is_defined = mrb_class_defined(mrb, method_p->class_name); 149 if (is_defined == FALSE) { 150 return MRB_DEBUG_OK; 151 } 152 153 sc = mrb_class_get(mrb, method_p->class_name); 154 ssym = mrb_symbol(mrb_check_intern_cstr(mrb, method_p->method_name)); 155 m = mrb_method_search_vm(mrb, &sc, ssym); 156 if (MRB_METHOD_UNDEF_P(m)) { 157 return MRB_DEBUG_OK; 158 } 159 160 class_name = mrb_class_name(mrb, class_obj); 161 sn = mrb_class_name(mrb, sc); 162 if (strcmp(sn, class_name) == 0) { 163 return bp->bpno; 164 } 165 } 166 } 167 return MRB_DEBUG_OK; 179 168 } 180 169 … … 182 171 mrb_debug_set_break_line(mrb_state *mrb, mrb_debug_context *dbg, const char *file, uint16_t lineno) 183 172 { 184 int32_t index; 185 char* set_file; 186 uint16_t result; 187 188 if ((mrb == NULL) || (dbg == NULL) || (file == NULL)) { 189 return MRB_DEBUG_INVALID_ARGUMENT; 190 } 191 192 if (dbg->bpnum >= MAX_BREAKPOINT) { 193 return MRB_DEBUG_BREAK_NUM_OVER; 194 } 195 196 if (dbg->next_bpno > MAX_BREAKPOINTNO) { 197 return MRB_DEBUG_BREAK_NO_OVER; 198 } 199 200 /* file and lineno check (line type mrb_debug_line_ary only.) */ 201 result = check_file_lineno(dbg->root_irep, file, lineno); 202 if (result == 0) { 203 return MRB_DEBUG_BREAK_INVALID_FILE; 204 } 205 else if (result == MRB_DEBUG_BP_FILE_OK) { 206 return MRB_DEBUG_BREAK_INVALID_LINENO; 207 } 208 209 int len = strlen(file) + 1; 210 set_file = (char *)mrb_malloc(mrb, len); 211 212 index = dbg->bpnum; 213 dbg->bp[index].bpno = dbg->next_bpno; 214 dbg->next_bpno++; 215 dbg->bp[index].enable = TRUE; 216 dbg->bp[index].type = MRB_DEBUG_BPTYPE_LINE; 217 dbg->bp[index].point.linepoint.lineno = lineno; 218 dbg->bpnum++; 219 220 strlcpy(set_file, file, len); 221 222 dbg->bp[index].point.linepoint.file = set_file; 223 224 return dbg->bp[index].bpno; 173 int32_t index; 174 char* set_file; 175 uint16_t result; 176 177 if ((mrb == NULL)||(dbg == NULL)||(file == NULL)) { 178 return MRB_DEBUG_INVALID_ARGUMENT; 179 } 180 181 if (dbg->bpnum >= MAX_BREAKPOINT) { 182 return MRB_DEBUG_BREAK_NUM_OVER; 183 } 184 185 if (dbg->next_bpno > MAX_BREAKPOINTNO) { 186 return MRB_DEBUG_BREAK_NO_OVER; 187 } 188 189 /* file and lineno check (line type mrb_debug_line_ary only.) */ 190 result = check_file_lineno(mrb, dbg->root_irep, file, lineno); 191 if (result == 0) { 192 return MRB_DEBUG_BREAK_INVALID_FILE; 193 } 194 else if (result == MRB_DEBUG_BP_FILE_OK) { 195 return MRB_DEBUG_BREAK_INVALID_LINENO; 196 } 197 198 set_file = (char*)mrb_malloc(mrb, strlen(file) + 1); 199 200 index = dbg->bpnum; 201 dbg->bp[index].bpno = dbg->next_bpno; 202 dbg->next_bpno++; 203 dbg->bp[index].enable = TRUE; 204 dbg->bp[index].type = MRB_DEBUG_BPTYPE_LINE; 205 dbg->bp[index].point.linepoint.lineno = lineno; 206 dbg->bpnum++; 207 208 strncpy(set_file, file, strlen(file) + 1); 209 210 dbg->bp[index].point.linepoint.file = set_file; 211 212 return dbg->bp[index].bpno; 225 213 } 226 214 … … 228 216 mrb_debug_set_break_method(mrb_state *mrb, mrb_debug_context *dbg, const char *class_name, const char *method_name) 229 217 { 230 int32_t index; 231 char* set_class; 232 char* set_method; 233 int len; 234 235 if ((mrb == NULL) || (dbg == NULL) || (method_name == NULL)) { 236 return MRB_DEBUG_INVALID_ARGUMENT; 237 } 238 239 if (dbg->bpnum >= MAX_BREAKPOINT) { 240 return MRB_DEBUG_BREAK_NUM_OVER; 241 } 242 243 if (dbg->next_bpno > MAX_BREAKPOINTNO) { 244 return MRB_DEBUG_BREAK_NO_OVER; 245 } 246 247 if (class_name != NULL) { 248 len = strlen(class_name) + 1; 249 set_class = (char *)mrb_malloc(mrb, len); 250 strlcpy(set_class, class_name, len); 251 } 252 else { 253 set_class = NULL; 254 } 255 256 len = strlen(method_name) + 1; 257 set_method = (char *)mrb_malloc(mrb, len); 258 259 strlcpy(set_method, method_name, len); 260 261 index = dbg->bpnum; 262 dbg->bp[index].bpno = dbg->next_bpno; 263 dbg->next_bpno++; 264 dbg->bp[index].enable = TRUE; 265 dbg->bp[index].type = MRB_DEBUG_BPTYPE_METHOD; 266 dbg->bp[index].point.methodpoint.method_name = set_method; 267 dbg->bp[index].point.methodpoint.class_name = set_class; 268 dbg->bpnum++; 269 270 return dbg->bp[index].bpno; 218 int32_t index; 219 char* set_class; 220 char* set_method; 221 222 if ((mrb == NULL) || (dbg == NULL) || (method_name == NULL)) { 223 return MRB_DEBUG_INVALID_ARGUMENT; 224 } 225 226 if (dbg->bpnum >= MAX_BREAKPOINT) { 227 return MRB_DEBUG_BREAK_NUM_OVER; 228 } 229 230 if (dbg->next_bpno > MAX_BREAKPOINTNO) { 231 return MRB_DEBUG_BREAK_NO_OVER; 232 } 233 234 if (class_name != NULL) { 235 set_class = (char*)mrb_malloc(mrb, strlen(class_name) + 1); 236 strncpy(set_class, class_name, strlen(class_name) + 1); 237 } 238 else { 239 set_class = NULL; 240 } 241 242 set_method = (char*)mrb_malloc(mrb, strlen(method_name) + 1); 243 244 strncpy(set_method, method_name, strlen(method_name) + 1); 245 246 index = dbg->bpnum; 247 dbg->bp[index].bpno = dbg->next_bpno; 248 dbg->next_bpno++; 249 dbg->bp[index].enable = TRUE; 250 dbg->bp[index].type = MRB_DEBUG_BPTYPE_METHOD; 251 dbg->bp[index].point.methodpoint.method_name = set_method; 252 dbg->bp[index].point.methodpoint.class_name = set_class; 253 dbg->bpnum++; 254 255 return dbg->bp[index].bpno; 271 256 } 272 257 … … 274 259 mrb_debug_get_breaknum(mrb_state *mrb, mrb_debug_context *dbg) 275 260 { 276 277 278 279 280 281 } 282 283 int32_t 284 mrb_debug_get_break_all(mrb_state *mrb, mrb_debug_context *dbg, uint32_t size, mrb_debug_breakpoint bp[])285 { 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 261 if ((mrb == NULL) || (dbg == NULL)) { 262 return MRB_DEBUG_INVALID_ARGUMENT; 263 } 264 265 return dbg->bpnum; 266 } 267 268 int32_t 269 mrb_debug_get_break_all(mrb_state *mrb, mrb_debug_context *dbg, uint32_t size, mrb_debug_breakpoint *bp) 270 { 271 uint32_t get_size = 0; 272 273 if ((mrb == NULL) || (dbg == NULL) || (bp == NULL)) { 274 return MRB_DEBUG_INVALID_ARGUMENT; 275 } 276 277 if (dbg->bpnum >= size) { 278 get_size = size; 279 } 280 else { 281 get_size = dbg->bpnum; 282 } 283 284 memcpy(bp, dbg->bp, sizeof(mrb_debug_breakpoint) * get_size); 285 286 return get_size; 302 287 } 303 288 … … 307 292 int32_t index; 308 293 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 294 if ((mrb == NULL) || (dbg == NULL) || (bp == NULL)) { 295 return MRB_DEBUG_INVALID_ARGUMENT; 296 } 297 298 index = get_break_index(dbg, bpno); 299 if (index == MRB_DEBUG_BREAK_INVALID_NO) { 300 return MRB_DEBUG_BREAK_INVALID_NO; 301 } 302 303 bp->bpno = dbg->bp[index].bpno; 304 bp->enable = dbg->bp[index].enable; 305 bp->point = dbg->bp[index].point; 306 bp->type = dbg->bp[index].type; 307 308 return 0; 324 309 } 325 310 … … 327 312 mrb_debug_delete_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno) 328 313 { 329 330 331 332 if ((mrb == NULL) ||(dbg == NULL)) {333 334 335 336 337 338 339 340 341 342 343 for (i = index; i < dbg->bpnum; i++) {344 345 346 347 348 349 350 351 352 353 354 314 uint32_t i; 315 int32_t index; 316 317 if ((mrb == NULL) ||(dbg == NULL)) { 318 return MRB_DEBUG_INVALID_ARGUMENT; 319 } 320 321 index = get_break_index(dbg, bpno); 322 if (index == MRB_DEBUG_BREAK_INVALID_NO) { 323 return MRB_DEBUG_BREAK_INVALID_NO; 324 } 325 326 free_breakpoint(mrb, &dbg->bp[index]); 327 328 for(i = index ; i < dbg->bpnum; i++) { 329 if ((i + 1) == dbg->bpnum) { 330 memset(&dbg->bp[i], 0, sizeof(mrb_debug_breakpoint)); 331 } 332 else { 333 memcpy(&dbg->bp[i], &dbg->bp[i + 1], sizeof(mrb_debug_breakpoint)); 334 } 335 } 336 337 dbg->bpnum--; 338 339 return MRB_DEBUG_OK; 355 340 } 356 341 … … 358 343 mrb_debug_delete_break_all(mrb_state *mrb, mrb_debug_context *dbg) 359 344 { 360 361 362 363 364 365 366 for (i = 0; i < dbg->bpnum; i++) {367 368 369 370 371 372 345 uint32_t i; 346 347 if ((mrb == NULL) || (dbg == NULL)) { 348 return MRB_DEBUG_INVALID_ARGUMENT; 349 } 350 351 for(i = 0 ; i < dbg->bpnum ; i++) { 352 free_breakpoint(mrb, &dbg->bp[i]); 353 } 354 355 dbg->bpnum = 0; 356 357 return MRB_DEBUG_OK; 373 358 } 374 359 … … 376 361 mrb_debug_enable_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno) 377 362 { 378 379 380 381 382 383 384 385 386 387 388 389 390 391 363 int32_t index = 0; 364 365 if ((mrb == NULL) || (dbg == NULL)) { 366 return MRB_DEBUG_INVALID_ARGUMENT; 367 } 368 369 index = get_break_index(dbg, bpno); 370 if (index == MRB_DEBUG_BREAK_INVALID_NO) { 371 return MRB_DEBUG_BREAK_INVALID_NO; 372 } 373 374 dbg->bp[index].enable = TRUE; 375 376 return MRB_DEBUG_OK; 392 377 } 393 378 … … 395 380 mrb_debug_enable_break_all(mrb_state *mrb, mrb_debug_context *dbg) 396 381 { 397 398 399 400 401 402 403 for (i = 0; i < dbg->bpnum; i++) {404 405 406 407 382 uint32_t i; 383 384 if ((mrb == NULL) || (dbg == NULL)) { 385 return MRB_DEBUG_INVALID_ARGUMENT; 386 } 387 388 for(i = 0 ; i < dbg->bpnum; i++) { 389 dbg->bp[i].enable = TRUE; 390 } 391 392 return MRB_DEBUG_OK; 408 393 } 409 394 … … 411 396 mrb_debug_disable_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno) 412 397 { 413 414 415 416 417 418 419 420 421 422 423 424 425 426 398 int32_t index = 0; 399 400 if ((mrb == NULL) || (dbg == NULL)) { 401 return MRB_DEBUG_INVALID_ARGUMENT; 402 } 403 404 index = get_break_index(dbg, bpno); 405 if (index == MRB_DEBUG_BREAK_INVALID_NO) { 406 return MRB_DEBUG_BREAK_INVALID_NO; 407 } 408 409 dbg->bp[index].enable = FALSE; 410 411 return MRB_DEBUG_OK; 427 412 } 428 413 … … 430 415 mrb_debug_disable_break_all(mrb_state *mrb, mrb_debug_context *dbg) 431 416 { 432 433 434 435 436 437 438 for (i = 0; i < dbg->bpnum; i++) {439 440 441 442 417 uint32_t i; 418 419 if ((mrb == NULL) || (dbg == NULL)) { 420 return MRB_DEBUG_INVALID_ARGUMENT; 421 } 422 423 for(i = 0 ; i < dbg->bpnum; i++) { 424 dbg->bp[i].enable = FALSE; 425 } 426 427 return MRB_DEBUG_OK; 443 428 } 444 429 445 430 static mrb_bool 446 check_start_pc_for_line(mrb_ irep *irep,mrb_code *pc, uint16_t line)447 { 448 449 if (line == mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq - 1))) {450 451 452 453 431 check_start_pc_for_line(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, uint16_t line) 432 { 433 if (pc > irep->iseq) { 434 if (line == mrb_debug_get_line(mrb, irep, pc - irep->iseq - 1)) { 435 return FALSE; 436 } 437 } 438 return TRUE; 454 439 } 455 440 … … 457 442 mrb_debug_check_breakpoint_line(mrb_state *mrb, mrb_debug_context *dbg, const char *file, uint16_t line) 458 443 { 459 460 461 uint32_t i; 462 463 464 465 466 467 if (!check_start_pc_for_line(dbg->irep, dbg->pc, line)) {468 469 470 471 472 for (i = 0; i <dbg->bpnum; i++) {473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 444 mrb_debug_breakpoint *bp; 445 mrb_debug_linepoint *line_p; 446 uint32_t i; 447 448 if ((mrb == NULL) || (dbg == NULL) || (file == NULL) || (line <= 0)) { 449 return MRB_DEBUG_INVALID_ARGUMENT; 450 } 451 452 if (!check_start_pc_for_line(mrb, dbg->irep, dbg->pc, line)) { 453 return MRB_DEBUG_OK; 454 } 455 456 bp = dbg->bp; 457 for(i=0; i<dbg->bpnum; i++) { 458 switch (bp->type) { 459 case MRB_DEBUG_BPTYPE_LINE: 460 if (bp->enable == TRUE) { 461 line_p = &bp->point.linepoint; 462 if ((strcmp(line_p->file, file) == 0) && (line_p->lineno == line)) { 463 return bp->bpno; 464 } 465 } 466 break; 467 case MRB_DEBUG_BPTYPE_METHOD: 468 break; 469 case MRB_DEBUG_BPTYPE_NONE: 470 default: 471 return MRB_DEBUG_OK; 472 } 473 bp++; 474 } 475 return MRB_DEBUG_OK; 491 476 } 492 477 … … 495 480 mrb_debug_check_breakpoint_method(mrb_state *mrb, mrb_debug_context *dbg, struct RClass *class_obj, mrb_sym method_sym, mrb_bool* isCfunc) 496 481 { 497 mrb_debug_breakpoint *bp; 498 int32_t bpno; 499 uint32_t i; 500 501 if ((mrb == NULL) || (dbg == NULL) || (class_obj == NULL)) { 502 return MRB_DEBUG_INVALID_ARGUMENT; 503 } 504 505 bp = dbg->bp; 506 for (i = 0; i < dbg->bpnum; i++) { 507 if (bp->type == MRB_DEBUG_BPTYPE_METHOD) { 508 if (bp->enable == TRUE) { 509 bpno = compare_break_method(mrb, bp, class_obj, method_sym, isCfunc); 510 if (bpno > 0) { 511 return bpno; 512 } 513 } 514 } 515 else if (bp->type == MRB_DEBUG_BPTYPE_NONE) { 516 break; 517 } 518 bp++; 519 } 520 521 return 0; 522 } 523 524 482 mrb_debug_breakpoint *bp; 483 int32_t bpno; 484 uint32_t i; 485 486 if ((mrb == NULL) || (dbg == NULL) || (class_obj == NULL)) { 487 return MRB_DEBUG_INVALID_ARGUMENT; 488 } 489 490 bp = dbg->bp; 491 for(i=0; i<dbg->bpnum; i++) { 492 if (bp->type == MRB_DEBUG_BPTYPE_METHOD) { 493 if (bp->enable == TRUE) { 494 bpno = compare_break_method(mrb, bp, class_obj, method_sym, isCfunc); 495 if (bpno > 0) { 496 return bpno; 497 } 498 } 499 } 500 else if (bp->type == MRB_DEBUG_BPTYPE_NONE) { 501 break; 502 } 503 bp++; 504 } 505 506 return 0; 507 } -
EcnlProtoTool/trunk/prototool/src/apibreak.h
r321 r439 7 7 #define APIBREAK_H_ 8 8 9 #include "mruby.h"9 #include <mruby.h> 10 10 #include "mrdb.h" 11 11 12 int32_t mrb_debug_set_break_line( mrb_state *, mrb_debug_context *, const char *, uint16_t);13 int32_t mrb_debug_set_break_method( mrb_state *, mrb_debug_context *, const char *, const char *);14 int32_t mrb_debug_get_breaknum( mrb_state *, mrb_debug_context *);15 int32_t mrb_debug_get_break_all( 16 int32_t mrb_debug_get_break( mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint *);17 int32_t mrb_debug_delete_break( mrb_state *, mrb_debug_context *, uint32_t);18 int32_t mrb_debug_delete_break_all( mrb_state *, mrb_debug_context *);19 int32_t mrb_debug_enable_break( mrb_state *, mrb_debug_context *, uint32_t);20 int32_t mrb_debug_enable_break_all( mrb_state *, mrb_debug_context *);21 int32_t mrb_debug_disable_break( mrb_state *, mrb_debug_context *, uint32_t);22 int32_t mrb_debug_disable_break_all( mrb_state *, mrb_debug_context *);23 int32_t mrb_debug_check_breakpoint_line( mrb_state *, mrb_debug_context *, const char *, uint16_t);24 int32_t mrb_debug_check_breakpoint_method( mrb_state *, mrb_debug_context *, struct RClass *, mrb_sym, mrb_bool*);12 int32_t mrb_debug_set_break_line(mrb_state *, mrb_debug_context *, const char *, uint16_t); 13 int32_t mrb_debug_set_break_method(mrb_state *, mrb_debug_context *, const char *, const char *); 14 int32_t mrb_debug_get_breaknum(mrb_state *, mrb_debug_context *); 15 int32_t mrb_debug_get_break_all(mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint bp[]); 16 int32_t mrb_debug_get_break(mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint *); 17 int32_t mrb_debug_delete_break(mrb_state *, mrb_debug_context *, uint32_t); 18 int32_t mrb_debug_delete_break_all(mrb_state *, mrb_debug_context *); 19 int32_t mrb_debug_enable_break(mrb_state *, mrb_debug_context *, uint32_t); 20 int32_t mrb_debug_enable_break_all(mrb_state *, mrb_debug_context *); 21 int32_t mrb_debug_disable_break(mrb_state *, mrb_debug_context *, uint32_t); 22 int32_t mrb_debug_disable_break_all(mrb_state *, mrb_debug_context *); 23 int32_t mrb_debug_check_breakpoint_line(mrb_state *, mrb_debug_context *, const char *, uint16_t); 24 int32_t mrb_debug_check_breakpoint_method(mrb_state *, mrb_debug_context *, struct RClass *, mrb_sym, mrb_bool*); 25 25 26 26 #endif /* APIBREAK_H_ */ -
EcnlProtoTool/trunk/prototool/src/apiprint.c
r321 r439 4 4 */ 5 5 6 #include <stdlib.h> 7 6 #include <string.h> 8 7 #include "mrdb.h" 9 #include "mruby/value.h"10 #include "mruby/class.h"11 #include "mruby/compile.h"12 #include "mruby/error.h"13 #include "mruby/numeric.h"14 #include "mruby/string.h"8 #include <mruby/value.h> 9 #include <mruby/class.h> 10 #include <mruby/compile.h> 11 #include <mruby/error.h> 12 #include <mruby/numeric.h> 13 #include <mruby/string.h> 15 14 #include "apiprint.h" 16 15 … … 18 17 mrdb_check_syntax(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len) 19 18 { 20 19 mrbc_context *c; 21 20 22 23 24 25 c->filename = (char*)dbg->prvfile;26 21 c = mrbc_context_new(mrb); 22 c->no_exec = TRUE; 23 c->capture_errors = TRUE; 24 mrbc_filename(mrb, c, (const char*)dbg->prvfile); 25 c->lineno = dbg->prvline; 27 26 28 29 27 /* Load program */ 28 mrb_load_nstring_cxt(mrb, expr, len, c); 30 29 31 30 mrbc_context_free(mrb, c); 32 31 } 33 32 34 33 mrb_value 35 mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc )34 mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc, int direct_eval) 36 35 { 37 void(*tmp)(struct mrb_state *, struct mrb_irep *,mrb_code *, mrb_value *);38 39 40 41 36 void (*tmp)(struct mrb_state *, struct mrb_irep *, const mrb_code *, mrb_value *); 37 mrb_value ruby_code; 38 mrb_value s; 39 mrb_value v; 40 mrb_value recv; 42 41 43 44 45 42 /* disable code_fetch_hook */ 43 tmp = mrb->code_fetch_hook; 44 mrb->code_fetch_hook = NULL; 46 45 47 mrdb_check_syntax(mrb, dbg, expr, len); 48 if (mrb->exc) { 49 v = mrb_obj_value(mrb->exc); 50 mrb->exc = 0; 51 } 52 else { 53 /* 54 * begin 55 * expr 56 * rescue => e 57 * e 58 * end 59 */ 60 ruby_code = mrb_str_new_lit(mrb, "begin\n"); 61 ruby_code = mrb_str_cat(mrb, ruby_code, expr, len); 62 ruby_code = mrb_str_cat_lit(mrb, ruby_code, "\nrescue => e\ne\nend"); 46 mrdb_check_syntax(mrb, dbg, expr, len); 47 if (mrb->exc) { 48 v = mrb_obj_value(mrb->exc); 49 mrb->exc = 0; 50 } 51 else if (direct_eval) { 52 recv = dbg->regs[0]; 63 53 64 recv = dbg->regs[0]; 54 v = mrb_funcall(mrb, recv, expr, 0); 55 } 56 else { 57 /* 58 * begin 59 * expr 60 * rescue => e 61 * e 62 * end 63 */ 64 ruby_code = mrb_str_new_lit(mrb, "begin\n"); 65 ruby_code = mrb_str_cat(mrb, ruby_code, expr, len); 66 ruby_code = mrb_str_cat_lit(mrb, ruby_code, "\nrescue => e\ne\nend"); 65 67 66 v = mrb_funcall(mrb, recv, "instance_eval", 1, ruby_code); 67 } 68 recv = dbg->regs[0]; 68 69 69 if (exc) { 70 *exc = mrb_obj_is_kind_of(mrb, v, mrb->eException_class); 71 } 70 v = mrb_funcall(mrb, recv, "instance_eval", 1, ruby_code); 71 } 72 72 73 s = mrb_funcall(mrb, v, "inspect", 0); 73 if (exc) { 74 *exc = mrb_obj_is_kind_of(mrb, v, mrb->eException_class); 75 } 74 76 75 /* enable code_fetch_hook */ 76 mrb->code_fetch_hook = tmp; 77 s = mrb_inspect(mrb, v); 77 78 78 return s; 79 /* enable code_fetch_hook */ 80 mrb->code_fetch_hook = tmp; 81 82 return s; 79 83 } -
EcnlProtoTool/trunk/prototool/src/apiprint.h
r321 r439 6 6 #define APIPRINT_H_ 7 7 8 #include "mruby.h"8 #include <mruby.h> 9 9 #include "mrdb.h" 10 10 11 mrb_value mrb_debug_eval(mrb_state*, mrb_debug_context*, const char*, size_t, mrb_bool* );11 mrb_value mrb_debug_eval(mrb_state*, mrb_debug_context*, const char*, size_t, mrb_bool*, int); 12 12 13 13 #endif /* APIPRINT_H_ */ -
EcnlProtoTool/trunk/prototool/src/cmdbreak.c
r321 r439 4 4 */ 5 5 6 #include < stdlib.h>6 #include <ctype.h> 7 7 #include <string.h> 8 9 #include "mruby.h" 10 #include "mruby/dump.h" 11 #include "mruby/debug.h" 12 #include "mruby/string.h" 8 #include <mruby.h> 9 #include <mruby/dump.h> 10 #include <mruby/debug.h> 11 #include <mruby/string.h> 13 12 #include "mrdb.h" 14 13 #include "mrdberror.h" … … 44 43 #define BPNO_LETTER_NUM 9 45 44 46 typedef int32_t (*all_command_func)(mrb_state *, mrb_debug_context *);47 typedef int32_t (*select_command_func)(mrb_state *, mrb_debug_context *, uint32_t);45 typedef int32_t (*all_command_func)(mrb_state *, mrb_debug_context *); 46 typedef int32_t (*select_command_func)(mrb_state *, mrb_debug_context *, uint32_t); 48 47 49 48 static void 50 49 print_api_common_error(int32_t error) 51 50 { 52 switch(error) {53 54 55 56 57 58 51 switch(error) { 52 case MRB_DEBUG_INVALID_ARGUMENT: 53 puts(BREAK_ERR_MSG_INVALIDARG); 54 break; 55 default: 56 break; 57 } 59 58 } 60 59 … … 69 68 parse_breakpoint_no(char* args) 70 69 { 71 72 73 74 if ((*ps == '0') ||(strlen(ps) >= BPNO_LETTER_NUM)) {75 76 77 78 while (!(ISBLANK(*ps) ||ISCNTRL(*ps))) {79 80 81 82 83 84 85 86 70 char* ps = args; 71 uint32_t l; 72 73 if ((*ps == '0')||(strlen(ps) >= BPNO_LETTER_NUM)) { 74 return 0; 75 } 76 77 while (!(ISBLANK(*ps)||ISCNTRL(*ps))) { 78 if (!ISDIGIT(*ps)) { 79 return 0; 80 } 81 ps++; 82 } 83 84 STRTOUL(l, args); 85 return l; 87 86 } 88 87 … … 90 89 exe_set_command_all(mrb_state *mrb, mrdb_state *mrdb, all_command_func func) 91 90 { 92 93 94 95 96 97 98 99 91 int32_t ret = MRB_DEBUG_OK; 92 93 if (mrdb->wcnt == 1) { 94 ret = func(mrb, mrdb->dbg); 95 print_api_common_error(ret); 96 return TRUE; 97 } 98 return FALSE; 100 99 } 101 100 … … 103 102 exe_set_command_select(mrb_state *mrb, mrdb_state *mrdb, select_command_func func) 104 103 { 105 106 107 108 109 110 for (i = 1; i <mrdb->wcnt; i++) {111 112 113 114 115 116 117 118 119 120 121 122 123 124 104 char* ps; 105 int32_t ret = MRB_DEBUG_OK; 106 int32_t bpno = 0; 107 int32_t i; 108 109 for(i=1; i<mrdb->wcnt; i++) { 110 ps = mrdb->words[i]; 111 bpno = parse_breakpoint_no(ps); 112 if (bpno == 0) { 113 printf(BREAK_ERR_MSG_INVALIDBPNO, ps); 114 break; 115 } 116 ret = func(mrb, mrdb->dbg, (uint32_t)bpno); 117 if (ret == MRB_DEBUG_BREAK_INVALID_NO) { 118 printf(BREAK_ERR_MSG_NOBPNO, bpno); 119 } 120 else if (ret != MRB_DEBUG_OK) { 121 print_api_common_error(ret); 122 } 123 } 125 124 } 126 125 … … 128 127 check_bptype(char* args) 129 128 { 130 131 132 if (ISBLANK(*ps) ||ISCNTRL(*ps)) {133 134 135 136 137 138 139 140 141 while (!(ISBLANK(*ps) ||ISCNTRL(*ps))) {142 143 144 145 146 147 148 149 if ((*args == '0') ||(strlen(args) >= LINENO_MAX_DIGIT)) {150 151 152 153 154 129 char* ps = args; 130 131 if (ISBLANK(*ps)||ISCNTRL(*ps)) { 132 puts(BREAK_ERR_MSG_BLANK); 133 return MRB_DEBUG_BPTYPE_NONE; 134 } 135 136 if (!ISDIGIT(*ps)) { 137 return MRB_DEBUG_BPTYPE_METHOD; 138 } 139 140 while (!(ISBLANK(*ps)||ISCNTRL(*ps))) { 141 if (!ISDIGIT(*ps)) { 142 printf(BREAK_ERR_MSG_INVALIDSTR, args); 143 return MRB_DEBUG_BPTYPE_NONE; 144 } 145 ps++; 146 } 147 148 if ((*args == '0')||(strlen(args) >= LINENO_MAX_DIGIT)) { 149 puts(BREAK_ERR_MSG_RANGEOVER); 150 return MRB_DEBUG_BPTYPE_NONE; 151 } 152 153 return MRB_DEBUG_BPTYPE_LINE; 155 154 } 156 155 … … 158 157 print_breakpoint(mrb_debug_breakpoint *bp) 159 158 { 160 const char* enable_letter[] = { BREAK_INFO_MSG_DISABLE, BREAK_INFO_MSG_ENABLE};161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 159 const char* enable_letter[] = {BREAK_INFO_MSG_DISABLE, BREAK_INFO_MSG_ENABLE}; 160 161 if (bp->type == MRB_DEBUG_BPTYPE_LINE) { 162 printf(BREAK_INFO_MSG_LINEBREAK, 163 bp->bpno, enable_letter[bp->enable], bp->point.linepoint.file, bp->point.linepoint.lineno); 164 } 165 else { 166 if (bp->point.methodpoint.class_name == NULL) { 167 printf(BREAK_INFO_MSG_METHODBREAK_NOCLASS, 168 bp->bpno, enable_letter[bp->enable], bp->point.methodpoint.method_name); 169 } 170 else { 171 printf(BREAK_INFO_MSG_METHODBREAK, 172 bp->bpno, enable_letter[bp->enable], bp->point.methodpoint.class_name, bp->point.methodpoint.method_name); 173 } 174 } 176 175 } 177 176 … … 179 178 info_break_all(mrb_state *mrb, mrdb_state *mrdb) 180 179 { 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 for (i = 0; i < bpnum; i++) {204 205 206 207 180 int32_t bpnum = 0; 181 int32_t i = 0; 182 int32_t ret = MRB_DEBUG_OK; 183 mrb_debug_breakpoint *bp_list; 184 185 bpnum = mrb_debug_get_breaknum(mrb, mrdb->dbg); 186 if (bpnum < 0) { 187 print_api_common_error(bpnum); 188 return; 189 } 190 else if (bpnum == 0) { 191 puts(BREAK_ERR_MSG_NOBPNO_INFOALL); 192 return; 193 } 194 bp_list = (mrb_debug_breakpoint*)mrb_malloc(mrb, bpnum * sizeof(mrb_debug_breakpoint)); 195 196 ret = mrb_debug_get_break_all(mrb, mrdb->dbg, (uint32_t)bpnum, bp_list); 197 if (ret < 0) { 198 print_api_common_error(ret); 199 return; 200 } 201 puts(BREAK_INFO_MSG_HEADER); 202 for(i = 0 ; i < bpnum ; i++) { 203 print_breakpoint(&bp_list[i]); 204 } 205 206 mrb_free(mrb, bp_list); 208 207 } 209 208 … … 211 210 info_break_select(mrb_state *mrb, mrdb_state *mrdb) 212 211 { 213 214 215 216 217 218 219 220 for (i = 2; i <mrdb->wcnt; i++) {221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 212 int32_t ret = MRB_DEBUG_OK; 213 int32_t bpno = 0; 214 char* ps = mrdb->command; 215 mrb_debug_breakpoint bp; 216 mrb_bool isFirst = TRUE; 217 int32_t i; 218 219 for(i=2; i<mrdb->wcnt; i++) { 220 ps = mrdb->words[i]; 221 bpno = parse_breakpoint_no(ps); 222 if (bpno == 0) { 223 puts(BREAK_ERR_MSG_INVALIDBPNO_INFO); 224 break; 225 } 226 227 ret = mrb_debug_get_break(mrb, mrdb->dbg, bpno, &bp); 228 if (ret == MRB_DEBUG_BREAK_INVALID_NO) { 229 printf(BREAK_ERR_MSG_NOBPNO_INFO, bpno); 230 break; 231 } 232 else if (ret != MRB_DEBUG_OK) { 233 print_api_common_error(ret); 234 break; 235 } 236 else if (isFirst == TRUE) { 237 isFirst = FALSE; 238 puts(BREAK_INFO_MSG_HEADER); 239 } 240 print_breakpoint(&bp); 241 } 243 242 } 244 243 245 244 mrb_debug_bptype 246 parse_breakcommand(mr db_state *mrdb, const char **file, uint32_t *line, char **cname, char **method)247 { 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 switch(type) {274 275 276 277 278 *file = (body == args) ? mrb_debug_get_filename(dbg->irep, (uint32_t)(dbg->pc - dbg->irep->iseq)): args;279 280 281 282 283 284 285 286 287 288 if (ISUPPER(*body) || ISLOWER(*body) ||(*body == '_')) {289 290 291 292 293 294 295 296 297 298 299 switch(*body) {300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 245 parse_breakcommand(mrb_state *mrb, mrdb_state *mrdb, const char **file, uint32_t *line, char **cname, char **method) 246 { 247 mrb_debug_context *dbg = mrdb->dbg; 248 char *args; 249 char *body; 250 mrb_debug_bptype type; 251 uint32_t l; 252 253 if (mrdb->wcnt <= 1) { 254 puts(BREAK_ERR_MSG_BLANK); 255 return MRB_DEBUG_BPTYPE_NONE; 256 } 257 258 args = mrdb->words[1]; 259 if ((body = strrchr(args, ':')) == NULL) { 260 body = args; 261 type = check_bptype(body); 262 } 263 else { 264 if (body == args) { 265 printf(BREAK_ERR_MSG_INVALIDSTR, args); 266 return MRB_DEBUG_BPTYPE_NONE; 267 } 268 *body = '\0'; 269 type = check_bptype(++body); 270 } 271 272 switch(type) { 273 case MRB_DEBUG_BPTYPE_LINE: 274 STRTOUL(l, body); 275 if (l <= 65535) { 276 *line = l; 277 *file = (body == args)? mrb_debug_get_filename(mrb, dbg->irep, dbg->pc - dbg->irep->iseq): args; 278 } 279 else { 280 puts(BREAK_ERR_MSG_RANGEOVER); 281 type = MRB_DEBUG_BPTYPE_NONE; 282 } 283 break; 284 case MRB_DEBUG_BPTYPE_METHOD: 285 if (body == args) { 286 /* method only */ 287 if (ISUPPER(*body)||ISLOWER(*body)||(*body == '_')) { 288 *method = body; 289 *cname = NULL; 290 } 291 else { 292 printf(BREAK_ERR_MSG_INVALIDMETHOD, args); 293 type = MRB_DEBUG_BPTYPE_NONE; 294 } 295 } 296 else { 297 if (ISUPPER(*args)) { 298 switch(*body) { 299 case '@': case '$': case '?': case '.': case ',': case ':': 300 case ';': case '#': case '\\': case '\'': case '\"': 301 printf(BREAK_ERR_MSG_INVALIDMETHOD, body); 302 type = MRB_DEBUG_BPTYPE_NONE; 303 break; 304 default: 305 *method = body; 306 *cname = args; 307 break; 308 } 309 } 310 else { 311 printf(BREAK_ERR_MSG_INVALIDCLASS, args); 312 type = MRB_DEBUG_BPTYPE_NONE; 313 } 314 } 315 break; 316 case MRB_DEBUG_BPTYPE_NONE: 317 default: 318 break; 319 } 320 321 return type; 323 322 } 324 323 … … 326 325 dbgcmd_break(mrb_state *mrb, mrdb_state *mrdb) 327 326 { 328 329 330 331 332 333 334 335 336 type = parse_breakcommand(mrdb, &file, &line, &cname, &method);337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 else if ((type == MRB_DEBUG_BPTYPE_METHOD) &&(cname == NULL)) {354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 327 mrb_debug_bptype type; 328 mrb_debug_context *dbg = mrdb->dbg; 329 const char *file = NULL; 330 uint32_t line = 0; 331 char *cname = NULL; 332 char *method = NULL; 333 int32_t ret; 334 335 type = parse_breakcommand(mrb, mrdb, &file, &line, &cname, &method); 336 switch (type) { 337 case MRB_DEBUG_BPTYPE_LINE: 338 ret = mrb_debug_set_break_line(mrb, dbg, file, line); 339 break; 340 case MRB_DEBUG_BPTYPE_METHOD: 341 ret = mrb_debug_set_break_method(mrb, dbg, cname, method); 342 break; 343 case MRB_DEBUG_BPTYPE_NONE: 344 default: 345 return DBGST_PROMPT; 346 } 347 348 if (ret >= 0) { 349 if (type == MRB_DEBUG_BPTYPE_LINE) { 350 printf(BREAK_SET_MSG_LINE, ret, file, line); 351 } 352 else if ((type == MRB_DEBUG_BPTYPE_METHOD)&&(cname == NULL)) { 353 printf(BREAK_SET_MSG_METHOD, ret, method); 354 } 355 else { 356 printf(BREAK_SET_MSG_CLASS_METHOD, ret, cname, method); 357 } 358 } 359 else { 360 switch (ret) { 361 case MRB_DEBUG_BREAK_INVALID_LINENO: 362 printf(BREAK_ERR_MSG_INVALIDLINENO, line, file); 363 break; 364 case MRB_DEBUG_BREAK_INVALID_FILE: 365 printf(BREAK_ERR_MSG_INVALIDFILE, file); 366 break; 367 case MRB_DEBUG_BREAK_NUM_OVER: 368 puts(BREAK_ERR_MSG_NUMOVER); 369 break; 370 case MRB_DEBUG_BREAK_NO_OVER: 371 puts(BREAK_ERR_MSG_NOOVER); 372 break; 373 case MRB_DEBUG_INVALID_ARGUMENT: 374 puts(BREAK_ERR_MSG_INVALIDARG); 375 break; 376 case MRB_DEBUG_NOBUF: 377 puts("T.B.D."); 378 break; 379 default: 380 break; 381 } 382 } 383 384 return DBGST_PROMPT; 386 385 } 387 386 … … 389 388 dbgcmd_info_break(mrb_state *mrb, mrdb_state *mrdb) 390 389 { 391 392 393 394 395 396 397 398 390 if (mrdb->wcnt == 2) { 391 info_break_all(mrb, mrdb); 392 } 393 else { 394 info_break_select(mrb, mrdb); 395 } 396 397 return DBGST_PROMPT; 399 398 } 400 399 … … 402 401 dbgcmd_delete(mrb_state *mrb, mrdb_state *mrdb) 403 402 { 404 405 406 407 408 409 410 411 403 mrb_bool ret = FALSE; 404 405 ret = exe_set_command_all(mrb, mrdb, mrb_debug_delete_break_all); 406 if (ret != TRUE) { 407 exe_set_command_select(mrb, mrdb, mrb_debug_delete_break); 408 } 409 410 return DBGST_PROMPT; 412 411 } 413 412 … … 415 414 dbgcmd_enable(mrb_state *mrb, mrdb_state *mrdb) 416 415 { 417 418 419 420 421 422 423 424 416 mrb_bool ret = FALSE; 417 418 ret = exe_set_command_all(mrb, mrdb, mrb_debug_enable_break_all); 419 if (ret != TRUE) { 420 exe_set_command_select(mrb, mrdb, mrb_debug_enable_break); 421 } 422 423 return DBGST_PROMPT; 425 424 } 426 425 … … 428 427 dbgcmd_disable(mrb_state *mrb, mrdb_state *mrdb) 429 428 { 430 431 432 433 434 435 436 437 } 429 mrb_bool ret = FALSE; 430 431 ret = exe_set_command_all(mrb, mrdb, mrb_debug_disable_break_all); 432 if (ret != TRUE) { 433 exe_set_command_select(mrb, mrdb, mrb_debug_disable_break); 434 } 435 return DBGST_PROMPT; 436 } -
EcnlProtoTool/trunk/prototool/src/cmdmisc.c
r321 r439 4 4 */ 5 5 6 #include <ctype.h> 6 7 #include <stdlib.h> 7 8 #include <string.h> 8 9 9 #include "mruby/compile.h" 10 #include "mrdb.h" 11 12 typedef struct help_msg 13 { 14 const char *cmd1; 15 const char *cmd2; 16 const char *short_msg; 17 const char *long_msg; 10 #include "apilist.h" 11 #include <mruby/compile.h> 12 13 typedef struct help_msg { 14 const char *cmd1; 15 const char *cmd2; 16 const char *short_msg; 17 const char *long_msg; 18 18 } help_msg; 19 19 20 20 static help_msg help_msg_list[] = { 21 21 { 22 "b[reak]", NULL, "Set breakpoint", 23 "Usage: break [file:]line\n" 24 " break [class:]method\n" 25 "\n" 26 "Set breakpoint at specified line or method.\n" 27 "If \'[file:]line\' is specified, break at start of code for that line (in a file).\n" 28 "If \'[class:]method\' is specified, break at start of code for that method (of the class).\n" 29 }, 30 { 31 "c[ontinue]", NULL, "Continue program being debugged", 32 "Usage: continue [N]\n" 33 "\n" 34 "Continue program stopped by a breakpoint.\n" 35 "If N, which is non negative value, is passed,\n" 36 "proceed program until the N-th breakpoint is coming.\n" 37 "If N is not passed, N is assumed 1.\n" 38 }, 39 { 40 "d[elete]", NULL, "Delete some breakpoints", 41 "Usage: delete [bpno1 [bpno2 [... [bpnoN]]]]\n" 42 "\n" 43 "Delete some breakpoints.\n" 44 "Arguments are breakpoint numbers with spaces in between.\n" 45 "To delete all breakpoints, give no argument.\n" 46 }, 47 { 48 "dis[able]", NULL, "Disable some breakpoints", 49 "Usage: disable [bpno1 [bpno2 [... [bpnoN]]]]\n" 50 "\n" 51 "Disable some breakpoints.\n" 52 "Arguments are breakpoint numbers with spaces in between.\n" 53 "To disable all breakpoints, give no argument.\n" 54 }, 55 { 56 "en[able]", NULL, "Enable some breakpoints", 57 "Usage: enable [bpno1 [bpno2 [... [bpnoN]]]]\n" 58 "\n" 59 "Enable some breakpoints.\n" 60 "Arguments are breakpoint numbers with spaces in between.\n" 61 "To enable all breakpoints, give no argument.\n" 62 }, 63 { 64 "ev[al]", NULL, "Evaluate expression", 65 "Usage: eval expr\n" 66 "\n" 67 "It evaluates and prints the value of the mruby expression.\n" 68 "This is equivalent to the \'print\' command.\n" 69 }, 70 { 71 "h[elp]", NULL, "Print this help", 72 "Usage: help [command]\n" 73 "\n" 74 "With no arguments, help displays a short list of commands.\n" 75 "With a command name as help argument, help displays how to use that command.\n" 76 }, 77 { 78 "i[nfo]", "b[reakpoints]", "Status of breakpoints", 79 "Usage: info breakpoints [bpno1 [bpno2 [... [bpnoN]]]]\n" 80 "\n" 81 "Status of specified breakpoints (all user-settable breakpoints if no argument).\n" 82 "Arguments are breakpoint numbers with spaces in between.\n" 83 }, 84 { 85 "l[ist]", NULL, "List specified line", 86 "Usage: list\n" 87 " list first[,last]\n" 88 " list filename:first[,last]\n" 89 "\n" 90 "Print lines from a source file.\n" 91 "\n" 92 "With first and last, list prints lines from first to last.\n" 93 "When last is empty, it stands for ten lines away from first.\n" 94 "With filename, list prints lines in the specified source file.\n" 95 }, 96 { 97 "p[rint]", NULL, "Print value of expression", 98 "Usage: print expr\n" 99 "\n" 100 "It evaluates and prints the value of the mruby expression.\n" 101 "This is equivalent to the \'eval\' command.\n" 102 }, 103 { 104 "q[uit]", NULL, "Exit mrdb", 105 "Usage: quit\n" 106 "\n" 107 "Exit mrdb.\n" 108 }, 109 { 110 "r[un]", NULL, "Start debugged program", 111 "Usage: run\n" 112 "\n" 113 "Start debugged program.\n" 114 }, 115 { 116 "s[tep]", NULL, "Step program until it reaches a different source line", 117 "Usage: step\n" 118 "\n" 119 "Step program until it reaches a different source line.\n" 22 "b[reak]", NULL, "Set breakpoint", 23 "Usage: break [file:]line\n" 24 " break [class:]method\n" 25 "\n" 26 "Set breakpoint at specified line or method.\n" 27 "If \'[file:]line\' is specified, break at start of code for that line (in a file).\n" 28 "If \'[class:]method\' is specified, break at start of code for that method (of the class).\n" 29 }, 30 { 31 "c[ontinue]", NULL, "Continue program being debugged", 32 "Usage: continue [N]\n" 33 "\n" 34 "Continue program stopped by a breakpoint.\n" 35 "If N, which is non negative value, is passed,\n" 36 "proceed program until the N-th breakpoint is coming.\n" 37 "If N is not passed, N is assumed 1.\n" 38 }, 39 { 40 "d[elete]", NULL, "Delete some breakpoints", 41 "Usage: delete [bpno1 [bpno2 [... [bpnoN]]]]\n" 42 "\n" 43 "Delete some breakpoints.\n" 44 "Arguments are breakpoint numbers with spaces in between.\n" 45 "To delete all breakpoints, give no argument.\n" 46 }, 47 { 48 "dis[able]", NULL, "Disable some breakpoints", 49 "Usage: disable [bpno1 [bpno2 [... [bpnoN]]]]\n" 50 "\n" 51 "Disable some breakpoints.\n" 52 "Arguments are breakpoint numbers with spaces in between.\n" 53 "To disable all breakpoints, give no argument.\n" 54 }, 55 { 56 "en[able]", NULL, "Enable some breakpoints", 57 "Usage: enable [bpno1 [bpno2 [... [bpnoN]]]]\n" 58 "\n" 59 "Enable some breakpoints.\n" 60 "Arguments are breakpoint numbers with spaces in between.\n" 61 "To enable all breakpoints, give no argument.\n" 62 }, 63 { 64 "ev[al]", NULL, "Evaluate expression", 65 "Usage: eval expr\n" 66 "\n" 67 "It evaluates and prints the value of the mruby expression.\n" 68 "This is equivalent to the \'print\' command.\n" 69 }, 70 { 71 "h[elp]", NULL, "Print this help", 72 "Usage: help [command]\n" 73 "\n" 74 "With no arguments, help displays a short list of commands.\n" 75 "With a command name as help argument, help displays how to use that command.\n" 76 }, 77 { 78 "i[nfo]", "b[reakpoints]", "Status of breakpoints", 79 "Usage: info breakpoints [bpno1 [bpno2 [... [bpnoN]]]]\n" 80 "\n" 81 "Status of specified breakpoints (all user-settable breakpoints if no argument).\n" 82 "Arguments are breakpoint numbers with spaces in between.\n" 83 }, 84 { 85 "i[nfo]", "l[ocals]", "Print name of local variables", 86 "Usage: info locals\n" 87 "\n" 88 "Print name of local variables.\n" 89 }, 90 { 91 "l[ist]", NULL, "List specified line", 92 "Usage: list\n" 93 " list first[,last]\n" 94 " list filename:first[,last]\n" 95 "\n" 96 "Print lines from a source file.\n" 97 "\n" 98 "With first and last, list prints lines from first to last.\n" 99 "When last is empty, it stands for ten lines away from first.\n" 100 "With filename, list prints lines in the specified source file.\n" 101 }, 102 { 103 "p[rint]", NULL, "Print value of expression", 104 "Usage: print expr\n" 105 "\n" 106 "It evaluates and prints the value of the mruby expression.\n" 107 "This is equivalent to the \'eval\' command.\n" 108 }, 109 { 110 "q[uit]", NULL, "Exit mrdb", 111 "Usage: quit\n" 112 "\n" 113 "Exit mrdb.\n" 114 }, 115 { 116 "r[un]", NULL, "Start debugged program", 117 "Usage: run\n" 118 "\n" 119 "Start debugged program.\n" 120 }, 121 { 122 "s[tep]", NULL, "Step program until it reaches a different source line", 123 "Usage: step\n" 124 "\n" 125 "Step program until it reaches a different source line.\n" 120 126 }, 121 127 { NULL, NULL, NULL, NULL } 122 128 }; 123 129 124 typedef struct listcmd_parser_state 125 { 126 mrb_bool parse_error; 127 mrb_bool has_line_min; 128 mrb_bool has_line_max; 129 char *filename; 130 uint16_t line_min; 131 uint16_t line_max; 130 typedef struct listcmd_parser_state { 131 mrb_bool parse_error; 132 mrb_bool has_line_min; 133 mrb_bool has_line_max; 134 char *filename; 135 uint16_t line_min; 136 uint16_t line_max; 132 137 } listcmd_parser_state; 133 138 … … 135 140 listcmd_parser_state_new(mrb_state *mrb) 136 141 { 137 listcmd_parser_state *st = (listcmd_parser_state*)mrb_malloc(mrb, sizeof(listcmd_parser_state));138 139 142 listcmd_parser_state *st = (listcmd_parser_state*)mrb_malloc(mrb, sizeof(listcmd_parser_state)); 143 memset(st, 0, sizeof(listcmd_parser_state)); 144 return st; 140 145 } 141 146 … … 143 148 listcmd_parser_state_free(mrb_state *mrb, listcmd_parser_state *st) 144 149 { 145 146 147 148 149 150 150 if (st != NULL) { 151 if (st->filename != NULL) { 152 mrb_free(mrb, st->filename); 153 } 154 mrb_free(mrb, st); 155 } 151 156 } 152 157 … … 154 159 parse_uint(char **sp, uint16_t *n) 155 160 { 156 157 158 159 160 161 162 163 for (p = *sp; *p != '\0' && ISDIGIT(*p); p++);164 165 166 167 168 169 170 161 char *p; 162 int i; 163 164 if (*sp == NULL || **sp == '\0') { 165 return FALSE; 166 } 167 168 for (p = *sp; *p != '\0' && ISDIGIT(*p); p++) ; 169 170 if (p != *sp && (i = atoi(*sp)) >= 0) { 171 *n = (uint16_t)i; 172 *sp = p; 173 return TRUE; 174 } 175 return FALSE; 171 176 } 172 177 … … 174 179 skip_char(char **sp, char c) 175 180 { 176 177 178 179 180 181 if (*sp != NULL && **sp == c) { 182 ++*sp; 183 return TRUE; 184 } 185 return FALSE; 181 186 } 182 187 … … 184 189 parse_lineno(mrb_state *mrb, char **sp, listcmd_parser_state *st) 185 190 { 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 191 if (*sp == NULL || **sp == '\0') { 192 return FALSE; 193 } 194 195 st->has_line_min = FALSE; 196 st->has_line_max = FALSE; 197 198 if (parse_uint(sp, &st->line_min)) { 199 st->has_line_min = TRUE; 200 } 201 else { 202 return FALSE; 203 } 204 205 if (skip_char(sp, ',')) { 206 if (parse_uint(sp, &st->line_max)) { 207 st->has_line_max = TRUE; 208 } 209 else { 210 st->parse_error = TRUE; 211 return FALSE; 212 } 213 } 214 return TRUE; 210 215 } 211 216 … … 213 218 parse_filename(mrb_state *mrb, char **sp, listcmd_parser_state *st) 214 219 { 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 st->filename =mrb_malloc(mrb, len + 1);232 strlcpy(st->filename, *sp, len + 1);233 234 235 236 237 238 239 220 char *p; 221 int len; 222 223 if (st->filename != NULL) { 224 mrb_free(mrb, st->filename); 225 st->filename = NULL; 226 } 227 228 if ((p = strchr(*sp, ':')) != NULL) { 229 len = p - *sp; 230 } 231 else { 232 len = strlen(*sp); 233 } 234 235 if (len > 0) { 236 st->filename = (char*)mrb_malloc(mrb, len + 1); 237 strncpy(st->filename, *sp, len); 238 st->filename[len] = '\0'; 239 *sp += len; 240 return TRUE; 241 } 242 else { 243 return FALSE; 244 } 240 245 } 241 246 … … 243 248 replace_ext(mrb_state *mrb, const char *filename, const char *ext) 244 249 { 245 size_t len, len2; 246 const char *p; 247 char *s; 248 249 if (filename == NULL) { 250 return NULL; 251 } 252 253 if ((p = strrchr(filename, '.')) != NULL && strchr(p, '/') == NULL) { 254 len = p - filename; 255 } 256 else { 257 len = strlen(filename); 258 } 259 260 len2 = len + strlen(ext) + 1; 261 s = mrb_malloc(mrb, len2); 262 memset(s, '\0', len2); 263 strlcpy(s, filename, len); 264 strlcat(s, ext, len2); 265 266 return s; 250 size_t len; 251 const char *p; 252 char *s; 253 254 if (filename == NULL) { 255 return NULL; 256 } 257 258 if ((p = strrchr(filename, '.')) != NULL && strchr(p, '/') == NULL) { 259 len = p - filename; 260 } 261 else { 262 len = strlen(filename); 263 } 264 265 s = (char*)mrb_malloc(mrb, len + strlen(ext) + 1); 266 memset(s, '\0', len + strlen(ext) + 1); 267 strncpy(s, filename, len); 268 strcat(s, ext); 269 270 return s; 267 271 } 268 272 … … 270 274 parse_listcmd_args(mrb_state *mrb, mrdb_state *mrdb, listcmd_parser_state *st) 271 275 { 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 276 char *p; 277 278 switch (mrdb->wcnt) { 279 case 2: 280 p = mrdb->words[1]; 281 282 /* mrdb->words[1] ::= <lineno> | <filename> ':' <lineno> | <filename> */ 283 if (!parse_lineno(mrb, &p, st)) { 284 if (parse_filename(mrb, &p, st)) { 285 if (skip_char(&p, ':')) { 286 if (!parse_lineno(mrb, &p, st)) { 287 st->parse_error = TRUE; 288 } 289 } 290 } 291 else { 292 st->parse_error = TRUE; 293 } 294 } 295 if (*p != '\0') { 296 st->parse_error = TRUE; 297 } 298 break; 299 case 1: 300 case 0: 301 /* do nothing */ 302 break; 303 default: 304 st->parse_error = TRUE; 305 printf("too many arguments\n"); 306 break; 307 } 308 309 if (!st->parse_error) { 310 if (!st->has_line_min) { 311 st->line_min = (!st->filename && mrdb->dbg->prvline > 0) ? mrdb->dbg->prvline : 1; 312 } 313 314 if (!st->has_line_max) { 315 st->line_max = st->line_min + 9; 316 } 317 318 if (st->filename == NULL) { 319 if (mrdb->dbg->prvfile && strcmp(mrdb->dbg->prvfile, "-")) { 320 st->filename = replace_ext(mrb, mrdb->dbg->prvfile, ".rb"); 321 } 322 } 323 } 324 325 if (st->parse_error || st->filename == NULL) { 326 return FALSE; 327 } 328 329 return TRUE; 326 330 } 327 331 … … 329 333 check_cmd_pattern(const char *pattern, const char *cmd) 330 334 { 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 for (; p < rbracket && *q != '\0'; p++, q++) {353 354 355 356 357 335 const char *lbracket, *rbracket, *p, *q; 336 337 if (pattern == NULL && cmd == NULL) { 338 return TRUE; 339 } 340 if (pattern == NULL || cmd == NULL) { 341 return FALSE; 342 } 343 if ((lbracket = strchr(pattern, '[')) == NULL) { 344 return !strcmp(pattern, cmd); 345 } 346 if ((rbracket = strchr(pattern, ']')) == NULL) { 347 return FALSE; 348 } 349 if (strncmp(pattern, cmd, lbracket - pattern)) { 350 return FALSE; 351 } 352 353 p = lbracket + 1; 354 q = (char *)cmd + (lbracket - pattern); 355 356 for ( ; p < rbracket && *q != '\0'; p++, q++) { 357 if (*p != *q) { 358 break; 359 } 360 } 361 return *q == '\0'; 358 362 } 359 363 … … 361 365 get_help_msg(char *cmd1, char *cmd2) 362 366 { 363 364 365 366 367 368 369 370 371 372 373 367 help_msg *p; 368 369 if (cmd1 == NULL) { 370 return NULL; 371 } 372 for (p = help_msg_list; p->cmd1 != NULL; p++) { 373 if (check_cmd_pattern(p->cmd1, cmd1) && check_cmd_pattern(p->cmd2, cmd2)) { 374 return p; 375 } 376 } 377 return NULL; 374 378 } 375 379 … … 377 381 show_short_help(void) 378 382 { 379 380 381 382 383 384 385 386 387 388 389 390 391 383 help_msg *p; 384 385 printf("Commands\n"); 386 387 for (p = help_msg_list; p->cmd1 != NULL; p++) { 388 if (p->cmd2 == NULL) { 389 printf(" %s -- %s\n", p->cmd1, p->short_msg); 390 } 391 else { 392 printf(" %s %s -- %s\n", p->cmd1, p->cmd2, p->short_msg); 393 } 394 } 395 return TRUE; 392 396 } 393 397 … … 395 399 show_long_help(char *cmd1, char *cmd2) 396 400 { 397 help_msg *help; 398 399 if ((help = get_help_msg(cmd1, cmd2)) == NULL) { 400 return FALSE; 401 } 402 printf("%s", help->long_msg); 403 return TRUE; 401 help_msg *help; 402 403 if ((help = get_help_msg(cmd1, cmd2)) == NULL) { 404 return FALSE; 405 } 406 printf("%s", help->long_msg); 407 return TRUE; 408 } 409 410 dbgcmd_state 411 dbgcmd_list(mrb_state *mrb, mrdb_state *mrdb) 412 { 413 char *filename; 414 listcmd_parser_state *st = listcmd_parser_state_new(mrb); 415 416 if (parse_listcmd_args(mrb, mrdb, st)) { 417 if ((filename = mrb_debug_get_source(mrb, mrdb, mrdb->srcpath, st->filename)) == NULL) { 418 filename = st->filename; 419 } 420 mrb_debug_list(mrb, mrdb->dbg, filename, st->line_min, st->line_max); 421 422 if (filename != NULL && filename != st->filename) { 423 mrb_free(mrb, filename); 424 } 425 listcmd_parser_state_free(mrb, st); 426 } 427 428 return DBGST_PROMPT; 404 429 } 405 430 … … 407 432 dbgcmd_help(mrb_state *mrb, mrdb_state *mrdb) 408 433 { 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 434 mrb_bool is_valid; 435 int i; 436 437 switch (mrdb->wcnt) { 438 case 0: 439 case 1: 440 is_valid = show_short_help(); 441 break; 442 case 2: 443 is_valid = show_long_help(mrdb->words[1], NULL); 444 break; 445 case 3: 446 is_valid = show_long_help(mrdb->words[1], mrdb->words[2]); 447 break; 448 default: 449 is_valid = FALSE; 450 break; 451 } 452 453 if (!is_valid) { 454 printf("Invalid command \""); 455 for (i = 1; i < mrdb->wcnt; i++) { 456 printf("%s%s", i == 1 ? "" : " ", mrdb->words[i]); 457 } 458 printf("\". Try \"help\".\n"); 459 } 460 461 return DBGST_PROMPT; 437 462 } 438 463 … … 440 465 dbgcmd_quit(mrb_state *mrb, mrdb_state *mrdb) 441 466 { 442 443 444 445 446 447 448 449 450 451 452 453 454 InterlockedExchange(&mrdb->dbg->xm, DBG_QUIT);455 456 457 458 while (buf != '\n' && (buf = getchar()) != EOF);459 460 461 InterlockedExchange(&mrdb->dbg->xm, DBG_QUIT);462 463 464 465 466 467 468 469 470 471 472 473 InterlockedExchange(&mrdb->dbg->xm, DBG_QUIT);474 475 476 477 478 479 exc = mrb_define_class(mrb, "DebuggerExit", mrb_class_get(mrb, "Exception"));480 481 482 483 } 467 switch (mrdb->dbg->xm) { 468 case DBG_RUN: 469 case DBG_STEP: 470 case DBG_NEXT: 471 while (1) { 472 char c; 473 int buf; 474 475 printf("The program is running. Exit anyway? (y or n) "); 476 fflush(stdout); 477 478 if ((buf = getchar()) == EOF) { 479 mrdb->dbg->xm = DBG_QUIT; 480 break; 481 } 482 c = buf; 483 while (buf != '\n' && (buf = getchar()) != EOF) ; 484 485 if (c == 'y' || c == 'Y') { 486 mrdb->dbg->xm = DBG_QUIT; 487 break; 488 } 489 else if (c == 'n' || c == 'N') { 490 break; 491 } 492 else { 493 printf("Please answer y or n.\n"); 494 } 495 } 496 break; 497 default: 498 mrdb->dbg->xm = DBG_QUIT; 499 break; 500 } 501 502 if (mrdb->dbg->xm == DBG_QUIT) { 503 struct RClass *exc; 504 exc = mrb_define_class(mrb, "DebuggerExit", mrb->eException_class); 505 mrb_raise(mrb, exc, "Exit mrdb."); 506 } 507 return DBGST_PROMPT; 508 } -
EcnlProtoTool/trunk/prototool/src/cmdprint.c
r321 r439 4 4 */ 5 5 6 #include <stdlib.h> 7 6 #include <string.h> 8 7 #include "mrdb.h" 9 #include "mruby/value.h"10 #include "mruby/class.h"11 #include "mruby/compile.h"12 #include "mruby/error.h"13 #include "mruby/numeric.h"14 #include "mruby/string.h"8 #include <mruby/value.h> 9 #include <mruby/class.h> 10 #include <mruby/compile.h> 11 #include <mruby/error.h> 12 #include <mruby/numeric.h> 13 #include <mruby/string.h> 15 14 #include "apiprint.h" 16 15 … … 18 17 dbgcmd_print(mrb_state *mrb, mrdb_state *mrdb) 19 18 { 20 mrb_value expr; 21 mrb_value result; 22 mrb_value s; 23 uint8_t wcnt; 24 int ai; 19 mrb_value expr; 20 mrb_value result; 21 uint8_t wcnt; 22 int ai; 25 23 26 27 28 29 24 if (mrdb->wcnt <= 1) { 25 puts("Parameter not specified."); 26 return DBGST_PROMPT; 27 } 30 28 31 29 ai = mrb_gc_arena_save(mrb); 32 30 33 34 35 for (wcnt = 1; wcnt <mrdb->wcnt; wcnt++) {36 37 38 31 /* eval expr */ 32 expr = mrb_str_new_cstr(mrb, NULL); 33 for (wcnt=1; wcnt<mrdb->wcnt; wcnt++) { 34 expr = mrb_str_cat_lit(mrb, expr, " "); 35 expr = mrb_str_cat_cstr(mrb, expr, mrdb->words[wcnt]); 36 } 39 37 40 result = mrb_debug_eval(mrb, mrdb->dbg, RSTRING_PTR(expr), RSTRING_LEN(expr), NULL);38 result = mrb_debug_eval(mrb, mrdb->dbg, RSTRING_PTR(expr), RSTRING_LEN(expr), NULL, 0); 41 39 42 /* $print_no = result */ 43 s = mrb_str_cat_lit(mrb, result, "\0"); 44 printf("$%lu = %s\n", (unsigned long)mrdb->print_no++, RSTRING_PTR(s)); 40 /* $print_no = result */ 41 printf("$%lu = ", (unsigned long)mrdb->print_no++); 42 fwrite(RSTRING_PTR(result), RSTRING_LEN(result), 1, stdout); 43 putc('\n', stdout); 45 44 46 47 48 45 if (mrdb->print_no == 0) { 46 mrdb->print_no = 1; 47 } 49 48 50 49 mrb_gc_arena_restore(mrb, ai); 51 50 52 51 return DBGST_PROMPT; 53 52 } 54 53 … … 56 55 dbgcmd_eval(mrb_state *mrb, mrdb_state *mrdb) 57 56 { 58 57 return dbgcmd_print(mrb, mrdb); 59 58 } 59 60 dbgcmd_state 61 dbgcmd_info_local(mrb_state *mrb, mrdb_state *mrdb) 62 { 63 mrb_value result; 64 mrb_value s; 65 int ai; 66 67 ai = mrb_gc_arena_save(mrb); 68 69 result = mrb_debug_eval(mrb, mrdb->dbg, "local_variables", 0, NULL, 1); 70 71 s = mrb_str_cat_lit(mrb, result, "\0"); 72 printf("$%lu = %s\n", (unsigned long)mrdb->print_no++, RSTRING_PTR(s)); 73 74 if (mrdb->print_no == 0) { 75 mrdb->print_no = 1; 76 } 77 78 mrb_gc_arena_restore(mrb, ai); 79 80 return DBGST_PROMPT; 81 } -
EcnlProtoTool/trunk/prototool/src/cmdrun.c
r321 r439 4 4 */ 5 5 6 #include <stdlib.h> 7 8 #include "mruby/opcode.h" 6 #include <mruby/opcode.h> 9 7 #include "mrdb.h" 10 8 … … 12 10 dbgcmd_run(mrb_state *mrb, mrdb_state *mrdb) 13 11 { 14 12 mrb_debug_context *dbg = mrdb->dbg; 15 13 16 if (dbg->xm == DBG_INIT){17 InterlockedExchange(&dbg->xm, DBG_RUN);18 19 20 InterlockedExchange(&dbg->xm, DBG_QUIT);21 if (dbg->xphase == DBG_PHASE_RUNNING){22 23 24 exc = mrb_define_class(mrb, "DebuggerRestart", mrb_class_get(mrb, "Exception"));25 26 27 14 if (dbg->xm == DBG_INIT){ 15 dbg->xm = DBG_RUN; 16 } 17 else { 18 dbg->xm = DBG_QUIT; 19 if (dbg->xphase == DBG_PHASE_RUNNING){ 20 struct RClass *exc; 21 puts("Start it from the beginning."); 22 exc = mrb_define_class(mrb, "DebuggerRestart", mrb->eException_class); 23 mrb_raise(mrb, exc, "Restart mrdb."); 24 } 25 } 28 26 29 27 return DBGST_RESTART; 30 28 } 31 29 … … 33 31 dbgcmd_continue(mrb_state *mrb, mrdb_state *mrdb) 34 32 { 35 36 33 mrb_debug_context *dbg = mrdb->dbg; 34 int ccnt = 1; 37 35 38 if (mrdb->wcnt > 1){39 40 41 36 if (mrdb->wcnt > 1){ 37 sscanf(mrdb->words[1], "%d", &ccnt); 38 } 39 dbg->ccnt = (uint16_t)(ccnt > 0 ? ccnt : 1); /* count of continue */ 42 40 43 if (dbg->xphase == DBG_PHASE_AFTER_RUN){44 45 InterlockedExchange(&dbg->xm, DBG_QUIT);46 47 48 InterlockedExchange(&dbg->xm, DBG_RUN);49 50 41 if (dbg->xphase == DBG_PHASE_AFTER_RUN){ 42 puts("The program is not running."); 43 dbg->xm = DBG_QUIT; 44 } 45 else { 46 dbg->xm = DBG_RUN; 47 } 48 return DBGST_CONTINUE; 51 49 } 52 50 … … 54 52 dbgcmd_step(mrb_state *mrb, mrdb_state *mrdb) 55 53 { 56 InterlockedExchange(&mrdb->dbg->xm, DBG_STEP);57 54 mrdb->dbg->xm = DBG_STEP; 55 return DBGST_CONTINUE; 58 56 } 59 57 … … 61 59 dbgcmd_next(mrb_state *mrb, mrdb_state *mrdb) 62 60 { 63 InterlockedExchange(&mrdb->dbg->xm, DBG_NEXT);64 65 61 mrdb->dbg->xm = DBG_NEXT; 62 mrdb->dbg->prvci = mrb->c->ci; 63 return DBGST_CONTINUE; 66 64 } -
EcnlProtoTool/trunk/prototool/src/libbb/AUTHORS
-
Property svn:eol-style
set to
native
-
Property svn:eol-style
set to
-
EcnlProtoTool/trunk/prototool/src/libbb/LICENSE
-
Property svn:eol-style
set to
native
-
Property svn:eol-style
set to
-
EcnlProtoTool/trunk/prototool/src/libbb/README
-
Property svn:eol-style
set to
native
-
Property svn:eol-style
set to
-
EcnlProtoTool/trunk/prototool/src/linker_scriptDebug.ld
-
Property svn:eol-style
set to
native
-
Property svn:eol-style
set to
-
EcnlProtoTool/trunk/prototool/src/main.c
r428 r439 1 1 /* 2 * TOPPERS ECHONET Lite Communication Middleware2 * TOPPERS PROJECT Home Network Working Group Software 3 3 * 4 * Copyright (C) 201 4-2017Cores Co., Ltd. Japan4 * Copyright (C) 2017-2019 Cores Co., Ltd. Japan 5 5 * 6 6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ … … 515 515 } 516 516 517 extern char __start_rodata, __end_rodata; 518 519 mrb_bool mrb_ro_data_p(const char *p) 520 { 521 return (&__start_rodata <= p && p < &__end_rodata); 522 } 523 517 524 void _start_c(long *p); 518 525 extern int __start_idata, __start_data, __end_data; -
EcnlProtoTool/trunk/prototool/src/mirb.c
r321 r439 7 7 */ 8 8 9 #include <mruby.h> 10 11 #ifdef MRB_DISABLE_STDIO 12 # error mruby-bin-mirb conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 13 #endif 14 15 #include <mruby/array.h> 16 #include <mruby/proc.h> 17 #include <mruby/compile.h> 18 #include <mruby/dump.h> 19 #include <mruby/string.h> 20 #include <mruby/variable.h> 21 #include <mruby/throw.h> 22 9 23 #include <stdlib.h> 10 24 #include <string.h> 11 #include <stdio.h>12 25 #include <ctype.h> 26 27 #include <signal.h> 28 #include <setjmp.h> 13 29 14 30 #ifdef ENABLE_READLINE … … 17 33 #define MIRB_ADD_HISTORY(line) add_history(line) 18 34 #define MIRB_READLINE(ch) readline(ch) 35 #if !defined(RL_READLINE_VERSION) || RL_READLINE_VERSION < 0x600 36 /* libedit & older readline do not have rl_free() */ 37 #define MIRB_LINE_FREE(line) free(line) 38 #else 39 #define MIRB_LINE_FREE(line) rl_free(line) 40 #endif 19 41 #define MIRB_WRITE_HISTORY(path) write_history(path) 20 42 #define MIRB_READ_HISTORY(path) read_history(path) … … 25 47 #define MIRB_ADD_HISTORY(line) linenoiseHistoryAdd(line) 26 48 #define MIRB_READLINE(ch) linenoise(ch) 49 #define MIRB_LINE_FREE(line) linenoiseFree(line) 27 50 #define MIRB_WRITE_HISTORY(path) linenoiseHistorySave(path) 28 51 #define MIRB_READ_HISTORY(path) linenoiseHistoryLoad(history_path) … … 30 53 #endif 31 54 32 #include "mruby.h" 33 #include "mruby/array.h" 34 #include "mruby/proc.h" 35 #include "mruby/compile.h" 36 #include "mruby/string.h" 55 #ifndef _WIN32 56 #define MIRB_SIGSETJMP(env) sigsetjmp(env, 1) 57 #define MIRB_SIGLONGJMP(env, val) siglongjmp(env, val) 58 #define SIGJMP_BUF sigjmp_buf 59 #else 60 #define MIRB_SIGSETJMP(env) setjmp(env) 61 #define MIRB_SIGLONGJMP(env, val) longjmp(env, val) 62 #define SIGJMP_BUF jmp_buf 63 #endif 37 64 38 65 #ifdef ENABLE_READLINE … … 43 70 get_history_path(mrb_state *mrb) 44 71 { 45 46 72 char *path = NULL; 73 const char *home = getenv("HOME"); 47 74 48 75 #ifdef _WIN32 49 50 51 52 #endif 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 76 if (home != NULL) { 77 home = getenv("USERPROFILE"); 78 } 79 #endif 80 81 if (home != NULL) { 82 int len = snprintf(NULL, 0, "%s/%s", home, history_file_name); 83 if (len >= 0) { 84 size_t size = len + 1; 85 path = (char *)mrb_malloc_simple(mrb, size); 86 if (path != NULL) { 87 int n = snprintf(path, size, "%s/%s", home, history_file_name); 88 if (n != len) { 89 mrb_free(mrb, path); 90 path = NULL; 91 } 92 } 93 } 94 } 95 96 return path; 70 97 } 71 98 … … 75 102 p(mrb_state *mrb, mrb_value obj, int prompt) 76 103 { 77 mrb_value val; 78 79 val = mrb_funcall(mrb, obj, "inspect", 0); 80 if (prompt) { 81 if (!mrb->exc) { 82 fputs(" => ", stdout); 83 } 84 else { 85 val = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0); 86 } 87 } 88 if (!mrb_string_p(val)) { 89 val = mrb_obj_as_string(mrb, obj); 90 } 91 fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout); 92 putc('\n', stdout); 104 mrb_value val; 105 char* msg; 106 107 val = mrb_funcall(mrb, obj, "inspect", 0); 108 if (prompt) { 109 if (!mrb->exc) { 110 fputs(" => ", stdout); 111 } 112 else { 113 val = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0); 114 } 115 } 116 if (!mrb_string_p(val)) { 117 val = mrb_obj_as_string(mrb, obj); 118 } 119 msg = mrb_locale_from_utf8(RSTRING_PTR(val), (int)RSTRING_LEN(val)); 120 fwrite(msg, strlen(msg), 1, stdout); 121 mrb_locale_free(msg); 122 putc('\n', stdout); 93 123 } 94 124 … … 98 128 is_code_block_open(struct mrb_parser_state *parser) 99 129 { 100 mrb_bool code_block_open = FALSE; 101 102 /* check for heredoc */ 103 if (parser->parsing_heredoc != NULL) return TRUE; 104 if (parser->heredoc_end_now) { 105 parser->heredoc_end_now = FALSE; 106 return FALSE; 107 } 108 109 /* check for unterminated string */ 110 if (parser->lex_strterm) return TRUE; 111 112 /* check if parser error are available */ 113 if (0 < parser->nerr) { 114 const char unexpected_end[] = "syntax error, unexpected $end"; 115 const char *message = parser->error_buffer[0].message; 116 117 /* a parser error occur, we have to check if */ 118 /* we need to read one more line or if there is */ 119 /* a different issue which we have to show to */ 120 /* the user */ 121 122 if (strncmp(message, unexpected_end, sizeof(unexpected_end) - 1) == 0) { 123 code_block_open = TRUE; 124 } 125 else if (strcmp(message, "syntax error, unexpected keyword_end") == 0) { 126 code_block_open = FALSE; 127 } 128 else if (strcmp(message, "syntax error, unexpected tREGEXP_BEG") == 0) { 129 code_block_open = FALSE; 130 } 131 return code_block_open; 132 } 133 134 switch (parser->lstate) { 135 136 /* all states which need more code */ 137 138 case EXPR_BEG: 139 /* beginning of a statement, */ 140 /* that means previous line ended */ 141 code_block_open = FALSE; 142 break; 143 case EXPR_DOT: 144 /* a message dot was the last token, */ 145 /* there has to come more */ 146 code_block_open = TRUE; 147 break; 148 case EXPR_CLASS: 149 /* a class keyword is not enough! */ 150 /* we need also a name of the class */ 151 code_block_open = TRUE; 152 break; 153 case EXPR_FNAME: 154 /* a method name is necessary */ 155 code_block_open = TRUE; 156 break; 157 case EXPR_VALUE: 158 /* if, elsif, etc. without condition */ 159 code_block_open = TRUE; 160 break; 161 162 /* now all the states which are closed */ 163 164 case EXPR_ARG: 165 /* an argument is the last token */ 166 code_block_open = FALSE; 167 break; 168 169 /* all states which are unsure */ 170 171 case EXPR_CMDARG: 172 break; 173 case EXPR_END: 174 /* an expression was ended */ 175 break; 176 case EXPR_ENDARG: 177 /* closing parenthese */ 178 break; 179 case EXPR_ENDFN: 180 /* definition end */ 181 break; 182 case EXPR_MID: 183 /* jump keyword like break, return, ... */ 184 break; 185 case EXPR_MAX_STATE: 186 /* don't know what to do with this token */ 187 break; 188 default: 189 /* this state is unexpected! */ 190 break; 191 } 192 193 return code_block_open; 130 mrb_bool code_block_open = FALSE; 131 132 /* check for heredoc */ 133 if (parser->parsing_heredoc != NULL) return TRUE; 134 135 /* check for unterminated string */ 136 if (parser->lex_strterm) return TRUE; 137 138 /* check if parser error are available */ 139 if (0 < parser->nerr) { 140 const char unexpected_end[] = "syntax error, unexpected $end"; 141 const char *message = parser->error_buffer[0].message; 142 143 /* a parser error occur, we have to check if */ 144 /* we need to read one more line or if there is */ 145 /* a different issue which we have to show to */ 146 /* the user */ 147 148 if (strncmp(message, unexpected_end, sizeof(unexpected_end) - 1) == 0) { 149 code_block_open = TRUE; 150 } 151 else if (strcmp(message, "syntax error, unexpected keyword_end") == 0) { 152 code_block_open = FALSE; 153 } 154 else if (strcmp(message, "syntax error, unexpected tREGEXP_BEG") == 0) { 155 code_block_open = FALSE; 156 } 157 return code_block_open; 158 } 159 160 switch (parser->lstate) { 161 162 /* all states which need more code */ 163 164 case EXPR_BEG: 165 /* beginning of a statement, */ 166 /* that means previous line ended */ 167 code_block_open = FALSE; 168 break; 169 case EXPR_DOT: 170 /* a message dot was the last token, */ 171 /* there has to come more */ 172 code_block_open = TRUE; 173 break; 174 case EXPR_CLASS: 175 /* a class keyword is not enough! */ 176 /* we need also a name of the class */ 177 code_block_open = TRUE; 178 break; 179 case EXPR_FNAME: 180 /* a method name is necessary */ 181 code_block_open = TRUE; 182 break; 183 case EXPR_VALUE: 184 /* if, elsif, etc. without condition */ 185 code_block_open = TRUE; 186 break; 187 188 /* now all the states which are closed */ 189 190 case EXPR_ARG: 191 /* an argument is the last token */ 192 code_block_open = FALSE; 193 break; 194 195 /* all states which are unsure */ 196 197 case EXPR_CMDARG: 198 break; 199 case EXPR_END: 200 /* an expression was ended */ 201 break; 202 case EXPR_ENDARG: 203 /* closing parenthese */ 204 break; 205 case EXPR_ENDFN: 206 /* definition end */ 207 break; 208 case EXPR_MID: 209 /* jump keyword like break, return, ... */ 210 break; 211 case EXPR_MAX_STATE: 212 /* don't know what to do with this token */ 213 break; 214 default: 215 /* this state is unexpected! */ 216 break; 217 } 218 219 return code_block_open; 194 220 } 195 221 196 222 struct _args { 197 mrb_bool verbose : 1; 198 int argc; 199 char** argv; 223 FILE *rfp; 224 mrb_bool verbose : 1; 225 mrb_bool debug : 1; 226 int argc; 227 char** argv; 228 int libc; 229 char **libv; 200 230 }; 201 231 … … 203 233 usage(const char *name) 204 234 { 205 static const char *const usage_msg[] = { 206 "switches:", 207 "-v print version number, then run in verbose mode", 208 "--verbose run in verbose mode", 209 "--version print the version", 210 "--copyright print the copyright", 211 NULL 212 }; 213 const char *const *p = usage_msg; 214 215 printf("Usage: %s [switches]\n", name); 216 while (*p) 217 printf(" %s\n", *p++); 235 static const char *const usage_msg[] = { 236 "switches:", 237 "-d set $DEBUG to true (same as `mruby -d`)", 238 "-r library same as `mruby -r`", 239 "-v print version number, then run in verbose mode", 240 "--verbose run in verbose mode", 241 "--version print the version", 242 "--copyright print the copyright", 243 NULL 244 }; 245 const char *const *p = usage_msg; 246 247 printf("Usage: %s [switches] [programfile] [arguments]\n", name); 248 while (*p) 249 printf(" %s\n", *p++); 250 } 251 252 static char * 253 dup_arg_item(mrb_state *mrb, const char *item) 254 { 255 size_t buflen = strlen(item) + 1; 256 char *buf = (char*)mrb_malloc(mrb, buflen); 257 memcpy(buf, item, buflen); 258 return buf; 218 259 } 219 260 … … 221 262 parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) 222 263 { 223 static const struct _args args_zero = {0}; 224 225 *args = args_zero; 226 227 for (argc--, argv++; argc > 0; argc--, argv++) { 228 char *item; 229 if (argv[0][0] != '-') break; 230 231 item = argv[0] + 1; 232 switch (*item++) { 233 case 'v': 234 if (!args->verbose) mrb_show_version(mrb); 235 args->verbose = TRUE; 236 break; 237 case '-': 238 if (strcmp((*argv) + 2, "version") == 0) { 239 mrb_show_version(mrb); 240 exit(EXIT_SUCCESS); 241 } 242 else if (strcmp((*argv) + 2, "verbose") == 0) { 243 args->verbose = TRUE; 244 break; 245 } 246 else if (strcmp((*argv) + 2, "copyright") == 0) { 247 mrb_show_copyright(mrb); 248 exit(EXIT_SUCCESS); 249 } 250 default: 251 return EXIT_FAILURE; 252 } 253 } 254 return EXIT_SUCCESS; 264 char **origargv = argv; 265 static const struct _args args_zero = { 0 }; 266 267 *args = args_zero; 268 269 for (argc--,argv++; argc > 0; argc--,argv++) { 270 char *item; 271 if (argv[0][0] != '-') break; 272 273 item = argv[0] + 1; 274 switch (*item++) { 275 case 'd': 276 args->debug = TRUE; 277 break; 278 case 'r': 279 if (!item[0]) { 280 if (argc <= 1) { 281 printf("%s: No library specified for -r\n", *origargv); 282 return EXIT_FAILURE; 283 } 284 argc--; argv++; 285 item = argv[0]; 286 } 287 if (args->libc == 0) { 288 args->libv = (char**)mrb_malloc(mrb, sizeof(char*)); 289 } 290 else { 291 args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1)); 292 } 293 args->libv[args->libc++] = dup_arg_item(mrb, item); 294 break; 295 case 'v': 296 if (!args->verbose) mrb_show_version(mrb); 297 args->verbose = TRUE; 298 break; 299 case '-': 300 if (strcmp((*argv) + 2, "version") == 0) { 301 mrb_show_version(mrb); 302 exit(EXIT_SUCCESS); 303 } 304 else if (strcmp((*argv) + 2, "verbose") == 0) { 305 args->verbose = TRUE; 306 break; 307 } 308 else if (strcmp((*argv) + 2, "copyright") == 0) { 309 mrb_show_copyright(mrb); 310 exit(EXIT_SUCCESS); 311 } 312 default: 313 return EXIT_FAILURE; 314 } 315 } 316 317 if (args->rfp == NULL) { 318 if (*argv != NULL) { 319 args->rfp = fopen(argv[0], "r"); 320 if (args->rfp == NULL) { 321 printf("Cannot open program file. (%s)\n", *argv); 322 return EXIT_FAILURE; 323 } 324 argc--; argv++; 325 } 326 } 327 args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1)); 328 memcpy(args->argv, argv, (argc+1) * sizeof(char*)); 329 args->argc = argc; 330 331 return EXIT_SUCCESS; 255 332 } 256 333 … … 258 335 cleanup(mrb_state *mrb, struct _args *args) 259 336 { 260 mrb_close(mrb); 337 if (args->rfp) 338 fclose(args->rfp); 339 mrb_free(mrb, args->argv); 340 if (args->libc) { 341 while (args->libc--) { 342 mrb_free(mrb, args->libv[args->libc]); 343 } 344 mrb_free(mrb, args->libv); 345 } 346 mrb_close(mrb); 261 347 } 262 348 … … 265 351 print_hint(void) 266 352 { 267 353 printf("mirb - Embeddable Interactive Ruby Shell\n\n"); 268 354 } 269 355 … … 273 359 print_cmdline(int code_block_open) 274 360 { 275 276 277 278 279 280 281 361 if (code_block_open) { 362 printf("* "); 363 } 364 else { 365 printf("> "); 366 } 367 fflush(stdout); 282 368 } 283 369 #endif … … 288 374 check_keyword(const char *buf, const char *word) 289 375 { 290 const char *p = buf; 291 size_t len = strlen(word); 292 293 /* skip preceding spaces */ 294 while (*p && isspace((unsigned char)*p)) { 295 p++; 296 } 297 /* check keyword */ 298 if (strncmp(p, word, len) != 0) { 299 return 0; 300 } 301 p += len; 302 /* skip trailing spaces */ 303 while (*p) { 304 if (!isspace((unsigned char)*p)) return 0; 305 p++; 306 } 307 return 1; 308 } 376 const char *p = buf; 377 size_t len = strlen(word); 378 379 /* skip preceding spaces */ 380 while (*p && ISSPACE(*p)) { 381 p++; 382 } 383 /* check keyword */ 384 if (strncmp(p, word, len) != 0) { 385 return 0; 386 } 387 p += len; 388 /* skip trailing spaces */ 389 while (*p) { 390 if (!ISSPACE(*p)) return 0; 391 p++; 392 } 393 return 1; 394 } 395 396 397 #ifndef ENABLE_READLINE 398 volatile sig_atomic_t input_canceled = 0; 399 void 400 ctrl_c_handler(int signo) 401 { 402 input_canceled = 1; 403 } 404 #else 405 SIGJMP_BUF ctrl_c_buf; 406 void 407 ctrl_c_handler(int signo) 408 { 409 MIRB_SIGLONGJMP(ctrl_c_buf, 1); 410 } 411 #endif 412 413 #ifndef DISABLE_MIRB_UNDERSCORE 414 void decl_lv_underscore(mrb_state *mrb, mrbc_context *cxt) 415 { 416 struct RProc *proc; 417 struct mrb_parser_state *parser; 418 419 parser = mrb_parse_string(mrb, "_=nil", cxt); 420 if (parser == NULL) { 421 fputs("create parser state error\n", stderr); 422 mrb_close(mrb); 423 exit(EXIT_FAILURE); 424 } 425 426 proc = mrb_generate_code(mrb, parser); 427 mrb_vm_run(mrb, proc, mrb_top_self(mrb), 0); 428 429 mrb_parser_free(parser); 430 } 431 #endif 309 432 310 433 int 311 434 mirb_main(int argc, char **argv) 312 435 { 313 char ruby_code[1024] = {0};314 char last_code_line[1024] = {0};436 char ruby_code[4096] = { 0 }; 437 char last_code_line[1024] = { 0 }; 315 438 #ifndef ENABLE_READLINE 316 317 int char_index;439 int last_char; 440 size_t char_index; 318 441 #else 319 char *history_path; 320 #endif 321 mrbc_context *cxt; 322 struct mrb_parser_state *parser; 323 mrb_state *mrb; 324 mrb_value result; 325 struct _args args; 326 int n; 327 mrb_bool code_block_open = FALSE; 328 int ai; 329 unsigned int stack_keep = 0; 330 331 /* new interpreter instance */ 332 mrb = mrb_open(); 333 if (mrb == NULL) { 334 fputs("Invalid mrb interpreter, exiting mirb\n", stderr); 335 return EXIT_FAILURE; 336 } 337 mrb_define_global_const(mrb, "ARGV", mrb_ary_new_capa(mrb, 0)); 338 339 n = parse_args(mrb, argc, argv, &args); 340 if (n == EXIT_FAILURE) { 341 cleanup(mrb, &args); 342 usage(argv[0]); 343 return n; 344 } 442 char *history_path; 443 char* line; 444 #endif 445 mrbc_context *cxt; 446 struct mrb_parser_state *parser; 447 mrb_state *mrb; 448 mrb_value result; 449 struct _args args; 450 mrb_value ARGV; 451 int n; 452 int i; 453 mrb_bool code_block_open = FALSE; 454 int ai; 455 unsigned int stack_keep = 0; 456 457 /* new interpreter instance */ 458 mrb = mrb_open(); 459 if (mrb == NULL) { 460 fputs("Invalid mrb interpreter, exiting mirb\n", stderr); 461 return EXIT_FAILURE; 462 } 463 464 n = parse_args(mrb, argc, argv, &args); 465 if (n == EXIT_FAILURE) { 466 cleanup(mrb, &args); 467 usage(argv[0]); 468 return n; 469 } 470 471 ARGV = mrb_ary_new_capa(mrb, args.argc); 472 for (i = 0; i < args.argc; i++) { 473 char* utf8 = mrb_utf8_from_locale(args.argv[i], -1); 474 if (utf8) { 475 mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8)); 476 mrb_utf8_free(utf8); 477 } 478 } 479 mrb_define_global_const(mrb, "ARGV", ARGV); 480 mrb_gv_set(mrb, mrb_intern_lit(mrb, "$DEBUG"), mrb_bool_value(args.debug)); 345 481 346 482 #ifdef ENABLE_READLINE 347 history_path = get_history_path(mrb); 348 if (history_path == NULL) { 349 fputs("failed to get history path\n", stderr); 350 mrb_close(mrb); 351 return EXIT_FAILURE; 352 } 353 354 MIRB_USING_HISTORY(); 355 MIRB_READ_HISTORY(history_path); 356 #endif 357 358 print_hint(); 359 360 cxt = mrbc_context_new(mrb); 361 cxt->capture_errors = TRUE; 362 cxt->lineno = 1; 363 mrbc_filename(mrb, cxt, "(mirb)"); 364 if (args.verbose) cxt->dump_result = TRUE; 365 366 ai = mrb_gc_arena_save(mrb); 367 368 while (TRUE) { 369 char *utf8; 483 history_path = get_history_path(mrb); 484 if (history_path == NULL) { 485 fputs("failed to get history path\n", stderr); 486 mrb_close(mrb); 487 return EXIT_FAILURE; 488 } 489 490 MIRB_USING_HISTORY(); 491 MIRB_READ_HISTORY(history_path); 492 #endif 493 494 print_hint(); 495 496 cxt = mrbc_context_new(mrb); 497 498 #ifndef DISABLE_MIRB_UNDERSCORE 499 decl_lv_underscore(mrb, cxt); 500 #endif 501 502 /* Load libraries */ 503 for (i = 0; i < args.libc; i++) { 504 FILE *lfp = fopen(args.libv[i], "r"); 505 if (lfp == NULL) { 506 printf("Cannot open library file. (%s)\n", args.libv[i]); 507 cleanup(mrb, &args); 508 return EXIT_FAILURE; 509 } 510 mrb_load_file_cxt(mrb, lfp, cxt); 511 fclose(lfp); 512 } 513 514 cxt->capture_errors = TRUE; 515 cxt->lineno = 1; 516 mrbc_filename(mrb, cxt, "(mirb)"); 517 if (args.verbose) cxt->dump_result = TRUE; 518 519 ai = mrb_gc_arena_save(mrb); 520 521 while (TRUE) { 522 char *utf8; 523 struct mrb_jmpbuf c_jmp; 524 525 MRB_TRY(&c_jmp); 526 mrb->jmp = &c_jmp; 527 if (args.rfp) { 528 if (fgets(last_code_line, sizeof(last_code_line)-1, args.rfp) != NULL) 529 goto done; 530 break; 531 } 370 532 371 533 #ifndef ENABLE_READLINE 372 print_cmdline(code_block_open); 373 374 char_index = 0; 375 while ((last_char = getchar()) != '\n') { 376 if (last_char == EOF) break; 377 if (char_index > sizeof(last_code_line) - 2) { 378 fputs("input string too long\n", stderr); 379 continue; 380 } 381 last_code_line[char_index++] = last_char; 382 } 383 if (last_char == EOF) { 384 fputs("\n", stdout); 385 break; 386 } 387 388 last_code_line[char_index++] = '\n'; 389 last_code_line[char_index] = '\0'; 534 print_cmdline(code_block_open); 535 536 signal(SIGINT, ctrl_c_handler); 537 char_index = 0; 538 while ((last_char = getchar()) != '\n') { 539 if (last_char == EOF) break; 540 if (char_index >= sizeof(last_code_line)-2) { 541 fputs("input string too long\n", stderr); 542 continue; 543 } 544 last_code_line[char_index++] = last_char; 545 } 546 signal(SIGINT, SIG_DFL); 547 if (input_canceled) { 548 ruby_code[0] = '\0'; 549 last_code_line[0] = '\0'; 550 code_block_open = FALSE; 551 puts("^C"); 552 input_canceled = 0; 553 continue; 554 } 555 if (last_char == EOF) { 556 fputs("\n", stdout); 557 break; 558 } 559 560 last_code_line[char_index++] = '\n'; 561 last_code_line[char_index] = '\0'; 390 562 #else 391 char* line = MIRB_READLINE(code_block_open ? "* " : "> "); 392 if (line == NULL) { 393 printf("\n"); 394 break; 395 } 396 if (strlen(line) > sizeof(last_code_line) - 2) { 397 fputs("input string too long\n", stderr); 398 continue; 399 } 400 strlcpy(last_code_line, line, sizeof(last_code_line)); 401 strlcat(last_code_line, "\n", sizeof(last_code_line)); 402 MIRB_ADD_HISTORY(line); 403 free(line); 404 #endif 405 406 if (code_block_open) { 407 if (strlen(ruby_code) + strlen(last_code_line) > sizeof(ruby_code) - 1) { 408 fputs("concatenated input string too long\n", stderr); 409 continue; 410 } 411 strlcat(ruby_code, last_code_line, sizeof(ruby_code)); 412 } 413 else { 414 if (check_keyword(last_code_line, "quit") || check_keyword(last_code_line, "exit")) { 415 break; 416 } 417 strlcpy(ruby_code, last_code_line, sizeof(ruby_code)); 418 } 419 420 utf8 = mrb_utf8_from_locale(ruby_code, -1); 421 if (!utf8) abort(); 422 423 /* parse code */ 424 parser = mrb_parser_new(mrb); 425 if (parser == NULL) { 426 fputs("create parser state error\n", stderr); 427 break; 428 } 429 parser->s = utf8; 430 parser->send = utf8 + strlen(utf8); 431 parser->lineno = cxt->lineno; 432 mrb_parser_parse(parser, cxt); 433 code_block_open = is_code_block_open(parser); 434 mrb_utf8_free(utf8); 435 436 if (code_block_open) { 437 /* no evaluation of code */ 438 } 439 else { 440 if (0 < parser->nerr) { 441 /* syntax error */ 442 printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message); 443 } 444 else { 445 /* generate bytecode */ 446 struct RProc *proc = mrb_generate_code(mrb, parser); 447 if (proc == NULL) { 448 fputs("codegen error\n", stderr); 449 mrb_parser_free(parser); 450 break; 451 } 452 453 if (args.verbose) { 454 mrb_codedump_all(mrb, proc); 455 } 456 /* pass a proc for evaulation */ 457 /* evaluate the bytecode */ 458 result = mrb_context_run(mrb, 459 proc, 460 mrb_top_self(mrb), 461 stack_keep); 462 stack_keep = proc->body.irep->nlocals; 463 /* did an exception occur? */ 464 if (mrb->exc) { 465 p(mrb, mrb_obj_value(mrb->exc), 0); 466 mrb->exc = 0; 467 } 468 else { 469 /* no */ 470 if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))) { 471 result = mrb_any_to_s(mrb, result); 472 } 473 p(mrb, result, 1); 474 } 475 } 476 ruby_code[0] = '\0'; 477 last_code_line[0] = '\0'; 478 mrb_gc_arena_restore(mrb, ai); 479 } 480 mrb_parser_free(parser); 481 cxt->lineno++; 482 } 563 if (MIRB_SIGSETJMP(ctrl_c_buf) == 0) { 564 ; 565 } 566 else { 567 ruby_code[0] = '\0'; 568 last_code_line[0] = '\0'; 569 code_block_open = FALSE; 570 puts("^C"); 571 } 572 signal(SIGINT, ctrl_c_handler); 573 line = MIRB_READLINE(code_block_open ? "* " : "> "); 574 signal(SIGINT, SIG_DFL); 575 576 if (line == NULL) { 577 printf("\n"); 578 break; 579 } 580 if (strlen(line) > sizeof(last_code_line)-2) { 581 fputs("input string too long\n", stderr); 582 continue; 583 } 584 strcpy(last_code_line, line); 585 strcat(last_code_line, "\n"); 586 MIRB_ADD_HISTORY(line); 587 MIRB_LINE_FREE(line); 588 #endif 589 590 done: 591 if (code_block_open) { 592 if (strlen(ruby_code)+strlen(last_code_line) > sizeof(ruby_code)-1) { 593 fputs("concatenated input string too long\n", stderr); 594 continue; 595 } 596 strcat(ruby_code, last_code_line); 597 } 598 else { 599 if (check_keyword(last_code_line, "quit") || check_keyword(last_code_line, "exit")) { 600 break; 601 } 602 strcpy(ruby_code, last_code_line); 603 } 604 605 utf8 = mrb_utf8_from_locale(ruby_code, -1); 606 if (!utf8) abort(); 607 608 /* parse code */ 609 parser = mrb_parser_new(mrb); 610 if (parser == NULL) { 611 fputs("create parser state error\n", stderr); 612 break; 613 } 614 parser->s = utf8; 615 parser->send = utf8 + strlen(utf8); 616 parser->lineno = cxt->lineno; 617 mrb_parser_parse(parser, cxt); 618 code_block_open = is_code_block_open(parser); 619 mrb_utf8_free(utf8); 620 621 if (code_block_open) { 622 /* no evaluation of code */ 623 } 624 else { 625 if (0 < parser->nwarn) { 626 /* warning */ 627 char* msg = mrb_locale_from_utf8(parser->warn_buffer[0].message, -1); 628 printf("line %d: %s\n", parser->warn_buffer[0].lineno, msg); 629 mrb_locale_free(msg); 630 } 631 if (0 < parser->nerr) { 632 /* syntax error */ 633 char* msg = mrb_locale_from_utf8(parser->error_buffer[0].message, -1); 634 printf("line %d: %s\n", parser->error_buffer[0].lineno, msg); 635 mrb_locale_free(msg); 636 } 637 else { 638 /* generate bytecode */ 639 struct RProc *proc = mrb_generate_code(mrb, parser); 640 if (proc == NULL) { 641 fputs("codegen error\n", stderr); 642 mrb_parser_free(parser); 643 break; 644 } 645 646 if (args.verbose) { 647 mrb_codedump_all(mrb, proc); 648 } 649 /* adjust stack length of toplevel environment */ 650 if (mrb->c->cibase->env) { 651 struct REnv *e = mrb->c->cibase->env; 652 if (e && MRB_ENV_STACK_LEN(e) < proc->body.irep->nlocals) { 653 MRB_ENV_SET_STACK_LEN(e, proc->body.irep->nlocals); 654 } 655 } 656 /* pass a proc for evaluation */ 657 /* evaluate the bytecode */ 658 result = mrb_vm_run(mrb, 659 proc, 660 mrb_top_self(mrb), 661 stack_keep); 662 stack_keep = proc->body.irep->nlocals; 663 /* did an exception occur? */ 664 if (mrb->exc) { 665 p(mrb, mrb_obj_value(mrb->exc), 0); 666 mrb->exc = 0; 667 } 668 else { 669 /* no */ 670 if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){ 671 result = mrb_any_to_s(mrb, result); 672 } 673 p(mrb, result, 1); 674 #ifndef DISABLE_MIRB_UNDERSCORE 675 *(mrb->c->stack + 1) = result; 676 #endif 677 } 678 } 679 ruby_code[0] = '\0'; 680 last_code_line[0] = '\0'; 681 mrb_gc_arena_restore(mrb, ai); 682 } 683 mrb_parser_free(parser); 684 cxt->lineno++; 685 MRB_CATCH(&c_jmp) { 686 p(mrb, mrb_obj_value(mrb->exc), 0); 687 mrb->exc = 0; 688 } 689 MRB_END_EXC(&c_jmp); 690 } 483 691 484 692 #ifdef ENABLE_READLINE 485 MIRB_WRITE_HISTORY(history_path); 486 mrb_free(mrb, history_path); 487 #endif 488 489 mrbc_context_free(mrb, cxt); 490 mrb_close(mrb); 491 492 return 0; 493 } 693 MIRB_WRITE_HISTORY(history_path); 694 mrb_free(mrb, history_path); 695 #endif 696 697 if (args.rfp) fclose(args.rfp); 698 mrb_free(mrb, args.argv); 699 if (args.libv) { 700 for (i = 0; i < args.libc; ++i) { 701 mrb_free(mrb, args.libv[i]); 702 } 703 mrb_free(mrb, args.libv); 704 } 705 mrbc_context_free(mrb, cxt); 706 mrb_close(mrb); 707 708 return 0; 709 } -
EcnlProtoTool/trunk/prototool/src/mrbc.c
r321 r439 1 #include <mruby.h> 2 3 #ifdef MRB_DISABLE_STDIO 4 # error mruby-bin-mrbc conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 5 #endif 6 1 7 #include <stdlib.h> 2 3 #include "mruby.h" 4 #include "mruby/compile.h" 5 #include "mruby/dump.h" 6 #include "mruby/proc.h" 8 #include <string.h> 9 #include <mruby/compile.h> 10 #include <mruby/dump.h> 11 #include <mruby/proc.h> 7 12 8 13 #define RITEBIN_EXT ".mrb" 9 14 #define C_EXT ".c" 10 15 11 struct mrbc_args 12 { 13 int argc;14 char **argv;15 int idx;16 const char *prog;17 const char *outfile;18 const char *initname;19 mrb_bool check_syntax: 1;20 mrb_bool verbose: 1;21 unsigned int flags: 4;16 struct mrbc_args { 17 int argc; 18 char **argv; 19 int idx; 20 const char *prog; 21 const char *outfile; 22 const char *initname; 23 mrb_bool check_syntax : 1; 24 mrb_bool verbose : 1; 25 mrb_bool remove_lv : 1; 26 unsigned int flags : 4; 22 27 }; 23 28 … … 25 30 usage(const char *name) 26 31 { 27 static const char *const usage_msg[] = { 28 "switches:", 29 "-c check syntax only", 30 "-o<outfile> place the output into <outfile>", 31 "-v print version number, then turn on verbose mode", 32 "-g produce debugging information", 33 "-B<symbol> binary <symbol> output in C language format", 34 "-e generate little endian iseq data", 35 "-E generate big endian iseq data", 36 "--verbose run at verbose mode", 37 "--version print the version", 38 "--copyright print the copyright", 39 NULL 40 }; 41 const char *const *p = usage_msg; 42 43 printf("Usage: %s [switches] programfile\n", name); 44 while (*p) 45 printf(" %s\n", *p++); 32 static const char *const usage_msg[] = { 33 "switches:", 34 "-c check syntax only", 35 "-o<outfile> place the output into <outfile>", 36 "-v print version number, then turn on verbose mode", 37 "-g produce debugging information", 38 "-B<symbol> binary <symbol> output in C language format", 39 "-e generate little endian iseq data", 40 "-E generate big endian iseq data", 41 "--remove-lv remove local variables", 42 "--verbose run at verbose mode", 43 "--version print the version", 44 "--copyright print the copyright", 45 NULL 46 }; 47 const char *const *p = usage_msg; 48 49 printf("Usage: %s [switches] programfile\n", name); 50 while (*p) 51 printf(" %s\n", *p++); 46 52 } 47 53 … … 49 55 get_outfilename(mrb_state *mrb, char *infile, const char *ext) 50 56 { 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 57 size_t infilelen; 58 size_t extlen; 59 char *outfile; 60 char *p; 61 62 infilelen = strlen(infile); 63 extlen = strlen(ext); 64 outfile = (char*)mrb_malloc(mrb, infilelen + extlen + 1); 65 memcpy(outfile, infile, infilelen + 1); 66 if (*ext) { 67 if ((p = strrchr(outfile, '.')) == NULL) 68 p = outfile + infilelen; 69 memcpy(p, ext, extlen + 1); 70 } 71 72 return outfile; 67 73 } 68 74 … … 70 76 parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args) 71 77 { 72 static const struct mrbc_args args_zero = { 0 }; 73 int i; 74 75 *args = args_zero; 76 args->argc = argc; 77 args->argv = argv; 78 args->prog = argv[0]; 79 80 for (i = 1; i < argc; i++) { 81 if (argv[i][0] == '-') { 82 switch ((argv[i])[1]) { 83 case 'o': 84 if (args->outfile) { 85 fprintf(stderr, "%s: an output file is already specified. (%s)\n", 86 args->prog, args->outfile); 87 return -1; 88 } 89 if (argv[i][2] == '\0' && argv[i + 1]) { 90 i++; 91 args->outfile = get_outfilename(mrb, argv[i], ""); 92 } 93 else { 94 args->outfile = get_outfilename(mrb, argv[i] + 2, ""); 95 } 96 break; 97 case 'B': 98 if (argv[i][2] == '\0' && argv[i + 1]) { 99 i++; 100 args->initname = argv[i]; 101 } 102 else { 103 args->initname = argv[i] + 2; 104 } 105 if (*args->initname == '\0') { 106 fprintf(stderr, "%s: function name is not specified.\n", args->prog); 107 return -1; 108 } 109 break; 110 case 'c': 111 args->check_syntax = TRUE; 112 break; 113 case 'v': 114 if (!args->verbose) mrb_show_version(mrb); 115 args->verbose = TRUE; 116 break; 117 case 'g': 118 args->flags |= DUMP_DEBUG_INFO; 119 break; 120 case 'E': 121 args->flags = DUMP_ENDIAN_BIG | (args->flags & ~DUMP_ENDIAN_MASK); 122 break; 123 case 'e': 124 args->flags = DUMP_ENDIAN_LIL | (args->flags & ~DUMP_ENDIAN_MASK); 125 break; 126 case 'h': 127 return -1; 128 case '-': 129 if (argv[i][1] == '\n') { 130 return i; 131 } 132 if (strcmp(argv[i] + 2, "version") == 0) { 133 mrb_show_version(mrb); 134 exit(EXIT_SUCCESS); 135 } 136 else if (strcmp(argv[i] + 2, "verbose") == 0) { 137 args->verbose = TRUE; 138 break; 139 } 140 else if (strcmp(argv[i] + 2, "copyright") == 0) { 141 mrb_show_copyright(mrb); 142 exit(EXIT_SUCCESS); 143 } 144 return -1; 145 default: 146 return i; 147 } 148 } 149 else { 150 break; 151 } 152 } 153 if (args->verbose && args->initname && (args->flags & DUMP_ENDIAN_MASK) == 0) { 154 fprintf(stderr, "%s: generating %s endian C file. specify -e/-E for cross compiling.\n", 155 args->prog, bigendian_p() ? "big" : "little"); 156 } 157 return i; 78 static const struct mrbc_args args_zero = { 0 }; 79 int i; 80 81 *args = args_zero; 82 args->argc = argc; 83 args->argv = argv; 84 args->prog = argv[0]; 85 86 for (i=1; i<argc; i++) { 87 if (argv[i][0] == '-') { 88 switch ((argv[i])[1]) { 89 case 'o': 90 if (args->outfile) { 91 fprintf(stderr, "%s: an output file is already specified. (%s)\n", 92 args->prog, args->outfile); 93 return -1; 94 } 95 if (argv[i][2] == '\0' && argv[i+1]) { 96 i++; 97 args->outfile = get_outfilename(mrb, argv[i], ""); 98 } 99 else { 100 args->outfile = get_outfilename(mrb, argv[i] + 2, ""); 101 } 102 break; 103 case 'B': 104 if (argv[i][2] == '\0' && argv[i+1]) { 105 i++; 106 args->initname = argv[i]; 107 } 108 else { 109 args->initname = argv[i]+2; 110 } 111 if (*args->initname == '\0') { 112 fprintf(stderr, "%s: function name is not specified.\n", args->prog); 113 return -1; 114 } 115 break; 116 case 'c': 117 args->check_syntax = TRUE; 118 break; 119 case 'v': 120 if (!args->verbose) mrb_show_version(mrb); 121 args->verbose = TRUE; 122 break; 123 case 'g': 124 args->flags |= DUMP_DEBUG_INFO; 125 break; 126 case 'E': 127 args->flags = DUMP_ENDIAN_BIG | (args->flags & ~DUMP_ENDIAN_MASK); 128 break; 129 case 'e': 130 args->flags = DUMP_ENDIAN_LIL | (args->flags & ~DUMP_ENDIAN_MASK); 131 break; 132 case 'h': 133 return -1; 134 case '-': 135 if (argv[i][1] == '\n') { 136 return i; 137 } 138 if (strcmp(argv[i] + 2, "version") == 0) { 139 mrb_show_version(mrb); 140 exit(EXIT_SUCCESS); 141 } 142 else if (strcmp(argv[i] + 2, "verbose") == 0) { 143 args->verbose = TRUE; 144 break; 145 } 146 else if (strcmp(argv[i] + 2, "copyright") == 0) { 147 mrb_show_copyright(mrb); 148 exit(EXIT_SUCCESS); 149 } 150 else if (strcmp(argv[i] + 2, "remove-lv") == 0) { 151 args->remove_lv = TRUE; 152 break; 153 } 154 return -1; 155 default: 156 return i; 157 } 158 } 159 else { 160 break; 161 } 162 } 163 if (args->verbose && args->initname && (args->flags & DUMP_ENDIAN_MASK) == 0) { 164 fprintf(stderr, "%s: generating %s endian C file. specify -e/-E for cross compiling.\n", 165 args->prog, bigendian_p() ? "big" : "little"); 166 } 167 return i; 158 168 } 159 169 … … 161 171 cleanup(mrb_state *mrb, struct mrbc_args *args) 162 172 { 163 164 173 mrb_free(mrb, (void*)args->outfile); 174 mrb_close(mrb); 165 175 } 166 176 … … 168 178 partial_hook(struct mrb_parser_state *p) 169 179 { 170 171 172 173 174 175 176 177 178 179 180 p->f = fopen(fn, "r");181 182 183 184 185 186 180 mrbc_context *c = p->cxt; 181 struct mrbc_args *args = (struct mrbc_args *)c->partial_data; 182 const char *fn; 183 184 if (p->f) fclose(p->f); 185 if (args->idx >= args->argc) { 186 p->f = NULL; 187 return -1; 188 } 189 fn = args->argv[args->idx++]; 190 p->f = fopen(fn, "rb"); 191 if (p->f == NULL) { 192 fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, fn); 193 return -1; 194 } 195 mrb_parser_set_filename(p, fn); 196 return 0; 187 197 } 188 198 … … 190 200 load_file(mrb_state *mrb, struct mrbc_args *args) 191 201 { 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 if ((infile = fopen(input, "r")) == NULL) {208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 202 mrbc_context *c; 203 mrb_value result; 204 char *input = args->argv[args->idx]; 205 FILE *infile; 206 mrb_bool need_close = FALSE; 207 208 c = mrbc_context_new(mrb); 209 if (args->verbose) 210 c->dump_result = TRUE; 211 c->no_exec = TRUE; 212 if (input[0] == '-' && input[1] == '\0') { 213 infile = stdin; 214 } 215 else { 216 need_close = TRUE; 217 if ((infile = fopen(input, "rb")) == NULL) { 218 fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, input); 219 return mrb_nil_value(); 220 } 221 } 222 mrbc_filename(mrb, c, input); 223 args->idx++; 224 if (args->idx < args->argc) { 225 need_close = FALSE; 226 mrbc_partial_hook(mrb, c, partial_hook, (void*)args); 227 } 228 229 result = mrb_load_file_cxt(mrb, infile, c); 230 if (need_close) fclose(infile); 231 mrbc_context_free(mrb, c); 232 if (mrb_undef_p(result)) { 233 return mrb_nil_value(); 234 } 235 return result; 226 236 } 227 237 … … 229 239 dump_file(mrb_state *mrb, FILE *wfp, const char *outfile, struct RProc *proc, struct mrbc_args *args) 230 240 { 231 int n = MRB_DUMP_OK; 232 mrb_irep *irep = proc->body.irep; 233 234 if (args->initname) { 235 n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname); 236 if (n == MRB_DUMP_INVALID_ARGUMENT) { 237 fprintf(stderr, "%s: invalid C language symbol name\n", args->initname); 238 } 239 } 240 else { 241 n = mrb_dump_irep_binary(mrb, irep, args->flags, wfp); 242 } 243 if (n != MRB_DUMP_OK) { 244 fprintf(stderr, "%s: error in mrb dump (%s) %d\n", args->prog, outfile, n); 245 } 246 return n; 241 int n = MRB_DUMP_OK; 242 mrb_irep *irep = proc->body.irep; 243 244 if (args->remove_lv) { 245 mrb_irep_remove_lv(mrb, irep); 246 } 247 if (args->initname) { 248 n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname); 249 if (n == MRB_DUMP_INVALID_ARGUMENT) { 250 fprintf(stderr, "%s: invalid C language symbol name\n", args->initname); 251 } 252 } 253 else { 254 n = mrb_dump_irep_binary(mrb, irep, args->flags, wfp); 255 } 256 if (n != MRB_DUMP_OK) { 257 fprintf(stderr, "%s: error in mrb dump (%s) %d\n", args->prog, outfile, n); 258 } 259 return n; 247 260 } 248 261 … … 250 263 mrbc_main(int argc, char **argv) 251 264 { 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 } 265 mrb_state *mrb = mrb_open_allocf(mrb_default_allocf, NULL, TRUE); 266 int n, result; 267 struct mrbc_args args; 268 FILE *wfp; 269 mrb_value load; 270 271 if (mrb == NULL) { 272 fputs("Invalid mrb_state, exiting mrbc\n", stderr); 273 return EXIT_FAILURE; 274 } 275 276 n = parse_args(mrb, argc, argv, &args); 277 if (n < 0) { 278 cleanup(mrb, &args); 279 usage(argv[0]); 280 return EXIT_FAILURE; 281 } 282 if (n == argc) { 283 fprintf(stderr, "%s: no program file given\n", args.prog); 284 return EXIT_FAILURE; 285 } 286 if (args.outfile == NULL && !args.check_syntax) { 287 if (n + 1 == argc) { 288 args.outfile = get_outfilename(mrb, argv[n], args.initname ? C_EXT : RITEBIN_EXT); 289 } 290 else { 291 fprintf(stderr, "%s: output file should be specified to compile multiple files\n", args.prog); 292 return EXIT_FAILURE; 293 } 294 } 295 296 args.idx = n; 297 load = load_file(mrb, &args); 298 if (mrb_nil_p(load)) { 299 cleanup(mrb, &args); 300 return EXIT_FAILURE; 301 } 302 if (args.check_syntax) { 303 printf("%s:%s:Syntax OK\n", args.prog, argv[n]); 304 } 305 306 if (args.check_syntax) { 307 cleanup(mrb, &args); 308 return EXIT_SUCCESS; 309 } 310 311 if (args.outfile) { 312 if (strcmp("-", args.outfile) == 0) { 313 wfp = stdout; 314 } 315 else if ((wfp = fopen(args.outfile, "wb")) == NULL) { 316 fprintf(stderr, "%s: cannot open output file:(%s)\n", args.prog, args.outfile); 317 return EXIT_FAILURE; 318 } 319 } 320 else { 321 fprintf(stderr, "Output file is required\n"); 322 return EXIT_FAILURE; 323 } 324 result = dump_file(mrb, wfp, args.outfile, mrb_proc_ptr(load), &args); 325 fclose(wfp); 326 cleanup(mrb, &args); 327 if (result != MRB_DUMP_OK) { 328 return EXIT_FAILURE; 329 } 330 return EXIT_SUCCESS; 331 } -
EcnlProtoTool/trunk/prototool/src/mrdb.c
r321 r439 6 6 #include <stdlib.h> 7 7 #include <string.h> 8 9 #include "mruby.h" 10 #include "mruby/dump.h" 11 #include "mruby/debug.h" 12 #include "mruby/class.h" 13 #include "mruby/opcode.h" 14 #include "mruby/variable.h" 8 #include <ctype.h> 9 10 #include <mruby.h> 11 #include <mruby/dump.h> 12 #include <mruby/debug.h> 13 #include <mruby/class.h> 14 #include <mruby/opcode.h> 15 #include <mruby/variable.h> 15 16 16 17 #include "mrdb.h" 17 18 #include "apibreak.h" 19 #include "apilist.h" 18 20 19 21 void mrdb_state_free(mrb_state *); … … 22 24 static mrdb_state *_mrdb_state = NULL; 23 25 24 struct _args 25 { 26 FILE *rfp; 27 char* fname; 28 char* srcpath; 29 int argc; 30 char** argv; 31 mrb_bool mrbfile : 1; 26 struct _args { 27 FILE *rfp; 28 char* fname; 29 char* srcpath; 30 int argc; 31 char** argv; 32 mrb_bool mrbfile : 1; 32 33 }; 33 34 34 typedef struct debug_command 35 { 36 const char *cmd1; 37 const char *cmd2; 38 uint8_t len1; 39 uint8_t len2; 40 uint8_t div; 41 debug_command_id id; 42 debug_command_func func; 35 typedef struct debug_command { 36 const char *cmd1; 37 const char *cmd2; 38 uint8_t len1; 39 uint8_t len2; 40 uint8_t div; 41 debug_command_id id; 42 debug_command_func func; 43 43 } debug_command; 44 44 … … 52 52 {"help", NULL, 1, 0, 1, DBGCMD_HELP, dbgcmd_help}, /* h[elp] */ 53 53 {"info", "breakpoints", 1, 1, 1, DBGCMD_INFO_BREAK, dbgcmd_info_break}, /* i[nfo] b[reakpoints] */ 54 {"info", "locals", 1, 1, 0, DBGCMD_INFO_LOCAL, dbgcmd_info_local}, /* i[nfo] l[ocals] */ 55 {"list", NULL, 1, 0, 1, DBGCMD_LIST, dbgcmd_list}, /* l[ist] */ 54 56 {"print", NULL, 1, 0, 0, DBGCMD_PRINT, dbgcmd_print}, /* p[rint] */ 55 57 {"quit", NULL, 1, 0, 0, DBGCMD_QUIT, dbgcmd_quit}, /* q[uit] */ … … 64 66 usage(const char *name) 65 67 { 66 67 68 69 70 71 72 73 74 75 76 77 78 79 68 static const char *const usage_msg[] = { 69 "switches:", 70 "-b load and execute RiteBinary (mrb) file", 71 "-d specify source directory", 72 "--version print the version", 73 "--copyright print the copyright", 74 NULL 75 }; 76 const char *const *p = usage_msg; 77 78 printf("Usage: %s [switches] programfile\n", name); 79 while (*p) { 80 printf(" %s\n", *p++); 81 } 80 82 } 81 83 … … 83 85 parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) 84 86 { 85 86 87 88 89 90 for (argc--, argv++; argc > 0; argc--,argv++) {91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 memcpy(args->argv, argv, (argc +1) * sizeof(char*));164 165 166 87 char **origargv = argv; 88 static const struct _args args_zero = { 0 }; 89 90 *args = args_zero; 91 92 for (argc--,argv++; argc > 0; argc--,argv++) { 93 char *item; 94 if (argv[0][0] != '-') break; 95 96 item = argv[0] + 1; 97 switch (*item++) { 98 case 'b': 99 args->mrbfile = TRUE; 100 break; 101 case 'd': 102 if (item[0]) { 103 goto append_srcpath; 104 } 105 else if (argc > 1) { 106 argc--; argv++; 107 item = argv[0]; 108 append_srcpath: 109 if (!args->srcpath) { 110 size_t buflen; 111 char *buf; 112 113 buflen = strlen(item) + 1; 114 buf = (char *)mrb_malloc(mrb, buflen); 115 memcpy(buf, item, buflen); 116 args->srcpath = buf; 117 } 118 else { 119 size_t srcpathlen; 120 size_t itemlen; 121 122 srcpathlen = strlen(args->srcpath); 123 itemlen = strlen(item); 124 args->srcpath = 125 (char *)mrb_realloc(mrb, args->srcpath, srcpathlen + itemlen + 2); 126 args->srcpath[srcpathlen] = '\n'; 127 memcpy(args->srcpath + srcpathlen + 1, item, itemlen + 1); 128 } 129 } 130 else { 131 printf("%s: No path specified for -d\n", *origargv); 132 return EXIT_SUCCESS; 133 } 134 break; 135 case '-': 136 if (strcmp((*argv) + 2, "version") == 0) { 137 mrb_show_version(mrb); 138 exit(EXIT_SUCCESS); 139 } 140 else if (strcmp((*argv) + 2, "copyright") == 0) { 141 mrb_show_copyright(mrb); 142 exit(EXIT_SUCCESS); 143 } 144 default: 145 return EXIT_FAILURE; 146 } 147 } 148 149 if (args->rfp == NULL) { 150 if (*argv == NULL) { 151 printf("%s: Program file not specified.\n", *origargv); 152 return EXIT_FAILURE; 153 } 154 else { 155 args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r"); 156 if (args->rfp == NULL) { 157 printf("%s: Cannot open program file. (%s)\n", *origargv, *argv); 158 return EXIT_FAILURE; 159 } 160 args->fname = argv[0]; 161 argc--; argv++; 162 } 163 } 164 args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1)); 165 memcpy(args->argv, argv, (argc+1) * sizeof(char*)); 166 args->argc = argc; 167 168 return EXIT_SUCCESS; 167 169 } 168 170 … … 170 172 cleanup(mrb_state *mrb, struct _args *args) 171 173 { 172 173 174 175 176 177 178 179 174 if (args->rfp) 175 fclose(args->rfp); 176 if (args->srcpath) 177 mrb_free(mrb, args->srcpath); 178 if (args->argv) 179 mrb_free(mrb, args->argv); 180 mrdb_state_free(mrb); 181 mrb_close(mrb); 180 182 } 181 183 … … 183 185 mrb_debug_context_new(mrb_state *mrb) 184 186 { 185 mrb_debug_context *dbg = (mrb_debug_context*)mrb_malloc(mrb, sizeof(mrb_debug_context));186 187 188 189 InterlockedExchange(&dbg->xm, DBG_INIT);190 191 192 193 187 mrb_debug_context *dbg = (mrb_debug_context*)mrb_malloc(mrb, sizeof(mrb_debug_context)); 188 189 memset(dbg, 0, sizeof(mrb_debug_context)); 190 191 dbg->xm = DBG_INIT; 192 dbg->xphase = DBG_PHASE_BEFORE_RUN; 193 dbg->next_bpno = 1; 194 195 return dbg; 194 196 } 195 197 … … 197 199 mrb_debug_context_get(mrb_state *mrb) 198 200 { 199 200 201 202 201 if (!_debug_context) { 202 _debug_context = mrb_debug_context_new(mrb); 203 } 204 return _debug_context; 203 205 } 204 206 … … 206 208 mrb_debug_context_set(mrb_debug_context *dbg) 207 209 { 208 210 _debug_context = dbg; 209 211 } 210 212 … … 212 214 mrb_debug_context_free(mrb_state *mrb) 213 215 { 214 215 216 217 218 216 if (_debug_context) { 217 mrb_debug_delete_break_all(mrb, _debug_context); 218 mrb_free(mrb, _debug_context); 219 _debug_context = NULL; 220 } 219 221 } 220 222 … … 222 224 mrdb_state_new(mrb_state *mrb) 223 225 { 224 mrdb_state *mrdb = (mrdb_state*)mrb_malloc(mrb, sizeof(mrdb_state));225 226 227 228 229 mrdb->command = (char *)mrb_malloc(mrb, MAX_COMMAND_LINE +1);230 231 232 226 mrdb_state *mrdb = (mrdb_state*)mrb_malloc(mrb, sizeof(mrdb_state)); 227 228 memset(mrdb, 0, sizeof(mrdb_state)); 229 230 mrdb->dbg = mrb_debug_context_get(mrb); 231 mrdb->command = (char*)mrb_malloc(mrb, MAX_COMMAND_LINE+1); 232 mrdb->print_no = 1; 233 234 return mrdb; 233 235 } 234 236 … … 236 238 mrdb_state_get(mrb_state *mrb) 237 239 { 238 239 240 241 240 if (!_mrdb_state) { 241 _mrdb_state = mrdb_state_new(mrb); 242 } 243 return _mrdb_state; 242 244 } 243 245 … … 245 247 mrdb_state_set(mrdb_state *mrdb) 246 248 { 247 249 _mrdb_state = mrdb; 248 250 } 249 251 … … 251 253 mrdb_state_free(mrb_state *mrb) 252 254 { 253 254 255 256 257 258 255 mrb_debug_context_free(mrb); 256 if (_mrdb_state) { 257 mrb_free(mrb, _mrdb_state->command); 258 mrb_free(mrb, _mrdb_state); 259 _mrdb_state = NULL; 260 } 259 261 } 260 262 … … 262 264 get_command(mrb_state *mrb, mrdb_state *mrdb) 263 265 { 264 265 266 267 for (i = 0; i <MAX_COMMAND_LINE; i++) {268 if ((c =getchar()) == EOF || c == '\n') break;269 270 271 272 273 274 strlcpy(mrdb->command, "quit", MAX_COMMAND_LINE + 1);275 276 277 278 279 for (; (c = getchar()) != EOF && c != '\n'; i++);280 281 282 283 284 285 286 287 288 266 int i; 267 int c; 268 269 for (i=0; i<MAX_COMMAND_LINE; i++) { 270 if ((c=getchar()) == EOF || c == '\n') break; 271 mrdb->command[i] = c; 272 } 273 274 if (i == 0 && feof(stdin)) { 275 clearerr(stdin); 276 strcpy(mrdb->command, "quit"); 277 i += sizeof("quit") - 1; 278 } 279 280 if (i == MAX_COMMAND_LINE) { 281 for ( ; (c=getchar()) != EOF && c !='\n'; i++) ; 282 } 283 284 if (i > MAX_COMMAND_LINE) { 285 printf("command line too long.\n"); 286 i = 0; /* discard command data */ 287 } 288 mrdb->command[i] = '\0'; 289 290 return mrdb->command; 289 291 } 290 292 … … 292 294 pick_out_word(mrb_state *mrb, char **pp) 293 295 { 294 295 296 for (ps = *pp; ISBLANK(*ps); ps++);297 298 299 300 301 302 *pp = strchr(ps +1, *ps);303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 296 char *ps; 297 298 for (ps=*pp; ISBLANK(*ps); ps++) ; 299 if (*ps == '\0') { 300 return NULL; 301 } 302 303 if (*ps == '\"' || *ps == '\'') { 304 *pp = strchr(ps+1, *ps); 305 if (*pp) (*pp)++; 306 } 307 else { 308 *pp = strpbrk(ps, " \t"); 309 } 310 311 if (!*pp) { 312 *pp = ps + strlen(ps); 313 } 314 315 if (**pp != '\0') { 316 **pp = '\0'; 317 (*pp)++; 318 } 319 320 return ps; 319 321 } 320 322 … … 322 324 parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) 323 325 { 324 325 326 327 328 329 330 331 332 333 334 335 for (; *p && ISBLANK(*p); p++);336 337 338 339 340 341 for (cmd =(debug_command*)debug_command_list; cmd->cmd1; cmd++) {342 343 344 345 346 347 348 349 350 351 352 353 354 355 for (; *p && ISBLANK(*p); p++);356 357 358 359 360 361 362 363 for (; cmd->cmd1; cmd++) {364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 for (; mrdb->wcnt <MAX_COMMAND_WORD; mrdb->wcnt++) {386 387 388 389 390 391 392 393 326 debug_command *cmd = NULL; 327 char *p = buf; 328 size_t wlen; 329 330 /* get word #1 */ 331 mrdb->words[0] = pick_out_word(mrb, &p); 332 if (!mrdb->words[0]) { 333 return NULL; 334 } 335 mrdb->wcnt = 1; 336 /* set remain parameter */ 337 for ( ; *p && ISBLANK(*p); p++) ; 338 if (*p) { 339 mrdb->words[mrdb->wcnt++] = p; 340 } 341 342 /* check word #1 */ 343 for (cmd=(debug_command*)debug_command_list; cmd->cmd1; cmd++) { 344 wlen = strlen(mrdb->words[0]); 345 if (wlen >= cmd->len1 && 346 strncmp(mrdb->words[0], cmd->cmd1, wlen) == 0) { 347 break; 348 } 349 } 350 351 if (cmd->cmd2) { 352 if (mrdb->wcnt > 1) { 353 /* get word #2 */ 354 mrdb->words[1] = pick_out_word(mrb, &p); 355 if (mrdb->words[1]) { 356 /* update remain parameter */ 357 for ( ; *p && ISBLANK(*p); p++) ; 358 if (*p) { 359 mrdb->words[mrdb->wcnt++] = p; 360 } 361 } 362 } 363 364 /* check word #1,#2 */ 365 for ( ; cmd->cmd1; cmd++) { 366 wlen = strlen(mrdb->words[0]); 367 if (wlen < cmd->len1 || 368 strncmp(mrdb->words[0], cmd->cmd1, wlen)) { 369 continue; 370 } 371 372 if (!cmd->cmd2) break; /* word #1 only */ 373 374 if (mrdb->wcnt == 1) continue; /* word #2 not specified */ 375 376 wlen = strlen(mrdb->words[1]); 377 if (wlen >= cmd->len2 && 378 strncmp(mrdb->words[1], cmd->cmd2, wlen) == 0) { 379 break; /* word #1 and #2 */ 380 } 381 } 382 } 383 384 /* divide remain parameters */ 385 if (cmd->cmd1 && cmd->div) { 386 p = mrdb->words[--mrdb->wcnt]; 387 for ( ; mrdb->wcnt<MAX_COMMAND_WORD; mrdb->wcnt++) { 388 mrdb->words[mrdb->wcnt] = pick_out_word(mrb, &p); 389 if (!mrdb->words[mrdb->wcnt]) { 390 break; 391 } 392 } 393 } 394 395 return cmd->cmd1 ? cmd : NULL; 394 396 } 395 397 … … 397 399 print_info_stopped_break(mrb_state *mrb, mrdb_state *mrdb) 398 400 { 399 400 401 402 403 404 405 406 407 408 switch(bp.type) {409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 401 mrb_debug_breakpoint bp; 402 int32_t ret; 403 uint16_t lineno; 404 const char *file; 405 const char *method_name; 406 const char *class_name; 407 408 ret = mrb_debug_get_break(mrb, mrdb->dbg, mrdb->dbg->stopped_bpno, &bp); 409 if (ret == 0) { 410 switch(bp.type) { 411 case MRB_DEBUG_BPTYPE_LINE: 412 file = bp.point.linepoint.file; 413 lineno = bp.point.linepoint.lineno; 414 printf("Breakpoint %d, at %s:%d\n", bp.bpno, file, lineno); 415 break; 416 case MRB_DEBUG_BPTYPE_METHOD: 417 method_name = bp.point.methodpoint.method_name; 418 class_name = bp.point.methodpoint.class_name; 419 if (class_name == NULL) { 420 printf("Breakpoint %d, %s\n", bp.bpno, method_name); 421 } 422 else { 423 printf("Breakpoint %d, %s:%s\n", bp.bpno, class_name, method_name); 424 } 425 if (mrdb->dbg->isCfunc) { 426 printf("Stopped before calling the C function.\n"); 427 } 428 break; 429 default: 430 break; 431 } 432 } 431 433 } 432 434 … … 434 436 print_info_stopped_step_next(mrb_state *mrb, mrdb_state *mrdb) 435 437 { 436 const char* file = mrdb->dbg->prvfile; 437 uint16_t lineno = mrdb->dbg->prvline; 438 printf("%s:%d\n", file, lineno); 438 const char* file = mrdb->dbg->prvfile; 439 uint16_t lineno = mrdb->dbg->prvline; 440 printf("%s:%d\n", file, lineno); 441 } 442 443 static void 444 print_info_stopped_code(mrb_state *mrb, mrdb_state *mrdb) 445 { 446 char* file = mrb_debug_get_source(mrb, mrdb, mrdb->srcpath, mrdb->dbg->prvfile); 447 uint16_t lineno = mrdb->dbg->prvline; 448 if (file != NULL) { 449 mrb_debug_list(mrb, mrdb->dbg, file, lineno, lineno); 450 mrb_free(mrb, file); 451 } 439 452 } 440 453 … … 442 455 print_info_stopped(mrb_state *mrb, mrdb_state *mrdb) 443 456 { 444 switch (mrdb->dbg->bm) { 445 case BRK_BREAK: 446 print_info_stopped_break(mrb, mrdb); 447 break; 448 case BRK_STEP: 449 case BRK_NEXT: 450 print_info_stopped_step_next(mrb, mrdb); 451 break; 452 default: 453 break; 454 } 457 switch(mrdb->dbg->bm) { 458 case BRK_BREAK: 459 print_info_stopped_break(mrb, mrdb); 460 print_info_stopped_code(mrb, mrdb); 461 break; 462 case BRK_STEP: 463 case BRK_NEXT: 464 print_info_stopped_step_next(mrb, mrdb); 465 print_info_stopped_code(mrb, mrdb); 466 break; 467 default: 468 break; 469 } 455 470 } 456 471 … … 458 473 get_and_parse_command(mrb_state *mrb, mrdb_state *mrdb) 459 474 { 460 461 462 463 464 465 for (p = NULL; !p || *p =='\0'; ) {466 467 468 469 470 471 475 debug_command *cmd = NULL; 476 char *p; 477 int i; 478 479 while (!cmd) { 480 for (p=NULL; !p || *p=='\0'; ) { 481 printf("(%s:%d) ", mrdb->dbg->prvfile, mrdb->dbg->prvline); 482 fflush(stdout); 483 p = get_command(mrb, mrdb); 484 } 485 486 cmd = parse_command(mrb, mrdb, p); 472 487 #ifdef _DBG_MRDB_PARSER_ 473 for (i = 0; i <mrdb->wcnt; i++) {474 475 488 for (i=0; i<mrdb->wcnt; i++) { 489 printf("%d: %s\n", i, mrdb->words[i]); 490 } 476 491 #endif 477 478 479 for (i = 0; i <mrdb->wcnt; i++) {480 if (i >0) {481 482 483 484 485 486 487 488 492 if (!cmd) { 493 printf("invalid command ("); 494 for (i=0; i<mrdb->wcnt; i++) { 495 if (i>0) { 496 printf(" "); 497 } 498 printf("%s", mrdb->words[i]); 499 } 500 puts(")"); 501 } 502 } 503 return cmd; 489 504 } 490 505 491 506 static int32_t 492 check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs) 493 { 494 struct RClass* c = NULL; 495 mrb_sym sym; 496 int32_t bpno; 497 mrb_bool isCfunc; 498 499 mrb_debug_context *dbg = mrb_debug_context_get(mrb); 500 501 isCfunc = FALSE; 502 bpno = dbg->method_bpno; 503 dbg->method_bpno = 0; 504 505 switch (GET_OPCODE(*pc)) { 506 case OP_SEND: 507 case OP_SENDB: 508 c = mrb_class(mrb, regs[GETARG_A(*pc)]); 509 sym = irep->syms[GETARG_B(*pc)]; 510 break; 511 case OP_SUPER: 512 c = mrb->c->ci->target_class->super; 513 sym = mrb->c->ci->mid; 514 break; 515 default: 516 sym = 0; 517 break; 518 } 519 if (sym != 0) { 520 dbg->method_bpno = mrb_debug_check_breakpoint_method(mrb, dbg, c, sym, &isCfunc); 521 if (isCfunc) { 522 bpno = dbg->method_bpno; 523 dbg->method_bpno = 0; 524 } 525 } 526 dbg->isCfunc = isCfunc; 527 return bpno; 507 check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs) 508 { 509 struct RClass* c; 510 mrb_sym sym; 511 int32_t bpno; 512 mrb_bool isCfunc; 513 struct mrb_insn_data insn; 514 515 mrb_debug_context *dbg = mrb_debug_context_get(mrb); 516 517 isCfunc = FALSE; 518 bpno = dbg->method_bpno; 519 dbg->method_bpno = 0; 520 521 insn = mrb_decode_insn(pc); 522 switch(insn.insn) { 523 case OP_SEND: 524 case OP_SENDB: 525 c = mrb_class(mrb, regs[insn.a]); 526 sym = irep->syms[insn.b]; 527 break; 528 case OP_SUPER: 529 c = mrb->c->ci->target_class->super; 530 sym = mrb->c->ci->mid; 531 break; 532 default: 533 sym = 0; 534 break; 535 } 536 if (sym != 0) { 537 dbg->method_bpno = mrb_debug_check_breakpoint_method(mrb, dbg, c, sym, &isCfunc); 538 if (isCfunc) { 539 bpno = dbg->method_bpno; 540 dbg->method_bpno = 0; 541 } 542 } 543 dbg->isCfunc = isCfunc; 544 return bpno; 528 545 } 529 546 530 547 static void 531 mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)532 { 533 534 535 536 537 538 539 540 541 542 dbg->pc= pc;543 544 545 546 547 548 549 550 InterlockedExchange(&dbg->xm, DBG_RUN);551 552 553 554 file = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq));555 line = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq));556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 548 mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs) 549 { 550 const char *file; 551 int32_t line; 552 int32_t bpno; 553 554 mrb_debug_context *dbg = mrb_debug_context_get(mrb); 555 556 mrb_assert(dbg); 557 558 dbg->irep = irep; 559 dbg->pc = pc; 560 dbg->regs = regs; 561 562 if (dbg->xphase == DBG_PHASE_RESTART) { 563 dbg->root_irep = irep; 564 dbg->prvfile = NULL; 565 dbg->prvline = 0; 566 dbg->prvci = NULL; 567 dbg->xm = DBG_RUN; 568 dbg->xphase = DBG_PHASE_RUNNING; 569 } 570 571 file = mrb_debug_get_filename(mrb, irep, pc - irep->iseq); 572 line = mrb_debug_get_line(mrb, irep, pc - irep->iseq); 573 574 switch (dbg->xm) { 575 case DBG_STEP: 576 if (!file || (dbg->prvfile == file && dbg->prvline == line)) { 577 return; 578 } 579 dbg->method_bpno = 0; 580 dbg->bm = BRK_STEP; 581 break; 582 583 case DBG_NEXT: 584 if (!file || (dbg->prvfile == file && dbg->prvline == line)) { 585 return; 586 } 587 if ((intptr_t)(dbg->prvci) < (intptr_t)(mrb->c->ci)) { 588 return; 589 } 590 dbg->prvci = NULL; 591 dbg->method_bpno = 0; 592 dbg->bm = BRK_NEXT; 593 break; 594 595 case DBG_RUN: 596 bpno = check_method_breakpoint(mrb, irep, pc, regs); 597 if (bpno > 0) { 598 dbg->stopped_bpno = bpno; 599 dbg->bm = BRK_BREAK; 600 break; 601 } 602 if (dbg->prvfile != file || dbg->prvline != line) { 603 bpno = mrb_debug_check_breakpoint_line(mrb, dbg, file, line); 604 if (bpno > 0) { 605 dbg->stopped_bpno = bpno; 606 dbg->bm = BRK_BREAK; 607 break; 608 } 609 } 610 dbg->prvfile = file; 611 dbg->prvline = line; 612 return; 613 case DBG_INIT: 614 dbg->root_irep = irep; 615 dbg->bm = BRK_INIT; 616 if (!file || line < 0) { 617 puts("Cannot get debugging information."); 618 } 619 break; 620 621 default: 622 return; 623 } 624 625 dbg->prvfile = file; 626 dbg->prvline = line; 627 628 if (dbg->bm == BRK_BREAK && --dbg->ccnt > 0) { 629 return; 630 } 631 dbg->break_hook(mrb, dbg); 632 633 dbg->xphase = DBG_PHASE_RUNNING; 617 634 } 618 635 … … 620 637 mrb_debug_break_hook(mrb_state *mrb, mrb_debug_context *dbg) 621 638 { 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 639 debug_command *cmd; 640 dbgcmd_state st = DBGST_CONTINUE; 641 mrdb_state *mrdb = mrdb_state_get(mrb); 642 643 print_info_stopped(mrb, mrdb); 644 645 while (1) { 646 cmd = get_and_parse_command(mrb, mrdb); 647 mrb_assert(cmd); 648 649 st = cmd->func(mrb, mrdb); 650 651 if ((st == DBGST_CONTINUE) || (st == DBGST_RESTART)) break; 652 } 653 return dbg->xm; 637 654 } 638 655 … … 643 660 if (mrdb == NULL) 644 661 return 0; 645 return InterlockedCompareExchange(&mrdb->dbg->xm, DBG_STEP, DBG_RUN) == DBG_RUN; 662 long prev = mrdb->dbg->xm; 663 if (mrdb->dbg->xm == DBG_RUN) 664 mrdb->dbg->xm = DBG_STEP; 665 return prev == DBG_RUN; 646 666 } 647 667 … … 649 669 mrdb_main(int argc, char **argv) 650 670 { 651 652 653 654 655 656 657 658 659 660 l_restart:661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 InterlockedExchange(&mrdb->dbg->xm, DBG_INIT);687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 if (cmd->func(mrb, mrdb) == DBGST_RESTART) goto l_restart;748 749 750 751 752 753 } 671 mrb_state *mrb = mrb_open(); 672 int n = -1; 673 struct _args args; 674 mrb_value v; 675 mrdb_state *mrdb; 676 mrdb_state *mrdb_backup; 677 mrb_debug_context* dbg_backup; 678 debug_command *cmd; 679 680 l_restart: 681 682 if (mrb == NULL) { 683 fputs("Invalid mrb_state, exiting mruby\n", stderr); 684 return EXIT_FAILURE; 685 } 686 687 /* parse command parameters */ 688 n = parse_args(mrb, argc, argv, &args); 689 if (n == EXIT_FAILURE || args.rfp == NULL) { 690 cleanup(mrb, &args); 691 usage(argv[0]); 692 return n; 693 } 694 695 /* initialize debugger information */ 696 mrdb = mrdb_state_get(mrb); 697 mrb_assert(mrdb && mrdb->dbg); 698 mrdb->srcpath = args.srcpath; 699 700 if (mrdb->dbg->xm == DBG_QUIT) { 701 mrdb->dbg->xphase = DBG_PHASE_RESTART; 702 } 703 else { 704 mrdb->dbg->xphase = DBG_PHASE_BEFORE_RUN; 705 } 706 mrdb->dbg->xm = DBG_INIT; 707 mrdb->dbg->ccnt = 1; 708 709 /* setup hook functions */ 710 mrb->code_fetch_hook = mrb_code_fetch_hook; 711 mrdb->dbg->break_hook = mrb_debug_break_hook; 712 713 if (args.mrbfile) { /* .mrb */ 714 v = mrb_load_irep_file(mrb, args.rfp); 715 } 716 else { /* .rb */ 717 mrbc_context *cc = mrbc_context_new(mrb); 718 mrbc_filename(mrb, cc, args.fname); 719 v = mrb_load_file_cxt(mrb, args.rfp, cc); 720 mrbc_context_free(mrb, cc); 721 } 722 if (mrdb->dbg->xm == DBG_QUIT && !mrb_undef_p(v) && mrb->exc) { 723 const char *classname = mrb_obj_classname(mrb, mrb_obj_value(mrb->exc)); 724 if (!strcmp(classname, "DebuggerExit")) { 725 cleanup(mrb, &args); 726 return 0; 727 } 728 if (!strcmp(classname, "DebuggerRestart")) { 729 mrdb_backup = mrdb_state_get(mrb); 730 dbg_backup = mrb_debug_context_get(mrb); 731 732 mrdb_state_set(NULL); 733 mrb_debug_context_set(NULL); 734 735 cleanup(mrb, &args); 736 mrb = mrb_open(); 737 738 mrdb_state_set(mrdb_backup); 739 mrb_debug_context_set(dbg_backup); 740 741 goto l_restart; 742 } 743 } 744 puts("mruby application exited."); 745 mrdb->dbg->xphase = DBG_PHASE_AFTER_RUN; 746 if (!mrb_undef_p(v)) { 747 if (mrb->exc) { 748 mrb_print_error(mrb); 749 } 750 else { 751 printf(" => "); 752 mrb_p(mrb, v); 753 } 754 } 755 756 mrdb->dbg->prvfile = "-"; 757 mrdb->dbg->prvline = 0; 758 759 while (1) { 760 cmd = get_and_parse_command(mrb, mrdb); 761 mrb_assert(cmd); 762 763 if (cmd->id == DBGCMD_QUIT) { 764 break; 765 } 766 767 if ( cmd->func(mrb, mrdb) == DBGST_RESTART ) goto l_restart; 768 } 769 770 cleanup(mrb, &args); 771 772 return 0; 773 } -
EcnlProtoTool/trunk/prototool/src/mrdb.h
r321 r439 7 7 #define MRDB_H 8 8 9 #include "mruby.h"9 #include <mruby.h> 10 10 11 11 #include "mrdbconf.h" 12 13 #ifdef _MSC_VER 14 # define __func__ __FUNCTION__ 15 #endif 12 16 13 17 #define MAX_COMMAND_WORD (16) … … 20 24 DBGCMD_BREAK, 21 25 DBGCMD_INFO_BREAK, 26 DBGCMD_INFO_LOCAL, 22 27 DBGCMD_WATCH, 23 28 DBGCMD_INFO_WATCH, … … 52 57 DBG_QUIT, 53 58 } mrdb_exemode; 54 55 #ifdef _MSC_VER56 # define __func__ __FUNCTION__57 extern long __stdcall InterlockedExchange(long *dst, long src);58 extern long __stdcall InterlockedCompareExchange(long *dst, long src, long cmp);59 #else60 #define InterlockedExchange(dst, src) do { *(dst) = src; } while(0)61 __inline__ static enum mrdb_exemode InterlockedCompareExchange(enum mrdb_exemode *dst, enum mrdb_exemode src, enum mrdb_exemode cmp) { long prev = *(dst); if (*(dst) == cmp) *(dst) = src; return prev; }62 #endif63 59 64 60 typedef enum mrdb_exephase { … … 110 106 struct mrb_irep *root_irep; 111 107 struct mrb_irep *irep; 112 mrb_code *pc;108 const mrb_code *pc; 113 109 mrb_value *regs; 114 110 … … 117 113 mrb_callinfo *prvci; 118 114 119 #ifdef _MSC_VER120 long xm;121 #else122 115 mrdb_exemode xm; 123 #endif124 116 mrdb_exephase xphase; 125 117 mrdb_brkmode bm; … … 161 153 dbgcmd_state dbgcmd_break(mrb_state*, mrdb_state*); 162 154 dbgcmd_state dbgcmd_info_break(mrb_state*, mrdb_state*); 155 dbgcmd_state dbgcmd_info_local(mrb_state*, mrdb_state*); 163 156 dbgcmd_state dbgcmd_delete(mrb_state*, mrdb_state*); 164 157 dbgcmd_state dbgcmd_enable(mrb_state*, mrdb_state*); … … 168 161 dbgcmd_state dbgcmd_eval(mrb_state*, mrdb_state*); 169 162 /* cmdmisc.c */ 163 dbgcmd_state dbgcmd_list(mrb_state*, mrdb_state*); 170 164 dbgcmd_state dbgcmd_help(mrb_state*, mrdb_state*); 171 165 dbgcmd_state dbgcmd_quit(mrb_state*, mrdb_state*); -
EcnlProtoTool/trunk/prototool/src/mrdbconf.h
r321 r439 6 6 #ifndef MRDBCONF_H 7 7 #define MRDBCONF_H 8 9 #ifndef MRB_ENABLE_DEBUG_HOOK 10 # error mruby-bin-debugger need 'MRB_ENABLE_DEBUG_HOOK' configuration in your 'build_config.rb' 11 #endif 12 13 #ifdef MRB_DISABLE_STDIO 14 # error mruby-bin-debugger conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 15 #endif 8 16 9 17 /* configuration options: */ -
EcnlProtoTool/trunk/prototool/src/mruby.c
r321 r439 1 #include <mruby.h> 2 3 #ifdef MRB_DISABLE_STDIO 4 # error mruby-bin-mruby conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 5 #endif 6 1 7 #include <stdlib.h> 2 8 #include <string.h> 3 4 #include "mruby.h" 5 #include "mruby/array.h" 6 #include "mruby/compile.h" 7 #include "mruby/dump.h" 8 #include "mruby/variable.h" 9 10 #ifdef MRB_DISABLE_STDIO 11 static void 12 p(mrb_state *mrb, mrb_value obj) 13 { 14 mrb_value val = mrb_inspect(mrb, obj); 15 16 fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout); 17 putc('\n', stdout); 18 } 19 #else 20 #define p(mrb,obj) mrb_p(mrb,obj) 21 #endif 22 23 struct _args 24 { 25 FILE *rfp; 26 char* cmdline; 27 mrb_bool fname : 1; 28 mrb_bool mrbfile : 1; 29 mrb_bool check_syntax : 1; 30 mrb_bool verbose : 1; 31 int argc; 32 char** argv; 9 #include <mruby/array.h> 10 #include <mruby/compile.h> 11 #include <mruby/dump.h> 12 #include <mruby/variable.h> 13 14 struct _args { 15 FILE *rfp; 16 char *cmdline; 17 mrb_bool fname : 1; 18 mrb_bool mrbfile : 1; 19 mrb_bool check_syntax : 1; 20 mrb_bool verbose : 1; 21 mrb_bool version : 1; 22 mrb_bool debug : 1; 23 int argc; 24 char **argv; 25 int libc; 26 char **libv; 27 }; 28 29 struct options { 30 int argc; 31 char **argv; 32 char *program; 33 char *opt; 34 char short_opt[2]; 33 35 }; 34 36 … … 36 38 usage(const char *name) 37 39 { 38 static const char *const usage_msg[] = { 39 "switches:", 40 "-b load and execute RiteBinary (mrb) file", 41 "-c check syntax only", 42 "-e 'command' one line of script", 43 "-v print version number, then run in verbose mode", 44 "--verbose run in verbose mode", 45 "--version print the version", 46 "--copyright print the copyright", 47 NULL 48 }; 49 const char *const *p = usage_msg; 50 51 printf("Usage: %s [switches] programfile\n", name); 52 while (*p) 53 printf(" %s\n", *p++); 40 static const char *const usage_msg[] = { 41 "switches:", 42 "-b load and execute RiteBinary (mrb) file", 43 "-c check syntax only", 44 "-d set debugging flags (set $DEBUG to true)", 45 "-e 'command' one line of script", 46 "-r library load the library before executing your script", 47 "-v print version number, then run in verbose mode", 48 "--verbose run in verbose mode", 49 "--version print the version", 50 "--copyright print the copyright", 51 NULL 52 }; 53 const char *const *p = usage_msg; 54 55 printf("Usage: %s [switches] [programfile] [arguments]\n", name); 56 while (*p) 57 printf(" %s\n", *p++); 58 } 59 60 static void 61 options_init(struct options *opts, int argc, char **argv) 62 { 63 opts->argc = argc; 64 opts->argv = argv; 65 opts->program = *argv; 66 *opts->short_opt = 0; 67 } 68 69 static const char * 70 options_opt(struct options *opts) 71 { 72 /* concatenated short options (e.g. `-cv`) */ 73 if (*opts->short_opt && *++opts->opt) { 74 short_opt: 75 opts->short_opt[0] = *opts->opt; 76 opts->short_opt[1] = 0; 77 return opts->short_opt; 78 } 79 80 while (++opts->argv, --opts->argc) { 81 opts->opt = *opts->argv; 82 83 /* empty || not start with `-` || `-` */ 84 if (!opts->opt[0] || opts->opt[0] != '-' || !opts->opt[1]) return NULL; 85 86 if (opts->opt[1] == '-') { 87 /* `--` */ 88 if (!opts->opt[2]) { 89 ++opts->argv, --opts->argc; 90 return NULL; 91 } 92 /* long option */ 93 opts->opt += 2; 94 *opts->short_opt = 0; 95 return opts->opt; 96 } 97 else { 98 /* short option */ 99 ++opts->opt; 100 goto short_opt; 101 } 102 } 103 return NULL; 104 } 105 106 static const char * 107 options_arg(struct options *opts) 108 { 109 if (*opts->short_opt && opts->opt[1]) { 110 /* concatenated short option and option argument (e.g. `-rLIBRARY`) */ 111 *opts->short_opt = 0; 112 return opts->opt + 1; 113 } 114 --opts->argc, ++opts->argv; 115 return opts->argc ? *opts->argv : NULL; 116 } 117 118 static char * 119 dup_arg_item(mrb_state *mrb, const char *item) 120 { 121 size_t buflen = strlen(item) + 1; 122 char *buf = (char*)mrb_malloc(mrb, buflen); 123 memcpy(buf, item, buflen); 124 return buf; 54 125 } 55 126 … … 57 128 parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) 58 129 { 59 char **origargv = argv; 60 static const struct _args args_zero = { 0 }; 61 62 *args = args_zero; 63 64 for (argc--, argv++; argc > 0; argc--, argv++) { 65 char *item; 66 if (argv[0][0] != '-') break; 67 68 if (strlen(*argv) <= 1) { 69 argc--; argv++; 70 args->rfp = stdin; 71 break; 72 } 73 74 item = argv[0] + 1; 75 switch (*item++) { 76 case 'b': 77 args->mrbfile = TRUE; 78 break; 79 case 'c': 80 args->check_syntax = TRUE; 81 break; 82 case 'e': 83 if (item[0]) { 84 goto append_cmdline; 85 } 86 else if (argc > 1) { 87 argc--; argv++; 88 item = argv[0]; 89 append_cmdline: 90 if (!args->cmdline) { 91 size_t buflen; 92 char *buf; 93 94 buflen = strlen(item) + 1; 95 buf = (char *)mrb_malloc(mrb, buflen); 96 memcpy(buf, item, buflen); 97 args->cmdline = buf; 98 } 99 else { 100 size_t cmdlinelen; 101 size_t itemlen; 102 103 cmdlinelen = strlen(args->cmdline); 104 itemlen = strlen(item); 105 args->cmdline = 106 (char *)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2); 107 args->cmdline[cmdlinelen] = '\n'; 108 memcpy(args->cmdline + cmdlinelen + 1, item, itemlen + 1); 109 } 110 } 111 else { 112 printf("%s: No code specified for -e\n", *origargv); 113 return EXIT_SUCCESS; 114 } 115 break; 116 case 'v': 117 if (!args->verbose) mrb_show_version(mrb); 118 args->verbose = TRUE; 119 break; 120 case '-': 121 if (strcmp((*argv) + 2, "version") == 0) { 122 mrb_show_version(mrb); 123 exit(EXIT_SUCCESS); 124 } 125 else if (strcmp((*argv) + 2, "verbose") == 0) { 126 args->verbose = TRUE; 127 break; 128 } 129 else if (strcmp((*argv) + 2, "copyright") == 0) { 130 mrb_show_copyright(mrb); 131 exit(EXIT_SUCCESS); 132 } 133 default: 134 return EXIT_FAILURE; 135 } 136 } 137 138 if (args->rfp == NULL && args->cmdline == NULL) { 139 if (*argv == NULL) args->rfp = stdin; 140 else { 141 args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r"); 142 if (args->rfp == NULL) { 143 printf("%s: Cannot open program file. (%s)\n", *origargv, *argv); 144 return EXIT_FAILURE; 145 } 146 args->fname = TRUE; 147 args->cmdline = argv[0]; 148 argc--; argv++; 149 } 150 } 151 args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1)); 152 memcpy(args->argv, argv, (argc + 1) * sizeof(char*)); 153 args->argc = argc; 154 155 return EXIT_SUCCESS; 130 static const struct _args args_zero = { 0 }; 131 struct options opts[1]; 132 const char *opt, *item; 133 134 *args = args_zero; 135 options_init(opts, argc, argv); 136 while ((opt = options_opt(opts))) { 137 if (strcmp(opt, "b") == 0) { 138 args->mrbfile = TRUE; 139 } 140 else if (strcmp(opt, "c") == 0) { 141 args->check_syntax = TRUE; 142 } 143 else if (strcmp(opt, "d") == 0) { 144 args->debug = TRUE; 145 } 146 else if (strcmp(opt, "e") == 0) { 147 if ((item = options_arg(opts))) { 148 if (!args->cmdline) { 149 args->cmdline = dup_arg_item(mrb, item); 150 } 151 else { 152 size_t cmdlinelen; 153 size_t itemlen; 154 155 cmdlinelen = strlen(args->cmdline); 156 itemlen = strlen(item); 157 args->cmdline = 158 (char *)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2); 159 args->cmdline[cmdlinelen] = '\n'; 160 memcpy(args->cmdline + cmdlinelen + 1, item, itemlen + 1); 161 } 162 } 163 else { 164 fprintf(stderr, "%s: No code specified for -e\n", opts->program); 165 return EXIT_FAILURE; 166 } 167 } 168 else if (strcmp(opt, "h") == 0) { 169 usage(opts->program); 170 exit(EXIT_SUCCESS); 171 } 172 else if (strcmp(opt, "r") == 0) { 173 if ((item = options_arg(opts))) { 174 if (args->libc == 0) { 175 args->libv = (char**)mrb_malloc(mrb, sizeof(char*)); 176 } 177 else { 178 args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1)); 179 } 180 args->libv[args->libc++] = dup_arg_item(mrb, item); 181 } 182 else { 183 fprintf(stderr, "%s: No library specified for -r\n", opts->program); 184 return EXIT_FAILURE; 185 } 186 } 187 else if (strcmp(opt, "v") == 0) { 188 if (!args->verbose) { 189 mrb_show_version(mrb); 190 args->version = TRUE; 191 } 192 args->verbose = TRUE; 193 } 194 else if (strcmp(opt, "version") == 0) { 195 mrb_show_version(mrb); 196 exit(EXIT_SUCCESS); 197 } 198 else if (strcmp(opt, "verbose") == 0) { 199 args->verbose = TRUE; 200 } 201 else if (strcmp(opt, "copyright") == 0) { 202 mrb_show_copyright(mrb); 203 exit(EXIT_SUCCESS); 204 } 205 else { 206 fprintf(stderr, "%s: invalid option %s%s (-h will show valid options)\n", 207 opts->program, opt[1] ? "--" : "-", opt); 208 return EXIT_FAILURE; 209 } 210 } 211 212 argc = opts->argc; argv = opts->argv; 213 if (args->cmdline == NULL) { 214 if (*argv == NULL) { 215 if (args->version) exit(EXIT_SUCCESS); 216 args->rfp = stdin; 217 } 218 else { 219 args->rfp = strcmp(argv[0], "-") == 0 ? 220 stdin : fopen(argv[0], args->mrbfile ? "rb" : "r"); 221 if (args->rfp == NULL) { 222 fprintf(stderr, "%s: Cannot open program file: %s\n", opts->program, argv[0]); 223 return EXIT_FAILURE; 224 } 225 args->fname = TRUE; 226 args->cmdline = argv[0]; 227 argc--; argv++; 228 } 229 } 230 args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1)); 231 memcpy(args->argv, argv, (argc+1) * sizeof(char*)); 232 args->argc = argc; 233 234 return EXIT_SUCCESS; 156 235 } 157 236 … … 159 238 cleanup(mrb_state *mrb, struct _args *args) 160 239 { 161 if (args->rfp && args->rfp != stdin) 162 fclose(args->rfp); 163 if (!args->fname) 164 mrb_free(mrb, args->cmdline); 165 mrb_free(mrb, args->argv); 166 mrb_close(mrb); 240 if (args->rfp && args->rfp != stdin) 241 fclose(args->rfp); 242 if (!args->fname) 243 mrb_free(mrb, args->cmdline); 244 mrb_free(mrb, args->argv); 245 if (args->libc) { 246 while (args->libc--) { 247 mrb_free(mrb, args->libv[args->libc]); 248 } 249 mrb_free(mrb, args->libv); 250 } 251 mrb_close(mrb); 167 252 } 168 253 … … 170 255 mruby_main(int argc, char **argv) 171 256 { 172 mrb_state *mrb = mrb_open(); 173 int n = -1; 174 int i; 175 struct _args args; 176 mrb_value ARGV; 177 mrbc_context *c; 178 mrb_value v; 179 mrb_sym zero_sym; 180 181 if (mrb == NULL) { 182 fputs("Invalid mrb_state, exiting mruby\n", stderr); 183 return EXIT_FAILURE; 184 } 185 186 n = parse_args(mrb, argc, argv, &args); 187 if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) { 188 cleanup(mrb, &args); 189 usage(argv[0]); 190 return n; 191 } 192 else { 193 int ai = mrb_gc_arena_save(mrb); 194 ARGV = mrb_ary_new_capa(mrb, args.argc); 195 for (i = 0; i < args.argc; i++) { 196 mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, args.argv[i])); 197 } 198 mrb_define_global_const(mrb, "ARGV", ARGV); 199 200 c = mrbc_context_new(mrb); 201 if (args.verbose) 202 c->dump_result = TRUE; 203 if (args.check_syntax) 204 c->no_exec = TRUE; 205 206 /* Set $0 */ 207 zero_sym = mrb_intern_lit(mrb, "$0"); 208 if (args.rfp) { 209 const char *cmdline; 210 cmdline = args.cmdline ? args.cmdline : "-"; 211 mrbc_filename(mrb, c, cmdline); 212 mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline)); 213 } 214 else { 215 mrbc_filename(mrb, c, "-e"); 216 mrb_gv_set(mrb, zero_sym, mrb_str_new_lit(mrb, "-e")); 217 } 218 219 /* Load program */ 220 if (args.mrbfile) { 221 v = mrb_load_irep_file_cxt(mrb, args.rfp, c); 222 } 223 else if (args.rfp) { 224 v = mrb_load_file_cxt(mrb, args.rfp, c); 225 } 226 else { 227 v = mrb_load_string_cxt(mrb, args.cmdline, c); 228 } 229 230 mrb_gc_arena_restore(mrb, ai); 231 mrbc_context_free(mrb, c); 232 if (mrb->exc) { 233 if (!mrb_undef_p(v)) { 234 mrb_print_error(mrb); 235 } 236 n = -1; 237 } 238 else if (args.check_syntax) { 239 printf("Syntax OK\n"); 240 } 241 } 242 cleanup(mrb, &args); 243 244 return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE; 245 } 257 mrb_state *mrb = mrb_open(); 258 int n = -1; 259 int i; 260 struct _args args; 261 mrb_value ARGV; 262 mrbc_context *c; 263 mrb_value v; 264 mrb_sym zero_sym; 265 266 if (mrb == NULL) { 267 fprintf(stderr, "%s: Invalid mrb_state, exiting mruby\n", *argv); 268 return EXIT_FAILURE; 269 } 270 271 n = parse_args(mrb, argc, argv, &args); 272 if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) { 273 cleanup(mrb, &args); 274 return n; 275 } 276 else { 277 int ai = mrb_gc_arena_save(mrb); 278 ARGV = mrb_ary_new_capa(mrb, args.argc); 279 for (i = 0; i < args.argc; i++) { 280 char* utf8 = mrb_utf8_from_locale(args.argv[i], -1); 281 if (utf8) { 282 mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8)); 283 mrb_utf8_free(utf8); 284 } 285 } 286 mrb_define_global_const(mrb, "ARGV", ARGV); 287 mrb_gv_set(mrb, mrb_intern_lit(mrb, "$DEBUG"), mrb_bool_value(args.debug)); 288 289 c = mrbc_context_new(mrb); 290 if (args.verbose) 291 c->dump_result = TRUE; 292 if (args.check_syntax) 293 c->no_exec = TRUE; 294 295 /* Set $0 */ 296 zero_sym = mrb_intern_lit(mrb, "$0"); 297 if (args.rfp) { 298 const char *cmdline; 299 cmdline = args.cmdline ? args.cmdline : "-"; 300 mrbc_filename(mrb, c, cmdline); 301 mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline)); 302 } 303 else { 304 mrbc_filename(mrb, c, "-e"); 305 mrb_gv_set(mrb, zero_sym, mrb_str_new_lit(mrb, "-e")); 306 } 307 308 /* Load libraries */ 309 for (i = 0; i < args.libc; i++) { 310 FILE *lfp = fopen(args.libv[i], args.mrbfile ? "rb" : "r"); 311 if (lfp == NULL) { 312 fprintf(stderr, "%s: Cannot open library file: %s\n", *argv, args.libv[i]); 313 mrbc_context_free(mrb, c); 314 cleanup(mrb, &args); 315 return EXIT_FAILURE; 316 } 317 if (args.mrbfile) { 318 v = mrb_load_irep_file_cxt(mrb, lfp, c); 319 } 320 else { 321 v = mrb_load_file_cxt(mrb, lfp, c); 322 } 323 fclose(lfp); 324 } 325 326 /* Load program */ 327 if (args.mrbfile) { 328 v = mrb_load_irep_file_cxt(mrb, args.rfp, c); 329 } 330 else if (args.rfp) { 331 v = mrb_load_file_cxt(mrb, args.rfp, c); 332 } 333 else { 334 char* utf8 = mrb_utf8_from_locale(args.cmdline, -1); 335 if (!utf8) abort(); 336 v = mrb_load_string_cxt(mrb, utf8, c); 337 mrb_utf8_free(utf8); 338 } 339 340 mrb_gc_arena_restore(mrb, ai); 341 mrbc_context_free(mrb, c); 342 if (mrb->exc) { 343 if (!mrb_undef_p(v)) { 344 mrb_print_error(mrb); 345 } 346 n = EXIT_FAILURE; 347 } 348 else if (args.check_syntax) { 349 puts("Syntax OK"); 350 } 351 } 352 cleanup(mrb, &args); 353 354 return n; 355 }
Note:
See TracChangeset
for help on using the changeset viewer.