naksh 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +1 -0
- data/COPYING +674 -0
- data/COPYING-DOCS +15 -0
- data/README.md +45 -0
- data/Rakefile +129 -0
- data/TODO +19 -0
- data/bin/naksh +2 -0
- data/data/default.mo +0 -0
- data/data/default.po +16 -0
- data/data/default2.mo +0 -0
- data/data/default2.po +27 -0
- data/data/starter.pot +29 -0
- data/docs/bash_flow.dia +0 -0
- data/docs/gtk_manual.txt +13 -0
- data/docs/master_plan.dia +0 -0
- data/docs/master_plan.png +0 -0
- data/docs/master_plan.svg +74 -0
- data/docs/master_plan.svgz +0 -0
- data/docs/userguide/en/about.xml +42 -0
- data/docs/userguide/en/gnu-fdl-1.2.xml +543 -0
- data/docs/userguide/en/naksh.xml +881 -0
- data/docs/userguide/en/naksh_start_window.png +0 -0
- data/docs/userguide/en/old_naksh.xml +180 -0
- data/docs/userguide/en/userguide-en.omf +37 -0
- data/lib/naksh.rb +165 -0
- data/lib/naksh/buffer.rb +153 -0
- data/lib/naksh/command_handling.rb +117 -0
- data/lib/naksh/commands/bash/README +2 -0
- data/lib/naksh/commands/bash/echo.nkc.rb +50 -0
- data/lib/naksh/commands/bsd.rb +25 -0
- data/lib/naksh/commands/dos.rb +25 -0
- data/lib/naksh/commands/fuse.rb +25 -0
- data/lib/naksh/commands/gnu.rb +30 -0
- data/lib/naksh/commands/gnu/README +2 -0
- data/lib/naksh/commands/gnu/cat.nkc.rb +50 -0
- data/lib/naksh/commands/gnu/cd.nkc.rb +11 -0
- data/lib/naksh/commands/gnu/echo.documentation.json +57 -0
- data/lib/naksh/commands/gnu/echo.documentation.rb +60 -0
- data/lib/naksh/commands/gnu/echo.nkc.rb +52 -0
- data/lib/naksh/commands/gnu/ls.nkc.rb +11 -0
- data/lib/naksh/commands/gnu/mv.nkc.rb +15 -0
- data/lib/naksh/commands/gnu/pwd.nkc.rb +11 -0
- data/lib/naksh/commands/naksh/addpath.nkc.rb +15 -0
- data/lib/naksh/commands/naksh/broken.nkc.rb +10 -0
- data/lib/naksh/commands/naksh/empty.nkc.rb +4 -0
- data/lib/naksh/commands/naksh/exit.nkc.rb +10 -0
- data/lib/naksh/commands/naksh/help.nkc.rb +21 -0
- data/lib/naksh/commands/naksh/man.nkc.rb +8 -0
- data/lib/naksh/commands/ruby.rb +31 -0
- data/lib/naksh/commands/unix.rb +131 -0
- data/lib/naksh/configuration/gconf.rb +51 -0
- data/lib/naksh/configuration/hash.rb +38 -0
- data/lib/naksh/defaults.rb +40 -0
- data/lib/naksh/history.rb +85 -0
- data/lib/naksh/interfaces.rb +59 -0
- data/lib/naksh/interfaces/fox.rb +49 -0
- data/lib/naksh/interfaces/gtk.rb +103 -0
- data/lib/naksh/interfaces/gtk/abtwin.rb +53 -0
- data/lib/naksh/interfaces/gtk/gnomeapp.rb +31 -0
- data/lib/naksh/interfaces/gtk/helpwin.rb +70 -0
- data/lib/naksh/interfaces/gtk/io.rb +94 -0
- data/lib/naksh/interfaces/gtk/mainwin.rb +56 -0
- data/lib/naksh/interfaces/gtk/mainwin/console.rb +121 -0
- data/lib/naksh/interfaces/gtk/mainwin/main_menu.rb +143 -0
- data/lib/naksh/interfaces/gtk/optwin.rb +78 -0
- data/lib/naksh/interfaces/tab.rb +58 -0
- data/lib/naksh/interfaces/wxw.rb +75 -0
- data/lib/naksh/interfaces/wxw/abtwin.rb +38 -0
- data/lib/naksh/interfaces/wxw/helpwin.rb +40 -0
- data/lib/naksh/interfaces/wxw/io.rb +61 -0
- data/lib/naksh/interfaces/wxw/mainwin.rb +42 -0
- data/lib/naksh/interfaces/wxw/mainwin/main_menu.rb +126 -0
- data/lib/naksh/interfaces/wxw/mainwin/sessions.rb +49 -0
- data/lib/naksh/interfaces/wxw/optwin.rb +37 -0
- data/lib/naksh/path_entry.rb +101 -0
- data/lib/naksh/regexp.rb +31 -0
- data/lib/naksh/session.rb +72 -0
- data/lib/naksh/stdlibext.rb +48 -0
- data/lib/naksh/syntax.rb +57 -0
- data/lib/naksh/syntax/bash.rb +219 -0
- data/lib/naksh/syntax/bash/antlr/bottomup.g +24 -0
- data/lib/naksh/syntax/bash/antlr/topdown.g +52 -0
- data/lib/naksh/syntax/bash/dhaka/evaluator.rb +353 -0
- data/lib/naksh/syntax/bash/dhaka/grammar.rb +71 -0
- data/lib/naksh/syntax/bash/dhaka/lexer.rb +52 -0
- data/lib/naksh/syntax/bash/treetop/bash.treetop +17 -0
- data/lib/old/abbr_call.rb +39 -0
- data/lib/old/autocomplete.rb +29 -0
- data/lib/old/command.rb +106 -0
- data/lib/old/command_holder.rb +75 -0
- data/lib/old/commands.rb +24 -0
- data/lib/old/old_executor.rb +95 -0
- data/lib/old/options.rb +31 -0
- data/lib/old/rush.rb +113 -0
- data/lib/old/sortissimo.rb +205 -0
- data/lib/old/systems.rb +25 -0
- data/lib/old/systems/ruby.rb +26 -0
- data/lib/old/un.rb +240 -0
- data/lib/rust/Rakefile +6 -0
- data/lib/rust/commands/builtins.rb +46 -0
- data/lib/rust/commands/builtins/cd.rb +17 -0
- data/lib/rust/commands/builtins/exit.rb +13 -0
- data/lib/rust/commands/builtins/help.rb +14 -0
- data/lib/rust/commands/builtins/parser.rb +13 -0
- data/lib/rust/commands/builtins/pwd.rb +13 -0
- data/lib/rust/commands/builtins/type.rb +13 -0
- data/lib/rust/commands/commands/ls.rb +13 -0
- data/lib/rust/commands/commands/read.rb +13 -0
- data/lib/rust/commands/commands/rm.rb +14 -0
- data/lib/rust/commands/commands/test.rb +20 -0
- data/lib/rust/helpers/array.rb +10 -0
- data/lib/rust/helpers/command_center.rb +78 -0
- data/lib/rust/helpers/constants.rb +58 -0
- data/lib/rust/helpers/io.rb +132 -0
- data/lib/rust/helpers/parser.rb +45 -0
- data/lib/rust/helpers/rush_control.rb +40 -0
- data/lib/rust/helpers/string.rb +50 -0
- data/lib/rust/helpers/trollop.rb +475 -0
- data/lib/rust/parsers/bash.rb +220 -0
- data/lib/rust/parsers/bash/stdlibext.rb +32 -0
- data/lib/rust/parsers/ren.rb +57 -0
- data/lib/rust/rust.rb +75 -0
- data/lib/rust/syntax/command.rb +23 -0
- data/lib/rust/syntax/paths.rb +31 -0
- data/lib/rust/syntax/pipes.rb +148 -0
- data/naksh.gemspec +55 -0
- data/test/naksh/arg_parser.rspec.rb +27 -0
- data/test/naksh/commands/bash/echo.rspec.rb +32 -0
- data/test/naksh/commands/sortlist +127 -0
- data/test/naksh/external_command.rspec.rb +46 -0
- data/test/naksh/send_error.rspec.rb +60 -0
- data/test/naksh/suggest.rspec.rb +38 -0
- data/test/naksh/syntax/bash.rspec.rb +69 -0
- data/test/naksh/syntax/bash/execute.rspec.rb +51 -0
- data/test/naksh/syntax/rspec.rb +63 -0
- data/test/run_rspecs.rb +20 -0
- metadata +217 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/local/bin/ruby
|
|
2
|
+
# 2011 Mahmut Bulut, thefed, and Antonio Salazar
|
|
3
|
+
|
|
4
|
+
# This file is part of Naksh.
|
|
5
|
+
#
|
|
6
|
+
# Naksh is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# Naksh is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with Naksh. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
# this is bash.rb with piping removed
|
|
20
|
+
|
|
21
|
+
require "rubygems"
|
|
22
|
+
require 'gettext'
|
|
23
|
+
#require "../helpers/parser.rb"
|
|
24
|
+
#require "bash/stdlibext.rb"
|
|
25
|
+
#require "../commands/builtins.rb"
|
|
26
|
+
Dir[File.join(File.dirname(__FILE__), "bash/*")].each {|l| require l }
|
|
27
|
+
|
|
28
|
+
module Naksh
|
|
29
|
+
module Syntax
|
|
30
|
+
module Bash
|
|
31
|
+
|
|
32
|
+
extend ::Parser
|
|
33
|
+
#executes a script
|
|
34
|
+
#entrance point
|
|
35
|
+
def Bash.execute(script_str)
|
|
36
|
+
end_res = []
|
|
37
|
+
styles = []
|
|
38
|
+
#splits at ';'
|
|
39
|
+
Bash.split_script(Bash.clean_script(script_str)).each do |pipeline|
|
|
40
|
+
|
|
41
|
+
result=[]
|
|
42
|
+
|
|
43
|
+
#splits at '|'
|
|
44
|
+
pipeline=Bash.split_pipeline(Bash.clean_pipeline(pipeline))
|
|
45
|
+
pipeline.each_index do |i|
|
|
46
|
+
|
|
47
|
+
#split into [command_name,['array','of','space',"separated arguments"]]
|
|
48
|
+
d=Bash.split_command(Bash.clean_command(pipeline[i]))
|
|
49
|
+
|
|
50
|
+
result<<[d[0],d[1]]
|
|
51
|
+
|
|
52
|
+
#if an error gets thrown by a command, just quit
|
|
53
|
+
# return nil if Naksh.stopped?
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
styles = result.map do |part|
|
|
58
|
+
if builtin_commands.include? part[0].strip.to_sym
|
|
59
|
+
:builtin
|
|
60
|
+
else
|
|
61
|
+
:cmd
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end_res.concat result
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
end_res << styles
|
|
69
|
+
print run(*end_res)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
#should call any tidying methods helpful to other steps
|
|
73
|
+
#currently just removes comments
|
|
74
|
+
def Bash.clean_script(script_str)
|
|
75
|
+
Bash.remove_comments(script_str)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
#should remove all comments from script
|
|
80
|
+
def Bash.remove_comments(script_str)
|
|
81
|
+
loop do
|
|
82
|
+
start=Bash.find_unescaped_nonstring(script_str,'#')
|
|
83
|
+
return script_str unless start
|
|
84
|
+
close=Bash.find_unescaped_nonstring(script_str,"\n",start)
|
|
85
|
+
return script_str[0..start-1] unless close
|
|
86
|
+
script_str=script_str[0..start-1]<<script_str[close+1..script_str.length]
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
#splits a script into wholly independant segments
|
|
92
|
+
def Bash.split_script(str)
|
|
93
|
+
Bash.split_unescaped(str,';')
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
#should call any tidying methods helpful to other steps
|
|
98
|
+
#currently returns input
|
|
99
|
+
def Bash.clean_pipeline(pipe_str)
|
|
100
|
+
pipe_str
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
#separate commands in a pipeline
|
|
105
|
+
def Bash.split_pipeline(str)
|
|
106
|
+
Bash.split_unescaped(str,'|')
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
#prepares for Bash.split_command
|
|
111
|
+
#by unifying syntax variations
|
|
112
|
+
#removing excess whitespace, etc
|
|
113
|
+
|
|
114
|
+
#it wraps the actual command in single quotes
|
|
115
|
+
def Bash.clean_command(com_str)
|
|
116
|
+
|
|
117
|
+
#remove leading whitespace
|
|
118
|
+
com_str.sub!(/\A\s+/,'')
|
|
119
|
+
|
|
120
|
+
#need to evaluate variables before this
|
|
121
|
+
com_str.sub!(/\A'([^']+)'(\S*)/,'\'\1\2\'')
|
|
122
|
+
com_str.sub!(/\A"([^"]+)"(\S*)/,'\'\1\2\'')
|
|
123
|
+
com_str.sub!(/\A(\S+)/,'\'\1\'')
|
|
124
|
+
|
|
125
|
+
#I think this section may be useless, not belong here, etc.
|
|
126
|
+
invalid_starting_characters=%w[; | #]
|
|
127
|
+
invalid_starting_characters.each do |chr|
|
|
128
|
+
if (/^/+chr).match(com_str)
|
|
129
|
+
err _('commands cannot begin with the following character')<<' '<<chr
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
com_str
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
#I couldn't make a good regexp version, but THIS WORKS
|
|
138
|
+
#takes into account escaping (\) and quotation ("')
|
|
139
|
+
def Bash.find_unescaped_nonstring(str,search_char,starting_index=0)
|
|
140
|
+
search_char=search_char.chr if search_char.kind_of? Integer
|
|
141
|
+
raise ArgumentError,"Naksh::Syntax::Bash.find_unescaped_nonstring(#{re.inspect},#{str.inspect})" unless search_char.kind_of? String and str.kind_of? String and search_char.length==1 and starting_index.kind_of? Integer
|
|
142
|
+
return nil if str.length<=starting_index
|
|
143
|
+
escaped=false
|
|
144
|
+
string_open=false
|
|
145
|
+
starting_index.upto str.length-1 do |i|
|
|
146
|
+
next if i<starting_index
|
|
147
|
+
if str[i].chr==search_char
|
|
148
|
+
return i unless escaped or string_open
|
|
149
|
+
elsif str[i].chr=="\\"
|
|
150
|
+
escaped=!escaped
|
|
151
|
+
elsif not escaped and str[i].chr=='\''
|
|
152
|
+
case string_open
|
|
153
|
+
when false
|
|
154
|
+
string_open='\''
|
|
155
|
+
when '\''
|
|
156
|
+
string_open=false
|
|
157
|
+
end
|
|
158
|
+
elsif not escaped and str[i].chr=='"'
|
|
159
|
+
case string_open
|
|
160
|
+
when false
|
|
161
|
+
string_open='"'
|
|
162
|
+
when '"'
|
|
163
|
+
string_open=false
|
|
164
|
+
end
|
|
165
|
+
else
|
|
166
|
+
escaped=false
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
#Regexp requires zero-width negative lookbehind
|
|
170
|
+
#/\A(([^\\](\\\\)*)(("[^"]*")|('[^']*'))*/<<re
|
|
171
|
+
nil
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def Bash.split_command(com_str)
|
|
176
|
+
com_arr=Bash.split_unescaped(com_str,' ')
|
|
177
|
+
com_arr=[com_str,[]] unless com_arr
|
|
178
|
+
raise RuntimeError,'single quotes should have been added around command earlier in processing'<<"\ncommand as recieved = #{com_str.inspect}" unless /\A'.*'\z/.match(com_arr[0])
|
|
179
|
+
com_arr[0].replace(com_arr[0][1,com_arr[0].length-2])
|
|
180
|
+
[com_arr[0],com_arr[1,com_arr.length]]
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
#returns an Array of Strings,
|
|
186
|
+
#made of str split at every unescaped instance of char
|
|
187
|
+
#not enclosed in an unescaped string delimiter ('")
|
|
188
|
+
def Bash.split_unescaped(str,char)
|
|
189
|
+
result=[]
|
|
190
|
+
split_index=0
|
|
191
|
+
loop do
|
|
192
|
+
split_index=Bash.find_unescaped_nonstring(str,char)
|
|
193
|
+
return result<<str unless split_index
|
|
194
|
+
result<<str[0,split_index] unless split_index.zero?
|
|
195
|
+
str=str[split_index+1,str.length]
|
|
196
|
+
return result if str.empty?
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def Bash.complete(command)
|
|
203
|
+
possible = []
|
|
204
|
+
builtin_commands.each do |com|
|
|
205
|
+
possible << com if com.to_s.match command # only if it matches
|
|
206
|
+
break if com[0] > command[0] # break if we're after it
|
|
207
|
+
end
|
|
208
|
+
if possible.length > 1 # if we found multiple matches
|
|
209
|
+
raise Hell, "Too ambiguous of a command" # raise Hell
|
|
210
|
+
else # else its size = 1
|
|
211
|
+
return possible[0] # return the chosen one
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
#Naksh::Syntax::Bash.execute('ls | wc -l')
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/local/bin/ruby
|
|
2
|
+
# 2011 Mahmut Bulut
|
|
3
|
+
|
|
4
|
+
# This file is part of Naksh.
|
|
5
|
+
#
|
|
6
|
+
# Naksh is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# Naksh is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with Naksh. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
def Regexp.join(re_list,preserve_options=true)
|
|
20
|
+
raise ArgumentError,"Regexp.join: 1st argument should be an array #{re_list}" unless re_list.respond_to? :collect and re_list.respond_to? :join
|
|
21
|
+
re_list.collect! do |re|
|
|
22
|
+
re= Regexp.new(Regexp.escape(re)) if re.kind_of? String
|
|
23
|
+
re= Regexp.new(re) unless re.kind_of? Regexp
|
|
24
|
+
preserve_options ? re.to_s : '(?:'<<re.source<<')'
|
|
25
|
+
end
|
|
26
|
+
Regexp.compile(re_list.join('').gsub(/\(\?[\w\-]*\:\)/,''))
|
|
27
|
+
end
|
|
28
|
+
class Regexp
|
|
29
|
+
def +(other)
|
|
30
|
+
Regexp.join([self,other],false)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/local/bin/ruby
|
|
2
|
+
#
|
|
3
|
+
# Created by me on 2011-12-15.
|
|
4
|
+
# Copyright (c) 2011. All pwnage reserved.
|
|
5
|
+
|
|
6
|
+
#
|
|
7
|
+
# run_as_ruby is not allowed in Ren
|
|
8
|
+
|
|
9
|
+
module Ren
|
|
10
|
+
class << self
|
|
11
|
+
include Parser
|
|
12
|
+
|
|
13
|
+
def execute(line)
|
|
14
|
+
(eval(line); return) if line.strip.slice(0).chr =~ /!/
|
|
15
|
+
|
|
16
|
+
package = check_for_pipes(line)
|
|
17
|
+
p package
|
|
18
|
+
print run_standard(package[0], package[1])
|
|
19
|
+
|
|
20
|
+
# Gotta catch 'em all
|
|
21
|
+
# rescue NameError => e
|
|
22
|
+
# err "Internal Command Unknown"
|
|
23
|
+
rescue ArgumentError => e
|
|
24
|
+
err "Improper use of command syntax"
|
|
25
|
+
rescue SyntaxError => e
|
|
26
|
+
err "Incorrect Ruby Grammar"
|
|
27
|
+
rescue Errno::ENOENT => e
|
|
28
|
+
err "Command not found"
|
|
29
|
+
rescue => e
|
|
30
|
+
raise e
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def check_for_pipes(line)
|
|
34
|
+
cmd_parts = (line.match('|') ? line.split('|') : [line] ) # check for pipelining
|
|
35
|
+
# because between the pipes,
|
|
36
|
+
# it's nothing but commands
|
|
37
|
+
|
|
38
|
+
clean_whitespace!(cmd_parts)
|
|
39
|
+
|
|
40
|
+
styles = cmd_parts.map do |cmd_part|
|
|
41
|
+
parts = cmd_part.split(' ')
|
|
42
|
+
cmd = parts[0]
|
|
43
|
+
if builtin_commands.include? cmd.strip.to_sym
|
|
44
|
+
:builtin
|
|
45
|
+
else
|
|
46
|
+
:cmd
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
[cmd_parts, styles]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def clean_whitespace!(parts)
|
|
53
|
+
parts.map! {|p| p.strip }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/rust/rust.rb
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/local/bin/ruby
|
|
2
|
+
#
|
|
3
|
+
# Created by me on 2011-12-07.
|
|
4
|
+
# Copyright (c) 2011. All pwnage reserved.
|
|
5
|
+
|
|
6
|
+
require "rubygems"
|
|
7
|
+
require "highline/system_extensions"
|
|
8
|
+
require "shellwords"
|
|
9
|
+
|
|
10
|
+
require "helpers/trollop.rb"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
require "commands/builtins.rb"
|
|
14
|
+
require "syntax/paths.rb"
|
|
15
|
+
require "syntax/pipes.rb"
|
|
16
|
+
require "helpers/array.rb"
|
|
17
|
+
require "helpers/command_center.rb"
|
|
18
|
+
require "helpers/constants.rb"
|
|
19
|
+
require "helpers/io.rb"
|
|
20
|
+
require "helpers/parser.rb"
|
|
21
|
+
require "helpers/string.rb"
|
|
22
|
+
|
|
23
|
+
Dir['parsers/*'].each {|l| require l }
|
|
24
|
+
require "helpers/rush_control.rb" # needs to be loaded AFTER the parsers
|
|
25
|
+
|
|
26
|
+
include HighLine::SystemExtensions
|
|
27
|
+
|
|
28
|
+
class Rust
|
|
29
|
+
|
|
30
|
+
###
|
|
31
|
+
# Used by the parser
|
|
32
|
+
def self.io
|
|
33
|
+
@@io
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def initialize(stdin=$stdin, stdout=$stdout, stderr=$stderr)
|
|
37
|
+
$stdin, $stdout, $stderr = stdin, stdout, stderr
|
|
38
|
+
|
|
39
|
+
$keys ||= {}
|
|
40
|
+
@history = []
|
|
41
|
+
@io = InOut.new(stdin, stdout, stderr, $keys)
|
|
42
|
+
@@io = @io # a nice hack for parser compatiblity
|
|
43
|
+
|
|
44
|
+
run
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def run
|
|
48
|
+
######
|
|
49
|
+
## Read the user's .rustrc file
|
|
50
|
+
if File.exist? "#{ENV['HOME']}/.rustrc"
|
|
51
|
+
CommandCenter.instance_eval(File.read("#{ENV['HOME']}/.rustrc"))
|
|
52
|
+
else
|
|
53
|
+
File.open("#{ENV['HOME']}/.rustrc", 'w')
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
prompt
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def prompt
|
|
61
|
+
line = ''
|
|
62
|
+
loop {
|
|
63
|
+
line += ask($prompt)
|
|
64
|
+
# unless line.slice(-1) =~ /\\/
|
|
65
|
+
@history << line
|
|
66
|
+
$parser.execute line.strip unless line.strip =~ /^$/ # $parser.execute line
|
|
67
|
+
line = ''
|
|
68
|
+
# end
|
|
69
|
+
}
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
Rust.new
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/local/bin/ruby
|
|
2
|
+
#
|
|
3
|
+
# Created by me on 2011-12-07.
|
|
4
|
+
# Copyright (c) 2011. All pwnage reserved.
|
|
5
|
+
|
|
6
|
+
# NO LONGER IN USE
|
|
7
|
+
# BUT USED TO BE USED BY CommandCenter
|
|
8
|
+
|
|
9
|
+
class Command
|
|
10
|
+
|
|
11
|
+
attr_reader :command, :arguments
|
|
12
|
+
|
|
13
|
+
def initialize(name, args, str={:stdin => STDIN, :stdout => STDOUT, :stderr => STDERR})
|
|
14
|
+
@command = name
|
|
15
|
+
@arguments = args
|
|
16
|
+
@streams = { :stdin => str[:in], :stdout => str[:out], :stderr => str[:err] }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run
|
|
20
|
+
exec(@command, @arguments)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/local/bin/ruby
|
|
2
|
+
#
|
|
3
|
+
# Created by me on 2011-12-07.
|
|
4
|
+
# Copyright (c) 2011. All pwnage reserved.
|
|
5
|
+
#$path = ['/bin', '/usr/bin', '/usr/local/bin']
|
|
6
|
+
|
|
7
|
+
module Paths
|
|
8
|
+
class << self
|
|
9
|
+
|
|
10
|
+
############
|
|
11
|
+
public
|
|
12
|
+
############
|
|
13
|
+
|
|
14
|
+
# linear search
|
|
15
|
+
# checks if file if on path
|
|
16
|
+
def on_path? file
|
|
17
|
+
$path.each do |f|
|
|
18
|
+
return f if Dir[File.join(f, file)]
|
|
19
|
+
end
|
|
20
|
+
false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def find_path(file)
|
|
24
|
+
return Dir.pwd + file unless on_path? file
|
|
25
|
+
return File.join(on_path?(file), file)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#p Paths.find_path('ls')
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Created by me on 2011-12-07.
|
|
5
|
+
# Copyright (c) 2011. All pwnage reserved.
|
|
6
|
+
|
|
7
|
+
#require File.join(File.dirname(__FILE__), "../commands/builtins.rb")
|
|
8
|
+
#require File.join(File.dirname(__FILE__), "../helpers/command_center.rb")
|
|
9
|
+
|
|
10
|
+
module Pipes
|
|
11
|
+
|
|
12
|
+
#################
|
|
13
|
+
# Shamelessly borrowed from RS, written by kittensoft
|
|
14
|
+
# This totally rocks, despite it being pretty much popen3/4
|
|
15
|
+
#################
|
|
16
|
+
def self.pipe_to(*args)
|
|
17
|
+
error = nil
|
|
18
|
+
# Custom streams?
|
|
19
|
+
args, ios = if args.last.kind_of? Hash
|
|
20
|
+
[args[0...-1], args.last]
|
|
21
|
+
else
|
|
22
|
+
[args, {}]
|
|
23
|
+
end
|
|
24
|
+
style = ios[:style]
|
|
25
|
+
ios.reject! {|key, i| key == :style }
|
|
26
|
+
|
|
27
|
+
# pipe.first is read, pipe.last is write
|
|
28
|
+
in_pipe, out_pipe, err_pipe = IO.pipe, IO.pipe, IO.pipe
|
|
29
|
+
|
|
30
|
+
# Adjust the pipes if we have custom streams
|
|
31
|
+
ios.each {|n, stream| raise ArgumentError.new("#{n} must be an IO!") unless stream.kind_of? IO}
|
|
32
|
+
|
|
33
|
+
in_pipe[0] = ios[:stdin] if ios[:stdin]
|
|
34
|
+
out_pipe[1] = ios[:stdout] if ios[:stdout]
|
|
35
|
+
err_pipe[1] = ios[:stderr] if ios[:stderr]
|
|
36
|
+
|
|
37
|
+
child = fork do
|
|
38
|
+
# Reconfigure the standard I/O
|
|
39
|
+
in_pipe.last.close # Cannot write to STDIN
|
|
40
|
+
(IO.open(0)).reopen in_pipe.first # Input comes from reading in_pipe
|
|
41
|
+
in_pipe.first.close # Unnecessary, replaced above
|
|
42
|
+
|
|
43
|
+
out_pipe.first.close # Cannot read from STDOUT
|
|
44
|
+
(IO.open(1)).reopen out_pipe.last # Output goes to writing side of out_pipe
|
|
45
|
+
out_pipe.last.close # Close old read
|
|
46
|
+
|
|
47
|
+
err_pipe.first.close # Cannot read from STDERR
|
|
48
|
+
(IO.open(2)).reopen err_pipe.last # Error output goes to writing side of err_pipe
|
|
49
|
+
err_pipe.last.close # Close old read
|
|
50
|
+
|
|
51
|
+
# Run the command with the new environment
|
|
52
|
+
|
|
53
|
+
case style
|
|
54
|
+
when :standard
|
|
55
|
+
::CommandCenter.run_standard(args.join(' '))
|
|
56
|
+
when :ruby
|
|
57
|
+
::CommandCenter.run_as_ruby(args.join(' '))
|
|
58
|
+
when :builtin
|
|
59
|
+
::CommandCenter.run_as_builtin(args.join(' '))
|
|
60
|
+
when :cmd
|
|
61
|
+
arr = ::Shellwords.shellwords(args.join(''))
|
|
62
|
+
cmd = arr.shift
|
|
63
|
+
exec(::Paths.find_path(cmd), *arr)
|
|
64
|
+
end
|
|
65
|
+
end # fork
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# Close unnecessary sides
|
|
69
|
+
# in_pipe.first.close # Cannot read from other program's STDIN
|
|
70
|
+
out_pipe.last.close # Cannot write to other program's STDOUT
|
|
71
|
+
err_pipe.last.close # Cannot write to other program's STDERR
|
|
72
|
+
|
|
73
|
+
# Do not wait for child
|
|
74
|
+
res = [child, in_pipe.last, out_pipe.first, err_pipe.first]
|
|
75
|
+
|
|
76
|
+
# Block-form
|
|
77
|
+
if block_given?
|
|
78
|
+
begin
|
|
79
|
+
value = yield(*res)
|
|
80
|
+
ensure
|
|
81
|
+
Process.waitpid child
|
|
82
|
+
res[1..-1].each {|pipe| pipe.close unless pipe.closed?}
|
|
83
|
+
value
|
|
84
|
+
end
|
|
85
|
+
# Raw
|
|
86
|
+
else
|
|
87
|
+
res
|
|
88
|
+
end # if block_given?
|
|
89
|
+
end # self.pipe_to
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
__END__
|
|
95
|
+
run(["ls", []], ["wc", ["-l"]], [:builtin, :cmd])
|
|
96
|
+
run_standard(["ls", "wc"], [:builtin, :cmd])
|
|
97
|
+
run_standard(["echo foo", "cat", "cat"], [:cmd, :cmd, :cmd])
|
|
98
|
+
|
|
99
|
+
Pipes.pipe_to('ls') {|pid, i, o, e|
|
|
100
|
+
Pipes.pipe_to('wc -l', :stdin => o) {|ppid, ii, oo, ee| oo.read.should.equal res}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
def |(other)
|
|
104
|
+
Pipes.pipe_to(self.to_s) {|p, i, o, e|
|
|
105
|
+
Pipes.pipe_to(other.to_s, :stdin => o) {|pid, in, out, err| say out.read}
|
|
106
|
+
}
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def run_standard(parts, styles)
|
|
110
|
+
# Please note that this will
|
|
111
|
+
# work for even single commands!
|
|
112
|
+
# :stding is STDIN and :stdout is STDOUT
|
|
113
|
+
|
|
114
|
+
# this is the actual pipage
|
|
115
|
+
inp = STDIN
|
|
116
|
+
res = []
|
|
117
|
+
parts.each_with_index do |part, i|
|
|
118
|
+
# pipe_to returns the pid, in, out, and err
|
|
119
|
+
pipes = ::Pipes.pipe_to(part, :stdin => inp, :style => styles[i])
|
|
120
|
+
inp = pipes[2]
|
|
121
|
+
res.concat pipes[1..-1]
|
|
122
|
+
end
|
|
123
|
+
# p res
|
|
124
|
+
puts res[-2].read
|
|
125
|
+
# close them all off
|
|
126
|
+
res.each {|pipe| pipe.close unless pipe.closed? }
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def line(args)
|
|
131
|
+
pipes = []
|
|
132
|
+
pipes << ::Pipes.pipe_to(args[0])
|
|
133
|
+
# pipes << ::Pipes.pipe_to(args[1],:stdin => pipes[0][2])
|
|
134
|
+
::Pipes.pipe_to(args[1], :stdin => pipes[0][2]) {|pid, inp, out, err| puts out.read}
|
|
135
|
+
pipes.each{|p| p[1..-1].each{|l| l.close unless l.closed? } }
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
case style
|
|
140
|
+
when :standard
|
|
141
|
+
CommandCenter.run_standard(args.join(' '))
|
|
142
|
+
when :ruby
|
|
143
|
+
CommandCenter.run_as_ruby(args.join(' '))
|
|
144
|
+
when :builtin
|
|
145
|
+
CommandCenter.run_as_builtin(args.join(' '))
|
|
146
|
+
when :cmd
|
|
147
|
+
exec(*args)
|
|
148
|
+
end
|