mysh 0.1.14 → 0.1.15
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.
- checksums.yaml +4 -4
- data/README.md +7 -2
- data/lib/mysh/expression/lineage.rb +24 -0
- data/lib/mysh/expression.rb +53 -51
- data/lib/mysh/external_ruby.rb +1 -1
- data/lib/mysh/{support/frame.rb → internal/action.rb} +4 -4
- data/lib/mysh/{support/command_pool.rb → internal/action_pool.rb} +8 -8
- data/lib/mysh/internal/actions/actions_path.rb +15 -0
- data/lib/mysh/{commands → internal/actions}/cd.rb +2 -2
- data/lib/mysh/{commands → internal/actions}/exit.rb +2 -2
- data/lib/mysh/{commands → internal/actions}/help.rb +7 -7
- data/lib/mysh/{commands → internal/actions}/help.txt +1 -1
- data/lib/mysh/{commands → internal/actions}/help_expr.txt +1 -0
- data/lib/mysh/{commands → internal/actions}/help_help.txt +1 -1
- data/lib/mysh/{commands → internal/actions}/help_math.txt +0 -0
- data/lib/mysh/{commands → internal/actions}/history.rb +2 -2
- data/lib/mysh/{support → internal}/decorate.rb +2 -2
- data/lib/mysh/internal/format.rb +48 -0
- data/lib/mysh/internal/manage.rb +34 -0
- data/lib/mysh/internal.rb +7 -9
- data/lib/mysh/user_input/handlebars.rb +33 -0
- data/lib/mysh/user_input/parse.rb +65 -0
- data/lib/mysh/{smart_source.rb → user_input/smart_source.rb} +2 -1
- data/lib/mysh/user_input.rb +39 -0
- data/lib/mysh/version.rb +1 -1
- data/lib/mysh.rb +14 -25
- data/mysh.reek +112 -0
- data/rakefile.rb +1 -1
- data/tests/my_shell_tests.rb +13 -13
- metadata +22 -19
- data/lib/mysh/commands/command_path.rb +0 -15
- data/lib/mysh/support/format.rb +0 -50
- data/lib/mysh/support/handlebars.rb +0 -30
- data/lib/mysh/support/manage.rb +0 -26
- data/lib/mysh/support/parse.rb +0 -70
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5357ad0b3384cce27b2e53bf392dde640f5b21ec
|
4
|
+
data.tar.gz: a84115ea89d9d586dae27bdbcaaffcff3060dbe0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9336ae69aaf60132e7af4eaea1e09e3d98e1aded2daa1239508a843069f9729f539b80244bd5d59aa455bd9847f54f199968acb5bbe68b6a5c260e61dab1f0e
|
7
|
+
data.tar.gz: 52a3ceecf702aeb6c135f93c99249e2a3c8bd78c2f46a1a6a286bb438ad4e0223e2c0d23b8c920f2011d653d411809a7a04a5c1f60daa6b00da84cc7c5dd1725
|
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Mysh
|
2
2
|
|
3
|
+
mysh -- A ruby based command line shell program.
|
4
|
+
|
5
|
+
## Background
|
6
|
+
|
3
7
|
Inspired by the excellent article "Writing a Shell in 25 Lines of Ruby Code"
|
4
8
|
I thought it would be fun to experiment with that concept and see if it could
|
5
9
|
be taken further.
|
@@ -47,8 +51,8 @@ presented with a command prompt:
|
|
47
51
|
$ mysh
|
48
52
|
mysh>
|
49
53
|
|
50
|
-
|
51
|
-
|
54
|
+
Then start entering some commands! This prompt can be used to execute four
|
55
|
+
sorts of commands:
|
52
56
|
|
53
57
|
* Ruby expressions, which are preceded by the equal (=) sign.
|
54
58
|
* Internal commands that are processed directly by mysh
|
@@ -70,6 +74,7 @@ A few noteworthy methods exist that facilitate use of Ruby expressions:
|
|
70
74
|
```
|
71
75
|
reset Reset the execution environment to the default state.
|
72
76
|
result Returns the result of the previous expression.
|
77
|
+
x.lineage Get the class lineage of the object x.
|
73
78
|
vls "mask" List modules with version info. The optional mask string value is
|
74
79
|
used to filter for modules containing that string.
|
75
80
|
```
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#Object monkey patch for the mysh lineage command.
|
4
|
+
class Object
|
5
|
+
|
6
|
+
#Get the lineage of this object.
|
7
|
+
def lineage
|
8
|
+
klass = self.class
|
9
|
+
klass.name + " instance < " + klass.lineage
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
#Class monkey patch for the mysh lineage command.
|
15
|
+
class Class
|
16
|
+
|
17
|
+
#Get the lineage of this class.
|
18
|
+
def lineage
|
19
|
+
klass = superclass
|
20
|
+
name + (klass ? " < " + klass.lineage : "")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
data/lib/mysh/expression.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require 'pp'
|
4
4
|
require 'mathn'
|
5
5
|
|
6
|
+
require_relative 'expression/lineage'
|
7
|
+
|
6
8
|
#* expression.rb -- mysh ruby expression processor.
|
7
9
|
#<br>Endemic Code Smells
|
8
10
|
#* :reek:Attribute
|
@@ -14,82 +16,82 @@ module Mysh
|
|
14
16
|
include Math
|
15
17
|
|
16
18
|
#These variables live here so that they are not part of the mysh
|
17
|
-
#execution environment. This provides a little isolation.
|
19
|
+
#execution environment. This provides a little bit of isolation.
|
18
20
|
class << self
|
21
|
+
#The result of the last expression evaluated.
|
19
22
|
attr_accessor :result
|
20
|
-
|
23
|
+
|
24
|
+
#The execution binding used for ruby expressions.
|
21
25
|
attr_accessor :exec_binding
|
22
|
-
attr_accessor :exec_result
|
23
26
|
end
|
24
27
|
|
25
28
|
#Set up a new execution environment
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
ExecHost.result = nil
|
31
|
-
|
32
|
-
ExecHost.exec_fiber = Fiber.new do |cmd|
|
33
|
-
ExecHost.exec_binding = binding
|
34
|
-
|
35
|
-
while true
|
36
|
-
begin
|
37
|
-
ExecHost.exec_result = ExecHost.exec_binding.eval(cmd)
|
38
|
-
rescue StandardError, ScriptError => err
|
39
|
-
ExecHost.exec_result = "#{err.class.to_s}: #{err}"
|
40
|
-
end
|
41
|
-
|
42
|
-
cmd = Fiber.yield
|
43
|
-
end
|
44
|
-
end
|
29
|
+
def initialize(owner)
|
30
|
+
@owner = owner
|
31
|
+
mysh_binding
|
32
|
+
end
|
45
33
|
|
34
|
+
#Create a binding for mysh to execute expressions in.
|
35
|
+
def mysh_binding
|
36
|
+
ExecHost.exec_binding = binding
|
46
37
|
end
|
47
38
|
|
48
39
|
#Process an expression.
|
49
40
|
def execute(str)
|
50
41
|
if str.start_with?('=')
|
51
|
-
do_execute(
|
52
|
-
|
53
|
-
false
|
42
|
+
do_execute(str)
|
43
|
+
:expression
|
54
44
|
end
|
55
45
|
end
|
56
46
|
|
57
|
-
#Reset the state of the execution host.
|
58
|
-
#<br>Endemic Code Smells
|
59
|
-
#* :reek:UtilityFunction
|
60
|
-
def reset
|
61
|
-
Mysh.reset_host
|
62
|
-
nil
|
63
|
-
end
|
64
|
-
|
65
47
|
private
|
66
48
|
|
67
|
-
#
|
68
|
-
#<br>Endemic Code Smells
|
69
|
-
#* :reek:TooManyStatements
|
70
|
-
def do_build(str)
|
71
|
-
if /\\\s*$/ =~ str
|
72
|
-
parms = {prompt: 'mysh\\',
|
73
|
-
auto_source: MiniReadline::QuotedFileFolderSource}
|
74
|
-
|
75
|
-
do_build($PREMATCH + "\n" + Mysh.input.readline(parms))
|
76
|
-
else
|
77
|
-
str
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
#Execute the string
|
49
|
+
#Do the actual work of executing an expression.
|
82
50
|
def do_execute(str)
|
83
|
-
|
84
|
-
result = ExecHost.exec_result
|
51
|
+
self.result = exec_binding.eval(str[1..-1])
|
85
52
|
send(result ? :pp : :puts, result)
|
86
|
-
|
53
|
+
rescue Interrupt, StandardError, ScriptError => err
|
54
|
+
puts "#{err.class.to_s}: #{err}"
|
55
|
+
end
|
56
|
+
|
57
|
+
#Get the execute binding.
|
58
|
+
def exec_binding
|
59
|
+
self.class.exec_binding
|
87
60
|
end
|
88
61
|
|
89
62
|
#Get the previous result
|
90
63
|
def result
|
91
64
|
self.class.result
|
92
65
|
end
|
66
|
+
|
67
|
+
#Set the current result
|
68
|
+
def result=(value)
|
69
|
+
self.class.result=value
|
70
|
+
end
|
71
|
+
|
72
|
+
#Reset the state of the execution host.
|
73
|
+
def reset
|
74
|
+
@owner.reset_host
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
#A proxy for instance_eval.
|
79
|
+
def instance_eval(str)
|
80
|
+
exec_binding.eval(str)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
#Try to execute the string as a ruby expression.
|
85
|
+
def self.try_execute_ruby_expression(str)
|
86
|
+
if str.start_with?('=')
|
87
|
+
@exec_host.execute(str)
|
88
|
+
:expression
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
#Reset the state of the execution hosting environment.
|
93
|
+
def self.reset_host
|
94
|
+
@exec_host = ExecHost.new(self)
|
93
95
|
end
|
94
96
|
|
95
97
|
end
|
data/lib/mysh/external_ruby.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
#*
|
3
|
+
#* internal/action.rb -- The framework of mysh internal actions.
|
4
4
|
module Mysh
|
5
5
|
|
6
|
-
#The mysh internal
|
7
|
-
class
|
6
|
+
#The mysh internal action class.
|
7
|
+
class Action
|
8
8
|
#The name of the command.
|
9
9
|
attr_reader :name
|
10
10
|
|
@@ -25,7 +25,7 @@ module Mysh
|
|
25
25
|
end
|
26
26
|
|
27
27
|
#Get information about the command.
|
28
|
-
def
|
28
|
+
def action_info
|
29
29
|
[@name, @description]
|
30
30
|
end
|
31
31
|
|
@@ -1,17 +1,17 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
#*
|
3
|
+
#* internal/action_pool.rb -- A managed hash of mysh commands.
|
4
4
|
module Mysh
|
5
5
|
|
6
|
-
#*
|
7
|
-
class
|
6
|
+
#* A managed hash of mysh commands.
|
7
|
+
class ActionPool
|
8
8
|
|
9
9
|
#Create a new command pool
|
10
10
|
def initialize(&default_action)
|
11
11
|
@pool = {}
|
12
12
|
|
13
13
|
if default_action
|
14
|
-
@pool.default =
|
14
|
+
@pool.default = Action.new("", "", &default_action)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -24,7 +24,7 @@ module Mysh
|
|
24
24
|
def add(name, description, &action)
|
25
25
|
split_name = name.split[0] || ""
|
26
26
|
|
27
|
-
@pool[split_name] =
|
27
|
+
@pool[split_name] = Action.new(name, description, &action)
|
28
28
|
end
|
29
29
|
|
30
30
|
#Add an alias for an existing command.
|
@@ -36,14 +36,14 @@ module Mysh
|
|
36
36
|
split_name = new_name.split[0]
|
37
37
|
|
38
38
|
@pool[split_name] =
|
39
|
-
|
39
|
+
Action.new(new_name, command.description, &command.action)
|
40
40
|
end
|
41
41
|
|
42
42
|
#Get information on all commands.
|
43
|
-
def
|
43
|
+
def actions_info
|
44
44
|
@pool
|
45
45
|
.values
|
46
|
-
.map {|
|
46
|
+
.map {|action| action.action_info }
|
47
47
|
.sort {|first, second| first[0] <=> second[0] }
|
48
48
|
end
|
49
49
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* internal/actions/actions_path.rb -- A convenient hook to the command folder.
|
4
|
+
module Mysh
|
5
|
+
|
6
|
+
#* internal/actions/actions_path.rb -- A convenient hook to the command folder.
|
7
|
+
class Action
|
8
|
+
|
9
|
+
#Capture this folder's name.
|
10
|
+
ACTIONS_PATH = File.dirname(__FILE__) + "/"
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
#*
|
3
|
+
#* internal/actions/cd.rb -- The mysh internal cd command.
|
4
4
|
module Mysh
|
5
5
|
|
6
6
|
#* cd.rb -- The mysh internal cd command.
|
7
|
-
class
|
7
|
+
class Action
|
8
8
|
#Add the cd command to the library.
|
9
9
|
desc = ['Change directory to the optional <dir> parameter',
|
10
10
|
'and then display the current working directory.']
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
#*
|
3
|
+
#* internal/actions/exit.rb -- The mysh internal exit command.
|
4
4
|
module Mysh
|
5
5
|
|
6
6
|
#* exit.rb -- The mysh internal exit command.
|
7
|
-
class
|
7
|
+
class Action
|
8
8
|
#Add the exit command to the library.
|
9
9
|
COMMANDS.add('exit', 'Exit mysh.') do |args|
|
10
10
|
raise MiniReadlineEOI
|
@@ -1,30 +1,30 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
#*
|
3
|
+
#* internal/actions/help.rb -- The mysh internal help command.
|
4
4
|
module Mysh
|
5
5
|
|
6
6
|
#* help.rb -- The mysh internal help command.
|
7
|
-
class
|
7
|
+
class Action
|
8
8
|
|
9
9
|
# Help topics
|
10
|
-
HELP =
|
10
|
+
HELP = ActionPool.new do |args|
|
11
11
|
puts "No help found for #{args[0].inspect}."
|
12
12
|
end
|
13
13
|
|
14
14
|
HELP.add("", "General help on mysh.") do |args|
|
15
|
-
|
15
|
+
show_handlebar_file(ACTIONS_PATH + 'help.txt')
|
16
16
|
end
|
17
17
|
|
18
18
|
HELP.add("math", "Help on mysh math functions.") do |args|
|
19
|
-
|
19
|
+
show_handlebar_file(ACTIONS_PATH + 'help_math.txt')
|
20
20
|
end
|
21
21
|
|
22
22
|
HELP.add("=", "Help on mysh ruby expressions.") do |args|
|
23
|
-
|
23
|
+
show_handlebar_file(ACTIONS_PATH + 'help_expr.txt')
|
24
24
|
end
|
25
25
|
|
26
26
|
HELP.add("help", "Help on mysh help.") do |args|
|
27
|
-
|
27
|
+
show_handlebar_file(ACTIONS_PATH + 'help_help.txt')
|
28
28
|
end
|
29
29
|
|
30
30
|
HELP.add_alias('?', 'help')
|
@@ -24,7 +24,7 @@ the name of an internal command is processed internally by mysh.
|
|
24
24
|
|
25
25
|
The following set of commands are supported:
|
26
26
|
|
27
|
-
{{ format_items(COMMANDS.
|
27
|
+
{{ format_items(Mysh::COMMANDS.actions_info).join("\n") }}
|
28
28
|
|
29
29
|
3) External commands:
|
30
30
|
|
@@ -15,6 +15,7 @@ A few noteworthy special methods exist:
|
|
15
15
|
|
16
16
|
=reset Reset the execution environment to the default state.
|
17
17
|
=result Returns the result of the previous expression.
|
18
|
+
=x.lineage Get the class lineage of the object x.
|
18
19
|
=vls "mask" List modules with version info. The optional mask string value is
|
19
20
|
used to filter for modules containing that string.
|
20
21
|
|
File without changes
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
#*
|
3
|
+
#* internal/actions/history.rb -- The mysh internal history command.
|
4
4
|
module Mysh
|
5
5
|
|
6
6
|
#* history.rb -- The mysh internal history command.
|
7
|
-
class
|
7
|
+
class Action
|
8
8
|
#Add the exit command to the library.
|
9
9
|
COMMANDS.add('history', 'Display the mysh command history.') do |args|
|
10
10
|
history = Mysh.input.history
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
#*
|
3
|
+
#* internal/decorate.rb -- mysh internal file name beauty treatments.
|
4
4
|
module Mysh
|
5
5
|
|
6
6
|
#The mysh internal file name beauty treatments.
|
7
|
-
class
|
7
|
+
class Action
|
8
8
|
|
9
9
|
#Make the file name fit the local system.
|
10
10
|
def decorate(name)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#The mysh internal command class level report formatting.
|
4
|
+
class Object
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
#Display an array of items.
|
9
|
+
def display_items(items)
|
10
|
+
puts format_items(items)
|
11
|
+
puts
|
12
|
+
end
|
13
|
+
|
14
|
+
#Format an array of items.
|
15
|
+
#<br>Endemic Code Smells
|
16
|
+
#* :reek:FeatureEnvy
|
17
|
+
def format_items(items, buffer=[])
|
18
|
+
#Determine the width of the tag area.
|
19
|
+
tag_width = items.max_by {|item| item[0].length}[0].length + 1
|
20
|
+
|
21
|
+
#Display the information.
|
22
|
+
items.each {|item| format_item(item, buffer, tag_width) }
|
23
|
+
|
24
|
+
buffer
|
25
|
+
end
|
26
|
+
|
27
|
+
#Display one item.
|
28
|
+
def display_item(item, tag_width=nil)
|
29
|
+
puts format_item(item, [], tag_width)
|
30
|
+
puts
|
31
|
+
end
|
32
|
+
|
33
|
+
#Format one item.
|
34
|
+
#<br>Endemic Code Smells
|
35
|
+
#* :reek:UtilityFunction
|
36
|
+
def format_item(item, buffer=[], tag_width)
|
37
|
+
tag = item[0]
|
38
|
+
|
39
|
+
item[1].each do |detail|
|
40
|
+
buffer << "#{tag.ljust(tag_width)} #{detail}"
|
41
|
+
tag = ""
|
42
|
+
end
|
43
|
+
|
44
|
+
buffer
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* internal/manage.rb -- Manage mysh internal commands.
|
4
|
+
module Mysh
|
5
|
+
|
6
|
+
#Set up the command library hash.
|
7
|
+
COMMANDS = ActionPool.new
|
8
|
+
|
9
|
+
#Parse a command string for use by commands.
|
10
|
+
def self.parse_command(str)
|
11
|
+
result = Mysh.parse_args(str.chomp)
|
12
|
+
|
13
|
+
[COMMANDS[result.shift], result]
|
14
|
+
end
|
15
|
+
|
16
|
+
#Execute an internal command
|
17
|
+
def self.execute(str)
|
18
|
+
unless str[0] == ' '
|
19
|
+
command, args = parse_command(str.chomp)
|
20
|
+
|
21
|
+
if (command)
|
22
|
+
command.execute(args)
|
23
|
+
:internal
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
#Try to execute the string as an internal command.
|
29
|
+
def self.try_execute_internal_command(str)
|
30
|
+
execute(str)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
data/lib/mysh/internal.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
6
|
-
require_relative '
|
7
|
-
require_relative '
|
8
|
-
require_relative '
|
9
|
-
require_relative 'support/decorate'
|
10
|
-
require_relative 'support/handlebars'
|
3
|
+
require_relative 'internal/actions/actions_path'
|
4
|
+
require_relative 'internal/action'
|
5
|
+
require_relative 'internal/action_pool'
|
6
|
+
require_relative 'internal/manage'
|
7
|
+
require_relative 'internal/format'
|
8
|
+
require_relative 'internal/decorate'
|
11
9
|
|
12
10
|
#Load up the internal commands!
|
13
|
-
Dir[Mysh::
|
11
|
+
Dir[Mysh::Action::ACTIONS_PATH + '*.rb'].each {|file| require file }
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* user_input/handlebars.rb -- Handlebar embedded ruby support.
|
4
|
+
class Object
|
5
|
+
|
6
|
+
#Process a string with embedded Ruby code.
|
7
|
+
def eval_handlebars(str)
|
8
|
+
loop do
|
9
|
+
pre_match, match, post_match = str.partition(/{{.*?}}/m)
|
10
|
+
|
11
|
+
return pre_match if match.empty?
|
12
|
+
|
13
|
+
result = instance_eval(code = match[2...-2])
|
14
|
+
|
15
|
+
str = pre_match + (result unless code.end_with?("#")).to_s + post_match
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#Expand a file with embedded ruby handlebars.
|
20
|
+
def eval_handlebar_file(name)
|
21
|
+
eval_handlebars(IO.read(name))
|
22
|
+
end
|
23
|
+
|
24
|
+
#Show a file with embedded ruby handlebars.
|
25
|
+
def show_handlebar_file(name)
|
26
|
+
puts eval_handlebar_file(name)
|
27
|
+
rescue Interrupt, StandardError, ScriptError => err
|
28
|
+
puts "Error in file: #{name}\n#{err.class}: #{err}"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* user_input/parse.rb -- mysh general parser.
|
4
|
+
module Mysh
|
5
|
+
|
6
|
+
#Parse a string into components.
|
7
|
+
#<br>Endemic Code Smells
|
8
|
+
#* :reek:TooManyStatements
|
9
|
+
def self.parse_args(input)
|
10
|
+
result, read_point = [], input.chars.each
|
11
|
+
|
12
|
+
loop do
|
13
|
+
next_parse_char = read_point.next
|
14
|
+
|
15
|
+
if next_parse_char == '"'
|
16
|
+
result.concat(get_string(read_point))
|
17
|
+
elsif next_parse_char != ' '
|
18
|
+
result.concat(get_parameter(next_parse_char, read_point))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
#Get a string parameter.
|
28
|
+
#<br>Endemic Code Smells
|
29
|
+
#* :reek:TooManyStatements
|
30
|
+
def self.get_string(read_point)
|
31
|
+
result = ""
|
32
|
+
|
33
|
+
loop do
|
34
|
+
next_str_char = read_point.next
|
35
|
+
|
36
|
+
break if next_str_char == '"'
|
37
|
+
|
38
|
+
result << next_str_char
|
39
|
+
end
|
40
|
+
|
41
|
+
[result]
|
42
|
+
end
|
43
|
+
|
44
|
+
#Get a parameter.
|
45
|
+
#<br>Endemic Code Smells
|
46
|
+
#* :reek:TooManyStatements
|
47
|
+
def self.get_parameter(first_char, read_point)
|
48
|
+
result = first_char
|
49
|
+
|
50
|
+
loop do
|
51
|
+
next_parm_char = read_point.next
|
52
|
+
|
53
|
+
if next_parm_char == '"'
|
54
|
+
return [result].concat(get_string(read_point))
|
55
|
+
elsif next_parm_char == ' '
|
56
|
+
break
|
57
|
+
else
|
58
|
+
result << next_parm_char
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
[result]
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -8,13 +8,14 @@ module Mysh
|
|
8
8
|
|
9
9
|
#Create a new file/folder auto-data source. NOP
|
10
10
|
def initialize(options)
|
11
|
+
@prefix = options[:prefix]
|
11
12
|
@auto_source = MiniReadline::AutoFileSource.new(options)
|
12
13
|
@quote_source = MiniReadline::QuotedFileFolderSource.new(options)
|
13
14
|
end
|
14
15
|
|
15
16
|
#Construct a new data list for auto-complete
|
16
17
|
def rebuild(str)
|
17
|
-
@active_source = str[0] == '=' ? @quote_source : @auto_source
|
18
|
+
@active_source = (@prefix || str[0]) == '=' ? @quote_source : @auto_source
|
18
19
|
@active_source.rebuild(str)
|
19
20
|
end
|
20
21
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'user_input/smart_source'
|
4
|
+
require_relative 'user_input/parse'
|
5
|
+
require_relative 'user_input/handlebars'
|
6
|
+
|
7
|
+
#* user_input.rb -- Get a command from the user.
|
8
|
+
module Mysh
|
9
|
+
|
10
|
+
#Get one command from the user.
|
11
|
+
def self.get_command
|
12
|
+
input = @input.readline(prompt: 'mysh>')
|
13
|
+
get_command_extra(input)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
#Get any continuations of the inputs
|
19
|
+
def self.get_command_extra(str)
|
20
|
+
if /\\\s*$/ =~ str
|
21
|
+
parms = {prompt: 'mysh\\', prefix: str[0] }
|
22
|
+
get_command_extra($PREMATCH + "\n" + @input.readline(parms))
|
23
|
+
else
|
24
|
+
str
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
#Get the user input ready.
|
30
|
+
def self.init_input
|
31
|
+
@input = MiniReadline::Readline.new(history: true,
|
32
|
+
eoi_detect: true,
|
33
|
+
auto_complete: true,
|
34
|
+
auto_source: SmartSource)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
|
data/lib/mysh/version.rb
CHANGED
data/lib/mysh.rb
CHANGED
@@ -7,7 +7,7 @@ require 'mini_readline'
|
|
7
7
|
require 'vls'
|
8
8
|
require 'in_array'
|
9
9
|
|
10
|
-
require_relative 'mysh/
|
10
|
+
require_relative 'mysh/user_input'
|
11
11
|
require_relative 'mysh/expression'
|
12
12
|
require_relative 'mysh/internal'
|
13
13
|
require_relative 'mysh/external_ruby'
|
@@ -25,36 +25,25 @@ module Mysh
|
|
25
25
|
#<br>Endemic Code Smells
|
26
26
|
#* :reek:TooManyStatements
|
27
27
|
def self.run
|
28
|
-
|
28
|
+
reset_host
|
29
|
+
init_input
|
29
30
|
|
30
31
|
loop do
|
31
|
-
input = @input.readline(prompt: 'mysh>')
|
32
|
-
|
33
32
|
begin
|
34
|
-
@exec_host.
|
35
|
-
Command.execute(input) ||
|
36
|
-
ruby_execute(input) ||
|
37
|
-
system(input)
|
38
|
-
rescue Interrupt => err
|
39
|
-
puts err
|
40
|
-
end
|
41
|
-
end
|
33
|
+
input = @exec_host.eval_handlebars(get_command)
|
42
34
|
|
43
|
-
|
44
|
-
|
35
|
+
try_execute_ruby_expression(input) ||
|
36
|
+
try_execute_internal_command(input) ||
|
37
|
+
try_execute_external_ruby(input) ||
|
38
|
+
system(input)
|
45
39
|
|
46
|
-
|
47
|
-
|
48
|
-
reset_host
|
49
|
-
@input = MiniReadline::Readline.new(history: true,
|
50
|
-
eoi_detect: true,
|
51
|
-
auto_complete: true,
|
52
|
-
auto_source: SmartSource)
|
53
|
-
end
|
40
|
+
rescue MiniReadlineEOI
|
41
|
+
break
|
54
42
|
|
55
|
-
|
56
|
-
|
57
|
-
|
43
|
+
rescue Interrupt, StandardError, ScriptError => err
|
44
|
+
puts err, err.backtrace
|
45
|
+
end
|
46
|
+
end
|
58
47
|
end
|
59
48
|
|
60
49
|
end
|
data/mysh.reek
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
---
|
2
|
+
Attribute:
|
3
|
+
enabled: false
|
4
|
+
exclude: []
|
5
|
+
BooleanParameter:
|
6
|
+
enabled: true
|
7
|
+
exclude: []
|
8
|
+
ClassVariable:
|
9
|
+
enabled: true
|
10
|
+
exclude: []
|
11
|
+
ControlParameter:
|
12
|
+
enabled: true
|
13
|
+
exclude: []
|
14
|
+
DataClump:
|
15
|
+
enabled: true
|
16
|
+
exclude: []
|
17
|
+
max_copies: 2
|
18
|
+
min_clump_size: 2
|
19
|
+
DuplicateMethodCall:
|
20
|
+
enabled: true
|
21
|
+
exclude: []
|
22
|
+
max_calls: 1
|
23
|
+
allow_calls: []
|
24
|
+
FeatureEnvy:
|
25
|
+
enabled: true
|
26
|
+
exclude: []
|
27
|
+
IrresponsibleModule:
|
28
|
+
enabled: true
|
29
|
+
exclude: []
|
30
|
+
LongParameterList:
|
31
|
+
enabled: true
|
32
|
+
exclude: []
|
33
|
+
max_params: 3
|
34
|
+
overrides:
|
35
|
+
initialize:
|
36
|
+
max_params: 5
|
37
|
+
LongYieldList:
|
38
|
+
enabled: true
|
39
|
+
exclude: []
|
40
|
+
max_params: 3
|
41
|
+
NestedIterators:
|
42
|
+
enabled: true
|
43
|
+
exclude: []
|
44
|
+
max_allowed_nesting: 1
|
45
|
+
ignore_iterators: []
|
46
|
+
NilCheck:
|
47
|
+
enabled: true
|
48
|
+
exclude: []
|
49
|
+
PrimaDonnaMethod:
|
50
|
+
enabled: true
|
51
|
+
exclude: []
|
52
|
+
RepeatedConditional:
|
53
|
+
enabled: true
|
54
|
+
exclude: []
|
55
|
+
max_ifs: 2
|
56
|
+
TooManyInstanceVariables:
|
57
|
+
enabled: true
|
58
|
+
exclude: []
|
59
|
+
max_instance_variables: 9
|
60
|
+
TooManyMethods:
|
61
|
+
enabled: true
|
62
|
+
exclude: []
|
63
|
+
max_methods: 25
|
64
|
+
TooManyStatements:
|
65
|
+
enabled: true
|
66
|
+
exclude:
|
67
|
+
- initialize
|
68
|
+
max_statements: 5
|
69
|
+
UncommunicativeMethodName:
|
70
|
+
enabled: true
|
71
|
+
exclude: []
|
72
|
+
reject:
|
73
|
+
- !ruby/regexp /^[a-z]$/
|
74
|
+
- !ruby/regexp /[0-9]$/
|
75
|
+
- !ruby/regexp /[A-Z]/
|
76
|
+
accept: []
|
77
|
+
UncommunicativeModuleName:
|
78
|
+
enabled: true
|
79
|
+
exclude: []
|
80
|
+
reject:
|
81
|
+
- !ruby/regexp /^.$/
|
82
|
+
- !ruby/regexp /[0-9]$/
|
83
|
+
accept:
|
84
|
+
- Inline::C
|
85
|
+
UncommunicativeParameterName:
|
86
|
+
enabled: true
|
87
|
+
exclude: []
|
88
|
+
reject:
|
89
|
+
- !ruby/regexp /^.$/
|
90
|
+
- !ruby/regexp /[0-9]$/
|
91
|
+
- !ruby/regexp /[A-Z]/
|
92
|
+
- !ruby/regexp /^_/
|
93
|
+
accept: []
|
94
|
+
UncommunicativeVariableName:
|
95
|
+
enabled: true
|
96
|
+
exclude: []
|
97
|
+
reject:
|
98
|
+
- !ruby/regexp /^.$/
|
99
|
+
- !ruby/regexp /[0-9]$/
|
100
|
+
- !ruby/regexp /[A-Z]/
|
101
|
+
accept:
|
102
|
+
- _
|
103
|
+
UnusedParameters:
|
104
|
+
enabled: true
|
105
|
+
exclude: []
|
106
|
+
UtilityFunction:
|
107
|
+
enabled: true
|
108
|
+
exclude: []
|
109
|
+
max_helper_calls: 1
|
110
|
+
UnusedPrivateMethod:
|
111
|
+
enabled: false
|
112
|
+
exclude: []
|
data/rakefile.rb
CHANGED
@@ -10,7 +10,7 @@ RDoc::Task.new do |rdoc|
|
|
10
10
|
rdoc.rdoc_dir = "rdoc"
|
11
11
|
|
12
12
|
#List out all the files to be documented.
|
13
|
-
rdoc.rdoc_files.include("lib/**/*.rb", "license.txt"
|
13
|
+
rdoc.rdoc_files.include("lib/**/*.rb", "license.txt")
|
14
14
|
|
15
15
|
#Set a title.
|
16
16
|
rdoc.options << '--title' << 'My Shell Gem Internals'
|
data/tests/my_shell_tests.rb
CHANGED
@@ -13,32 +13,32 @@ class MyShellTester < Minitest::Test
|
|
13
13
|
|
14
14
|
def test_that_module_entities_exists
|
15
15
|
assert_equal(Module, Mysh.class)
|
16
|
-
assert_equal(Class, Mysh::
|
16
|
+
assert_equal(Class, Mysh::Action.class)
|
17
17
|
assert_equal(Class, Mysh::ExecHost.class)
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_for_internal_commands
|
21
|
-
assert(Mysh::
|
22
|
-
assert(Mysh::
|
21
|
+
assert(Mysh::COMMANDS['exit'], "The exit command is missing.")
|
22
|
+
assert(Mysh::COMMANDS['quit'], "The quit command is missing.")
|
23
23
|
|
24
|
-
assert(Mysh::
|
25
|
-
assert(Mysh::
|
24
|
+
assert(Mysh::COMMANDS['history'], "The history command is missing.")
|
25
|
+
assert(Mysh::COMMANDS['!'], "The ! command is missing.")
|
26
26
|
|
27
|
-
assert(Mysh::
|
28
|
-
assert(Mysh::
|
27
|
+
assert(Mysh::COMMANDS['help'], "The help command is missing.")
|
28
|
+
assert(Mysh::COMMANDS['?'], "The ? command is missing.")
|
29
29
|
|
30
|
-
assert(Mysh::
|
31
|
-
assert(Mysh::
|
30
|
+
assert(Mysh::COMMANDS['cd'], "The cd command is missing.")
|
31
|
+
assert(Mysh::COMMANDS['pwd'], "The pwd command is missing.")
|
32
32
|
|
33
|
-
assert_raises { Mysh::
|
33
|
+
assert_raises { Mysh::COMMANDS.add_alias('blam', 'shazzam') }
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_handlebars
|
37
|
-
cmd = Mysh::Command::COMMANDS['help']
|
38
|
-
|
39
37
|
assert_equal("ABC 123 DEF",
|
40
|
-
|
38
|
+
eval_handlebars("ABC {{ (1..3).to_a.join }} DEF"))
|
41
39
|
|
40
|
+
assert_equal("ABC", eval_handlebars("{{ 'ABC' }}"))
|
41
|
+
assert_equal("", eval_handlebars("{{ 'ABC' #}}"))
|
42
42
|
end
|
43
43
|
|
44
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mysh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -151,28 +151,31 @@ files:
|
|
151
151
|
- README.md
|
152
152
|
- bin/mysh
|
153
153
|
- lib/mysh.rb
|
154
|
-
- lib/mysh/commands/cd.rb
|
155
|
-
- lib/mysh/commands/command_path.rb
|
156
|
-
- lib/mysh/commands/exit.rb
|
157
|
-
- lib/mysh/commands/help.rb
|
158
|
-
- lib/mysh/commands/help.txt
|
159
|
-
- lib/mysh/commands/help_expr.txt
|
160
|
-
- lib/mysh/commands/help_help.txt
|
161
|
-
- lib/mysh/commands/help_math.txt
|
162
|
-
- lib/mysh/commands/history.rb
|
163
154
|
- lib/mysh/expression.rb
|
155
|
+
- lib/mysh/expression/lineage.rb
|
164
156
|
- lib/mysh/external_ruby.rb
|
165
157
|
- lib/mysh/internal.rb
|
166
|
-
- lib/mysh/
|
167
|
-
- lib/mysh/
|
168
|
-
- lib/mysh/
|
169
|
-
- lib/mysh/
|
170
|
-
- lib/mysh/
|
171
|
-
- lib/mysh/
|
172
|
-
- lib/mysh/
|
173
|
-
- lib/mysh/
|
158
|
+
- lib/mysh/internal/action.rb
|
159
|
+
- lib/mysh/internal/action_pool.rb
|
160
|
+
- lib/mysh/internal/actions/actions_path.rb
|
161
|
+
- lib/mysh/internal/actions/cd.rb
|
162
|
+
- lib/mysh/internal/actions/exit.rb
|
163
|
+
- lib/mysh/internal/actions/help.rb
|
164
|
+
- lib/mysh/internal/actions/help.txt
|
165
|
+
- lib/mysh/internal/actions/help_expr.txt
|
166
|
+
- lib/mysh/internal/actions/help_help.txt
|
167
|
+
- lib/mysh/internal/actions/help_math.txt
|
168
|
+
- lib/mysh/internal/actions/history.rb
|
169
|
+
- lib/mysh/internal/decorate.rb
|
170
|
+
- lib/mysh/internal/format.rb
|
171
|
+
- lib/mysh/internal/manage.rb
|
172
|
+
- lib/mysh/user_input.rb
|
173
|
+
- lib/mysh/user_input/handlebars.rb
|
174
|
+
- lib/mysh/user_input/parse.rb
|
175
|
+
- lib/mysh/user_input/smart_source.rb
|
174
176
|
- lib/mysh/version.rb
|
175
177
|
- mysh.gemspec
|
178
|
+
- mysh.reek
|
176
179
|
- rakefile.rb
|
177
180
|
- reek.txt
|
178
181
|
- test.rb
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
#* commands/command_path.rb -- A convenient hook to the command folder.
|
4
|
-
module Mysh
|
5
|
-
|
6
|
-
#* commands/command_path.rb -- A convenient hook to the command folder.
|
7
|
-
class Command
|
8
|
-
|
9
|
-
#Capture this folder's name.
|
10
|
-
COMMAND_PATH = File.dirname(__FILE__) + "/"
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
data/lib/mysh/support/format.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
#* support/format.rb -- Format mysh internal reports.
|
4
|
-
module Mysh
|
5
|
-
|
6
|
-
#The mysh internal command class level report formatting.
|
7
|
-
class Command
|
8
|
-
|
9
|
-
#Display an array of items.
|
10
|
-
def display_items(items)
|
11
|
-
puts format_items(items)
|
12
|
-
puts
|
13
|
-
end
|
14
|
-
|
15
|
-
#Format an array of items.
|
16
|
-
#<br>Endemic Code Smells
|
17
|
-
#* :reek:FeatureEnvy
|
18
|
-
def format_items(items, buffer=[])
|
19
|
-
#Determine the width of the tag area.
|
20
|
-
tag_width = items.max_by {|item| item[0].length}[0].length + 1
|
21
|
-
|
22
|
-
#Display the information.
|
23
|
-
items.each {|item| format_item(item, buffer, tag_width) }
|
24
|
-
|
25
|
-
buffer
|
26
|
-
end
|
27
|
-
|
28
|
-
#Display one item.
|
29
|
-
def display_item(item, tag_width=nil)
|
30
|
-
puts format_item(item, [], tag_width)
|
31
|
-
puts
|
32
|
-
end
|
33
|
-
|
34
|
-
#Format one item.
|
35
|
-
#<br>Endemic Code Smells
|
36
|
-
#* :reek:UtilityFunction
|
37
|
-
def format_item(item, buffer=[], tag_width)
|
38
|
-
tag = item[0]
|
39
|
-
|
40
|
-
item[1].each do |detail|
|
41
|
-
buffer << "#{tag.ljust(tag_width)} #{detail}"
|
42
|
-
tag = ""
|
43
|
-
end
|
44
|
-
|
45
|
-
buffer
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
#* support/handlebars.rb -- Allow text files to embed ruby code.
|
4
|
-
module Mysh
|
5
|
-
|
6
|
-
#The mysh embedded ruby text formatting.
|
7
|
-
class Command
|
8
|
-
|
9
|
-
#Process a string with embedded Ruby code.
|
10
|
-
def expand_handlebars(str)
|
11
|
-
loop do
|
12
|
-
pre_match, match, post_match = str.partition(/{{.*?}}/m)
|
13
|
-
|
14
|
-
return pre_match if match.empty?
|
15
|
-
|
16
|
-
str = pre_match + eval(match[2...-2]) + post_match
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
#Show a file with embedded ruby handlebars.
|
21
|
-
def show_file(name)
|
22
|
-
puts expand_handlebars(IO.read(full_name = COMMAND_PATH + name))
|
23
|
-
rescue StandardError, ScriptError => err
|
24
|
-
puts "Error in file: #{full_name}\n#{err.class}: #{err}"
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
|
data/lib/mysh/support/manage.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
#* support/manage.rb -- Manage mysh internal commands.
|
4
|
-
module Mysh
|
5
|
-
|
6
|
-
#The mysh internal command class level data and methods.
|
7
|
-
class Command
|
8
|
-
|
9
|
-
#Set up the command library hash.
|
10
|
-
COMMANDS = CommandPool.new
|
11
|
-
|
12
|
-
#Execute an internal command
|
13
|
-
def self.execute(str)
|
14
|
-
unless str[0] == ' '
|
15
|
-
command, args = parse(str.chomp)
|
16
|
-
|
17
|
-
if (command)
|
18
|
-
command.execute(args)
|
19
|
-
:internal
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
data/lib/mysh/support/parse.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
#* support/parse.rb -- mysh internal command parser.
|
4
|
-
module Mysh
|
5
|
-
|
6
|
-
#The mysh internal command instance data and methods.
|
7
|
-
class Command
|
8
|
-
|
9
|
-
#Parse a command string for use by commands.
|
10
|
-
#<br>Endemic Code Smells
|
11
|
-
#* :reek:TooManyStatements
|
12
|
-
def self.parse(input)
|
13
|
-
result, read_point = [], input.chars.each
|
14
|
-
|
15
|
-
loop do
|
16
|
-
next_parse_char = read_point.next
|
17
|
-
|
18
|
-
if next_parse_char == '"'
|
19
|
-
result.concat(get_string(read_point))
|
20
|
-
elsif next_parse_char != ' '
|
21
|
-
result.concat(get_parameter(next_parse_char, read_point))
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
[COMMANDS[result.shift], result]
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
#Get a string parameter.
|
31
|
-
#<br>Endemic Code Smells
|
32
|
-
#* :reek:TooManyStatements
|
33
|
-
def self.get_string(read_point)
|
34
|
-
result = ""
|
35
|
-
|
36
|
-
loop do
|
37
|
-
next_str_char = read_point.next
|
38
|
-
|
39
|
-
break if next_str_char == '"'
|
40
|
-
|
41
|
-
result << next_str_char
|
42
|
-
end
|
43
|
-
|
44
|
-
[result]
|
45
|
-
end
|
46
|
-
|
47
|
-
#Get a parameter.
|
48
|
-
#<br>Endemic Code Smells
|
49
|
-
#* :reek:TooManyStatements
|
50
|
-
def self.get_parameter(first_char, read_point)
|
51
|
-
result = first_char
|
52
|
-
|
53
|
-
loop do
|
54
|
-
next_parm_char = read_point.next
|
55
|
-
|
56
|
-
if next_parm_char == '"'
|
57
|
-
return [result].concat(get_string(read_point))
|
58
|
-
elsif next_parm_char == ' '
|
59
|
-
break
|
60
|
-
else
|
61
|
-
result << next_parm_char
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
[result]
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|