+/* First pass over FORMAT to gather ARGS. Returns number of args. */
+
+static unsigned int
+_bfd_doprnt_scan (const char *format, union _bfd_doprnt_args *args)
+{
+ const char *ptr = format;
+ unsigned int arg_count = 0;
+
+ while (*ptr != '\0')
+ {
+ if (*ptr != '%')
+ {
+ ptr = strchr (ptr, '%');
+ if (ptr == NULL)
+ break;
+ }
+ else if (ptr[1] == '%')
+ ptr += 2;
+ else
+ {
+ int wide_width = 0, short_width = 0;
+ unsigned int arg_no;
+
+ ptr++;
+
+ /* Check for a positional parameter. */
+ arg_no = -1u;
+ if (*ptr != '0' && ISDIGIT (*ptr) && ptr[1] == '$')
+ {
+ arg_no = *ptr - '1';
+ ptr += 2;
+ }
+
+ /* Move past flags. */
+ while (strchr ("-+ #0", *ptr))
+ ptr++;
+
+ if (*ptr == '*')
+ {
+ unsigned int arg_index;
+
+ ptr++;
+ arg_index = arg_count;
+ if (*ptr != '0' && ISDIGIT (*ptr) && ptr[1] == '$')
+ {
+ arg_index = *ptr - '1';
+ ptr += 2;
+ }
+ if (arg_index >= 9)
+ abort ();
+ args[arg_index].type = Int;
+ arg_count++;
+ }
+ else
+ /* Handle explicit numeric value. */
+ while (ISDIGIT (*ptr))
+ ptr++;
+
+ /* Precision. */
+ if (*ptr == '.')
+ {
+ ptr++;
+ if (*ptr == '*')
+ {
+ unsigned int arg_index;
+
+ ptr++;
+ arg_index = arg_count;
+ if (*ptr != '0' && ISDIGIT (*ptr) && ptr[1] == '$')
+ {
+ arg_index = *ptr - '1';
+ ptr += 2;
+ }
+ if (arg_index >= 9)
+ abort ();
+ args[arg_index].type = Int;
+ arg_count++;
+ }
+ else
+ /* Handle explicit numeric value. */
+ while (ISDIGIT (*ptr))
+ ptr++;
+ }
+ while (strchr ("hlL", *ptr))
+ {
+ switch (*ptr)
+ {
+ case 'h':
+ short_width = 1;
+ break;
+ case 'l':
+ wide_width++;
+ break;
+ case 'L':
+ wide_width = 2;
+ break;
+ default:
+ abort();
+ }
+ ptr++;
+ }
+
+ ptr++;
+ if ((int) arg_no < 0)
+ arg_no = arg_count;
+
+ if (arg_no >= 9)
+ abort ();
+ switch (ptr[-1])
+ {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ {
+ if (short_width)
+ args[arg_no].type = Int;
+ else
+ {
+ if (ptr[-2] == 'L')
+ {
+ if (BFD_ARCH_SIZE < 64 || BFD_HOST_64BIT_LONG)
+ wide_width = 1;
+ }
+
+ switch (wide_width)
+ {
+ case 0:
+ args[arg_no].type = Int;
+ break;
+ case 1:
+ args[arg_no].type = Long;
+ break;
+ case 2:
+ default:
+#if defined (__GNUC__) || defined (HAVE_LONG_LONG)
+ args[arg_no].type = LongLong;
+#else
+ args[arg_no].type = Long;
+#endif
+ break;
+ }
+ }
+ }
+ break;
+ case 'f':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ {
+ if (wide_width == 0)
+ args[arg_no].type = Double;
+ else
+ {
+#if defined (__GNUC__) || defined (HAVE_LONG_DOUBLE)
+ args[arg_no].type = LongDouble;
+#else
+ args[arg_no].type = Double;
+#endif
+ }
+ }
+ break;
+ case 's':
+ case 'p':
+ case 'A':
+ case 'B':
+ args[arg_no].type = Ptr;
+ break;
+ default:
+ abort();
+ }
+ arg_count++;
+ }
+ }
+
+ return arg_count;
+}
+