def Run(self, cmd_val): arg, arg_r = flag_spec.ParseOilCmdVal('write', cmd_val) #print(arg) if arg.unicode == 'raw': bit8_display = qsn.BIT8_UTF8 elif arg.unicode == 'u': bit8_display = qsn.BIT8_U_ESCAPE elif arg.unicode == 'x': bit8_display = qsn.BIT8_X_ESCAPE else: raise AssertionError() i = 0 while not arg_r.AtEnd(): if i != 0: sys.stdout.write(arg.sep) s = arg_r.Peek() if arg.qsn: s = qsn.maybe_encode(s, bit8_display) sys.stdout.write(s) arg_r.Next() i += 1 if arg.n: pass elif arg.end: sys.stdout.write(arg.end) return 0
def _PrintArgv(argv, buf): # type: (List[str], mylib.BufWriter) -> None """Uses QSN encoding without $ for xtrace_rich.""" for arg in argv: buf.write(' ') buf.write(qsn.maybe_encode(arg)) buf.write('\n')
def _TrySingleLine(node, f, max_chars): # type: (hnode_t, ColorOutput, int) -> bool """Try printing on a single line. Args: node: homogeneous tree node f: ColorOutput instance max_chars: maximum number of characters to print on THIS line indent: current indent level Returns: ok: whether it fit on the line of the given size. If False, you can't use the value of f. """ UP_node = node # for mycpp tag = node.tag_() if tag == hnode_e.Leaf: node = cast(hnode__Leaf, UP_node) f.PushColor(node.color) f.write(qsn.maybe_encode(node.s)) f.PopColor() elif tag == hnode_e.External: node = cast(hnode__External, UP_node) f.PushColor(color_e.External) f.write(repr(node.obj)) f.PopColor() elif tag == hnode_e.Array: node = cast(hnode__Array, UP_node) # Can we fit the WHOLE array on the line? f.write('[') for i, item in enumerate(node.children): if i != 0: f.write(' ') if not _TrySingleLine(item, f, max_chars): return False f.write(']') elif tag == hnode_e.Record: node = cast(hnode__Record, UP_node) return _TrySingleLineObj(node, f, max_chars) else: raise AssertionError(hnode_str(tag)) # Take into account the last char. num_chars_so_far = f.NumChars() if num_chars_so_far > max_chars: return False return True
def PopMessage(self, label, arg): # type: (str, Optional[str]) -> None """For synchronous constructs that aren't processes.""" self._Dec() buf = self._RichTraceBegin('<') if buf: buf.write(label) if arg is not None: buf.write(' ') buf.write(qsn.maybe_encode(arg)) buf.write('\n') self.f.write(buf.getvalue())
def PrintNode(self, node, f, indent): # type: (hnode_t, ColorOutput, int) -> None """Second step of printing: turn homogeneous tree into a colored string. Args: node: homogeneous tree node f: ColorOutput instance. max_col: don't print past this column number on ANY line NOTE: See asdl/run.sh line-length-hist for a test of this. It's approximate. TODO: Use the terminal width. """ ind = ' ' * indent # Try printing on a single line single_f = f.NewTempBuffer() single_f.write(ind) if _TrySingleLine(node, single_f, self.max_col - indent): s, num_chars = single_f.GetRaw() # extra unpacking for mycpp f.WriteRaw((s, num_chars)) return UP_node = node # for mycpp tag = node.tag_() if tag == hnode_e.Leaf: node = cast(hnode__Leaf, UP_node) f.PushColor(node.color) f.write(qsn.maybe_encode(node.s)) f.PopColor() elif tag == hnode_e.External: node = cast(hnode__External, UP_node) f.PushColor(color_e.External) f.write(repr(node.obj)) f.PopColor() elif tag == hnode_e.Record: node = cast(hnode__Record, UP_node) self._PrintRecord(node, f, indent) else: raise AssertionError(hnode_str(tag))
def Run(self, cmd_val): arg_r = args.Reader(cmd_val.argv, spids=cmd_val.arg_spids) arg_r.Next() # skip 'echo' arg, _ = WRITE_SPEC.Parse(arg_r) #print(arg) if arg.unicode == 'raw': bit8_display = qsn.BIT8_UTF8 elif arg.unicode == 'u': bit8_display = qsn.BIT8_U_ESCAPE elif arg.unicode == 'x': bit8_display = qsn.BIT8_X_ESCAPE else: raise AssertionError() i = 0 while not arg_r.AtEnd(): if i != 0: sys.stdout.write(arg.sep) s = arg_r.Peek() if arg.qsn: s = qsn.maybe_encode(s, bit8_display) sys.stdout.write(s) arg_r.Next() i += 1 if arg.n: pass elif arg.end: sys.stdout.write(arg.end) return 0
def testEncodeDecode(self): CASES = [ '', '"', "'", '\\', 'hello', '_my-report.c', 'a+b', '()[]{}', 'one two', 'one\ttwo\r\n', "'one\0two'", '\x00\x01', #'\xbc\x00\x01', u'[\u03bc]'.encode('utf-8'), '\xce\xbc', '\xce\xbc\xce', # char then byte '\xce\xce\xbc', # byte then char # two invalid bytes, then restart '\xce\xce\xce\xbe', # 1 2 3 4 u'\u007a \u03bb \u4e09 \U0001f618'.encode('utf-8'), # \xce\bb \xe4\xb8\x89 \xf0\x9f\x98\x98 '\xe4\xb8\x89', '\xe4\xb8a', '\xe4a', '\xf0\x9f\x98\x98', '\xf0\x9f\x98.', '\xf0\x9f.', '\xf0.', ] for c in CASES: print('-----') print('CASE %r' % c) print() sh = qsn.maybe_shell_encode(c) q1 = qsn.maybe_encode(c) q2 = qsn.encode(c) qu = qsn.encode(c, bit8_display=qsn.BIT8_U_ESCAPE) qx = qsn.encode(c, bit8_display=qsn.BIT8_X_ESCAPE) print(' sh %s' % sh) print('qsn maybe %s' % q1) print('qsn UTF-8 %s' % q2) print('qsn U %s' % qu) print('qsn X %s' % qx) decoded1 = qsn.decode(q1) print('decoded = %r' % decoded1) print() decoded2 = qsn.decode(q2) decoded_u = qsn.decode(qu) decoded_x = qsn.decode(qx) self.assertEqual(c, decoded1) self.assertEqual(c, decoded2) self.assertEqual(c, decoded_u) self.assertEqual(c, decoded_x) # character codes, e.g. U+03bc UNICODE_CASES = [ 0x03bc, 0x0001, 0x00010000, ] for c in UNICODE_CASES: print(repr(c)) s = unichr(c).encode('utf-8') # what it should decode to q = '\\u{%0x}' % c # the QSTR encoding print('qsn %s' % q) decoded = qsn.decode(q) print('decoded = %r' % decoded) print() self.assertEqual(s, decoded) OTHER_CASES = [ # '"' and '\"' are the same thing "'\\\"'", # never encoded, but still legal "", # Would have quotes "%%%", ] for c in OTHER_CASES: decoded = qsn.decode(c) print('qsn = %s' % c) print('decoded = %r' % decoded) print() # note: INVALID = [ # lone backslash "'\\", # illegal escape. Python's JSON library also disallows this, e.g. with # ValueError: Invalid \escape: line 1 column 2 (char 1) "'\\a'", ] for c in INVALID: try: s = qsn.decode(c) except RuntimeError as e: print(e) else: self.fail('Expected %r to be invalid' % c)
def Run(self, cmd_val): arg, arg_r = flag_spec.ParseOilCmdVal('repr', cmd_val) action, action_spid = arg_r.ReadRequired2( 'expected an action (proc, .cell, etc.)') # Actions that print unstable formats start with '.' if action == '.cell': argv, spids = arg_r.Rest2() status = 0 for i, name in enumerate(argv): if name.startswith(':'): name = name[1:] if not match.IsValidVarName(name): raise error.Usage('got invalid variable name %r' % name, span_id=spids[i]) cell = self.mem.GetCell(name) if cell is None: self.errfmt.Print("Couldn't find a variable named %r" % name, span_id=spids[i]) status = 1 else: sys.stdout.write('%s = ' % name) cell.PrettyPrint() # may be color sys.stdout.write('\n') elif action == 'proc': names, spids = arg_r.Rest2() if len(names): for i, name in enumerate(names): node = self.procs.get(name) if node is None: self.errfmt.Print_('Invalid proc %r' % name, span_id=spids[i]) return 1 else: names = sorted(self.procs) # QTSV header print('proc_name\tdoc_comment') for name in names: node = self.procs[name] # must exist body = node.body # TODO: not just command__ShFunction, but command__Proc! doc = '' if body.tag_() == command_e.BraceGroup: if body.doc_token: span_id = body.doc_token.span_id span = self.arena.GetLineSpan(span_id) line = self.arena.GetLine(span.line_id) # 1 to remove leading space doc = line[span.col+1 : span.col + span.length] # No limits on proc names print('%s\t%s' % (qsn.maybe_encode(name), qsn.maybe_encode(doc))) status = 0 else: e_usage('got invalid action %r' % action, span_id=action_spid) return status