Module: Naksh::Syntax::Bash

Extended by:
Parser
Defined in:
lib/naksh/syntax/bash.rb,
lib/rust/parsers/bash.rb

Class Method Summary collapse

Methods included from Parser

run, run_standard

Class Method Details

.clean_command(com_str) ⇒ Object

it wraps the actual command in single quotes



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/naksh/syntax/bash.rb', line 129

def Bash.clean_command(com_str)

  #remove leading whitespace
  com_str.sub!(/\A\s+/,'')

  #need to evaluate variables before this
  com_str.sub!(/\A'([^']+)'(\S*)/,'\'\1\2\'')
  com_str.sub!(/\A"([^"]+)"(\S*)/,'\'\1\2\'')
  com_str.sub!(/\A(\S+)/,'\'\1\'')

  #I think this section may be useless, not belong here, etc.
  invalid_starting_characters=%w[; | #]
  invalid_starting_characters.each do |chr|
    if (/^/+chr).match(com_str)
      raise ParseError,_('commands cannot begin with the following character: %s')%[chr]
    end
  end

  com_str
end

.clean_pipeline(pipe_str) ⇒ Object

should call any tidying methods helpful to other steps currently returns input



113
114
115
# File 'lib/naksh/syntax/bash.rb', line 113

def Bash.clean_pipeline(pipe_str)
  pipe_str
end

.clean_script(script_str) ⇒ Object

should call any tidying methods helpful to other steps currently just removes comments



88
89
90
# File 'lib/naksh/syntax/bash.rb', line 88

def Bash.clean_script(script_str)
  Bash.remove_comments(script_str)
end

.complete(command) ⇒ Object



202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/rust/parsers/bash.rb', line 202

def Bash.complete(command)
  possible = []
  builtin_commands.each do |com|
    possible << com if com.to_s.match command # only if it matches
    break if com[0] > command[0] # break if we're after it
  end
  if possible.length > 1 # if we found multiple matches
    raise Hell, "Too ambiguous of a command" # raise Hell
  else # else its size = 1
    return possible[0] # return the chosen one
  end
end

.complete?(script_str) ⇒ Boolean

may return false if the script is syntactically incomplete see Bash.try_execute

Returns:

  • (Boolean)


60
61
62
# File 'lib/naksh/syntax/bash.rb', line 60

def Bash.complete? script_str
  true
end

.execute(script_str) ⇒ Object

executes a script entrance point



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/naksh/syntax/bash.rb', line 27

def Bash.execute script_str

  #keeps output from commands from showing on the command line
  Naksh.buffer.silence

  #splits at ';'
  Bash.split_script(Bash.clean_script(script_str)).each do |pipeline|

    #splits at '|'
    pipeline = Bash.split_pipeline(Bash.clean_pipeline(pipeline))
    pipeline.each_index do |i|

      #allow direct output if this is the last commmand in the pipeline
      Naksh.buffer.speak if i==pipeline.length-1

      #split into [command_name,['array','of','space',"separated arguments"]]
      d = Bash.split_command(Bash.clean_command(pipeline[i]))

      #send command unless the command is all whitespace or something silly
      Naksh.send_command(*d) if d

      #tell the buffer another command is about to begin
      Naksh.buffer.next unless i==pipeline.length-1

    end
  end
  true
end

.find_unescaped_nonstring(str, search_char, starting_index = 0) ⇒ Object

I couldn’t make a good regexp version, but THIS WORKS takes into account escaping () and quotation (“‘)

Raises:

  • (ArgumentError)


153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/naksh/syntax/bash.rb', line 153

def Bash.find_unescaped_nonstring(str,search_char,starting_index=0)
  search_char=search_char.chr if search_char.kind_of? Integer
  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
  return nil if str.length<=starting_index
  escaped=false
  string_open=false
  starting_index.upto str.length-1 do |i|
    next if i<starting_index
    if str[i].chr==search_char
      return i unless escaped or string_open
    elsif str[i].chr=="\\"
      escaped=!escaped
    elsif not escaped and str[i].chr=='\''
      case string_open
        when false
          string_open='\''
        when '\''
          string_open=false
      end
    elsif not escaped and str[i].chr=='"'
      case string_open
        when false
          string_open='"'
        when '"'
          string_open=false
      end
    else
      escaped=false
    end
  end
  #Regexp requires zero-width negative lookbehind
  #/\A(([^\\](\\\\)*)(("[^"]*")|('[^']*'))*/<<re
  nil
end

.remove_comments(script_str) ⇒ Object

should remove all comments from script



94
95
96
97
98
99
100
101
102
# File 'lib/naksh/syntax/bash.rb', line 94

def Bash.remove_comments(script_str)
  loop do
    start=Bash.find_unescaped_nonstring(script_str,'#')
    return script_str unless start
    close=Bash.find_unescaped_nonstring(script_str,"\n",start)
    return script_str[0..start-1] unless close
    script_str=script_str[0..start-1]<<script_str[close+1..script_str.length]
  end
end

.split_command(com_str) ⇒ Object

Raises:

  • (RuntimeError)


189
190
191
192
193
194
195
196
# File 'lib/naksh/syntax/bash.rb', line 189

def Bash.split_command(com_str)
  return false if not com_str or com_str.empty?
  com_arr=Bash.split_unescaped(com_str,' ')
  com_arr=[com_str,[]] unless com_arr
  raise RuntimeError,'single quotes should have been added around command earlier in processing'<<"\ncommand as recieved = #{com_str.inspect}, class=#{com_str.class}" unless /\A'.*'\z/.match(com_arr[0])
  com_arr[0].replace(com_arr[0][1,com_arr[0].length-2])
  [com_arr[0],com_arr[1,com_arr.length]]
end

.split_pipeline(str) ⇒ Object

separate commands in a pipeline



119
120
121
# File 'lib/naksh/syntax/bash.rb', line 119

def Bash.split_pipeline(str)
  Bash.split_unescaped(str,'|')
end

.split_script(str) ⇒ Object

splits a script into wholly independant segments



106
107
108
# File 'lib/naksh/syntax/bash.rb', line 106

def Bash.split_script(str)
  Bash.split_unescaped(str,';')
end

.split_unescaped(str, char) ⇒ Object

returns an Array of Strings, made of str split at every unescaped instance of char not enclosed in an unescaped string delimiter (‘“)



203
204
205
206
207
208
209
210
211
212
213
# File 'lib/naksh/syntax/bash.rb', line 203

def Bash.split_unescaped(str,char)
  result=[]
  split_index=0
  loop do
    split_index=Bash.find_unescaped_nonstring(str,char)
    return result<<str unless split_index
    result<<str[0,split_index] unless split_index.zero?
    str=str[split_index+1,str.length]
    return result if str.empty?
  end
end

.try_execute(script_str) ⇒ Object

A Naksh syntax module is NOT required to use complete? or try_execute, but it is recommended that is use one of them



78
79
80
81
# File 'lib/naksh/syntax/bash.rb', line 78

def Bash.try_execute script_str
  Bash.execute script_str
  true
end