def __call__(self, cmd_val): arg_r = args.Reader(cmd_val.argv, spids=cmd_val.arg_spids) arg_r.Next() arg, _ = GETLINE_SPEC.Parse(arg_r) if arg.cstr: # TODO: implement it # returns error if it can't decode raise NotImplementedError() var_name, var_spid = arg_r.ReadRequired2('requires a variable name') if var_name.startswith(':'): # optional : sigil var_name = var_name[1:] next_arg, next_spid = arg_r.Peek2() if next_arg is not None: raise args.UsageError('got extra argument', span_id=next_spid) # TODO: use a more efficient function in C line = builtin.ReadLineFromStdin() if not line: # EOF return 1 if not arg.end: if line.endswith('\r\n'): line = line[:-2] elif line.endswith('\n'): line = line[:-1] self.mem.SetVar(sh_lhs_expr.Name(var_name), value.Str(line), (), scope_e.LocalOnly) return 0
def testStdinRedirect(self): waiter = process.Waiter() fd_state = process.FdState(_ERRFMT) PATH = '_tmp/one-two.txt' # Write two lines with open(PATH, 'w') as f: f.write('one\ntwo\n') # Should get the first line twice, because Pop() closes it! r = redirect.PathRedirect(Id.Redir_Less, 0, PATH) fd_state.Push([r], waiter) line1 = builtin.ReadLineFromStdin() fd_state.Pop() fd_state.Push([r], waiter) line2 = builtin.ReadLineFromStdin() fd_state.Pop() # sys.stdin.readline() would erroneously return 'two' because of buffering. self.assertEqual('one\n', line1) self.assertEqual('one\n', line2)