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.
Files changed (43) hide show
  1. data/Changelog +16 -0
  2. data/lib/ctioga2/commands/arguments.rb +5 -2
  3. data/lib/ctioga2/commands/commands.rb +45 -13
  4. data/lib/ctioga2/commands/context.rb +9 -1
  5. data/lib/ctioga2/commands/doc/help.rb +2 -2
  6. data/lib/ctioga2/commands/doc/html.rb +8 -8
  7. data/lib/ctioga2/commands/doc/introspection.rb +7 -5
  8. data/lib/ctioga2/commands/parsers/file.rb +123 -120
  9. data/lib/ctioga2/commands/parsers/old-file.rb +191 -0
  10. data/lib/ctioga2/commands/strings.rb +2 -2
  11. data/lib/ctioga2/data/datacolumn.rb +5 -2
  12. data/lib/ctioga2/data/dataset.rb +3 -13
  13. data/lib/ctioga2/data/indexed-dtable.rb +43 -11
  14. data/lib/ctioga2/data/stack.rb +65 -8
  15. data/lib/ctioga2/graphics/elements.rb +2 -1
  16. data/lib/ctioga2/graphics/elements/containers.rb +22 -3
  17. data/lib/ctioga2/graphics/elements/primitive.rb +5 -5
  18. data/lib/ctioga2/graphics/elements/xyz-contour.rb +123 -0
  19. data/lib/ctioga2/graphics/generator.rb +31 -5
  20. data/lib/ctioga2/graphics/legends.rb +44 -3
  21. data/lib/ctioga2/graphics/legends/area.rb +28 -9
  22. data/lib/ctioga2/graphics/legends/items.rb +34 -23
  23. data/lib/ctioga2/graphics/legends/multicols.rb +132 -0
  24. data/lib/ctioga2/graphics/styles.rb +3 -1
  25. data/lib/ctioga2/graphics/styles/axes.rb +10 -4
  26. data/lib/ctioga2/graphics/styles/base.rb +65 -11
  27. data/lib/ctioga2/graphics/styles/colormap.rb +2 -1
  28. data/lib/ctioga2/graphics/styles/contour.rb +141 -0
  29. data/lib/ctioga2/graphics/styles/curve.rb +49 -67
  30. data/lib/ctioga2/graphics/styles/drawable.rb +17 -8
  31. data/lib/ctioga2/graphics/styles/factory.rb +79 -38
  32. data/lib/ctioga2/graphics/styles/legend.rb +49 -6
  33. data/lib/ctioga2/graphics/styles/plot.rb +10 -9
  34. data/lib/ctioga2/graphics/styles/sheet.rb +11 -11
  35. data/lib/ctioga2/graphics/styles/texts.rb +38 -9
  36. data/lib/ctioga2/graphics/types.rb +20 -1
  37. data/lib/ctioga2/graphics/types/dimensions.rb +7 -1
  38. data/lib/ctioga2/metabuilder/types/lists.rb +4 -4
  39. data/lib/ctioga2/metabuilder/types/numbers.rb +3 -3
  40. data/lib/ctioga2/metabuilder/types/styles.rb +2 -2
  41. data/lib/ctioga2/plotmaker.rb +12 -1
  42. data/lib/ctioga2/utils.rb +27 -3
  43. 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: 355 $', '$Date: 2012-12-26 00:19:04 +0100 (Wed, 26 Dec 2012) $')
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: 355 $', '$Date: 2012-12-26 00:19:04 +0100 (Wed, 26 Dec 2012) $')
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
- caller[1].gsub(/.*\/ctioga2\//, 'lib/ctioga2/') =~ /(.*):(\d+)/
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
- if ! @optional_arguments.key? k
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[k]
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 || k
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 @optional_arguments.key? option
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
- "command #{@command} in file #{@file} line #{@number}"
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: 132 $', '$Date: 2010-01-14 23:18:19 +0100 (Thu, 14 Jan 2010) $')
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: 216 $', '$Date: 2010-12-31 16:18:17 +0100 (Fri, 31 Dec 2010) $')
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 << ")</span>\n"
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.upcase}</a>"
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: 336 $', '$Date: 2012-12-23 00:29:48 +0100 (Sun, 23 Dec 2012) $')
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
- edit_file(*cmd.context)
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')]) do |plotmaker, cmd|
209
- Introspection.new.edit_command(cmd)
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: a file parser for ctioga2
2
- # copyright (c) 2009 by Vincent Fourmond
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
- require 'stringio'
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: 327 $', '$Date: 2012-11-28 14:47:52 +0100 (Wed, 28 Nov 2012) $')
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
- # Raised when EOF is encountered during a symbol parsing
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
- # The process is simple: we look for symbols and
72
- # corresponding syntax element: parentheses or assignments
73
-
74
- ## @todo It would be really great if assignments could be
75
- ## made conditional (a bit like in makefiles)
76
- while(1)
77
- symbol = up_to_next_symbol(io)
78
- break if not symbol
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
- while(1)
81
- c = io.getc
82
- if ! c # EOF
83
- raise ParserSyntaxError, "Expecting something after symbol #{symbol}"
84
- end
85
- ch = c.chr
86
- if ch =~ /\s/ # blank...
87
- next
88
- elsif ch == '(' # beginning of a function call
89
- # Parse string:
90
- str = InterpreterString.parse_until_unquoted(io,")")
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
- interpreter.context.parsing_file(symbol, io) # Missing line number
114
- interpreter.run_command(cmd, real_args, options)
115
- io.getc # Slurp up the )
116
- break
117
- elsif ch == ':' # Assignment
118
- c = io.getc
119
- if ! c # EOF
120
- raise ParserSyntaxError, "Expecting = after :"
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
- protected
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
- SYMBOL_CHAR_REGEX = /[a-zA-Z0-9_-]/
144
-
145
- # Parses the _io_ stream up to and including the next
146
- # symbol. Only white space or comments may be found on the
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
- ch = c.chr
166
- if symbol # We have started
167
- if ch =~ SYMBOL_CHAR_REGEX
168
- symbol += ch
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
- io.ungetc(c)
171
- return symbol
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
- if ch =~ SYMBOL_CHAR_REGEX
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