def _ParseFormatStr(self): # type: () -> printf_part_t """ fmt production """ self._Next(lex_mode_e.PrintfPercent) # move past % part = printf_part.Percent() while self.token_type in (Id.Format_Flag, Id.Format_Zero): # space and + could be implemented flag = self.cur_token.val if flag in '# +': p_die("osh printf doesn't support the %r flag", flag, token=self.cur_token) part.flags.append(self.cur_token) self._Next(lex_mode_e.PrintfPercent) if self.token_type in (Id.Format_Num, Id.Format_Star): part.width = self.cur_token self._Next(lex_mode_e.PrintfPercent) if self.token_type == Id.Format_Dot: part.precision = self.cur_token self._Next(lex_mode_e.PrintfPercent) # past dot if self.token_type in (Id.Format_Num, Id.Format_Star, Id.Format_Zero): part.precision = self.cur_token self._Next(lex_mode_e.PrintfPercent) if self.token_type in (Id.Format_Type, Id.Format_Time): part.type = self.cur_token # ADDITIONAL VALIDATION outside the "grammar". if part.type.val in 'eEfFgG': p_die("osh printf doesn't support floating point", token=part.type) # These two could be implemented. %c needs utf-8 decoding. if part.type.val == 'c': p_die("osh printf doesn't support single characters (bytes)", token=part.type) elif self.token_type == Id.Unknown_Tok: p_die('Invalid printf format character', token=self.cur_token) else: p_die('Expected a printf format character', token=self.cur_token) # Do this check AFTER the floating point checks if part.precision and part.type.val[-1] not in 'fsT': p_die("printf precision can't be specified with type %r" % part.type.val, token=part.precision) return part
def _ParseFormatStr(self): # type: () -> printf_part_t self._Next(lex_mode_e.PrintfPercent) # move past % part = printf_part.Percent() if self.token_type == Id.Format_Flag: part.flag = self.cur_token self._Next(lex_mode_e.PrintfPercent) # space and + could be implemented flag = part.flag.val if flag in '# +': p_die("osh printf doesn't support the %r flag", flag, token=part.flag) if self.token_type == Id.Format_Num: part.width = self.cur_token self._Next(lex_mode_e.PrintfPercent) if self.token_type == Id.Format_Dot: self._Next(lex_mode_e.PrintfPercent) # past dot part.precision = self.cur_token self._Next(lex_mode_e.PrintfPercent) if self.token_type == Id.Format_Type: part.type = self.cur_token # ADDITIONAL VALIDATION outside the "grammar". if part.type.val in 'eEfFgG': p_die("osh printf doesn't support floating point", token=part.type) # These two could be implemented. %c needs utf-8 decoding. if part.type.val == 'b': p_die( "osh printf doesn't support backslash escaping (try $'\\n')", token=part.type) if part.type.val == 'c': p_die("osh printf doesn't support single characters (bytes)", token=part.type) else: if self.cur_token.val: msg = 'Invalid printf format character' else: # for printf '%' msg = 'Expected a printf format character' p_die(msg, token=self.cur_token) # Do this check AFTER the floating point checks if part.precision and part.type.val not in 'fs': p_die("precision can't be specified when here", token=part.precision) return part