@@ -6,6 +6,8 @@ Author: Daniel Poetzl
6
6
7
7
\******************************************************************/
8
8
9
+ #include < algorithm>
10
+
9
11
#include " memory_snapshot_harness_generator.h"
10
12
11
13
#include < goto-programs/goto_convert.h>
@@ -350,3 +352,133 @@ void memory_snapshot_harness_generatort::generate(
350
352
351
353
goto_functions.update ();
352
354
}
355
+
356
+ memory_snapshot_harness_generatort::entry_goto_locationt
357
+ memory_snapshot_harness_generatort::parse_goto_location (
358
+ const std::string &cmdl_option)
359
+ {
360
+ std::vector<std::string> start;
361
+ split_string (cmdl_option, ' :' , start, true );
362
+
363
+ if (
364
+ start.empty () || start.front ().empty () ||
365
+ (start.size () == 2 && start.back ().empty ()) || start.size () > 2 )
366
+ {
367
+ throw invalid_command_line_argument_exceptiont (
368
+ " invalid initial location specification" , " --initial-location" );
369
+ }
370
+
371
+ if (start.size () == 2 )
372
+ {
373
+ const auto location_number = string2optional_unsigned (start.back ());
374
+ CHECK_RETURN (location_number.has_value ());
375
+ return entry_goto_locationt{start.front (), *location_number};
376
+ }
377
+ else
378
+ {
379
+ return entry_goto_locationt{start.front ()};
380
+ }
381
+ }
382
+
383
+ memory_snapshot_harness_generatort::entry_source_locationt
384
+ memory_snapshot_harness_generatort::parse_source_location (
385
+ const std::string &cmdl_option)
386
+ {
387
+ std::string initial_file_string;
388
+ std::string initial_line_string;
389
+ split_string (
390
+ cmdl_option, ' :' , initial_file_string, initial_line_string, true );
391
+
392
+ if (initial_file_string.empty () || initial_line_string.empty ())
393
+ {
394
+ throw invalid_command_line_argument_exceptiont (
395
+ " invalid initial location specification" , " --initial-file-line" );
396
+ }
397
+
398
+ const auto line_number = string2optional_unsigned (initial_line_string);
399
+ CHECK_RETURN (line_number.has_value ());
400
+ return entry_source_locationt{initial_file_string, *line_number};
401
+ }
402
+
403
+ memory_snapshot_harness_generatort::entry_locationt
404
+ memory_snapshot_harness_generatort::initialize_entry_via_goto (
405
+ const entry_goto_locationt &entry_goto_location,
406
+ const goto_functionst &goto_functions)
407
+ {
408
+ PRECONDITION (!entry_goto_location.function_name .empty ());
409
+ const irep_idt &function_name = entry_goto_location.function_name ;
410
+
411
+ // by function(+location): search for the function then jump to n-th
412
+ // location, then check the number
413
+ const auto &goto_function =
414
+ goto_functions.function_map .find (entry_goto_location.function_name );
415
+ if (
416
+ goto_function != goto_functions.function_map .end () &&
417
+ goto_function->second .body_available ())
418
+ {
419
+ const auto &goto_program = goto_function->second .body ;
420
+
421
+ const auto corresponding_instruction =
422
+ entry_goto_location.find_first_corresponding_instruction (
423
+ goto_program.instructions );
424
+
425
+ if (corresponding_instruction != goto_program.instructions .end ())
426
+ return entry_locationt{function_name, corresponding_instruction};
427
+ }
428
+ throw invalid_command_line_argument_exceptiont (
429
+ " could not find the specified entry point" , " --initial-goto-location" );
430
+ }
431
+
432
+ memory_snapshot_harness_generatort::entry_locationt
433
+ memory_snapshot_harness_generatort::initialize_entry_via_source (
434
+ const entry_source_locationt &entry_source_location,
435
+ const goto_functionst &goto_functions)
436
+ {
437
+ PRECONDITION (!entry_source_location.file_name .empty ());
438
+
439
+ // by line: iterate over all instructions until source location match
440
+ for (const auto &entry : goto_functions.function_map )
441
+ {
442
+ const auto &goto_function = entry.second ;
443
+ // if !body_available() then body.instruction.empty() and that's fine
444
+ const auto &goto_program = goto_function.body ;
445
+
446
+ const auto corresponding_instruction =
447
+ entry_source_location.find_first_corresponding_instruction (
448
+ goto_program.instructions );
449
+
450
+ if (corresponding_instruction != goto_program.instructions .end ())
451
+ return entry_locationt{entry.first , corresponding_instruction};
452
+ }
453
+ throw invalid_command_line_argument_exceptiont (
454
+ " could not find the specified entry point" , " --initial-source-location" );
455
+ }
456
+
457
+ goto_programt::const_targett memory_snapshot_harness_generatort::
458
+ entry_goto_locationt::find_first_corresponding_instruction (
459
+ const goto_programt::instructionst &instructions) const
460
+ {
461
+ if (!location_number.has_value ())
462
+ return instructions.begin ();
463
+
464
+ return std::find_if (
465
+ instructions.begin (),
466
+ instructions.end (),
467
+ [this ](const goto_programt::instructiont &instruction) {
468
+ return *location_number == instruction.location_number ;
469
+ });
470
+ }
471
+
472
+ goto_programt::const_targett memory_snapshot_harness_generatort::
473
+ entry_source_locationt::find_first_corresponding_instruction (
474
+ const goto_programt::instructionst &instructions) const
475
+ {
476
+ return std::find_if (
477
+ instructions.begin (),
478
+ instructions.end (),
479
+ [this ](const goto_programt::instructiont &instruction) {
480
+ return instruction.source_location .get_file () == file_name &&
481
+ safe_string2unsigned (id2string (
482
+ instruction.source_location .get_line ())) >= line_number;
483
+ });
484
+ }
0 commit comments