rpicsim 0.1.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/Gemfile +7 -6
- data/Introduction.md +3 -1
- data/README.md +2 -2
- data/docs/ChangeLog.md +6 -0
- data/docs/Contributing.md +1 -1
- data/docs/DefiningSimulationClass.md +11 -10
- data/docs/HowMPLABXIsFound.md +1 -1
- data/docs/IntegrationTesting.md +1 -1
- data/docs/IntroductionToRSpec.md +8 -5
- data/docs/IntroductionToRuby.md +2 -2
- data/docs/KnownIssues.md +46 -57
- data/docs/Labels.md +5 -4
- data/docs/Manual.md +1 -1
- data/docs/Memories.md +70 -0
- data/docs/PersistentExpectations.md +31 -2
- data/docs/Pins.md +5 -7
- data/docs/PreventingCallStackOverflow.md +4 -6
- data/docs/QuickStartGuide.md +5 -5
- data/docs/RSpecIntegration.md +2 -2
- data/docs/RamWatcher.md +22 -11
- data/docs/Running.md +4 -6
- data/docs/Stubbing.md +4 -4
- data/docs/SupportedDevices.md +2 -11
- data/docs/SupportedMPLABXVersions.md +1 -0
- data/docs/SupportedOperatingSystems.md +3 -2
- data/docs/UnitTesting.md +1 -1
- data/docs/Variables.md +81 -25
- data/lib/rpicsim.rb +0 -12
- data/lib/rpicsim/call_stack_info.rb +43 -47
- data/lib/rpicsim/composite_memory.rb +53 -0
- data/lib/rpicsim/flaws.rb +34 -22
- data/lib/rpicsim/instruction.rb +204 -48
- data/lib/rpicsim/label.rb +4 -4
- data/lib/rpicsim/memory.rb +44 -23
- data/lib/rpicsim/memory_watcher.rb +14 -22
- data/lib/rpicsim/mplab.rb +38 -119
- data/lib/rpicsim/mplab/mplab_assembly.rb +23 -18
- data/lib/rpicsim/mplab/mplab_device_info.rb +9 -9
- data/lib/rpicsim/mplab/mplab_disassembler.rb +5 -6
- data/lib/rpicsim/mplab/mplab_instruction.rb +87 -16
- data/lib/rpicsim/mplab/mplab_loader.rb +106 -0
- data/lib/rpicsim/mplab/mplab_memory.rb +19 -6
- data/lib/rpicsim/mplab/mplab_nmmr_info.rb +4 -4
- data/lib/rpicsim/mplab/mplab_observer.rb +15 -10
- data/lib/rpicsim/mplab/mplab_pin.rb +3 -3
- data/lib/rpicsim/mplab/mplab_processor.rb +5 -5
- data/lib/rpicsim/mplab/mplab_program_file.rb +29 -17
- data/lib/rpicsim/mplab/mplab_register.rb +5 -5
- data/lib/rpicsim/mplab/mplab_sfr_info.rb +4 -4
- data/lib/rpicsim/mplab/mplab_simulator.rb +27 -30
- data/lib/rpicsim/pin.rb +6 -6
- data/lib/rpicsim/program_counter.rb +3 -3
- data/lib/rpicsim/program_file.rb +39 -81
- data/lib/rpicsim/rspec/be_predicate.rb +1 -1
- data/lib/rpicsim/rspec/helpers.rb +1 -1
- data/lib/rpicsim/rspec/persistent_expectations.rb +17 -2
- data/lib/rpicsim/rspec/sim_diagnostics.rb +5 -5
- data/lib/rpicsim/search.rb +1 -1
- data/lib/rpicsim/sim.rb +153 -228
- data/lib/rpicsim/stack_pointer.rb +41 -0
- data/lib/rpicsim/stack_trace.rb +1 -1
- data/lib/rpicsim/storage/memory_integer.rb +235 -0
- data/lib/rpicsim/{register.rb → storage/register.rb} +18 -18
- data/lib/rpicsim/variable.rb +25 -211
- data/lib/rpicsim/variable_set.rb +93 -0
- data/lib/rpicsim/version.rb +2 -2
- metadata +9 -4
- data/docs/SFRs.md +0 -71
data/lib/rpicsim/label.rb
CHANGED
@@ -4,7 +4,7 @@ module RPicSim
|
|
4
4
|
# The name of the label from the firmware.
|
5
5
|
# @return (Symbol)
|
6
6
|
attr_reader :name
|
7
|
-
|
7
|
+
|
8
8
|
# The address/value of the label from the firmware.
|
9
9
|
# @return (Integer)
|
10
10
|
attr_reader :address
|
@@ -19,10 +19,10 @@ module RPicSim
|
|
19
19
|
def to_i
|
20
20
|
address
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Returns a nice string representation of the label.
|
24
24
|
def to_s
|
25
|
-
|
25
|
+
'<Label %s address=0x%x>' % [name, address]
|
26
26
|
end
|
27
27
|
end
|
28
|
-
end
|
28
|
+
end
|
data/lib/rpicsim/memory.rb
CHANGED
@@ -1,29 +1,50 @@
|
|
1
|
-
|
2
|
-
# This object allows read and write access to the
|
1
|
+
module RPicSim
|
2
|
+
# This object allows read and write access to the data currently
|
3
3
|
# stored in a memory space of the simulated device.
|
4
|
+
# Instances are usually retrieved from a {Sim} object by calling
|
5
|
+
# {Sim#ram}, {Sim#program_memory}, or {Sim#eeprom}.
|
4
6
|
#
|
5
|
-
# The behavior of
|
6
|
-
#
|
7
|
+
# The behavior of +read_word+ and +write_word+ differs depending on
|
8
|
+
# what kind of Memory is being used, as shown in the table below:
|
7
9
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# PIC18
|
10
|
+
# Memory type Address type Read/write chunk
|
11
|
+
# RAM and EEPROM: Byte address 1 byte (8 bits)
|
12
|
+
# PIC18 program memory: Byte address 1 word (16 bits)
|
13
|
+
# Non-PIC18 program memory: Word address 1 word (12 or 14 bits)
|
12
14
|
#
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
# The +read_byte+ and +write_byte+ methods use the same type of address as
|
16
|
+
# +read_word+ and +write_word+, but they can only read and write from the
|
17
|
+
# lower 8 bits of the word.
|
18
|
+
# The upper bits of the word, if there are any, are left unchanged.
|
19
|
+
# For RAM and EEPROM, +read_byte+ and +write_byte+ behave the same way as
|
20
|
+
# +read_word+ and +write_word+.
|
21
|
+
#
|
22
|
+
# For more information, see {file:Memories.md}.
|
23
|
+
class Memory
|
24
|
+
# @param mplab_memory [Mplab::Memory]
|
25
|
+
def initialize(mplab_memory)
|
26
|
+
@mplab_memory = mplab_memory
|
27
|
+
end
|
28
|
+
|
29
|
+
def read_byte(address)
|
30
|
+
@mplab_memory.read_byte(address)
|
31
|
+
end
|
32
|
+
|
33
|
+
def write_byte(address, value)
|
34
|
+
@mplab_memory.write_byte(address, value)
|
35
|
+
end
|
36
|
+
|
37
|
+
def read_word(address)
|
38
|
+
@mplab_memory.read_word(address)
|
39
|
+
end
|
40
|
+
|
41
|
+
def write_word(address, value)
|
42
|
+
@mplab_memory.write_word(address, value)
|
43
|
+
end
|
44
|
+
|
45
|
+
def valid_address?(address)
|
46
|
+
@mplab_memory.valid_address?(address)
|
47
|
+
end
|
17
48
|
|
18
|
-
def write_word(address, value)
|
19
|
-
@mplab_memory.write_word(address, value)
|
20
|
-
end
|
21
|
-
|
22
|
-
def read_word(address)
|
23
|
-
@mplab_memory.read_word(address)
|
24
|
-
end
|
25
|
-
|
26
|
-
def is_valid_address?(address)
|
27
|
-
@mplab_memory.is_valid_address?(address)
|
28
49
|
end
|
29
|
-
end
|
50
|
+
end
|
@@ -12,7 +12,7 @@ module RPicSim
|
|
12
12
|
class MemoryWatcher
|
13
13
|
attr_accessor :var_names_ignored
|
14
14
|
attr_accessor :var_names_ignored_on_first_step
|
15
|
-
|
15
|
+
|
16
16
|
# Creates a new instance.
|
17
17
|
# @param sim [Sim]
|
18
18
|
# @param memory [Mplab::MplabMemory] The memory to watch
|
@@ -23,20 +23,19 @@ module RPicSim
|
|
23
23
|
vars.each do |var|
|
24
24
|
var.addresses.each do |address|
|
25
25
|
if @vars_by_address[address]
|
26
|
-
raise
|
26
|
+
raise 'Variable %s overlaps with %s at 0x%x' %
|
27
27
|
[var, @vars_by_address[address], address]
|
28
28
|
end
|
29
29
|
@vars_by_address[address] = var
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
@sim = sim
|
34
34
|
@memory = memory
|
35
35
|
@memory.on_change { |ar| handle_change(ar) }
|
36
|
-
|
36
|
+
|
37
37
|
@vars_written = Set.new
|
38
38
|
@var_names_ignored = default_var_names_ignored(sim.device)
|
39
|
-
@var_names_ignored_on_first_step = default_var_names_ignored_on_first_step(sim.device)
|
40
39
|
end
|
41
40
|
|
42
41
|
# Generate a nice report of what variables have been written to since the
|
@@ -61,27 +60,13 @@ module RPicSim
|
|
61
60
|
def clear
|
62
61
|
@vars_written.clear
|
63
62
|
end
|
64
|
-
|
65
|
-
def default_var_names_ignored(device_name)
|
66
|
-
# The datasheet says the PCLATH is not affected by pushing or popping the stack, but
|
67
|
-
# we still get spurious events for it when a return instruction is executed.
|
68
63
|
|
69
|
-
[:PCL, :PCLATH, :STATUS]
|
70
|
-
end
|
71
|
-
|
72
|
-
def default_var_names_ignored_on_first_step(device_name)
|
73
|
-
#TODO: get rid of this stuff? people should just have a goto or something harmless at
|
74
|
-
# the beginning of their program and take a single step like we do.
|
75
|
-
[:PORTA, :LATA, :OSCCON, :PMCON2, :INTCON]
|
76
|
-
end
|
77
|
-
|
78
64
|
def handle_change(address_ranges)
|
79
65
|
addresses = address_ranges.flat_map(&:to_a)
|
80
66
|
vars = addresses.map { |a| @vars_by_address[a] || a }
|
81
67
|
|
82
68
|
remove_vars(vars, @var_names_ignored)
|
83
|
-
|
84
|
-
|
69
|
+
|
85
70
|
# The line below works because @vars_written is a Set, not a Hash.
|
86
71
|
@vars_written.merge vars
|
87
72
|
end
|
@@ -93,6 +78,13 @@ module RPicSim
|
|
93
78
|
var_names_to_remove.include?(name)
|
94
79
|
end
|
95
80
|
end
|
96
|
-
|
81
|
+
|
82
|
+
def default_var_names_ignored(device_name)
|
83
|
+
# The datasheet says the PCLATH is not affected by pushing or popping the stack, but
|
84
|
+
# we still get spurious events for it when a return instruction is executed.
|
85
|
+
|
86
|
+
[:PCL, :PCLATH, :STATUS]
|
87
|
+
end
|
88
|
+
|
97
89
|
end
|
98
|
-
end
|
90
|
+
end
|
data/lib/rpicsim/mplab.rb
CHANGED
@@ -1,138 +1,57 @@
|
|
1
|
-
|
2
|
-
require 'pathname'
|
1
|
+
require_relative 'mplab/mplab_loader'
|
3
2
|
|
4
|
-
module RPicSim
|
5
|
-
|
6
|
-
# Returns a Pathname object representing the directory of the MPLAB X we are using.
|
7
|
-
# This can either come from the +RPICSIM_MPLABX+ environment variable or it can
|
8
|
-
# be auto-detected by looking in the standard places that MPLAB X is installed.
|
9
|
-
# @return [Pathname]
|
10
|
-
def self.dir
|
11
|
-
@dir ||= begin
|
12
|
-
dir = ENV['RPICSIM_MPLABX']
|
3
|
+
module RPicSim::Mplab
|
4
|
+
MplabLoader.instance.load
|
13
5
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# TODO: add entries here for MPLAB X folders in Linux and Mac OS X
|
18
|
-
].detect { |d| File.directory?(d) }
|
19
|
-
|
20
|
-
if !dir
|
21
|
-
raise "Cannot find MPLABX. Install it in the standard location or " +
|
22
|
-
"set the RPICSIM_MPASM environment variable to its full path."
|
23
|
-
end
|
24
|
-
|
25
|
-
if !File.directory?(dir)
|
26
|
-
raise "MPLABX directory does not exist: #{dir}"
|
27
|
-
end
|
28
|
-
|
29
|
-
Pathname(dir)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# Adds all the needed MPLAB X jar files to the classpath so we can use the
|
34
|
-
# classes.
|
35
|
-
def self.load_dependencies
|
36
|
-
%w{ mplab_ide/mdbcore/modules/*.jar
|
37
|
-
mplab_ide/mplablibs/modules/*.jar
|
38
|
-
mplab_ide/mplablibs/modules/ext/*.jar
|
39
|
-
mplab_ide/platform/lib/org-openide-util*.jar
|
40
|
-
mplab_ide/platform/lib/org-openide-util.jar
|
41
|
-
mplab_ide/mdbcore/modules/ext/org-openide-filesystems.jar
|
42
|
-
}.each do |pattern|
|
43
|
-
Dir.glob(dir + pattern).each do |jar_file|
|
44
|
-
$CLASSPATH << jar_file
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# Do a quick test to make sure we can load some MPLAB X classes.
|
49
|
-
# In case MPLAB X was uninstalled and its directory remains, this can provide
|
50
|
-
# a useful error message to the user.
|
51
|
-
begin
|
52
|
-
org.openide.util.Lookup
|
53
|
-
com.microchip.mplab.mdbcore.simulator.Simulator
|
54
|
-
rescue NameError
|
55
|
-
$stderr.puts "Failed to load MPLAB X classes.\n" +
|
56
|
-
"MPLAB X dir: #{dir}\nClass path:\n" + $CLASSPATH.to_a.join("\n") + "\n\n"
|
57
|
-
raise
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
load_dependencies
|
62
|
-
|
63
|
-
|
64
|
-
# JRuby makes it hard to access packages with capital letters in their names.
|
65
|
-
# This is a workaround to let us access those packages.
|
66
|
-
module CapitalizedPackages
|
67
|
-
include_package "com.microchip.mplab.libs.MPLABDocumentLocator"
|
68
|
-
end
|
6
|
+
def self.version
|
7
|
+
MplabLoader.instance.mplab_version
|
8
|
+
end
|
69
9
|
|
70
|
-
|
71
|
-
|
10
|
+
# JRuby makes it hard to access packages with capital letters in their names.
|
11
|
+
# This is a workaround to let us access those packages.
|
12
|
+
capitalized_packages = Module.new do
|
13
|
+
include_package 'com.microchip.mplab.libs.MPLABDocumentLocator'
|
14
|
+
end
|
72
15
|
|
73
|
-
|
74
|
-
|
75
|
-
# Instead, you should add a new entry in flaws.rb and then use
|
76
|
-
# RPicSim::Flaws[:FLAWNAME] to see if the flaw exists and choose the appropriate workaround.
|
77
|
-
def self.version
|
78
|
-
# This implementation is not pretty; I would prefer to just find the right function
|
79
|
-
# to call.
|
80
|
-
@mplabx_version ||= begin
|
81
|
-
paths = Dir.glob(dir + "Uninstall_MPLAB_X_IDE_v*.dat")
|
82
|
-
if paths.empty?
|
83
|
-
raise "Cannot detect MPLAB X version. The Uninstall_MPLAB_X_IDE_v*.dat file was not found in #{mplabx_dir}."
|
84
|
-
end
|
85
|
-
match_data = paths.first.match(/v([0-9][0-9\.]*[0-9]+)\./)
|
86
|
-
match_data[1]
|
87
|
-
end
|
88
|
-
end
|
16
|
+
# The com.microchip.mplab.libs.MPLABDocumentLocator.MPLABDocumentLocator class from MPLAB X.
|
17
|
+
DocumentLocator = capitalized_packages::MPLABDocumentLocator
|
89
18
|
|
90
|
-
|
91
|
-
|
92
|
-
begin
|
93
|
-
orig = java.lang.System.out
|
94
|
-
java.lang.System.setOut(java.io.PrintStream.new(NullOutputStream.new))
|
95
|
-
yield
|
96
|
-
ensure
|
97
|
-
java.lang.System.setOut(orig)
|
98
|
-
end
|
99
|
-
end
|
19
|
+
Lookup = org.openide.util.Lookup
|
20
|
+
Mdbcore = com.microchip.mplab.mdbcore
|
100
21
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
ensure
|
110
|
-
log.setLevel(level)
|
111
|
-
end
|
112
|
-
end
|
22
|
+
# Mutes the standard output, calls the given block, and then unmutes it.
|
23
|
+
def self.mute_stdout
|
24
|
+
orig = java.lang.System.out
|
25
|
+
java.lang.System.setOut(java.io.PrintStream.new(NullOutputStream.new))
|
26
|
+
yield
|
27
|
+
ensure
|
28
|
+
java.lang.System.setOut(orig)
|
29
|
+
end
|
113
30
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
31
|
+
# Mutes a particular type of exception printed by NetBeans,
|
32
|
+
# calls the given block, then unmutes it.
|
33
|
+
def self.mute_exceptions
|
34
|
+
log = java.util.logging.Logger.getLogger('org.openide.util.Exceptions')
|
35
|
+
level = log.getLevel
|
36
|
+
begin
|
37
|
+
log.setLevel(java.util.logging.Level::OFF)
|
38
|
+
yield
|
39
|
+
ensure
|
40
|
+
log.setLevel(level)
|
119
41
|
end
|
42
|
+
end
|
120
43
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
44
|
+
# This class helps us suppress the standard output temporarily.
|
45
|
+
class NullOutputStream < Java::JavaIo::OutputStream
|
46
|
+
def write(b)
|
125
47
|
end
|
126
|
-
|
127
|
-
Lookup = org.openide.util.Lookup
|
128
|
-
Mdbcore = com.microchip.mplab.mdbcore
|
129
48
|
end
|
130
|
-
|
131
49
|
end
|
132
50
|
|
133
51
|
# We want as much awareness as possible; if it becomes a problem we can change this.
|
134
52
|
com.microchip.mplab.logger.MPLABLogger.mplog.setLevel(java.util.logging.Level::ALL)
|
135
53
|
|
54
|
+
# Require the rest of the RPicSim::Mplab Ruby classes now that MPLAB X has been loaded.
|
136
55
|
require_relative 'mplab/mplab_pin'
|
137
56
|
require_relative 'mplab/mplab_assembly'
|
138
57
|
require_relative 'mplab/mplab_program_file'
|
@@ -3,9 +3,12 @@ require_relative 'mplab_simulator'
|
|
3
3
|
require_relative 'mplab_disassembler'
|
4
4
|
|
5
5
|
module RPicSim::Mplab
|
6
|
+
# This class wraps objects belonging to the abstract Java class
|
7
|
+
# com.microchip.mplab.mdbcore.assemblies.Assembly,
|
8
|
+
# which represent a collection of objects being used together.
|
6
9
|
class MplabAssembly
|
7
10
|
attr_reader :device
|
8
|
-
|
11
|
+
|
9
12
|
def initialize(device)
|
10
13
|
@device = device
|
11
14
|
assembly_factory = Lookup.default.lookup(Mdbcore.assemblies.AssemblyFactory.java_class)
|
@@ -13,27 +16,27 @@ module RPicSim::Mplab
|
|
13
16
|
@assembly = assembly_factory.create(device)
|
14
17
|
end
|
15
18
|
end
|
16
|
-
|
19
|
+
|
17
20
|
# Connect the assembly to a simulator and debugger.
|
18
21
|
def start_simulator_and_debugger(filename)
|
19
22
|
# In MPLAB X v1.70, this line had to be before the call to SetTool, or else when we run
|
20
23
|
# debugger.Connect we will get two lines of: [Fatal Error] :1:1: Premature end of file.
|
21
24
|
simulator
|
22
|
-
|
23
|
-
sim_meta = Mdbcore.platformtool.PlatformToolMetaManager.getTool(
|
24
|
-
@assembly.SetTool(sim_meta.configuration_object_id, sim_meta.class_name, sim_meta.flavor,
|
25
|
-
if !sim_meta.getToolSupportForDevice(device).all?
|
26
|
-
raise "Microchip's simulator does not support " + device +
|
25
|
+
|
26
|
+
sim_meta = Mdbcore.platformtool.PlatformToolMetaManager.getTool('Simulator')
|
27
|
+
@assembly.SetTool(sim_meta.configuration_object_id, sim_meta.class_name, sim_meta.flavor, '')
|
28
|
+
if !sim_meta.getToolSupportForDevice(device).all?(&:isSupported)
|
29
|
+
raise "Microchip's simulator does not support " + device + '.'
|
27
30
|
end
|
28
|
-
@assembly.SetHeader(
|
31
|
+
@assembly.SetHeader('') # The Microchip documentation doesn't say what this is.
|
29
32
|
debugger.Connect(Mdbcore.debugger.Debugger::CONNECTION_TYPE::DEBUGGER)
|
30
|
-
|
33
|
+
|
31
34
|
# Load our firmware into the simulator.
|
32
35
|
load_file(filename)
|
33
36
|
debugger.Program(Mdbcore.debugger.Debugger::PROGRAM_OPERATION::AUTO_SELECT)
|
34
37
|
|
35
38
|
check_for_errors
|
36
|
-
|
39
|
+
|
37
40
|
nil
|
38
41
|
end
|
39
42
|
|
@@ -55,17 +58,17 @@ module RPicSim::Mplab
|
|
55
58
|
def disassembler
|
56
59
|
@disassembler ||= MplabDisassembler.new lookup Mdbcore.disasm.DisAsm.java_class
|
57
60
|
end
|
58
|
-
|
61
|
+
|
59
62
|
def device_info
|
60
63
|
@device_info ||= MplabDeviceInfo.new(@assembly.GetDevice)
|
61
64
|
end
|
62
|
-
|
65
|
+
|
63
66
|
private
|
64
67
|
# Gets a com.microchip.mplab.mdbcore.debugger.Debugger object.
|
65
68
|
def debugger
|
66
69
|
lookup Mdbcore.debugger.Debugger.java_class
|
67
70
|
end
|
68
|
-
|
71
|
+
|
69
72
|
def loader
|
70
73
|
lookup Mdbcore.loader.Loader.java_class
|
71
74
|
end
|
@@ -73,7 +76,7 @@ module RPicSim::Mplab
|
|
73
76
|
def lookup(klass)
|
74
77
|
@assembly.getLookup.lookup klass
|
75
78
|
end
|
76
|
-
|
79
|
+
|
77
80
|
def check_for_errors
|
78
81
|
warn_about_5C
|
79
82
|
warn_about_path_retrieval
|
@@ -83,9 +86,11 @@ module RPicSim::Mplab
|
|
83
86
|
def warn_about_5C
|
84
87
|
# Detect a problem that once caused peripherals to load incorrectly.
|
85
88
|
# More info: http://stackoverflow.com/q/15794170/28128
|
86
|
-
f = DocumentLocator.java_class.resource(
|
87
|
-
if f.include?(
|
88
|
-
$stderr.puts
|
89
|
+
f = DocumentLocator.java_class.resource('MPLABDocumentLocator.class').getFile
|
90
|
+
if f.include?('%5C')
|
91
|
+
$stderr.puts 'warning: A %5C character was detected in the ' \
|
92
|
+
'MPLABDocumentLoator.class file location. ' \
|
93
|
+
'This might cause errors in the Microchip code.'
|
89
94
|
end
|
90
95
|
end
|
91
96
|
|
@@ -93,7 +98,7 @@ module RPicSim::Mplab
|
|
93
98
|
# See spec/mplab_x/path_retrieval_spec.rb for more info.
|
94
99
|
retrieval = com.microchip.mplab.open.util.pathretrieval.PathRetrieval
|
95
100
|
path = retrieval.getPath(DocumentLocator.java_class)
|
96
|
-
if !java.io.File.new(path).exists
|
101
|
+
if !java.io.File.new(path).exists
|
97
102
|
$stderr.puts "warning: MPLAB X will be looking for files at a bad path: #{path}"
|
98
103
|
end
|
99
104
|
end
|