class AdLint::Cc1::ScanfFormat::ConversionSpecifier

Attributes

assignment_suppressing_character[R]
conversion_argument[R]
conversion_specifier_character[R]
field_width[R]
length_modifier[R]
scanset[R]

Public Class Methods

new(fmt, trailing_args, env, consume_args, as_char, field_width, len_mod, cs_char, scanset) click to toggle source
# File lib/adlint/cc1/format.rb, line 2181
def initialize(fmt, trailing_args, env, consume_args, as_char,
               field_width, len_mod, cs_char, scanset)
  super(fmt)

  if as_char == "*"
    @consume_arguments = false
  else
    @consume_arguments = consume_args
  end

  @assignment_suppressing_character = as_char
  @field_width = field_width
  @length_modifier = len_mod
  @conversion_specifier_character = cs_char
  @scanset = scanset

  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 2121
def self.scan(fmt_str)
  # NOTE: The ISO C99 standard says;
  #
  # 7.19.6.2 The fscanf function
  #
  # 3 The format shall be a multibyte character sequence, beginning and
  #   ending in its initial shift state.  The format is composed of zero
  #   or more directives: one or more white-space characters, an ordinary
  #   multibyte character (neither % nor a white-space character), or a
  #   conversion specification.  Each conversion specification is
  #   introduced by the character %.  After the %, the following appear
  #   in sequence:
  #
  #   -- An optional assignment-suppressing character *.
  #   -- An optional decimal integer greater than zero that specifies the
  #      maximum field width (in characters).
  #   -- An optional length modifier that specifies the size of the
  #      receiving object.
  #   -- 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 as_char = fmt_str.slice!(/\A#{as_char_re}/)
    scanned += as_char
  end

  if field_width = fmt_str.slice!(/\A#{field_width_re}/)
    scanned += field_width
  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

  if cs_char == "["
    if scanset = fmt_str.slice!(/\A#{scanset_re}/)
      scanned += scanset
    end
  else
    scanset = nil
  end

  return scanned, as_char, field_width, len_mod, cs_char, scanset
end

Private Class Methods

as_char_re() click to toggle source
# File lib/adlint/cc1/format.rb, line 2242
def self.as_char_re
  /\*?/
end
cs_char_re() click to toggle source
# File lib/adlint/cc1/format.rb, line 2290
def self.cs_char_re
  # NOTE: The ISO C99 standard says;
  #
  # 7.19.6.2 The fscanf function
  #
  # 12 The conversion specifiers and their meanings are:
  #
  #    d       Matches an optionally signed decimal integer, whose format
  #            is the same as expected for the subject sequence of the
  #            strtol function with the value 10 for the base argument.
  #            The corresponding argument shall be a pointer to signed
  #            integer.
  #    i       Matches an optionally signed integer, whose format is the
  #            same as expected for the subject sequence of the strtol
  #            function with the value 0 for the base argument.  The
  #            corresponding argument shall be a pointer to signed
  #            integer.
  #    o       Matches an optionally signed octal integer, whose format
  #            is the same as expected for the subject sequence of the
  #            strtoul function with the value 8 for the base argument.
  #            The corresponding argument shall be a pointer to unsigned
  #            integer.
  #    u       Matches an optionally signed decimal integer, whose format
  #            is the same as expected for the subject sequence of the
  #            strtoul function with the value 10 for the base argument.
  #            The corresponding argument shall be a pointer to unsigned
  #            integer.
  #    x       Matches an optionally signed hexadecimal integer, whose
  #            format is the same as expected for the subject sequence of
  #            the strtoul function with the value 16 for the base
  #            argument.  The corresponding argument shall be a pointer
  #            to unsigned integer.
  #    a,e,f,g Matches an optionally signed floating-point number,
  #            infinity, or NaN, whose format is the same as expected for
  #            the subject sequence of the strtod function.  The
  #            corresponding argument shall be a pointer to floating.
  #    c       Matches a sequence of characters of exactly the number
  #            specified by the field width (1 if no field width is
  #            present in the directive).
  #            If no l length modifier is present, the corresponding
  #            argument shall be a pointer to the initial element of
  #            character array large enough to accept the sequence.  No
  #            null character is added.
  #            If an l length modifier is present, the input shall be a
  #            sequence of multibyte characters that begins in the
  #            initial shift state.  Each multibyte character in the
  #            sequence is converted to a wide character as if by a call
  #            to the mbrtowc function, with the conversion state
  #            described by an mbstate_t object initialized to zero
  #            before the first multibyte character is converted.  The
  #            corresponding argument shall be a pointer to the initial
  #            element of an array of wchar_t large enough to accept the
  #            resulting sequence of wide characters.  No null wide
  #            character is added.
  #    s       Matches a sequence of non-white-space characters.
  #            If no l length modifier is present, the corresponding
  #            argument shall be a pointer to the initial element of a
  #            character array large enough to accept the sequence and a
  #            terminating null character, which will be added
  #            automatically.
  #            If an l length modifier is present, the input shall be a
  #            sequence of multibyte characters that begins in the
  #            initial shift state.  Each multibyte character is
  #            converted to a wide character as if by a call to the
  #            mbrtowc function, with the conversion state described by
  #            an mbstate_t object initialized to zero before the first
  #            multibyte character is converted.  The corresponding
  #            argument shall be a pointer to the initial element of an
  #            array of wchar_t large enough to accept the sequence and
  #            the terminating null wide character, which will be added
  #            automatically.
  #    [       Matches a nonempty sequence of characters from a set of
  #            expected characters (the scanset).
  #            If no l length modifier is present, the corresponding
  #            argument shall be a pointer to the initial element of a
  #            character array large enough to accept the sequence and a
  #            terminating null character, which will be added
  #            automatically.
  #            If an l length modifier is present, the input shall be a
  #            sequence of multibyte characters that begins in the
  #            initial shift state.  Each multibyte character is
  #            converted to a wide character as if by a call to the
  #            mbrtowc function, with the conversion state described by
  #            an mbstate_t object initialized to zero before the first
  #            multibyte character is converted.  The corresponding
  #            argument shall be a pointer to the initial element of an
  #            array of wchar_t large enough to accept the sequence and
  #            the terminating null wide character, which will be added
  #            automatically.
  #            The conversion specifier includes all subsequent
  #            characters in the format string, up to and including the
  #            matching right bracket (]).  The characters between the
  #            brackets (the scanlist) compose the scanset, unless the
  #            character after the left bracket is a circumflex (^), in
  #            which case the scanset contains all characters that do not
  #            appear in the scanlist between the circumflex and the
  #            right bracket.  If the conversion specifier begins with []
  #            or [^], the right bracket character is in the scanlist and
  #            the next following right bracket character is the matching
  #            right bracket that ends the specification; otherwise the
  #            first following right bracket character is the one that
  #            ends the specification.  If a - character is in the
  #            scanlist and is not the first, nor the second where the
  #            first character is a ^, nor the last character, the
  #            behavior is implementation-defined.
  #    p       Matches an implementation-defined set of sequences, which
  #            should be the same as the set of sequence that may be
  #            produced by the %p conversion of the fprintf function.
  #            The corresponding argument shall be a pointer to a pointer
  #            to void.  The input item is converted to a pointer value
  #            in an implementation-defined manner.  If the input item is
  #            a value converted earlier during the same program
  #            execution, the pointer that results shall compare equal to
  #            the value; otherwise the behavior of the %p conversion is
  #            undefined.
  #    n       No input is consumed.  The corresponding argument shall be
  #            a pointer to signed integer into which is to be written
  #            the number of characters read from the input stream so far
  #            by this call to the fscanf function.  Execution of a %n
  #            directive does not increment the assignment count returned
  #            at the completion of execution of the fscanf function.  No
  #            argument is converted, but one is consumed.  If the
  #            conversion specification includes an
  #            assignment-suppressing character or a field width, the
  #            behavior is undefined.
  #    %       Matches a single % character; no conversion or assignment
  #            occurs.  The complete conversion specification shall be
  #            %%.
  #
  # 14 The conversion specifiers A, E, F, G, and X are also valid and
  #    behave the same as, respectively, a, e, f, g, and x.
  /[diouxXaAeEfFgGcs\[pn%]/
end
field_width_re() click to toggle source
# File lib/adlint/cc1/format.rb, line 2247
def self.field_width_re
  /(?:[1-9][0-9]*)?/
end
length_modifier_re() click to toggle source
# File lib/adlint/cc1/format.rb, line 2252
def self.length_modifier_re
  # NOTE: The ISO C99 standard says;
  #
  # 7.19.6.2 The fscanf function
  #
  # 11 The length modifiers and their meanings are:
  #
  #    hh Specifies that a following d, i, o, u, x, X, or n conversion
  #       specifier applies to an argument with type pointer to signed
  #       char or unsigned char.
  #    h  Specifies that a following d, i, o, u, x, X, or n conversion
  #       specifier applies to an argument with type pointer to short int
  #       or unsigned short int.
  #    l  Specifies that a following d, i, o, u, x, X, or n conversion
  #       specifier applies to an argument with type pointer to long int
  #       or unsigned long int; that a following a, A, e, E, f, F, g, or
  #       G conversion specifier applies to an argument with type pointer
  #       to double; or that a following c, s, or [ conversion specifier
  #       applies to an argument with type pointer to wchar_t.
  #    ll Specifies that a following d, i, o, u, x, X, or n conversion
  #       specifier applies to an argument with type pointer to long long
  #       int or unsigned long long int.
  #    j  Specifies that a following d, i, o, u, x, X, or n conversion
  #       specifier applies to an argument with type pointer to intmax_t
  #       or uintmax_t.
  #    z  Specifies that a following d, i, o, u, x, X, or n conversion
  #       specifier applies to an argument with type pointer to size_t or
  #       the corresponding signed integer type.
  #    t  Specifies that a following d, i, o, u, x, X, or n conversion
  #       specifier applies to an argument with type pointer to ptrdiff_t
  #       or the corresponding unsigned integer type.
  #    L  Specifies that a following a, A, e, E, f, F, g, or G conversion
  #       specifier applies to an argument with type pointer to long
  #       double.
  /(?:h+|l+|j|z|t|L)?/
end
scanset_re() click to toggle source
# File lib/adlint/cc1/format.rb, line 2425
def self.scanset_re
  # NOTE: The ISO C99 standard says;
  #
  # 7.19.6.2 The fscanf function
  #
  # 12 The conversion specifiers and their meanings are:
  #
  #    [       Matches a nonempty sequence of characters from a set of
  #            expected characters (the scanset).
  #            If no l length modifier is present, the corresponding
  #            argument shall be a pointer to the initial element of a
  #            character array large enough to accept the sequence and a
  #            terminating null character, which will be added
  #            automatically.
  #            If an l length modifier is present, the input shall be a
  #            sequence of multibyte characters that begins in the
  #            initial shift state.  Each multibyte character is
  #            converted to a wide character as if by a call to the
  #            mbrtowc function, with the conversion state described by
  #            an mbstate_t object initialized to zero before the first
  #            multibyte character is converted.  The corresponding
  #            argument shall be a pointer to the initial element of an
  #            array of wchar_t large enough to accept the sequence and
  #            the terminating null wide character, which will be added
  #            automatically.
  #            The conversion specifier includes all subsequent
  #            characters in the format string, up to and including the
  #            matching right bracket (]).  The characters between the
  #            brackets (the scanlist) compose the scanset, unless the
  #            character after the left bracket is a circumflex (^), in
  #            which case the scanset contains all characters that do not
  #            appear in the scanlist between the circumflex and the
  #            right bracket.  If the conversion specifier begins with []
  #            or [^], the right bracket character is in the scanlist and
  #            the next following right bracket character is the matching
  #            right bracket that ends the specification; otherwise the
  #            first following right bracket character is the one that
  #            ends the specification.  If a - character is in the
  #            scanlist and is not the first, nor the second where the
  #            first character is a ^, nor the last character, the
  #            behavior is implementation-defined.
  /\].*?\]|\^\].*?\]|.*?\]/
end

Public Instance Methods

consume_arguments?() click to toggle source
# File lib/adlint/cc1/format.rb, line 2218
def consume_arguments?
  @consume_arguments
end
conversion_specifier?() click to toggle source
# File lib/adlint/cc1/format.rb, line 2214
def conversion_specifier?
  true
end
field_width_value() click to toggle source
# File lib/adlint/cc1/format.rb, line 2233
def field_width_value
  case @field_width
  when /\A[1-9][0-9]*\z/
    @field_width.to_i
  else
    1
  end
end
ordinary?() click to toggle source
# File lib/adlint/cc1/format.rb, line 2210
def ordinary?
  false
end
undefined?() click to toggle source
# File lib/adlint/cc1/format.rb, line 2222
def undefined?
  false
end
whitespace?() click to toggle source
# File lib/adlint/cc1/format.rb, line 2206
def whitespace?
  false
end