ctioga2 0.4 → 0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Changelog +16 -0
- data/lib/ctioga2/commands/arguments.rb +5 -2
- data/lib/ctioga2/commands/commands.rb +45 -13
- data/lib/ctioga2/commands/context.rb +9 -1
- data/lib/ctioga2/commands/doc/help.rb +2 -2
- data/lib/ctioga2/commands/doc/html.rb +8 -8
- data/lib/ctioga2/commands/doc/introspection.rb +7 -5
- data/lib/ctioga2/commands/parsers/file.rb +123 -120
- data/lib/ctioga2/commands/parsers/old-file.rb +191 -0
- data/lib/ctioga2/commands/strings.rb +2 -2
- data/lib/ctioga2/data/datacolumn.rb +5 -2
- data/lib/ctioga2/data/dataset.rb +3 -13
- data/lib/ctioga2/data/indexed-dtable.rb +43 -11
- data/lib/ctioga2/data/stack.rb +65 -8
- data/lib/ctioga2/graphics/elements.rb +2 -1
- data/lib/ctioga2/graphics/elements/containers.rb +22 -3
- data/lib/ctioga2/graphics/elements/primitive.rb +5 -5
- data/lib/ctioga2/graphics/elements/xyz-contour.rb +123 -0
- data/lib/ctioga2/graphics/generator.rb +31 -5
- data/lib/ctioga2/graphics/legends.rb +44 -3
- data/lib/ctioga2/graphics/legends/area.rb +28 -9
- data/lib/ctioga2/graphics/legends/items.rb +34 -23
- data/lib/ctioga2/graphics/legends/multicols.rb +132 -0
- data/lib/ctioga2/graphics/styles.rb +3 -1
- data/lib/ctioga2/graphics/styles/axes.rb +10 -4
- data/lib/ctioga2/graphics/styles/base.rb +65 -11
- data/lib/ctioga2/graphics/styles/colormap.rb +2 -1
- data/lib/ctioga2/graphics/styles/contour.rb +141 -0
- data/lib/ctioga2/graphics/styles/curve.rb +49 -67
- data/lib/ctioga2/graphics/styles/drawable.rb +17 -8
- data/lib/ctioga2/graphics/styles/factory.rb +79 -38
- data/lib/ctioga2/graphics/styles/legend.rb +49 -6
- data/lib/ctioga2/graphics/styles/plot.rb +10 -9
- data/lib/ctioga2/graphics/styles/sheet.rb +11 -11
- data/lib/ctioga2/graphics/styles/texts.rb +38 -9
- data/lib/ctioga2/graphics/types.rb +20 -1
- data/lib/ctioga2/graphics/types/dimensions.rb +7 -1
- data/lib/ctioga2/metabuilder/types/lists.rb +4 -4
- data/lib/ctioga2/metabuilder/types/numbers.rb +3 -3
- data/lib/ctioga2/metabuilder/types/styles.rb +2 -2
- data/lib/ctioga2/plotmaker.rb +12 -1
- data/lib/ctioga2/utils.rb +27 -3
- metadata +8 -4
data/Changelog
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
ctioga2 (0.5)
|
2
|
+
|
3
|
+
* Choose the side of axis ticks
|
4
|
+
* Multicolumn legends
|
5
|
+
* Much more control about the details of the legends
|
6
|
+
* A drop command to remove datasets from the stack
|
7
|
+
* A much simpler format for command files
|
8
|
+
* Improved error detection/report (including now LaTeX errors, with
|
9
|
+
Tioga version 1.16)
|
10
|
+
* Real contour plots
|
11
|
+
* Specify text size/shift with real dimensions
|
12
|
+
* Many bug fixes
|
13
|
+
* Default size of tick labels is now larger
|
14
|
+
|
15
|
+
-- Vincent <vincent.fourmond@9online.fr> Mon 26 Aug 22:04:05 CEST 2013
|
16
|
+
|
1
17
|
ctioga2 (0.4)
|
2
18
|
|
3
19
|
* Fixed a bug in /which (dataset) options
|
@@ -16,7 +16,7 @@ require 'ctioga2/commands/type'
|
|
16
16
|
|
17
17
|
module CTioga2
|
18
18
|
|
19
|
-
Version::register_svn_info('$Revision:
|
19
|
+
Version::register_svn_info('$Revision: 383 $', '$Date: 2013-03-11 21:57:53 +0100 (Mon, 11 Mar 2013) $')
|
20
20
|
|
21
21
|
module Commands
|
22
22
|
|
@@ -42,7 +42,10 @@ module CTioga2
|
|
42
42
|
# name
|
43
43
|
attr_accessor :option_target
|
44
44
|
|
45
|
-
# Whether or not the option is deprecated
|
45
|
+
# Whether or not the option is deprecated.
|
46
|
+
#
|
47
|
+
# If evaluates as true and different from _true_, is converted
|
48
|
+
# into a string used as an explanation to the user
|
46
49
|
attr_accessor :option_deprecated
|
47
50
|
|
48
51
|
# _type_ is a named CommandType
|
@@ -17,7 +17,7 @@ require 'ctioga2/commands/groups'
|
|
17
17
|
|
18
18
|
module CTioga2
|
19
19
|
|
20
|
-
Version::register_svn_info('$Revision:
|
20
|
+
Version::register_svn_info('$Revision: 430 $', '$Date: 2013-08-23 14:23:52 +0200 (Fri, 23 Aug 2013) $')
|
21
21
|
|
22
22
|
module Commands
|
23
23
|
|
@@ -90,6 +90,14 @@ module CTioga2
|
|
90
90
|
# The context of definition [file, line]
|
91
91
|
attr_accessor :context
|
92
92
|
|
93
|
+
# The context of the documentation
|
94
|
+
attr_accessor :documentation_context
|
95
|
+
|
96
|
+
def self.get_calling_context(id=2)
|
97
|
+
caller[id].gsub(/.*\/ctioga2\//, 'lib/ctioga2/') =~ /(.*):(\d+)/
|
98
|
+
return [$1, $2.to_i]
|
99
|
+
end
|
100
|
+
|
93
101
|
# Creates a Command, with all attributes set up. The code can be
|
94
102
|
# set using #set_code.
|
95
103
|
#
|
@@ -109,8 +117,7 @@ module CTioga2
|
|
109
117
|
@code = code
|
110
118
|
self.describe(d_short, d_long, group)
|
111
119
|
|
112
|
-
|
113
|
-
@context = [$1, $2.to_i]
|
120
|
+
@context = Command.get_calling_context
|
114
121
|
|
115
122
|
# Registers automatically the command
|
116
123
|
if register
|
@@ -132,6 +139,7 @@ module CTioga2
|
|
132
139
|
# Sets the descriptions of the command. If the long description
|
133
140
|
# is ommitted, the short is reused.
|
134
141
|
def describe(short, long = nil, group = nil)
|
142
|
+
@documentation_context = Command.get_calling_context(1)
|
135
143
|
@short_description = short
|
136
144
|
@long_description = long || short
|
137
145
|
if(group)
|
@@ -140,6 +148,15 @@ module CTioga2
|
|
140
148
|
end
|
141
149
|
end
|
142
150
|
|
151
|
+
# Sets the long documentation of the given command
|
152
|
+
def self.document_command(cmd, desc)
|
153
|
+
tg = Commands::Interpreter.command(cmd)
|
154
|
+
if tg
|
155
|
+
tg.documentation_context = Command.get_calling_context(1)
|
156
|
+
tg.long_description = desc
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
143
160
|
# Returns a list of three strings:
|
144
161
|
# * the short option
|
145
162
|
# * the long option with arguments
|
@@ -210,19 +227,24 @@ module CTioga2
|
|
210
227
|
# instance for the OptionParser with boolean options)
|
211
228
|
def convert_options(options)
|
212
229
|
target_options = {}
|
230
|
+
conv = target_option_names()
|
213
231
|
for k,v in options
|
214
|
-
|
232
|
+
kn = normalize_option_name(k)
|
233
|
+
if ! conv.key? kn
|
215
234
|
raise CommandOptionUnkown, "Unkown option #{k} for command #{@name}"
|
216
235
|
end
|
217
|
-
opt = @optional_arguments[
|
236
|
+
opt = @optional_arguments[conv[kn]]
|
218
237
|
if v.is_a? String
|
219
238
|
v = opt.type.string_to_type(v)
|
220
239
|
end
|
221
|
-
target = opt.option_target ||
|
240
|
+
target = opt.option_target || conv[kn]
|
222
241
|
if opt.option_deprecated
|
223
242
|
expl = ""
|
224
243
|
if opt.option_target
|
225
244
|
expl = " -- please use #{opt.option_target} instead"
|
245
|
+
elsif opt.option_deprecated != true # Ie more than plain
|
246
|
+
# true/false
|
247
|
+
expl = " -- #{opt.option_deprecated}"
|
226
248
|
end
|
227
249
|
Log::warn { "Deprecated option #{k}#{expl}" }
|
228
250
|
end
|
@@ -232,15 +254,25 @@ module CTioga2
|
|
232
254
|
return target_options
|
233
255
|
end
|
234
256
|
|
257
|
+
# Returns a hash "normalized option names" => 'real option name'
|
258
|
+
def target_option_names
|
259
|
+
return @tg_op_names if @tg_op_names
|
260
|
+
|
261
|
+
@tg_op_names = {}
|
262
|
+
for k in @optional_arguments.keys
|
263
|
+
@tg_op_names[normalize_option_name(k)] = k
|
264
|
+
end
|
265
|
+
return @tg_op_names
|
266
|
+
end
|
267
|
+
|
268
|
+
# Returns a lowercase
|
269
|
+
def normalize_option_name(opt)
|
270
|
+
return opt.gsub(/_/,"-").downcase
|
271
|
+
end
|
272
|
+
|
235
273
|
# Whether the Command accepts the named _option_.
|
236
|
-
#
|
237
|
-
# \todo Several conversions could be used, to facilitate the
|
238
|
-
# writing of options:
|
239
|
-
#
|
240
|
-
# * convert everything to lowercase .
|
241
|
-
# * ignore the difference between _ and - (a bit delicate).
|
242
274
|
def has_option?(option)
|
243
|
-
return
|
275
|
+
return target_option_names.key?(normalize_option_name(option))
|
244
276
|
end
|
245
277
|
|
246
278
|
# Whether the Command accepts any option at all ?
|
@@ -41,7 +41,15 @@ module CTioga2
|
|
41
41
|
if @option
|
42
42
|
"option #{@option} (##{@number})"
|
43
43
|
else
|
44
|
-
|
44
|
+
file = @file.inspect
|
45
|
+
if @file.respond_to?(:path)
|
46
|
+
file = @file.path
|
47
|
+
end
|
48
|
+
if @command
|
49
|
+
"command #{@command} in file '#{file}' line #{@number}"
|
50
|
+
else
|
51
|
+
"line #{@number} in file '#{file}'"
|
52
|
+
end
|
45
53
|
end
|
46
54
|
end
|
47
55
|
|
@@ -18,7 +18,7 @@ require 'ctioga2/commands/doc/wordwrap'
|
|
18
18
|
|
19
19
|
module CTioga2
|
20
20
|
|
21
|
-
Version::register_svn_info('$Revision:
|
21
|
+
Version::register_svn_info('$Revision: 409 $', '$Date: 2013-08-22 21:23:51 +0200 (Thu, 22 Aug 2013) $')
|
22
22
|
|
23
23
|
module Commands
|
24
24
|
|
@@ -154,7 +154,7 @@ module CTioga2
|
|
154
154
|
if cmd.has_options?
|
155
155
|
op_start = ' options: '
|
156
156
|
options = cmd.optional_arguments.
|
157
|
-
keys.sort.map { |x| "/#{x}"}.join(' ')
|
157
|
+
keys.sort.map { |x| "/#{cmd.normalize_option_name(x)}"}.join(' ')
|
158
158
|
opts_lines = WordWrapper.wrap(options, size - op_start.size)
|
159
159
|
str += "\n#{total_leading_spaces}#{style(op_start,'switch')}" +
|
160
160
|
style(opts_lines.join("\n#{total_leading_spaces}#{' ' * op_start.size}"), 'options')
|
@@ -16,7 +16,7 @@ require 'ctioga2/commands/commands'
|
|
16
16
|
|
17
17
|
module CTioga2
|
18
18
|
|
19
|
-
Version::register_svn_info('$Revision:
|
19
|
+
Version::register_svn_info('$Revision: 409 $', '$Date: 2013-08-22 21:23:51 +0200 (Thu, 22 Aug 2013) $')
|
20
20
|
|
21
21
|
module Commands
|
22
22
|
|
@@ -169,23 +169,23 @@ module CTioga2
|
|
169
169
|
str << "<p class='synopsis'>\n<span class='bold'>Synopsis (file)</span>\n"
|
170
170
|
|
171
171
|
str << "</p>\n<pre class='examples-cmdfile'>"
|
172
|
-
str << "<span class='cmd'>#{cmd.name}
|
172
|
+
str << "<span class='cmd'>#{cmd.name} "
|
173
173
|
str << cmd.arguments.map { |arg|
|
174
174
|
"<a class='argument' href='#{@types_url}#type-#{arg.type.name}'>#{arg.displayed_name}</a>"
|
175
|
-
}.join('
|
175
|
+
}.join(' ')
|
176
176
|
if cmd.has_options?
|
177
177
|
if(cmd.arguments.size > 0)
|
178
|
-
str << "
|
178
|
+
str << " "
|
179
179
|
end
|
180
|
-
str << "option=..."
|
180
|
+
str << "/option=..."
|
181
181
|
end
|
182
|
-
str << "
|
182
|
+
str << "</span>\n"
|
183
183
|
str << "</pre>\n"
|
184
184
|
|
185
185
|
# Command-line file synopsis
|
186
186
|
str << "<p class='synopsis'>\n<span class='bold'>Synopsis (command-line)</span>\n"
|
187
187
|
args = cmd.arguments.map { |arg|
|
188
|
-
"<a class='argument' href='#{@types_url}#type-#{arg.type.name}'>#{arg.displayed_name
|
188
|
+
"<a class='argument' href='#{@types_url}#type-#{arg.type.name}'>#{arg.displayed_name}</a>"
|
189
189
|
}.join(' ')
|
190
190
|
if cmd.has_options?
|
191
191
|
args << " /option=..."
|
@@ -204,7 +204,7 @@ module CTioga2
|
|
204
204
|
if cmd.has_options?
|
205
205
|
str << "<p class='synopsis'><span class='bold'>Available options</span>:\n"
|
206
206
|
opts = cmd.optional_arguments.sort.map do |k,arg|
|
207
|
-
"<a href='#{@types_url}#type-#{arg.type.name}'><code>#{k}</code></a>\n"
|
207
|
+
"<a href='#{@types_url}#type-#{arg.type.name}'><code>#{cmd.normalize_option_name(k)}</code></a>\n"
|
208
208
|
end
|
209
209
|
str << opts.join(' ')
|
210
210
|
str << "</p>"
|
@@ -16,7 +16,7 @@ require 'ctioga2/commands/commands'
|
|
16
16
|
|
17
17
|
module CTioga2
|
18
18
|
|
19
|
-
Version::register_svn_info('$Revision:
|
19
|
+
Version::register_svn_info('$Revision: 430 $', '$Date: 2013-08-23 14:23:52 +0200 (Fri, 23 Aug 2013) $')
|
20
20
|
|
21
21
|
module Commands
|
22
22
|
|
@@ -106,10 +106,11 @@ module CTioga2
|
|
106
106
|
end
|
107
107
|
|
108
108
|
# Lauches an editor to edit the given command:
|
109
|
-
def edit_command(cmd)
|
109
|
+
def edit_command(cmd, doc)
|
110
110
|
cmd = Interpreter::command(cmd)
|
111
111
|
if cmd
|
112
|
-
|
112
|
+
cntx = doc ? cmd.documentation_context : cmd.context
|
113
|
+
edit_file(*cntx)
|
113
114
|
end
|
114
115
|
end
|
115
116
|
|
@@ -205,8 +206,9 @@ EOH
|
|
205
206
|
|
206
207
|
EditCommandCmd =
|
207
208
|
Cmd.new('edit-command', nil, '--edit-command',
|
208
|
-
[ CmdArg.new('text')]
|
209
|
-
|
209
|
+
[ CmdArg.new('text')],
|
210
|
+
{'doc' => CmdArg.new('boolean')}) do |plotmaker, cmd, opts|
|
211
|
+
Introspection.new.edit_command(cmd, opts['doc'])
|
210
212
|
end
|
211
213
|
|
212
214
|
EditCommandCmd.describe("Edit the command",
|
@@ -1,5 +1,5 @@
|
|
1
|
-
# file.rb:
|
2
|
-
# copyright (c)
|
1
|
+
# file.rb: new style file parser for ctioga2
|
2
|
+
# copyright (c) 2013 by Vincent Fourmond
|
3
3
|
|
4
4
|
# This program is free software; you can redistribute it and/or modify
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -11,38 +11,28 @@
|
|
11
11
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
12
|
# GNU General Public License for more details (in the COPYING file).
|
13
13
|
|
14
|
-
|
14
|
+
|
15
15
|
require 'ctioga2/utils'
|
16
16
|
require 'ctioga2/log'
|
17
17
|
require 'ctioga2/commands/commands'
|
18
18
|
require 'ctioga2/commands/strings'
|
19
|
+
require 'ctioga2/commands/parsers/old-file'
|
19
20
|
|
20
21
|
module CTioga2
|
21
22
|
|
22
|
-
Version::register_svn_info('$Revision:
|
23
|
+
Version::register_svn_info('$Revision: 420 $', '$Date: 2013-08-23 01:05:44 +0200 (Fri, 23 Aug 2013) $')
|
23
24
|
|
24
25
|
module Commands
|
25
26
|
|
26
27
|
module Parsers
|
27
28
|
|
28
|
-
#
|
29
|
-
class UnterminatedSymbol < Exception
|
30
|
-
end
|
31
|
-
|
32
|
-
# Unexepected character.
|
33
|
-
class UnexpectedCharacter < Exception
|
34
|
-
end
|
35
|
-
|
36
|
-
# Syntax error
|
37
|
-
class ParserSyntaxError < Exception
|
38
|
-
end
|
39
|
-
|
40
|
-
# This class is in charge of parsing a command-line against a list
|
41
|
-
# of known commands.
|
29
|
+
# This class parses a "new style" command file, delegating
|
42
30
|
class FileParser
|
43
31
|
|
44
32
|
include Log
|
45
33
|
|
34
|
+
|
35
|
+
|
46
36
|
# Runs a command file targeting the given _interpreter_.
|
47
37
|
def self.run_command_file(file, interpreter)
|
48
38
|
FileParser.new.run_command_file(file, interpreter)
|
@@ -68,122 +58,135 @@ module CTioga2
|
|
68
58
|
# Parses a given _io_ object, sending commands/variable
|
69
59
|
# definitions to the given _interpreter_.
|
70
60
|
def parse_io_object(io, interpreter)
|
71
|
-
|
72
|
-
#
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
61
|
+
|
62
|
+
# We first split everything into lines
|
63
|
+
lines = io.readlines
|
64
|
+
|
65
|
+
# First, we look for old-style commands to see if we
|
66
|
+
# delegate to the other parser. In any case, we build up a
|
67
|
+
# list of "unsplit" lines (ie gather lines that end with \)
|
68
|
+
|
69
|
+
parsed_lines = []
|
70
|
+
cur = nil
|
71
|
+
|
72
|
+
lines_indices = []
|
73
|
+
idx = 0
|
74
|
+
|
75
|
+
|
76
|
+
## @todo line counting ?
|
77
|
+
for l in lines
|
78
|
+
idx += 1
|
79
|
+
# If we find something that looks like a command at the
|
80
|
+
# beginning of a line, we say this is an old style file.
|
81
|
+
|
82
|
+
## @todo Find a way to disable this compatibility stuff --
|
83
|
+
## or make it more accurate ? The problem is that in a
|
84
|
+
## large command file, there may be things that look like
|
85
|
+
## old style commands ?
|
79
86
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
# Now, we need to split str.
|
92
|
-
args = str.expand_and_split(/\s*,\s*/, interpreter)
|
93
|
-
|
94
|
-
cmd = interpreter.get_command(symbol)
|
95
|
-
real_args = args.slice!(0, cmd.argument_number)
|
96
|
-
# And now the options:
|
97
|
-
options = {}
|
98
|
-
|
99
|
-
# Problem: the space on the right of the = sign is
|
100
|
-
# *significant*.
|
101
|
-
for o in args
|
102
|
-
if o =~ /^\s*\/?([\w-]+)\s*=(.*)/
|
103
|
-
if cmd.has_option? $1
|
104
|
-
options[$1] = $2
|
105
|
-
else
|
106
|
-
error {
|
107
|
-
"Command #{cmd.name} does not take option #{$1}"
|
108
|
-
}
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
87
|
+
if l =~ /^([a-z0-9-]+)\(/
|
88
|
+
path = io.respond_to?(:path) ? io.path : io.to_s
|
89
|
+
warn { "Found old style (deprecated) commands in '#{path}', using old style parser"}
|
90
|
+
return OldFileParser.new.
|
91
|
+
run_commands(lines.join(""), interpreter)
|
92
|
+
end
|
93
|
+
if cur
|
94
|
+
cur << l
|
95
|
+
else
|
96
|
+
cur = l
|
97
|
+
end
|
112
98
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
end
|
122
|
-
ch = c.chr
|
123
|
-
if ch != '='
|
124
|
-
raise ParserSyntaxError, "Expecting = after :"
|
125
|
-
end
|
126
|
-
str = InterpreterString.parse_until_unquoted(io,"\n", false)
|
127
|
-
interpreter.variables.define_variable(symbol, str,
|
128
|
-
interpreter)
|
129
|
-
break
|
130
|
-
elsif ch == '='
|
131
|
-
str = InterpreterString.parse_until_unquoted(io,"\n", false)
|
132
|
-
interpreter.variables.define_variable(symbol, str, nil)
|
133
|
-
break
|
134
|
-
else
|
135
|
-
raise UnexpectedCharacter, "Did not expect #{ch} after #{symbol}"
|
136
|
-
end
|
99
|
+
if cur =~ /\\$/
|
100
|
+
cur.gsub!(/\\$/,'')
|
101
|
+
cur.chomp!
|
102
|
+
else
|
103
|
+
# Strip all white space at the end of unfinished lines.
|
104
|
+
parsed_lines << cur.gsub(/\s+$/,"\n")
|
105
|
+
lines_indices << idx
|
106
|
+
cur = nil
|
137
107
|
end
|
108
|
+
|
138
109
|
end
|
139
|
-
end
|
140
110
|
|
141
|
-
|
111
|
+
# Flush any pending unfinished line
|
112
|
+
parsed_lines << cur if cur
|
113
|
+
lines_indices << idx if cur
|
114
|
+
|
115
|
+
# Now, we rearrange the lines...
|
116
|
+
idx = -1
|
117
|
+
for l in parsed_lines
|
118
|
+
idx += 1
|
119
|
+
interpreter.context.parsing_file(nil, io, lines_indices[idx])
|
120
|
+
if l =~ /^\s*([a-zA-Z0-9_-]+)\s*(=|:=)\s*(.*)/
|
121
|
+
symbol = $1
|
122
|
+
value = InterpreterString.parse_until_unquoted(StringIO.new($3),"\n", false)
|
123
|
+
rec = (($2 == "=") ? nil : interpreter)
|
124
|
+
|
125
|
+
interpreter.variables.define_variable(symbol, value, rec)
|
126
|
+
elsif l =~ /^\s*#/
|
127
|
+
# comment...
|
128
|
+
else
|
129
|
+
l += "\n"
|
130
|
+
str = InterpreterString.parse_until_unquoted(StringIO.new(l),"\n")
|
131
|
+
words = str.expand_and_split(/\s+/, interpreter)
|
142
132
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
# way. This function returns the symbol.
|
148
|
-
#
|
149
|
-
# Symbols are composed of the alphabet SYMBOL_CHAR_REGEX.
|
150
|
-
def up_to_next_symbol(io)
|
151
|
-
|
152
|
-
symbol = nil # As long as no symbol as been started
|
153
|
-
# it will stay nil.
|
154
|
-
while(1)
|
155
|
-
c = io.getc
|
156
|
-
if ! c # EOF
|
157
|
-
if symbol
|
158
|
-
raise UnterminatedSymbol, "EOF reached during symbol parsing"
|
159
|
-
else
|
160
|
-
# File is finished and we didn't meet any symbol.
|
161
|
-
# Nothing to do !
|
162
|
-
return nil
|
133
|
+
# Take care of strings starting with spaces...
|
134
|
+
|
135
|
+
if words.size == 0
|
136
|
+
next
|
163
137
|
end
|
138
|
+
|
139
|
+
symbol = words[0]
|
140
|
+
all_args = words[1..-1]
|
141
|
+
|
142
|
+
cmd = interpreter.get_command(symbol)
|
143
|
+
|
144
|
+
args, opts = parse_args_and_opts(cmd, all_args)
|
145
|
+
|
146
|
+
interpreter.context.parsing_file(symbol, io, lines_indices[idx]) # Missing line number
|
147
|
+
interpreter.run_command(cmd, args, opts)
|
164
148
|
end
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
protected
|
153
|
+
|
154
|
+
|
155
|
+
# Parses the all_args into arguments and options.
|
156
|
+
def parse_args_and_opts(cmd, all_args)
|
157
|
+
|
158
|
+
opts = {}
|
159
|
+
args = []
|
160
|
+
while all_args.size > 0
|
161
|
+
a = all_args.shift
|
162
|
+
if a =~ /^\/([a-zA-Z0-9_-]+)(=(.*))?$/
|
163
|
+
o = $1
|
164
|
+
if cmd.has_option?(o)
|
165
|
+
if $2
|
166
|
+
if $3
|
167
|
+
opts[o] = $3
|
168
|
+
else
|
169
|
+
opts[o] = all_args.shift
|
170
|
+
end
|
171
|
+
else
|
172
|
+
nxt = all_args.shift
|
173
|
+
if nxt =~ /^\s*=\s*$/
|
174
|
+
opts[o] = all_args.shift
|
175
|
+
else
|
176
|
+
opts[o] = nxt.gsub(/^\s*=/,'')
|
177
|
+
end
|
178
|
+
end
|
169
179
|
else
|
170
|
-
|
171
|
-
|
180
|
+
warn { "#{o} looks like an option, but command #{cmd.name} does not have such an option" }
|
181
|
+
args << a
|
172
182
|
end
|
173
183
|
else
|
174
|
-
|
175
|
-
symbol = ch
|
176
|
-
elsif ch =~ /\s/
|
177
|
-
# Nothing
|
178
|
-
elsif ch == '#'
|
179
|
-
io.gets
|
180
|
-
else
|
181
|
-
raise UnexpectedCharacter, "Unexpected character: #{ch}, when looking for a symbol"
|
182
|
-
end
|
184
|
+
args << a
|
183
185
|
end
|
184
186
|
end
|
185
|
-
end
|
186
187
|
|
188
|
+
return [args, opts]
|
189
|
+
end
|
187
190
|
end
|
188
191
|
|
189
192
|
end
|