ctioga2 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|