Guest User

Untitled

a guest
Nov 10th, 2012
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.57 KB | None | 0 0
  1. #!/usr/bin/env ruby
  2. # echo.rb - display a line of text
  3. VERSION = "0.2"
  4.  
  5. # help and version
  6. if ARGV.size == 1
  7. if ARGV[0] == "--help"
  8. puts <<-'END'
  9. Usage: /usr/bin/echo [SHORT-OPTION]... [STRING]...
  10. or: /usr/bin/echo LONG-OPTION
  11. Echo the STRING(s) to standard output.
  12.  
  13. -n do not output the trailing newline
  14. -e enable interpretation of backslash escapes
  15. -E disable interpretation of backslash escapes (default)
  16. --help display this help and exit
  17. --version output version information and exit
  18.  
  19. If -e is in effect, the following sequences are recognized:
  20.  
  21. \\ backslash
  22. \a alert (BEL)
  23. \b backspace
  24. \c produce no further output
  25. \e escape
  26. \f form feed
  27. \n new line
  28. \r carriage return
  29. \t horizontal tab
  30. \v vertical tab
  31. \0NNN byte with octal value NNN (1 to 3 digits)
  32. \xHH byte with hexadecimal value HH (1 to 2 digits)
  33.  
  34. NOTE: your shell may have its own version of echo, which usually supersedes
  35. the version described here. Please refer to your shell's documentation
  36. for details about the options it supports.
  37. END
  38. exit
  39. end
  40.  
  41. if ARGV[0] == "--version"
  42. puts File.split(__FILE__).last + " " + VERSION
  43. exit
  44. end
  45. end
  46.  
  47. def isxdigit?(c)
  48. case c
  49. when '0'..'9', 'A'..'F', 'a'..'f'
  50. return true
  51. else
  52. return false
  53. end
  54. end
  55.  
  56. def isoctal?(c)
  57. case c
  58. when '0'..'7'
  59. return true
  60. else
  61. return false
  62. end
  63. end
  64.  
  65. # Convert C from hexadecimal character to integer.
  66. def hextobin(c)
  67. case c
  68. when 'a', 'A'
  69. return 10
  70. when 'b', 'B'
  71. return 11
  72. when 'c', 'C'
  73. return 12
  74. when 'd', 'D'
  75. return 13
  76. when 'e', 'E'
  77. return 14
  78. when 'f', 'F'
  79. return 15
  80. else
  81. return c.to_i
  82. end
  83. end
  84.  
  85. def just_echo
  86. # join tmpargv array (with valid options removed) into a string
  87. argv = $tmpargv.join(" ")
  88.  
  89. if $do_v9
  90. i = 0
  91. while i < argv.size do
  92. c = argv[i]
  93. if c == "\\"
  94. i += 1 # next char
  95. case argv[i]
  96. when 'a'
  97. c = "\a"
  98. when 'b'
  99. c = "\b"
  100. when 'c'
  101. exit
  102. when 'e'
  103. c = "\x1B"
  104. when 'f'
  105. c = "\f"
  106. when 'n'
  107. c = "\n"
  108. when 'r'
  109. c = "\r"
  110. when 't'
  111. c = "\t"
  112. when 'v'
  113. c = "\v"
  114.  
  115. # handle HEX
  116. when 'x'
  117. # FIRST DIGIT
  118. i += 1 # next char
  119. ch = argv[i]
  120. if ! isxdigit?(ch)
  121. print "\\x"
  122. next
  123. end
  124.  
  125. # 2ND DIGIT
  126. i += 1 # next char
  127. c = hextobin(ch)
  128. ch = argv[i]
  129. if isxdigit?(ch)
  130. c = c * 16 + hextobin(ch)
  131. c = c.chr
  132. else # 2nd hex digit invalid, print both
  133. print c.chr
  134. print ch
  135. i += 1 # next char
  136. next
  137. end
  138.  
  139. # handle octal
  140. when '0', '1', '2', '3', '4', '5', '6', '7'
  141. if argv[i] == '0'
  142. i += 1 # next char
  143. end
  144.  
  145. c = 0
  146.  
  147. # 1st or 2nd digit
  148. if isoctal?(argv[i])
  149. c = c * 8 + argv[i].to_i
  150. else
  151. print c.chr
  152. next
  153. end
  154.  
  155. # 2nd or 3rd digit
  156. i += 1 # next char
  157. if isoctal?(argv[i])
  158. c = c * 8 + argv[i].to_i
  159. else
  160. print c.chr
  161. next
  162. end
  163.  
  164. # 3rd or 4th digit
  165. i += 1 # next char
  166. if isoctal?(argv[i])
  167. c = c * 8 + argv[i].to_i
  168. else
  169. print c.chr
  170. next
  171. end
  172.  
  173. # convert decimal value to character
  174. c = c.chr
  175.  
  176. #when '\\'
  177. end
  178. end
  179. print c
  180. i += 1 # next char
  181. end
  182.  
  183. else # don't handle backslash escapes (default)
  184. print argv
  185. end
  186.  
  187. puts if $display_return # newline (default)
  188. exit
  189. end
  190.  
  191. # copy ARGV because we may remove some elements from it
  192. # and then our loop will be fucked
  193. $tmpargv = ARGV.dup # make sure to use DUP!
  194.  
  195. # Global options
  196. $do_v9, $display_return = false, true
  197.  
  198. # Parse arguments
  199. ARGV.each do |arg|
  200. if arg[0] == '-'
  201. temp = arg[1..-1] # remove '-'
  202.  
  203. # validate all options after '-'
  204. temp.each_char do |c|
  205. case c
  206. when 'e', 'E', 'n'
  207. # next
  208. else
  209. # Any char besides 'e', 'E', 'n' and the whole string is echoed
  210. just_echo
  211. end
  212. end
  213.  
  214. # If we get here, all options in temp are valid
  215. temp.each_char do |c|
  216. case c
  217. when 'e'
  218. $do_v9 = true
  219. when 'E'
  220. $do_v9 = false
  221. when 'n'
  222. $display_return = false
  223. end
  224. end
  225.  
  226. # REMOVE VALID arg from tmpargv
  227. # ARGV controls loop iteration so we can't delete from it
  228. $tmpargv.slice!($tmpargv.index(arg))
  229.  
  230. else
  231. just_echo # if the string doesn't begin with '-' we are done parsing
  232. end
  233. end
Advertisement
Add Comment
Please, Sign In to add comment