class AdLint::Cc1::PrintfFormat::ConversionSpecifier
Attributes
conversion_argument[R]
conversion_specifier_character[R]
field_width[R]
field_width_argument[R]
flags[R]
length_modifier[R]
precision[R]
precision_argument[R]
Public Class Methods
new(fmt, trailing_args, env, consume_args, flags, field_width, prec, len_mod, cs_char)
click to toggle source
Calls superclass method
AdLint::Cc1::PrintfFormat::Directive::new
# File lib/adlint/cc1/format.rb, line 406 def initialize(fmt, trailing_args, env, consume_args, flags, field_width, prec, len_mod, cs_char) super(fmt, consume_args) @flags = flags @field_width = field_width @precision = prec @length_modifier = len_mod @conversion_specifier_character = cs_char if consume_arguments? && @field_width == "*" @field_width_argument = trailing_args.shift else @field_width_argument = nil end if consume_arguments? && @precision == ".*" @precision_argument = trailing_args.shift else @precision_argument = nil end if consume_arguments? @conversion_argument = trailing_args.shift else @conversion_argument = nil end @environment = env end
scan(fmt_str)
click to toggle source
# File lib/adlint/cc1/format.rb, line 339 def self.scan(fmt_str) # NOTE: The ISO C99 standard says; # # 7.19.6.1 The fprintf function # # 4 Each conversion specification is introduced by the character %. # After the %, the following appear in sequence: # # -- Zero or more flags (in any order) that modify the meaning of the # conversion specification. # -- An optional minimum field width. If the converted value has # fewer characters than the field width, it is padded with spaces # (by default) on the left (or right, if the left adjustment flag, # described later, has been given) to the field width. The field # width takes the form of an asterisk * (described later) or a # nonnegative decimal integer. # -- An optional precision that gives the minimum number of digits to # appear for the d, i, o, u, x, and X conversions, the number of # digits to appear after the decimal-point character for a, A, e, # E, f, and F conversions, the maximum number of significant # digits for the g and G conversions, or the maximum number of # bytes to be written for s conversions. The precision takes the # form of a period (.) followed either by an asterisk * (described # later) or by an optional decimal interger; if only the period is # specified, the precision is taken as zero. If a precision # appears with any other conversion specifier, the behavior is # undefined. # -- An optional length modifier that specifies the size of the # argument. # -- A conversion specifier character that specifies the type of # conversion to be applied. if header = fmt_str.slice!(/\A%/) scanned = header else return nil, nil, nil, nil, nil, nil end if flags = fmt_str.slice!(/\A#{flags_re}/) scanned += flags end if field_width = fmt_str.slice!(/\A#{field_width_re}/) scanned += field_width end if prec = fmt_str.slice!(/\A#{precision_re}/) scanned += prec end if len_mod = fmt_str.slice!(/\A#{length_modifier_re}/) scanned += len_mod end if cs_char = fmt_str.slice!(/\A#{cs_char_re}/) scanned += cs_char else # NOTE: If no valid conversion specifier character, force to scan # the heading 1 character as a conversion specifier character. if cs_char = fmt_str.slice!(/\A[a-z]/i) scanned += cs_char end end return scanned, flags, field_width, prec, len_mod, cs_char end
Private Class Methods
cs_char_re()
click to toggle source
# File lib/adlint/cc1/format.rb, line 601 def self.cs_char_re # NOTE: The ISO C99 standard says; # # 7.19.6.1 The fprintf function # # 8 The conversion specifiers and their meanings are: # # d,i The int argument is converted to signed decimal in the # style [-]dddd. The precision specifies the minimum number # of digits to appear; if the value being converted can be # represented in fewer digits, it is expanded with leading # zeros. The default precision is 1. The result of # converting a zero value with a precision of zero is no # characters. # o,u,x,X The unsigned int argument is converted to unsigned octal # (o), unsigned decimal (u), or unsigned hexadecimal notation # (x or X) in the style dddd; the letters abcdef are used for # x conversion and the letters ABCDEF for X conversion. The # precision specifies the minimum number of digits to appear; # if the value being converted can be represented in fewer # digits, it is expanded with leading zeros. The default # precision in 1. The result of converting a zero value with # a precision of zero is no characters. # f,F A double argument representing a floating-point number is # converted to decimal notation in the style [-]ddd.ddd, # where the number of digits after the decimal-point # character is equal to the precision specification. If the # precision is missing, it is taken as 6; if the precision is # zero and the # flag is not specified, no decimal-point # character appears. If a decimal-point character appears, # at least one digit appears before it. The value is rounded # to the appropriate number of digits. # A double argument representing an infinity is converted in # one of the styles [-]inf or [-]infinity -- which style is # implementation-defined. A double argument representing a # NaN is converted in one of the styles [-]nan or # [-]nan(n-char-sequence) -- which style, and the meaning of # any n-char-sequence, is implementation-defined. The F # conversion specifier produces INF, INFINITY, or NAN instead # of inf, infinity, or nan, respectively. # e,E A double argument representing a floating-point number is # converted in the style [-]d.ddde[+-]dd, where there is one # digit (which is nonzero if the argument is nonzero) before # the decimal-point character and the number of digits after # it is equal to the precision; if the precision is missing, # it is taken as 6; if the precision is zero and the # flag # is not specified, no decimal-point character appears. The # value is rounded to the appropriate number of digits. The # E conversion specifier produces a number with E instead of # e introducing the exponent. The exponent always contains # at least two digits, and only as many more digits as # necessary to represent the exponent. If the value is zero, # the exponent is zero. # g,G A double argument representing a floating-point number is # converted in style f or e (or in style F or E in the case # of a G conversion specifier), depending on the value # converted and the precision. Let P equal the precision if # nonzero, 6 if the precision is omitted, or 1 if the # precision is zero. Then, if a conversion with style E # would have an exponent of X: # -- if P > X >= -4, the conversion is which style f (or F) # and precision P - (X + 1). # -- otherwise, the conversion is with style e (or E) and # precision P - 1. # Finally, unless the # flag is used, any trailing zeros are # removed from the fractional portion of the result and the # decimal-point character is removed if there is no # fractional portion remaining. # A double argument representing an infinity or NaN is # converted in the style of an f or F conversion specifier. # a,A A double argument representing a floating-point number is # converted in the style [-]0xh.hhhhp[+-]d, where there is # one hexadecimal digit (which is nonzero if the argument is # a normalized floating-point number and is otherwise # unspecified) before the decimal-point character and the # number of hexadecimal digits after it is equal to the # precision; if the precision is missing and FLT_RADIX is a # power of 2, then the precision is sufficient for an exact # representation of the value; if the precision is missing # and FLT_RADIX is not a power of 2, then the precision is # sufficient to distinguish values of type double, except # that trailing zeros may be omitted; if the precision is # zero and the # flag is not specified, no decimal-point # character appears. The letters abcdef are used for a # conversion and the letters ABCDEF for A conversion. The A # conversion specifier produces a number with X and P instead # of x and p. The exponent always contains at least one # digit, and only as many more digits as necessary to # represent the decimal exponent of 2. If the value is zero, # the exponent is zero. # c If no l length modifier is present, the int argument is # converted to an unsigned char, and the resulting character # is written. # s If no l length modifier is present, the argument shall be a # pointer to the initial element of an array of character # type. Characters from the array are written up to (but not # including) the terminating null character. If the # precision is specified, no more than that many bytes are # written. If the precision is not specified or is greater # than the size of the array, the array shall contain a null # character. # If an l length modifier is present, the argument shall be a # pointer to the initial element of an array of wchar_t type. # Wide characters from the array are converted to multibyte # characters (each as if by a call to the wcrtomb function, # with the conversion state described by an mbstate_t object # initialized to zero before the first wide character is # converted) up to and including a terminating null wide # character. The resulting multibyte characters are written # up to (but not including) the terminating null character # (byte). If no precision is specified, the array shall # contain a null wide character. If a precision is # specified, no more than that many bytes are written # (including shift sequence, if any), and the array shall # contain a null wide character if, to equal the multibyte # character sequence length given by the precision, the # function would need to access a wide character one past the # end of the array. In no case is a partial multibyte # character written. # p The argument shall be a pointer to void. The value of the # pointer is converted to a sequence of printing characters, # in an implementation-defined manner. # n The argument shall be a pointer to signed integer into # which is written the number of characters written to the # output stream so far by this call to fprintf. No argument # is converted, but one is consumed. If the conversion # specification includes any flags, a field width, or a # precision, the behavior is undefined. # % A % character is written. No argument is converted. The # complete conversion specification shall be %%. /[diouxXfFeEgGaAcspn%]/ end
field_width_re()
click to toggle source
# File lib/adlint/cc1/format.rb, line 539 def self.field_width_re /(?:\*|[1-9][0-9]*)?/ end
flags_re()
click to toggle source
# File lib/adlint/cc1/format.rb, line 498 def self.flags_re # NOTE: The ISO C99 standard says; # # 7.19.6.1 The fprintf function # # 6 The flag characters and their meaning are: # # - The result of the conversion is left-justified within the # field. (It is right-justified if this flag is not specified.) # + The result of a signed conversion always begins with a plus # or minus sign. (It begins with a sign only when a negative # value is converted if this flag is not specified.) # space If the first character of a signed conversion is not a sign, # or if a signed conversion results in no characters, a space # is prefixed to the result. If the space and + flags both # appear, the space flag is ignored. # # The result is converted to an "alternative form". For o # conversion, it increases the precision, if an only if # necessary, to force the first digit of the result to be a # zero (if the value and precision are both 0, a single 0 is # printed). For x (or X) conversion, a nonzero result has 0x # (or 0X) prefixed to it. For a, A, e, E, f, F, g, and G # conversions, the result of converting a floating-point number # always contains a decimal-point character, even if no digits # follow it. (Normally, a decimal-point character appears in # the result of these conversions only if a digit follows it.) # For g and G conversions, trailing zeros are not removed from # the result. For other conversions, the behavior is # undefined. # 0 For d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversions, # leading zeros (following any indication of sign or base) are # used to pad to the field width rather than performing space # padding, except when converting an infinity or NaN. If the 0 # and - flags both appear, the 0 flag is ignored. For d, i, o, # u, x, and X conversions, if a precision is specified, the 0 # flag is ignored. For other conversions, the behavior is # undefined. /[-+ #0]*/ end
length_modifier_re()
click to toggle source
# File lib/adlint/cc1/format.rb, line 549 def self.length_modifier_re # NOTE: The ISO C99 standard says; # # 7.19.6.1 The fprintf function # # 7 The length modifiers and their meanings are: # # hh Specifies that a following d, i, o, u, x, or X conversion # specifier applies to a signed char or unsigned char argument # (the argument will have been promoted according to the integer # promotions, but its value shall be converted to signed char or # unsigned char before printing); or that a following n # conversion specifier applies to a pointer to a signed char # argument. # h Specifies that a following d, i, o, u, x, or X conversion # specifier applies to a short int or unsigned short int # argument (the argument will have been promoted according to # the integer promotions, but its value shall be converted to # short int or unsigned short int before printing); or that a # following n conversion specifier applies to a pointer to a # short int argument. # l Specifies that a following d, i, o, u, x, or X conversion # specifier applies to a long int or unsigned long int argument; # that a following n conversion specifier applies to a pointer # to a long int argument; that a following c conversion # specifier applies to a wint_t argument; that a following s # conversion specifier applies to a pointer to a wchar_t # argument; or has no effect on a following a, A, e, E, f, F, g, # or G conversion specifier. # ll Specifies that a following d, i, o, u, x, or X conversion # specifier applies to a long long int or unsigned long long int # argument; or that a following n conversion specifier applies # to a pointer to a long long int argument. # j Specifies that a following d, i, o, u, x, or X conversion # specifier applies to an intmax_t or uintmax_t argument; or # that a following n conversion specifier applies to a pointer # to an intmax_t argument. # z Specifies that a following d, i, o, u, x, or X conversion # specifier applies to a size_t or the corresponding signed # integer type argument; or that a following n conversion # specifier applies to a pointer to a signed integer type # corresponding to size_t argument. # t Specifies that a following d, i, o, u, x, or X conversion # specifier applies to a ptrdiff_t or the corresponding unsigned # integer type argument; or that a following n conversion # specifier applies to a pointer to a ptrdiff_t argument. # L Specifies that a following a, A, e, E, f, F, g, or G # conversion specifier applies to a long double argument. /(?:h+|l+|j|z|t|L)?/ end
precision_re()
click to toggle source
# File lib/adlint/cc1/format.rb, line 544 def self.precision_re /(?:\.\*|\.[1-9][0-9]*)?/ end
Public Instance Methods
conversion_specifier?()
click to toggle source
# File lib/adlint/cc1/format.rb, line 437 def conversion_specifier? true end
field_width_value()
click to toggle source
# File lib/adlint/cc1/format.rb, line 454 def field_width_value case @field_width when "*" # TODO: Should support the parameterized field width. 1 when /\A[1-9][0-9]*\z/ @field_width.to_i else 1 end end
precision_value()
click to toggle source
# File lib/adlint/cc1/format.rb, line 466 def precision_value # NOTE: The ISO C99 standard says; # # 7.19.6.1 The fprintf function # # 4 Each conversion specification is introduced by the character %. # After the %, the following appear in sequence: # # -- An optional precision that gives the minimum number of digits to # appear for the d, i, o, u, x, and X conversions, the number of # digits to appear after the decimal-point character for a, A, e, # E, f, and F conversions, the maximum number of significant # digits for the g and G conversions, or the maximum number of # bytes to be written for s conversions. The precision takes the # form of a period (.) followed either by an asterisk * (described # later) or by an optional decimal interger; if only the period is # specified, the precision is taken as zero. If a precision # appears with any other conversion specifier, the behavior is # undefined. case @precision when "." 0 when ".*" # TODO: Should support the parameterized precision. default_precision_value when /\A\.([1-9][0-9]*)\z/ $1.to_i else default_precision_value end end
undefined?()
click to toggle source
# File lib/adlint/cc1/format.rb, line 441 def undefined? false end
Private Instance Methods
default_precision_value()
click to toggle source
# File lib/adlint/cc1/format.rb, line 736 def default_precision_value subclass_responsibility end
ruby_sprintf_format()
click to toggle source
# File lib/adlint/cc1/format.rb, line 740 def ruby_sprintf_format # TODO: Should support the parameterized field width and the # parameterized precision. fw = @field_width == "*" ? "1" : @field_width pr = @precision == ".*" ? ".1" : @precision "%#{flags}#{fw}#{pr}#{conversion_specifier_character}" end