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