Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env ruby
- # echo.rb - display a line of text
- VERSION = "0.2"
- # help and version
- if ARGV.size == 1
- if ARGV[0] == "--help"
- puts <<-'END'
- Usage: /usr/bin/echo [SHORT-OPTION]... [STRING]...
- or: /usr/bin/echo LONG-OPTION
- Echo the STRING(s) to standard output.
- -n do not output the trailing newline
- -e enable interpretation of backslash escapes
- -E disable interpretation of backslash escapes (default)
- --help display this help and exit
- --version output version information and exit
- If -e is in effect, the following sequences are recognized:
- \\ backslash
- \a alert (BEL)
- \b backspace
- \c produce no further output
- \e escape
- \f form feed
- \n new line
- \r carriage return
- \t horizontal tab
- \v vertical tab
- \0NNN byte with octal value NNN (1 to 3 digits)
- \xHH byte with hexadecimal value HH (1 to 2 digits)
- NOTE: your shell may have its own version of echo, which usually supersedes
- the version described here. Please refer to your shell's documentation
- for details about the options it supports.
- END
- exit
- end
- if ARGV[0] == "--version"
- puts File.split(__FILE__).last + " " + VERSION
- exit
- end
- end
- def isxdigit?(c)
- case c
- when '0'..'9', 'A'..'F', 'a'..'f'
- return true
- else
- return false
- end
- end
- def isoctal?(c)
- case c
- when '0'..'7'
- return true
- else
- return false
- end
- end
- # Convert C from hexadecimal character to integer.
- def hextobin(c)
- case c
- when 'a', 'A'
- return 10
- when 'b', 'B'
- return 11
- when 'c', 'C'
- return 12
- when 'd', 'D'
- return 13
- when 'e', 'E'
- return 14
- when 'f', 'F'
- return 15
- else
- return c.to_i
- end
- end
- def just_echo
- # join tmpargv array (with valid options removed) into a string
- argv = $tmpargv.join(" ")
- if $do_v9
- i = 0
- while i < argv.size do
- c = argv[i]
- if c == "\\"
- i += 1 # next char
- case argv[i]
- when 'a'
- c = "\a"
- when 'b'
- c = "\b"
- when 'c'
- exit
- when 'e'
- c = "\x1B"
- when 'f'
- c = "\f"
- when 'n'
- c = "\n"
- when 'r'
- c = "\r"
- when 't'
- c = "\t"
- when 'v'
- c = "\v"
- # handle HEX
- when 'x'
- # FIRST DIGIT
- i += 1 # next char
- ch = argv[i]
- if ! isxdigit?(ch)
- print "\\x"
- next
- end
- # 2ND DIGIT
- i += 1 # next char
- c = hextobin(ch)
- ch = argv[i]
- if isxdigit?(ch)
- c = c * 16 + hextobin(ch)
- c = c.chr
- else # 2nd hex digit invalid, print both
- print c.chr
- print ch
- i += 1 # next char
- next
- end
- # handle octal
- when '0', '1', '2', '3', '4', '5', '6', '7'
- if argv[i] == '0'
- i += 1 # next char
- end
- c = 0
- # 1st or 2nd digit
- if isoctal?(argv[i])
- c = c * 8 + argv[i].to_i
- else
- print c.chr
- next
- end
- # 2nd or 3rd digit
- i += 1 # next char
- if isoctal?(argv[i])
- c = c * 8 + argv[i].to_i
- else
- print c.chr
- next
- end
- # 3rd or 4th digit
- i += 1 # next char
- if isoctal?(argv[i])
- c = c * 8 + argv[i].to_i
- else
- print c.chr
- next
- end
- # convert decimal value to character
- c = c.chr
- #when '\\'
- end
- end
- print c
- i += 1 # next char
- end
- else # don't handle backslash escapes (default)
- print argv
- end
- puts if $display_return # newline (default)
- exit
- end
- # copy ARGV because we may remove some elements from it
- # and then our loop will be fucked
- $tmpargv = ARGV.dup # make sure to use DUP!
- # Global options
- $do_v9, $display_return = false, true
- # Parse arguments
- ARGV.each do |arg|
- if arg[0] == '-'
- temp = arg[1..-1] # remove '-'
- # validate all options after '-'
- temp.each_char do |c|
- case c
- when 'e', 'E', 'n'
- # next
- else
- # Any char besides 'e', 'E', 'n' and the whole string is echoed
- just_echo
- end
- end
- # If we get here, all options in temp are valid
- temp.each_char do |c|
- case c
- when 'e'
- $do_v9 = true
- when 'E'
- $do_v9 = false
- when 'n'
- $display_return = false
- end
- end
- # REMOVE VALID arg from tmpargv
- # ARGV controls loop iteration so we can't delete from it
- $tmpargv.slice!($tmpargv.index(arg))
- else
- just_echo # if the string doesn't begin with '-' we are done parsing
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment