def inspect_char(char)
  return "'\"'" if char=='"'.ord # Don't escape this char (we would in a string)
  "'" + escape_str_char(char) + "'"
end

def escape_str_char(char)
  return "\\0" if char == "\0".ord
  return "\\n" if char == "\n".ord
  return "\\\\" if char == "\\".ord
  return "\\\"" if char == "\"".ord
  return char.to_i.chr if char >= " ".ord && char <= "~".ord # all ascii printables
  return "\\x0%s" % char.to_i.to_s(16) if char < 16 && char >= 0
  return "\\x%s" % (char%256).to_i.to_s(16) if char < 256 && char >= -2
  return "\\%d" % char
end

def parse_char(s)
  ans,offset=parse_str_char(s,0)
  raise "internal char error" if ans.size != 1 || offset != s.size
  ans[0].ord
end

def parse_str_char(s,i) # parse char in a string starting at position i
  if s[i]=="\\"
    if s.size <= i+1
      ["\\",i+1]
    elsif s[i+1] == "n"
      ["\n",i+2]
    elsif s[i+1] == "0"
      ["\0",i+2]
    elsif s[i+1] == "\\"
      ["\\",i+2]
    elsif s[i+1] == "\""
      ["\"",i+2]
    elsif s[i+1,3] =~ /x[0-9a-fA-F][0-9a-fA-F]/
      [s[i+2,2].to_i(16).chr,i+4]
    else
      ["\\",i+1]
    end
  else
    [s[i],i+1]
  end
end

def parse_str(s)
  i=1 # skip initial "
  r=""
  while i<s.size && s[i] != '"'
    c,i=parse_str_char(s,i)
    r<<c
  end
  [r, s[i..-1]]
end