Print this page
Address Robert's feedback

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libsysdemangle/common/cpp.c
          +++ new/usr/src/lib/libsysdemangle/common/cxx.c
↓ open down ↓ 4 lines elided ↑ open up ↑
   5    5   *                     The LLVM Compiler Infrastructure
   6    6   *
   7    7   * This file is dual licensed under the MIT and the University of Illinois Open
   8    8   * Source Licenses. See LICENSE.TXT for details.
   9    9   *
  10   10   */
  11   11  
  12   12  /*
  13   13   * Copyright 2017 Jason King.
  14   14   */
  15      -
       15 +#include <ctype.h>
  16   16  #include <errno.h>
       17 +#include <locale.h>
  17   18  #include <string.h>
  18   19  #include <setjmp.h>
  19   20  #include <stdio.h>
  20   21  #include <stdlib.h>
  21   22  #include <sys/isa_defs.h>
  22   23  #include <sys/debug.h>
  23   24  #include "sysdemangle.h"
  24   25  #include "sysdemangle_int.h"
  25      -#include "cpp.h"
       26 +#include "cxx.h"
  26   27  
       28 +#ifndef ARRAY_SIZE
  27   29  #define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0]))
       30 +#endif
  28   31  
  29   32  #define CPP_QUAL_CONST          (1U)
  30   33  #define CPP_QUAL_VOLATILE       (2U)
  31   34  #define CPP_QUAL_RESTRICT       (4U)
  32   35  
  33   36  typedef struct cpp_db_s {
  34   37          sysdem_ops_t    *cpp_ops;
  35   38          jmp_buf         cpp_jmp;
  36   39          name_t          cpp_name;
  37   40          sub_t           cpp_subs;
  38   41          templ_t         cpp_templ;
  39   42          unsigned        cpp_cv;
  40   43          unsigned        cpp_ref;
  41   44          unsigned        cpp_depth;
  42   45          boolean_t       cpp_parsed_ctor_dtor_cv;
  43   46          boolean_t       cpp_tag_templates;
  44   47          boolean_t       cpp_fix_forward_references;
  45   48          boolean_t       cpp_try_to_parse_template_args;
       49 +        locale_t        cpp_loc;
  46   50  } cpp_db_t;
  47   51  
  48   52  #define CK(x)                                           \
  49   53          do {                                            \
  50   54                  if (!(x))                               \
  51   55                          longjmp(db->cpp_jmp, 1);        \
  52   56          } while (0)
  53   57  
  54   58  #define TOP_L(db) (&(name_top(&(db)->cpp_name)->strp_l))
  55   59  #define RLEN(f, l) ((size_t)((l) - (f)))
  56   60  #define NAMT(db, n) (nlen(db) - n)
  57   61  
  58      -static inline boolean_t is_digit(int);
  59      -static inline boolean_t is_upper(int);
  60   62  static inline boolean_t is_xdigit(int);
  61   63  
  62   64  static boolean_t nempty(cpp_db_t *);
  63   65  static size_t nlen(cpp_db_t *);
  64   66  static void nadd_l(cpp_db_t *, const char *, size_t);
  65   67  static void njoin(cpp_db_t *, size_t, const char *);
  66   68  static void nfmt(cpp_db_t *, const char *, const char *);
  67   69  
  68   70  static void save_top(cpp_db_t *, size_t);
  69   71  static void sub(cpp_db_t *, size_t);
  70   72  
  71   73  static boolean_t tempty(const cpp_db_t *);
  72   74  static size_t ttlen(const cpp_db_t *);
  73   75  
  74   76  static void tsub(cpp_db_t *, size_t);
  75   77  static void tpush(cpp_db_t *);
  76   78  static void tpop(cpp_db_t *);
  77   79  static void tsave(cpp_db_t *, size_t);
  78   80  
  79      -static void db_init(cpp_db_t *, sysdem_ops_t *);
       81 +static boolean_t db_init(cpp_db_t *, sysdem_ops_t *);
  80   82  static void db_fini(cpp_db_t *);
  81   83  static void dump(cpp_db_t *, FILE *);
  82   84  
  83   85  static void demangle(const char *, const char *, cpp_db_t *);
  84   86  
  85   87  static const char *parse_type(const char *, const char *, cpp_db_t *);
  86   88  static const char *parse_builtin_type(const char *, const char *, cpp_db_t *);
  87   89  static const char *parse_qual_type(const char *, const char *, cpp_db_t *);
  88   90  static const char *parse_encoding(const char *, const char *, cpp_db_t *);
  89   91  static const char *parse_dot_suffix(const char *, const char *, cpp_db_t *);
  90   92  static const char *parse_block_invoke(const char *, const char *, cpp_db_t *);
  91   93  static const char *parse_special_name(const char *, const char *, cpp_db_t *);
  92   94  static const char *parse_name(const char *, const char *, boolean_t *,
  93   95      cpp_db_t *);
  94      -static const char *parse_call_offset(const char *, const char *);
  95      -static const char *parse_number(const char *, const char *);
       96 +static const char *parse_call_offset(const char *, const char *, locale_t);
       97 +static const char *parse_number(const char *, const char *, locale_t);
  96   98  static const char *parse_nested_name(const char *, const char *, boolean_t *,
  97   99      cpp_db_t *);
  98  100  static const char *parse_local_name(const char *, const char *, boolean_t *,
  99  101      cpp_db_t *);
 100  102  static const char *parse_unscoped_name(const char *, const char *, cpp_db_t *);
 101  103  static const char *parse_template_args(const char *, const char *, cpp_db_t *);
 102  104  static const char *parse_substitution(const char *, const char *, cpp_db_t *);
 103      -static const char *parse_discriminator(const char *, const char *);
      105 +static const char *parse_discriminator(const char *, const char *, locale_t);
 104  106  static const char *parse_cv_qualifiers(const char *, const char *, unsigned *);
 105  107  static const char *parse_template_param(const char *, const char *, cpp_db_t *);
 106  108  static const char *parse_decltype(const char *, const char *, cpp_db_t *);
 107  109  static const char *parse_template_args(const char *, const char *, cpp_db_t *);
 108  110  static const char *parse_unqualified_name(const char *, const char *,
 109  111      cpp_db_t *);
 110  112  static const char *parse_template_arg(const char *, const char *, cpp_db_t *);
 111  113  static const char *parse_expression(const char *, const char *, cpp_db_t *);
 112  114  static const char *parse_expr_primary(const char *, const char *, cpp_db_t *);
 113  115  static const char *parse_binary_expr(const char *, const char *,
↓ open down ↓ 45 lines elided ↑ open up ↑
 159  161  
 160  162  size_t cpp_name_max_depth = 1024;       /* max depth of name stack */
 161  163  
 162  164  char *
 163  165  cpp_demangle(const char *src, sysdem_ops_t *ops)
 164  166  {
 165  167          char *result = NULL;
 166  168          cpp_db_t db;
 167  169          size_t srclen = strlen(src);
 168  170  
 169      -        db_init(&db, ops);
 170      -
      171 +        if (!db_init(&db, ops))
      172 +                goto done;
 171  173          if (setjmp(db.cpp_jmp) != 0)
 172  174                  goto done;
 173  175  
 174  176          errno = 0;
 175  177          demangle(src, src + srclen, &db);
 176  178  
 177  179          if (errno == 0 && db.cpp_fix_forward_references &&
 178  180              !templ_empty(&db.cpp_templ) &&
 179  181              !sub_empty(&db.cpp_templ.tpl_items[0])) {
 180  182                  db.cpp_fix_forward_references = B_FALSE;
↓ open down ↓ 83 lines elided ↑ open up ↑
 264  266                  t = parse_block_invoke(t, last, db);
 265  267  
 266  268  done:
 267  269          if (t != last)
 268  270                  errno = EINVAL;
 269  271  }
 270  272  
 271  273  static const char *
 272  274  parse_dot_suffix(const char *first, const char *last, cpp_db_t *db)
 273  275  {
 274      -        ASSERT3P(first, <=, last);
      276 +        VERIFY3P(first, <=, last);
 275  277  
 276  278          if (first == last || first[0] != '.')
 277  279                  return (first);
 278  280  
 279  281          if (nempty(db))
 280  282                  return (first);
 281  283  
 282  284          nadd_l(db, first, RLEN(first, last));
 283  285          nfmt(db, " ({0})", NULL);
 284  286  
↓ open down ↓ 1 lines elided ↑ open up ↑
 286  288  }
 287  289  
 288  290  /*
 289  291   * _block_invoke
 290  292   * _block_invoke<digit>+        XXX: should it be <digit>* ?
 291  293   * _block_invoke_<digit>+
 292  294   */
 293  295  static const char *
 294  296  parse_block_invoke(const char *first, const char *last, cpp_db_t *db)
 295  297  {
 296      -        ASSERT3P(first, <=, last);
      298 +        VERIFY3P(first, <=, last);
 297  299  
 298  300          if (last - first < 13)
 299  301                  return (first);
 300  302  
 301  303          const char test[] = "_block_invoke";
 302  304          const char *t = first;
 303  305  
 304  306          if (strncmp(first, test, sizeof (test) - 1) != 0)
 305  307                  return (first);
 306  308  
 307  309          t += sizeof (test);
 308  310          if (t == last)
 309  311                  goto done;
 310  312  
 311  313          if (t[0] == '_') {
 312  314                  /* need at least one digit */
 313      -                if (t + 1 == last || !is_digit(t[1]))
      315 +                if (t + 1 == last || !isdigit_l(t[1], db->cpp_loc))
 314  316                          return (first);
 315  317                  t += 2;
 316  318          }
 317  319  
 318      -        while (t < last && is_digit(t[0]))
      320 +        while (t < last && isdigit_l(t[0], db->cpp_loc))
 319  321                  t++;
 320  322  
 321  323  done:
 322  324          if (nempty(db))
 323  325                  return (first);
 324  326  
 325  327          nfmt(db, "invocation function for block in {0}", NULL);
 326  328          return (t);
 327  329  }
 328  330  
 329  331  /*
 330  332   * <encoding> ::= <function name><bare-function-type>
 331  333   *            ::= <data name>
 332  334   *            ::= <special name>
 333  335   */
 334  336  static const char *
 335  337  parse_encoding(const char *first, const char *last, cpp_db_t *db)
 336  338  {
 337      -        ASSERT3P(first, <=, last);
      339 +        VERIFY3P(first, <=, last);
 338  340  
 339  341          if (first == last)
 340  342                  return (first);
 341  343  
 342  344          const char *t = NULL;
 343  345          const char *t2 = NULL;
 344  346          unsigned cv = 0;
 345  347          unsigned ref = 0;
 346  348          boolean_t tag_templ_save = db->cpp_tag_templates;
 347  349  
↓ open down ↓ 52 lines elided ↑ open up ↑
 400  402                          t = t2;
 401  403                  }
 402  404          }
 403  405  
 404  406          /*
 405  407           * a bit of a hack, but a template substitution can apparently be
 406  408           * an empty string at the end of an argument list, so avoid
 407  409           * <...., >
 408  410           */
 409  411          if (NAMT(db, n) > 1 && str_pair_len(name_top(&db->cpp_name)) == 0)
 410      -                (void) name_pop(&db->cpp_name, NULL);
      412 +                name_pop(&db->cpp_name, NULL);
 411  413  
 412  414          njoin(db, NAMT(db, n), ", ");
 413  415          nfmt(db, "({0})", NULL);
 414  416  
 415  417          str_t *s = TOP_L(db);
 416  418  
 417  419          if (cv & CPP_QUAL_CONST) {
 418  420                  CK(str_append(s, " const", 0));
 419  421          }
 420  422          if (cv & CPP_QUAL_VOLATILE) {
↓ open down ↓ 37 lines elided ↑ open up ↑
 458  460   *                                     # No <type>
 459  461   *                ::= TW <object name> # Thread-local wrapper
 460  462   *                ::= TH <object name> # Thread-local initialization
 461  463   *      extension ::= TC <first type> <number> _ <second type>
 462  464   *                                     # construction vtable for second-in-first
 463  465   *      extension ::= GR <object name> # reference temporary for object
 464  466   */
 465  467  static const char *
 466  468  parse_special_name(const char *first, const char *last, cpp_db_t *db)
 467  469  {
 468      -        ASSERT3P(first, <=, last);
      470 +        VERIFY3P(first, <=, last);
 469  471  
 470  472          const char *t = first;
 471  473          const char *t1 = NULL;
 472  474          size_t n = nlen(db);
 473  475  
 474  476          if (last - first < 2)
 475  477                  return (first);
 476  478  
 477  479          switch (t[0]) {
 478  480          case 'T':
↓ open down ↓ 9 lines elided ↑ open up ↑
 488  490                  case 'I':
 489  491                          nadd_l(db, "typeinfo for", 0);
 490  492                          t = parse_type(first + 2, last, db);
 491  493                          break;
 492  494                  case 'S':
 493  495                          nadd_l(db, "typeinfo name for", 0);
 494  496                          t = parse_type(first + 2, last, db);
 495  497                          break;
 496  498                  case 'c':
 497  499                          nadd_l(db, "covariant return thunk to", 0);
 498      -                        t1 = parse_call_offset(first + 2, last);
      500 +                        t1 = parse_call_offset(first + 2, last, db->cpp_loc);
 499  501                          if (t1 == t)
 500  502                                  return (first);
 501      -                        t = parse_call_offset(t1, last);
      503 +                        t = parse_call_offset(t1, last, db->cpp_loc);
 502  504                          if (t == t1)
 503  505                                  return (first);
 504  506                          t1 = parse_encoding(t, last, db);
 505  507                          if (t1 == t)
 506  508                                  return (first);
 507  509                          break;
 508  510                  case 'C':
 509  511                          t = parse_type(first + 2, last, db);
 510  512                          if (t == first + 2)
 511  513                                  return (first);
 512      -                        t1 = parse_number(t, last);
      514 +                        t1 = parse_number(t, last, db->cpp_loc);
 513  515                          if (*t1 != '_')
 514  516                                  return (first);
 515  517                          t = parse_type(t1 + 1, last, db);
 516  518                          if (t == t1 + 1 || nlen(db) < 2)
 517  519                                  return (first);
 518  520                          nfmt(db, "construction vtable for {0}-in-{1}", NULL);
 519  521                          return (t);
 520  522                  case 'W':
 521  523                          nadd_l(db, "thread-local wrapper routine for", 0);
 522  524                          t = parse_name(first + 2, last, NULL, db);
↓ open down ↓ 3 lines elided ↑ open up ↑
 526  528                              0);
 527  529                          t = parse_name(first + 2, last, NULL, db);
 528  530                          break;
 529  531                  default:
 530  532                          if (first[1] == 'v') {
 531  533                                  nadd_l(db, "virtual thunk to", 0);
 532  534                          } else {
 533  535                                  nadd_l(db, "non-virtual thunk to", 0);
 534  536                          }
 535  537  
 536      -                        t = parse_call_offset(first + 1, last);
      538 +                        t = parse_call_offset(first + 1, last, db->cpp_loc);
 537  539                          if (t == first + 1)
 538  540                                  return (first);
 539  541                          t1 = parse_encoding(t, last, db);
 540  542                          if (t == t1)
 541  543                                  return (first);
 542  544                          t = t1;
 543  545                          break;
 544  546                  }
 545  547                  break;
 546  548          case 'G':
↓ open down ↓ 26 lines elided ↑ open up ↑
 573  575   * <call-offset> ::= h <nv-offset> _
 574  576   *               ::= v <v-offset> _
 575  577   *
 576  578   * <nv-offset> ::= <offset number>
 577  579   *               # non-virtual base override
 578  580   *
 579  581   * <v-offset>  ::= <offset number> _ <virtual offset number>
 580  582   *               # virtual base override, with vcall offset
 581  583   */
 582  584  static const char *
 583      -parse_call_offset(const char *first, const char *last)
      585 +parse_call_offset(const char *first, const char *last, locale_t loc)
 584  586  {
 585      -        ASSERT3P(first, <=, last);
      587 +        VERIFY3P(first, <=, last);
 586  588  
 587  589          const char *t = NULL;
 588  590          const char *t1 = NULL;
 589  591  
 590  592          if (first == last)
 591  593                  return (first);
 592  594  
 593  595          if (first[0] != 'h' && first[0] != 'v')
 594  596                  return (first);
 595  597  
 596      -        t = parse_number(first + 1, last);
      598 +        t = parse_number(first + 1, last, loc);
 597  599          if (t == first + 1 || t == last || t[0] != '_')
 598  600                  return (first);
 599  601  
 600  602          /* skip _ */
 601  603          t++;
 602  604  
 603  605          if (first[0] == 'h')
 604  606                  return (t);
 605  607  
 606      -        t1 = parse_number(t, last);
      608 +        t1 = parse_number(t, last, loc);
 607  609          if (t == t1 || t1 == last || t1[0] != '_')
 608  610                  return (first);
 609  611  
 610  612          /* skip _ */
 611  613          t1++;
 612  614  
 613  615          return (t1);
 614  616  }
 615  617  
 616  618  /*
↓ open down ↓ 2 lines elided ↑ open up ↑
 619  621   *        ::= <unscoped-template-name> <template-args>
 620  622   *        ::= <unscoped-name>
 621  623   *
 622  624   * <unscoped-template-name> ::= <unscoped-name>
 623  625   *                          ::= <substitution>
 624  626   */
 625  627  static const char *
 626  628  parse_name(const char *first, const char *last,
 627  629      boolean_t *ends_with_template_args, cpp_db_t *db)
 628  630  {
 629      -        ASSERT3P(first, <=, last);
      631 +        VERIFY3P(first, <=, last);
 630  632  
 631  633          const char *t = first;
 632  634          const char *t1 = NULL;
 633  635  
 634  636          if (last - first < 2)
 635  637                  return (first);
 636  638  
 637  639          /* extension: ignore L here */
 638  640          if (t[0] == 'L')
 639  641                  t++;
↓ open down ↓ 42 lines elided ↑ open up ↑
 682  684  /*
 683  685   * <local-name> := Z <function encoding> E <entity name> [<discriminator>]
 684  686   *              := Z <function encoding> E s [<discriminator>]
 685  687   *              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
 686  688   */
 687  689  /* END CSTYLED */
 688  690  const char *
 689  691  parse_local_name(const char *first, const char *last,
 690  692      boolean_t *ends_with_template_args, cpp_db_t *db)
 691  693  {
 692      -        ASSERT3P(first, <=, last);
      694 +        VERIFY3P(first, <=, last);
 693  695  
 694  696          const char *t = NULL;
 695  697          const char *t1 = NULL;
 696  698          const char *t2 = NULL;
 697  699  
 698  700          if (first == last || first[0] != 'Z')
 699  701                  return (first);
 700  702  
 701  703          t = parse_encoding(first + 1, last, db);
 702  704          if (t == first + 1 || t == last || t[0] != 'E')
 703  705                  return (first);
 704  706  
 705      -        ASSERT(!nempty(db));
      707 +        VERIFY(!nempty(db));
 706  708  
 707  709          /* skip E */
 708  710          t++;
 709  711  
 710  712          if (t[0] == 's') {
 711  713                  nfmt(db, "{0:L}::string literal", "{0:R}");
 712      -                return (parse_discriminator(t, last));
      714 +                return (parse_discriminator(t, last, db->cpp_loc));
 713  715          }
 714  716  
 715  717          if (t[0] == 'd') {
 716      -                t1 = parse_number(t + 1, last);
      718 +                t1 = parse_number(t + 1, last, db->cpp_loc);
 717  719                  if (t1[0] != '_')
 718  720                          return (first);
 719  721                  t1++;
 720  722          } else {
 721  723                  t1 = t;
 722  724          }
 723  725  
 724  726          t2 = parse_name(t1, last, ends_with_template_args, db);
 725  727          if (t2 == t1)
 726  728                  return (first);
 727  729  
 728  730          nfmt(db, "{1:L}::{0}", "{1:R}");
 729  731  
 730  732          /* parsed, but ignored */
 731  733          if (t[0] != 'd')
 732      -                t2 = parse_discriminator(t2, last);
      734 +                t2 = parse_discriminator(t2, last, db->cpp_loc);
 733  735  
 734  736          return (t2);
 735  737  }
 736  738  
 737  739  /* BEGIN CSTYLED */
 738  740  /*
 739  741   * <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
 740  742   *               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
 741  743   *
 742  744   * <prefix> ::= <prefix> <unqualified-name>
↓ open down ↓ 7 lines elided ↑ open up ↑
 750  752   *
 751  753   * <template-prefix> ::= <prefix> <template unqualified-name>
 752  754   *                   ::= <template-param>
 753  755   *                   ::= <substitution>
 754  756   */
 755  757  /* END CSTYLED */
 756  758  static const char *
 757  759  parse_nested_name(const char *first, const char *last,
 758  760      boolean_t *ends_with_template_args, cpp_db_t *db)
 759  761  {
 760      -        ASSERT3P(first, <=, last);
      762 +        VERIFY3P(first, <=, last);
 761  763  
 762  764          if (first == last || first[0] != 'N')
 763  765                  return (first);
 764  766  
 765  767          unsigned cv = 0;
 766  768          const char *t = parse_cv_qualifiers(first + 1, last, &cv);
 767  769  
 768  770          if (t == last)
 769  771                  return (first);
 770  772  
↓ open down ↓ 32 lines elided ↑ open up ↑
 803  805                          if (t + 1 != last && t[1] == 't')
 804  806                                  break;
 805  807  
 806  808                          t1 = parse_substitution(t, last, db);
 807  809                          if (t1 == t || t1 == last || NAMT(db, n) != 1)
 808  810                                  return (first);
 809  811  
 810  812                          if (!more) {
 811  813                                  nfmt(db, "{0}", NULL);
 812  814                          } else {
 813      -                                ASSERT3U(nlen(db), >, 1);
      815 +                                VERIFY3U(nlen(db), >, 1);
 814  816                                  nfmt(db, "{1:L}::{0}", "{1:R}");
 815  817                                  save_top(db, 1);
 816  818                          }
 817  819  
 818  820                          more = B_TRUE;
 819  821                          pop_subs = B_TRUE;
 820  822                          t = t1;
 821  823                          continue;
 822  824  
 823  825                  case 'T':
 824  826                          t1 = parse_template_param(t, last, db);
 825  827                          if (t1 == t || t1 == last || NAMT(db, n) != 1)
 826  828                                  return (first);
 827  829  
 828  830                          if (!more) {
 829  831                                  nfmt(db, "{0}", NULL);
 830  832                          } else {
 831      -                                ASSERT3U(nlen(db), >, 1);
      833 +                                VERIFY3U(nlen(db), >, 1);
 832  834                                  nfmt(db, "{1:L}::{0}", "{1:R}");
 833  835                          }
 834  836  
 835  837                          save_top(db, 1);
 836  838                          more = B_TRUE;
 837  839                          pop_subs = B_TRUE;
 838  840                          t = t1;
 839  841                          continue;
 840  842  
 841  843                  case 'D':
 842  844                          if (t + 1 != last && t[1] != 't' && t[1] != 'T')
 843  845                                  break;
 844  846                          t1 = parse_decltype(t, last, db);
 845  847                          if (t1 == t || t1 == last || NAMT(db, n) != 1)
 846  848                                  return (first);
 847  849  
 848  850                          if (!more) {
 849  851                                  nfmt(db, "{0}", NULL);
 850  852                          } else {
 851      -                                ASSERT3U(nlen(db), >, 1);
      853 +                                VERIFY3U(nlen(db), >, 1);
 852  854                                  nfmt(db, "{1:L}::{0}", "{1:R}");
 853  855                          }
 854  856  
 855  857                          save_top(db, 1);
 856  858                          more = B_TRUE;
 857  859                          pop_subs = B_TRUE;
 858  860                          t = t1;
 859  861                          continue;
 860  862  
 861  863                  case 'I':
↓ open down ↓ 1 lines elided ↑ open up ↑
 863  865                           * Must have at least one component before
 864  866                           * <template-args>
 865  867                           */
 866  868                          if (!more)
 867  869                                  return (first);
 868  870  
 869  871                          t1 = parse_template_args(t, last, db);
 870  872                          if (t1 == t || t1 == last)
 871  873                                  return (first);
 872  874  
 873      -                        ASSERT3U(nlen(db), >, 1);
      875 +                        VERIFY3U(nlen(db), >, 1);
 874  876                          nfmt(db, "{1:L}{0}", "{1:R}");
 875  877                          save_top(db, 1);
 876  878                          t = t1;
 877  879                          component_ends_with_template_args = B_TRUE;
 878  880                          continue;
 879  881  
 880  882                  case 'L':
 881  883                          if (t + 1 == last)
 882  884                                  return (first);
 883  885                          t++;
↓ open down ↓ 3 lines elided ↑ open up ↑
 887  889                          break;
 888  890                  }
 889  891  
 890  892                  t1 = parse_unqualified_name(t, last, db);
 891  893                  if (t1 == t || t1 == last || NAMT(db, n) != 1)
 892  894                          return (first);
 893  895  
 894  896                  if (!more) {
 895  897                          nfmt(db, "{0}", NULL);
 896  898                  } else {
 897      -                        ASSERT3U(nlen(db), >, 1);
      899 +                        VERIFY3U(nlen(db), >, 1);
 898  900                          nfmt(db, "{1:L}::{0}", "{1:R}");
 899  901                  }
 900  902  
 901  903                  save_top(db, 1);
 902  904                  more = B_TRUE;
 903  905                  pop_subs = B_TRUE;
 904  906                  t = t1;
 905  907          }
 906  908  
 907  909          /* need to parse at least one thing */
↓ open down ↓ 16 lines elided ↑ open up ↑
 924  926  /*
 925  927   * <template-arg> ::= <type>                   # type or template
 926  928   *                ::= X <expression> E         # expression
 927  929   *                ::= <expr-primary>           # simple expressions
 928  930   *                ::= J <template-arg>* E      # argument pack
 929  931   *                ::= LZ <encoding> E          # extension
 930  932   */
 931  933  static const char *
 932  934  parse_template_arg(const char *first, const char *last, cpp_db_t *db)
 933  935  {
 934      -        ASSERT3P(first, <=, last);
      936 +        VERIFY3P(first, <=, last);
 935  937  
 936  938          const char *t = NULL;
 937  939          const char *t1 = NULL;
 938  940  
 939  941          if (first == last)
 940  942                  return (first);
 941  943  
 942  944          switch (first[0]) {
 943  945          case 'X':
 944  946                  t = parse_expression(first + 1, last, db);
↓ open down ↓ 179 lines elided ↑ open up ↑
1124 1126          PN("te", parse_typeid_expr),
1125 1127          PN("tr", parse_throw_expr),
1126 1128          PN("tw", parse_throw_expr)
1127 1129  };
1128 1130  #undef PA
1129 1131  #undef PN
1130 1132  
1131 1133  static const char *
1132 1134  parse_expression(const char *first, const char *last, cpp_db_t *db)
1133 1135  {
1134      -        ASSERT3P(first, <=, last);
     1136 +        VERIFY3P(first, <=, last);
1135 1137  
1136 1138          if (last - first < 2)
1137 1139                  return (first);
1138 1140  
1139 1141          for (size_t i = 0; i < ARRAY_SIZE(expr_tbl); i++) {
1140 1142                  if (strncmp(expr_tbl[i].code, first, 2) != 0)
1141 1143                          continue;
1142 1144                  switch (expr_tbl[i].fntype) {
1143 1145                  case EXPR_ARG:
1144 1146                          return (expr_tbl[i].p.parse_expr_arg(first, last,
↓ open down ↓ 23 lines elided ↑ open up ↑
1168 1170                  return (parse_unresolved_name(first, last, db));
1169 1171          }
1170 1172  
1171 1173          return (first);
1172 1174  }
1173 1175  
1174 1176  static const char *
1175 1177  parse_binary_expr(const char *first, const char *last, const char *op,
1176 1178      cpp_db_t *db)
1177 1179  {
1178      -        ASSERT3P(first, <=, last);
     1180 +        VERIFY3P(first, <=, last);
1179 1181  
1180 1182          if (last - first < 2)
1181 1183                  return (first);
1182 1184  
1183 1185          size_t n = nlen(db);
1184 1186  
1185 1187          const char *t1 = parse_expression(first + 2, last, db);
1186 1188          if (t1 == first + 2)
1187 1189                  return (first);
1188 1190  
1189 1191          nadd_l(db, op, 0);
1190 1192  
1191 1193          const char *t2 = parse_expression(t1, last, db);
1192 1194          if (t2 == t1)
1193 1195                  return (first);
1194 1196  
1195 1197          if (NAMT(db, n) != 3)
1196 1198                  return (first);
1197 1199  
1198      -        ASSERT3U(nlen(db), >, 2);
     1200 +        VERIFY3U(nlen(db), >, 2);
1199 1201  
1200 1202          nfmt(db, "({2}) {1} ({0})", NULL);
1201 1203          if (strcmp(op, ">") == 0)
1202 1204                  nfmt(db, "({0})", NULL);
1203 1205  
1204 1206          return (t2);
1205 1207  }
1206 1208  
1207 1209  static const char *
1208 1210  parse_prefix_expr(const char *first, const char *last, const char *op,
1209 1211      cpp_db_t *db)
1210 1212  {
1211      -        ASSERT3P(first, <=, last);
     1213 +        VERIFY3P(first, <=, last);
1212 1214  
1213 1215          if (last - first < 2)
1214 1216                  return (first);
1215 1217  
1216 1218          nadd_l(db, op, 0);
1217 1219  
1218 1220          const char *t = parse_expression(first + 2, last, db);
1219 1221          if (t == first + 2) {
1220 1222                  return (first);
1221 1223          }
1222 1224  
1223      -        ASSERT3U(nlen(db), >, 1);
     1225 +        VERIFY3U(nlen(db), >, 1);
1224 1226  
1225 1227          nfmt(db, "{1}({0})", NULL);
1226 1228          return (t);
1227 1229  }
1228 1230  
1229 1231  static const char *
1230 1232  parse_gs(const char *first, const char *last, cpp_db_t *db)
1231 1233  {
1232      -        ASSERT3P(first, <=, last);
     1234 +        VERIFY3P(first, <=, last);
1233 1235  
1234 1236          const char *t = NULL;
1235 1237  
1236 1238          if (last - first < 4)
1237 1239                  return (first);
1238 1240  
1239 1241          if (first[2] == 'n' && (first[3] == 'a' || first[3] == 'w'))
1240 1242                  t = parse_new_expr(first + 2, last, db);
1241 1243          else if (first[2] == 'd' && (first[3] == 'l' || first[3] == 'a'))
1242 1244                  t = parse_del_expr(first + 2, last, db);
1243 1245          else
1244 1246                  return (first);
1245 1247  
1246 1248          if (t == first + 2)
1247 1249                  return (first);
1248 1250  
1249      -        ASSERT3U(nlen(db), >, 0);
     1251 +        VERIFY3U(nlen(db), >, 0);
1250 1252  
1251 1253          nfmt(db, "::{0}", NULL);
1252 1254          return (t);
1253 1255  }
1254 1256  
1255 1257  /*
1256 1258   * [gs] nw <expression>* _ <type> E             # new (expr-list) type
1257 1259   * [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
1258 1260   * [gs] na <expression>* _ <type> E             # new[] (expr-list) type
1259 1261   * [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
1260 1262   * <initializer> ::= pi <expression>* E         # parenthesized initialization
1261 1263   */
1262 1264  static const char *
1263 1265  parse_new_expr(const char *first, const char *last, cpp_db_t *db)
1264 1266  {
1265      -        ASSERT3P(first, <=, last);
     1267 +        VERIFY3P(first, <=, last);
1266 1268  
1267 1269          /* note [gs] is already handled by parse_gs() */
1268 1270          if (last - first < 3)
1269 1271                  return (first);
1270 1272  
1271      -        ASSERT3U(first[0], ==, 'n');
1272      -        ASSERT(first[1] == 'a' || first[1] == 'w');
     1273 +        VERIFY3U(first[0], ==, 'n');
     1274 +        VERIFY(first[1] == 'a' || first[1] == 'w');
1273 1275  
1274 1276          const char *t1 = first + 2;
1275 1277          const char *t2 = NULL;
1276 1278          size_t n = nlen(db);
1277 1279  
1278 1280          nadd_l(db, (first[1] == 'w') ? "new" : "new[]", 0);
1279 1281  
1280 1282          while (t1 != last && t1[0] != '_') {
1281 1283                  t2 = parse_expression(t1, last, db);
1282      -                ASSERT3P(t2, !=, NULL);
     1284 +                VERIFY3P(t2, !=, NULL);
1283 1285                  if (t2 == t1)
1284 1286                          return (first);
1285 1287                  t1 = t2;
1286 1288          }
1287 1289          if (t1 == last)
1288 1290                  return (first);
1289 1291  
1290 1292          if (NAMT(db, n) > 1) {
1291 1293                  njoin(db, NAMT(db, n) - 1, ", ");
1292 1294                  nfmt(db, "({0})", NULL);
↓ open down ↓ 29 lines elided ↑ open up ↑
1322 1324                  }
1323 1325          }
1324 1326  
1325 1327          njoin(db, NAMT(db, n), " ");
1326 1328          return (t2 + 1);
1327 1329  }
1328 1330  
1329 1331  static const char *
1330 1332  parse_del_expr(const char *first, const char *last, cpp_db_t *db)
1331 1333  {
1332      -        ASSERT3P(first, <=, last);
     1334 +        VERIFY3P(first, <=, last);
1333 1335  
1334 1336          if (last - first < 3)
1335 1337                  return (first);
1336 1338  
1337      -        ASSERT3U(first[0], ==, 'd');
1338      -        ASSERT(first[1] == 'l' || first[1] == 'a');
     1339 +        VERIFY3U(first[0], ==, 'd');
     1340 +        VERIFY(first[1] == 'l' || first[1] == 'a');
1339 1341  
1340 1342          size_t n = nlen(db);
1341 1343          const char *t = parse_expression(first + 2, last, db);
1342 1344          if (t == first + 2 || NAMT(db, n) != 1)
1343 1345                  return (first);
1344 1346  
1345 1347          nfmt(db, (first[1] == 'a') ? "delete[] {0}" : "delete {0}", NULL);
1346 1348          return (t);
1347 1349  }
1348 1350  
1349 1351  static const char *
1350 1352  parse_idx_expr(const char *first, const char *last, cpp_db_t *db)
1351 1353  {
1352      -        ASSERT3P(first, <=, last);
1353      -        ASSERT3U(first[0], ==, 'i');
1354      -        ASSERT3U(first[1], ==, 'x');
     1354 +        VERIFY3P(first, <=, last);
     1355 +        VERIFY3U(first[0], ==, 'i');
     1356 +        VERIFY3U(first[1], ==, 'x');
1355 1357  
1356 1358          size_t n = nlen(db);
1357 1359          const char *t1 = parse_expression(first + 2, last, db);
1358 1360          if (t1 == first + 2)
1359 1361                  return (first);
1360 1362  
1361 1363          const char *t2 = parse_expression(t1, last, db);
1362 1364          if (t2 == t1 || NAMT(db, n) != 2)
1363 1365                  return (first);
1364 1366  
1365 1367          nfmt(db, "({0})[{1}]", NULL);
1366 1368          return (t2);
1367 1369  }
1368 1370  
1369 1371  static const char *
1370 1372  parse_ppmm_expr(const char *first, const char *last, const char *fmt,
1371 1373      cpp_db_t *db)
1372 1374  {
1373      -        ASSERT3P(first, <=, last);
     1375 +        VERIFY3P(first, <=, last);
1374 1376  
1375 1377          if (last - first < 3)
1376 1378                  return (first);
1377 1379  
1378 1380          const char *t = NULL;
1379 1381          size_t n = nlen(db);
1380 1382  
1381 1383          if (first[2] == '_') {
1382 1384                  t = parse_binary_expr(first + 3, last, "--", db);
1383 1385                  if (t == first + 3)
↓ open down ↓ 5 lines elided ↑ open up ↑
1389 1391          if (t == first + 2 || NAMT(db, n) < 1)
1390 1392                  return (first);
1391 1393  
1392 1394          nfmt(db, fmt, NULL);
1393 1395          return (t);
1394 1396  }
1395 1397  
1396 1398  static const char *
1397 1399  parse_mm_expr(const char *first, const char *last, cpp_db_t *db)
1398 1400  {
1399      -        ASSERT3P(first, <=, last);
1400      -        ASSERT3U(first[0], ==, 'm');
1401      -        ASSERT3U(first[1], ==, 'm');
     1401 +        VERIFY3P(first, <=, last);
     1402 +        VERIFY3U(first[0], ==, 'm');
     1403 +        VERIFY3U(first[1], ==, 'm');
1402 1404  
1403 1405          return (parse_ppmm_expr(first, last, "({0})--", db));
1404 1406  }
1405 1407  
1406 1408  static const char *
1407 1409  parse_pp_expr(const char *first, const char *last, cpp_db_t *db)
1408 1410  {
1409      -        ASSERT3P(first, <=, last);
     1411 +        VERIFY3P(first, <=, last);
1410 1412  
1411      -        ASSERT3U(first[0], ==, 'p');
1412      -        ASSERT3U(first[0], ==, 'p');
     1413 +        VERIFY3U(first[0], ==, 'p');
     1414 +        VERIFY3U(first[0], ==, 'p');
1413 1415  
1414 1416          return (parse_ppmm_expr(first, last, "({0})++", db));
1415 1417  }
1416 1418  
1417 1419  static const char *
1418 1420  parse_trinary_expr(const char *first, const char *last, cpp_db_t *db)
1419 1421  {
1420      -        ASSERT3P(first, <=, last);
     1422 +        VERIFY3P(first, <=, last);
1421 1423  
1422 1424          const char *t1, *t2, *t3;
1423 1425          size_t n = nlen(db);
1424 1426  
1425 1427          if (last - first < 2)
1426 1428                  return (first);
1427 1429  
1428 1430          t1 = parse_expression(first + 2, last, db);
1429 1431          if (t1 == first + 2)
1430 1432                  return (first);
↓ open down ↓ 7 lines elided ↑ open up ↑
1438 1440          if (NAMT(db, n) != 3)
1439 1441                  return (first);
1440 1442  
1441 1443          nfmt(db, "({2}) ? ({1}) : ({0})", NULL);
1442 1444          return (t3);
1443 1445  }
1444 1446  
1445 1447  static const char *
1446 1448  parse_noexcept_expr(const char *first, const char *last, cpp_db_t *db)
1447 1449  {
1448      -        ASSERT3P(first, <=, last);
     1450 +        VERIFY3P(first, <=, last);
1449 1451  
1450 1452          if (last - first < 2)
1451 1453                  return (first);
1452 1454  
1453 1455          size_t n = nlen(db);
1454 1456          const char *t = parse_expression(first + 2, last, db);
1455 1457          if (t == first + 2 || NAMT(db, n) != 1)
1456 1458                  return (first);
1457 1459  
1458 1460          nfmt(db, "noexcept ({0})", NULL);
↓ open down ↓ 2 lines elided ↑ open up ↑
1461 1463  
1462 1464  /*
1463 1465   * cc <type> <expression>       # const_cast<type> (expression)
1464 1466   * dc <type> <expression>       # dynamic_cast<type> (expression)
1465 1467   * rc <type> <expression>       # reinterpret_cast<type> (expression)
1466 1468   * sc <type> <expression>       # static_cast<type> (expression)
1467 1469   */
1468 1470  static const char *
1469 1471  parse_cast_expr(const char *first, const char *last, cpp_db_t *db)
1470 1472  {
1471      -        ASSERT3P(first, <=, last);
     1473 +        VERIFY3P(first, <=, last);
1472 1474  
1473 1475          if (last - first < 2)
1474 1476                  return (first);
1475 1477  
1476 1478          const char *fmt = NULL;
1477 1479          switch (first[0]) {
1478 1480          case 'c':
1479 1481                  fmt = "const_cast<{1}> ({0})";
1480 1482                  break;
1481 1483          case 'd':
↓ open down ↓ 2 lines elided ↑ open up ↑
1484 1486          case 'r':
1485 1487                  fmt = "reinterpret_cast<{1}> ({0})";
1486 1488                  break;
1487 1489          case 's':
1488 1490                  fmt = "static_cast<{1}> ({0})";
1489 1491                  break;
1490 1492          default:
1491 1493                  return (first);
1492 1494          }
1493 1495  
1494      -        ASSERT3U(first[1], ==, 'c');
     1496 +        VERIFY3U(first[1], ==, 'c');
1495 1497  
1496 1498          const char *t1 = parse_type(first + 2, last, db);
1497 1499          if (t1 == first + 2)
1498 1500                  return (first);
1499 1501  
1500 1502          const char *t2 = parse_expression(t1, last, db);
1501 1503          if (t2 == t1)
1502 1504                  return (first);
1503 1505  
1504      -        ASSERT3U(nlen(db), >, 1);
     1506 +        VERIFY3U(nlen(db), >, 1);
1505 1507  
1506 1508          nfmt(db, fmt, NULL);
1507 1509          return (t2);
1508 1510  }
1509 1511  
1510 1512  /* pt <expression> <expression>         # expr->name */
1511 1513  static const char *
1512 1514  parse_arrow_expr(const char *first, const char *last, cpp_db_t *db)
1513 1515  {
1514      -        ASSERT3P(first, <=, last);
     1516 +        VERIFY3P(first, <=, last);
1515 1517  
1516 1518          if (last - first < 4)
1517 1519                  return (first);
1518 1520  
1519 1521          size_t n = nlen(db);
1520 1522  
1521 1523          const char *t1 = parse_expression(first + 2, last, db);
1522 1524          if (t1 == first + 2)
1523 1525                  return (first);
1524 1526  
↓ open down ↓ 44 lines elided ↑ open up ↑
1569 1571   * extension := U <objc-name> <objc-type>  # objc-type<identifier>
1570 1572   * extension := <vector-type> # <vector-type> starts with Dv
1571 1573   *
1572 1574   * <objc-name> ::= <k0 number> objcproto <k1 number> <identifier>  # k0 = 9 + <number of digits in k1> + k1
1573 1575   * <objc-type> := <source-name>  # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
1574 1576   */
1575 1577  /* END CSTYLED */
1576 1578  static const char *
1577 1579  parse_type(const char *first, const char *last, cpp_db_t *db)
1578 1580  {
1579      -        ASSERT3P(first, <=, last);
     1581 +        VERIFY3P(first, <=, last);
1580 1582  
1581 1583          if (first == last)
1582 1584                  return (first);
1583 1585  
1584 1586          switch (first[0]) {
1585 1587          case 'r':
1586 1588          case 'V':
1587 1589          case 'K':
1588 1590                  return (parse_qual_type(first, last, db));
1589 1591          }
↓ open down ↓ 146 lines elided ↑ open up ↑
1736 1738                      strncmp(name->str_s, "objcproto", 9) != 0) {
1737 1739                          nfmt(db, "{0} {1}", NULL);
1738 1740                  } else {
1739 1741                          t = parse_source_name(name->str_s + 9,
1740 1742                              name->str_s + name->str_len, db);
1741 1743                          if (t != name->str_s + 9) {
1742 1744                                  nfmt(db, "{1}<{0}>", NULL);
1743 1745  
1744 1746                                  str_pair_t save = {0};
1745 1747  
1746      -                                (void) name_pop(&db->cpp_name, &save);
     1748 +                                name_pop(&db->cpp_name, &save);
1747 1749  
1748 1750                                  /* get rid of 'objcproto' */
1749      -                                (void) name_pop(&db->cpp_name, NULL);
     1751 +                                name_pop(&db->cpp_name, NULL);
1750 1752                                  CK(name_add_str(&db->cpp_name, &save.strp_l,
1751 1753                                      &save.strp_r));
1752 1754                          } else {
1753 1755                                  nfmt(db, "{1} {0}", NULL);
1754 1756                          }
1755 1757                  }
1756 1758  
1757 1759                  save_top(db, 1);
1758 1760                  return (t1);
1759 1761  
↓ open down ↓ 74 lines elided ↑ open up ↑
1834 1836          if (t == first || NAMT(db, n) == 0)
1835 1837                  return (first);
1836 1838  
1837 1839          save_top(db, 1);
1838 1840          return (t);
1839 1841  }
1840 1842  
1841 1843  static const char *
1842 1844  parse_qual_type(const char *first, const char *last, cpp_db_t *db)
1843 1845  {
1844      -        ASSERT3P(first, <=, last);
     1846 +        VERIFY3P(first, <=, last);
1845 1847  
1846 1848          const char *t = NULL;
1847 1849          const char *t1 = NULL;
1848 1850          unsigned cv = 0;
1849 1851  
1850 1852          t = parse_cv_qualifiers(first, last, &cv);
1851 1853          if (t == first)
1852 1854                  return (first);
1853 1855  
1854 1856          size_t n = nlen(db);
↓ open down ↓ 54 lines elided ↑ open up ↑
1909 1911          return (t1);
1910 1912  }
1911 1913  
1912 1914  /*
1913 1915   * at <type>            # alignof (a type)
1914 1916   * az <expression>      # alignof (a expression)
1915 1917   */
1916 1918  static const char *
1917 1919  parse_alignof(const char *first, const char *last, cpp_db_t *db)
1918 1920  {
1919      -        ASSERT3P(first, <=, last);
     1921 +        VERIFY3P(first, <=, last);
1920 1922  
1921 1923          if (last - first < 2)
1922 1924                  return (first);
1923 1925  
1924 1926          const char *(*fn)(const char *, const char *, cpp_db_t *);
1925 1927  
1926 1928          fn = (first[1] == 't') ? parse_type : parse_expression;
1927 1929  
1928 1930          size_t n = nlen(db);
1929 1931          const char *t = fn(first + 2, last, db);
↓ open down ↓ 4 lines elided ↑ open up ↑
1934 1936          return (t);
1935 1937  }
1936 1938  
1937 1939  /*
1938 1940   * st <type>    # sizeof (a type)
1939 1941   * sz <expr>    # sizeof (a expression)
1940 1942   */
1941 1943  static const char *
1942 1944  parse_sizeof(const char *first, const char *last, cpp_db_t *db)
1943 1945  {
1944      -        ASSERT3P(first, <=, last);
     1946 +        VERIFY3P(first, <=, last);
1945 1947  
1946 1948          if (last - first < 2)
1947 1949                  return (first);
1948 1950  
1949      -        ASSERT3U(first[0], ==, 's');
     1951 +        VERIFY3U(first[0], ==, 's');
1950 1952  
1951 1953          const char *t = NULL;
1952 1954          size_t n = nlen(db);
1953 1955  
1954 1956          switch (first[1]) {
1955 1957          case 't':
1956 1958                  t = parse_type(first + 2, last, db);
1957 1959                  break;
1958 1960          case 'z':
1959 1961                  t = parse_expression(first + 2, last, db);
↓ open down ↓ 12 lines elided ↑ open up ↑
1972 1974  /*
1973 1975   * <function-param> ::= fp <top-level CV-qualifiers> _                                     # L == 0, first parameter
1974 1976   *                  ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L == 0, second and later parameters
1975 1977   *                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _         # L > 0, first parameter
1976 1978   *                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L > 0, second and later parameters
1977 1979   */
1978 1980  /* END CSTYLED */
1979 1981  static const char *
1980 1982  parse_function_param(const char *first, const char *last, cpp_db_t *db)
1981 1983  {
1982      -        ASSERT3P(first, <=, last);
     1984 +        VERIFY3P(first, <=, last);
1983 1985  
1984 1986          if (last - first < 3 || first[0] != 'f')
1985 1987                  return (first);
1986 1988  
1987 1989          const char *t1 = first + 2;
1988 1990          const char *t2 = NULL;
1989 1991          unsigned cv = 0;
1990 1992  
1991 1993          if (first[1] == 'L') {
1992      -                t2 = parse_number(t1, last);
     1994 +                t2 = parse_number(t1, last, db->cpp_loc);
1993 1995                  if (t2 == last || t2[0] != 'p')
1994 1996                          return (first);
1995 1997                  t1 = t2;
1996 1998          }
1997 1999  
1998 2000          if (first[1] != 'p')
1999 2001                  return (first);
2000 2002  
2001 2003          t1 = parse_cv_qualifiers(t1, last, &cv);
2002      -        t2 = parse_number(t1, last);
     2004 +        t2 = parse_number(t1, last, db->cpp_loc);
2003 2005          if (t2 == last || t2[0] != '_')
2004 2006                  return (first);
2005 2007  
2006 2008          if (t2 - t1 > 0)
2007 2009                  nadd_l(db, t1, (size_t)(t2 - t1));
2008 2010          else
2009 2011                  nadd_l(db, "", 0);
2010 2012  
2011 2013          nfmt(db, "fp{0}", NULL);
2012 2014          return (t2 + 1);
2013 2015  }
2014 2016  
2015 2017  /*
2016 2018   * sZ <template-param>          # size of a parameter pack
2017 2019   * sZ <function-param>          # size of a function parameter pack
2018 2020   */
2019 2021  static const char *
2020 2022  parse_sizeof_param_pack_expr(const char *first, const char *last, cpp_db_t *db)
2021 2023  {
2022      -        ASSERT3P(first, <=, last);
     2024 +        VERIFY3P(first, <=, last);
2023 2025  
2024 2026          if (last - first < 3)
2025 2027                  return (first);
2026 2028  
2027      -        ASSERT3U(first[0], ==, 's');
2028      -        ASSERT3U(first[1], ==, 'Z');
     2029 +        VERIFY3U(first[0], ==, 's');
     2030 +        VERIFY3U(first[1], ==, 'Z');
2029 2031  
2030 2032          if (first[2] != 'T' && first[2] != 'f')
2031 2033                  return (first);
2032 2034  
2033 2035          const char *t = NULL;
2034 2036          size_t n = nlen(db);
2035 2037  
2036 2038          if (first[2] == 'T')
2037 2039                  t = parse_template_param(first + 2, last, db);
2038 2040          else
↓ open down ↓ 7 lines elided ↑ open up ↑
2046 2048          return (t);
2047 2049  }
2048 2050  
2049 2051  /*
2050 2052   * te <expression>                                      # typeid (expression)
2051 2053   * ti <type>                                            # typeid (type)
2052 2054   */
2053 2055  static const char *
2054 2056  parse_typeid_expr(const char *first, const char *last, cpp_db_t *db)
2055 2057  {
2056      -        ASSERT3P(first, <=, last);
     2058 +        VERIFY3P(first, <=, last);
2057 2059  
2058 2060          if (last - first < 3)
2059 2061                  return (first);
2060 2062  
2061      -        ASSERT3U(first[0], ==, 't');
2062      -        ASSERT(first[1] == 'e' || first[1] == 'i');
     2063 +        VERIFY3U(first[0], ==, 't');
     2064 +        VERIFY(first[1] == 'e' || first[1] == 'i');
2063 2065  
2064 2066          const char *t = NULL;
2065 2067          size_t n = nlen(db);
2066 2068  
2067 2069          if (first[1] == 'e')
2068 2070                  t = parse_expression(first + 2, last, db);
2069 2071          else
2070 2072                  t = parse_type(first + 2, last, db);
2071 2073  
2072 2074          if (t == first + 2 || NAMT(db, n) != 1)
↓ open down ↓ 3 lines elided ↑ open up ↑
2076 2078          return (t);
2077 2079  }
2078 2080  
2079 2081  /*
2080 2082   * tr                                                   # throw
2081 2083   * tw <expression>                                      # throw expression
2082 2084   */
2083 2085  static const char *
2084 2086  parse_throw_expr(const char *first, const char *last, cpp_db_t *db)
2085 2087  {
2086      -        ASSERT3P(first, <=, last);
     2088 +        VERIFY3P(first, <=, last);
2087 2089  
2088 2090          if (last - first < 3)
2089 2091                  return (first);
2090 2092  
2091      -        ASSERT3U(first[0], ==, 't');
2092      -        ASSERT(first[1] == 'w' || first[1] == 'r');
     2093 +        VERIFY3U(first[0], ==, 't');
     2094 +        VERIFY(first[1] == 'w' || first[1] == 'r');
2093 2095  
2094 2096          if (first[1] == 'r') {
2095 2097                  nadd_l(db, "throw", 0);
2096 2098                  return (first + 2);
2097 2099          }
2098 2100  
2099 2101          size_t n = nlen(db);
2100 2102          const char *t = parse_expression(first + 2, last, db);
2101 2103          if (t == first + 2 || NAMT(db, n) != 1)
2102 2104                  return (first);
2103 2105  
2104 2106          nfmt(db, "throw {0}", NULL);
2105 2107          return (t);
2106 2108  }
2107 2109  
2108 2110  /* ds <expression> <expression>         # expr.*expr */
2109 2111  static const char *
2110 2112  parse_dot_star_expr(const char *first, const char *last, cpp_db_t *db)
2111 2113  {
2112      -        ASSERT3P(first, <=, last);
     2114 +        VERIFY3P(first, <=, last);
2113 2115  
2114 2116          if (last - first < 3)
2115 2117                  return (first);
2116 2118  
2117      -        ASSERT3U(first[0], ==, 'd');
2118      -        ASSERT3U(first[1], ==, 's');
     2119 +        VERIFY3U(first[0], ==, 'd');
     2120 +        VERIFY3U(first[1], ==, 's');
2119 2121  
2120 2122          size_t n = nlen(db);
2121 2123          const char *t = parse_expression(first + 2, last, db);
2122 2124          if (t == first + 2)
2123 2125                  return (first);
2124 2126  
2125 2127          const char *t2 = parse_expression(t, last, db);
2126 2128          if (t == t2 || NAMT(db, n) != 2)
2127 2129                  return (first);
2128 2130  
2129 2131          nfmt(db, "{1}.*{0}", NULL);
2130 2132          return (t2);
2131 2133  }
2132 2134  
2133 2135  /* dt <expression> <unresolved-name>            # expr.name */
2134 2136  static const char *
2135 2137  parse_dot_expr(const char *first, const char *last, cpp_db_t *db)
2136 2138  {
2137      -        ASSERT3P(first, <=, last);
     2139 +        VERIFY3P(first, <=, last);
2138 2140  
2139 2141          if (last - first < 3)
2140 2142                  return (first);
2141 2143  
2142      -        ASSERT3U(first[0], ==, 'd');
2143      -        ASSERT3U(first[1], ==, 't');
     2144 +        VERIFY3U(first[0], ==, 'd');
     2145 +        VERIFY3U(first[1], ==, 't');
2144 2146  
2145 2147          const char *t = parse_expression(first + 2, last, db);
2146 2148          if (t == first + 2)
2147 2149                  return (first);
2148 2150  
2149 2151          const char *t1 = parse_unresolved_name(t, last, db);
2150 2152          if (t1 == t)
2151 2153                  return (first);
2152 2154  
2153 2155          nfmt(db, "{1}.{0}", NULL);
2154 2156          return (t1);
2155 2157  }
2156 2158  
2157 2159  /* cl <expression>+ E           # call */
2158 2160  static const char *
2159 2161  parse_call_expr(const char *first, const char *last, cpp_db_t *db)
2160 2162  {
2161      -        ASSERT3P(first, <=, last);
     2163 +        VERIFY3P(first, <=, last);
2162 2164  
2163 2165          if (last - first < 4)
2164 2166                  return (first);
2165 2167  
2166      -        ASSERT3U(first[0], ==, 'c');
2167      -        ASSERT3U(first[1], ==, 'l');
     2168 +        VERIFY3U(first[0], ==, 'c');
     2169 +        VERIFY3U(first[1], ==, 'l');
2168 2170  
2169 2171          const char *t = first + 2;
2170 2172          const char *t1 = NULL;
2171 2173          size_t n = nlen(db);
2172 2174  
2173 2175          for (t = first + 2; t != last && t[0] != 'E'; t = t1) {
2174 2176                  t1 = parse_expression(t, last, db);
2175 2177                  if (t1 == t)
2176 2178                          return (first);
2177 2179          }
2178 2180  
2179 2181          size_t amt = NAMT(db, n);
2180 2182  
2181 2183          if (t == last || amt == 0)
2182 2184                  return (first);
2183 2185  
2184 2186          njoin(db, amt - 1, ", ");
2185 2187          nfmt(db, "{1}({0})", NULL);
2186 2188  
2187      -        ASSERT3U(t[0], ==, 'E');
     2189 +        VERIFY3U(t[0], ==, 'E');
2188 2190          return (t + 1);
2189 2191  }
2190 2192  
2191 2193  /* BEGIN CSTYLED */
2192 2194  /*
2193 2195   * cv <type> <expression>       # conversion with one argument
2194 2196   * cv <type> _ <expression>* E  # conversion with a different number of arguments
2195 2197   */
2196 2198  /* END CSTYLED */
2197 2199  static const char *
2198 2200  parse_conv_expr(const char *first, const char *last, cpp_db_t *db)
2199 2201  {
2200      -        ASSERT3P(first, <=, last);
     2202 +        VERIFY3P(first, <=, last);
2201 2203  
2202 2204          if (last - first < 3)
2203 2205                  return (first);
2204 2206  
2205      -        ASSERT3U(first[0], ==, 'c');
2206      -        ASSERT3U(first[1], ==, 'v');
     2207 +        VERIFY3U(first[0], ==, 'c');
     2208 +        VERIFY3U(first[1], ==, 'v');
2207 2209  
2208 2210          const char *t = NULL;
2209 2211          const char *t1 = NULL;
2210 2212          size_t n = nlen(db);
2211 2213  
2212 2214          boolean_t try_to_parse_template_args =
2213 2215              db->cpp_try_to_parse_template_args;
2214 2216  
2215 2217          db->cpp_try_to_parse_template_args = B_FALSE;
2216 2218          t = parse_type(first + 2, last, db);
↓ open down ↓ 30 lines elided ↑ open up ↑
2247 2249                  return (first);
2248 2250  
2249 2251          nfmt(db, "({1})({0})", NULL);
2250 2252          return (t);
2251 2253  }
2252 2254  
2253 2255  /* <simple-id> ::= <source-name> [ <template-args> ] */
2254 2256  static const char *
2255 2257  parse_simple_id(const char *first, const char *last, cpp_db_t *db)
2256 2258  {
2257      -        ASSERT3P(first, <=, last);
     2259 +        VERIFY3P(first, <=, last);
2258 2260  
2259 2261          const char *t = parse_source_name(first, last, db);
2260 2262          if (t == first)
2261 2263                  return (t);
2262 2264  
2263 2265          const char *t1 = parse_template_args(t, last, db);
2264 2266          if (t == t1)
2265 2267                  return (t);
2266 2268  
2267 2269          nfmt(db, "{1}{0}", NULL);
↓ open down ↓ 1 lines elided ↑ open up ↑
2269 2271  }
2270 2272  
2271 2273  /*
2272 2274   * <unresolved-type> ::= <template-param>
2273 2275   *                   ::= <decltype>
2274 2276   *                   ::= <substitution>
2275 2277   */
2276 2278  static const char *
2277 2279  parse_unresolved_type(const char *first, const char *last, cpp_db_t *db)
2278 2280  {
2279      -        ASSERT3P(first, <=, last);
     2281 +        VERIFY3P(first, <=, last);
2280 2282  
2281 2283          if (first == last)
2282 2284                  return (first);
2283 2285  
2284 2286          const char *t = first;
2285 2287          size_t n = nlen(db);
2286 2288  
2287 2289          switch (first[0]) {
2288 2290          case 'T':
2289 2291                  t = parse_template_param(first, last, db);
2290 2292                  if (t == first || NAMT(db, n) != 1) {
2291 2293                          for (size_t i = 0; i < NAMT(db, n); i++)
2292      -                                (void) name_pop(&db->cpp_name, NULL);
     2294 +                                name_pop(&db->cpp_name, NULL);
2293 2295                          return (first);
2294 2296                  }
2295 2297                  save_top(db, 1);
2296 2298                  return (t);
2297 2299  
2298 2300          case 'D':
2299 2301                  t = parse_decltype(first, last, db);
2300 2302                  if (t == first || NAMT(db, n) == 0)
2301 2303                          return (first);
2302 2304                  save_top(db, 1);
↓ open down ↓ 16 lines elided ↑ open up ↑
2319 2321                  return (t);
2320 2322          }
2321 2323  
2322 2324          return (first);
2323 2325  }
2324 2326  
2325 2327  /* sp <expression>              # pack expansion */
2326 2328  static const char *
2327 2329  parse_pack_expansion(const char *first, const char *last, cpp_db_t *db)
2328 2330  {
2329      -        ASSERT3P(first, <=, last);
     2331 +        VERIFY3P(first, <=, last);
2330 2332  
2331 2333          if (last - first < 3)
2332 2334                  return (first);
2333 2335  
2334      -        ASSERT3U(first[0], ==, 's');
2335      -        ASSERT3U(first[1], ==, 'p');
     2336 +        VERIFY3U(first[0], ==, 's');
     2337 +        VERIFY3U(first[1], ==, 'p');
2336 2338  
2337 2339          const char *t = parse_expression(first + 2, last, db);
2338 2340          if (t == first +2)
2339 2341                  return (first);
2340 2342  
2341 2343          return (t);
2342 2344  }
2343 2345  
2344 2346  /*
2345 2347   * <unscoped-name> ::= <unqualified-name>
2346 2348   *                 ::= St <unqualified-name>   # ::std::
2347 2349   * extension       ::= StL<unqualified-name>
2348 2350   */
2349 2351  static const char *
2350 2352  parse_unscoped_name(const char *first, const char *last, cpp_db_t *db)
2351 2353  {
2352      -        ASSERT3P(first, <=, last);
     2354 +        VERIFY3P(first, <=, last);
2353 2355  
2354 2356          if (last - first < 2)
2355 2357                  return (first);
2356 2358  
2357 2359          const char *t = first;
2358 2360          const char *t1 = NULL;
2359 2361          boolean_t st = B_FALSE;
2360 2362  
2361 2363          if (first[0] == 'S' && first[1] == 't') {
2362 2364                  st = B_TRUE;
↓ open down ↓ 15 lines elided ↑ open up ↑
2378 2380  
2379 2381  /*
2380 2382   * <unqualified-name> ::= <operator-name>
2381 2383   *                    ::= <ctor-dtor-name>
2382 2384   *                    ::= <source-name>
2383 2385   *                    ::= <unnamed-type-name>
2384 2386   */
2385 2387  const char *
2386 2388  parse_unqualified_name(const char *first, const char *last, cpp_db_t *db)
2387 2389  {
2388      -        ASSERT3P(first, <=, last);
     2390 +        VERIFY3P(first, <=, last);
2389 2391  
2390 2392          if (first == last)
2391 2393                  return (first);
2392 2394  
2393 2395          switch (*first) {
2394 2396          case 'C':
2395 2397          case 'D':
2396 2398                  return (parse_ctor_dtor_name(first, last, db));
2397 2399          case 'U':
2398 2400                  return (parse_unnamed_type_name(first, last, db));
↓ open down ↓ 18 lines elided ↑ open up ↑
2417 2419   *                     ::= <closure-type-name>
2418 2420   *
2419 2421   * <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2420 2422   *
2421 2423   * <lambda-sig> ::= <parameter type>+
2422 2424   *                      # Parameter types or "v" if the lambda has no parameters
2423 2425   */
2424 2426  static const char *
2425 2427  parse_unnamed_type_name(const char *first, const char *last, cpp_db_t *db)
2426 2428  {
2427      -        ASSERT3P(first, <=, last);
     2429 +        VERIFY3P(first, <=, last);
2428 2430  
2429 2431          if (last - first < 2 || first[0] != 'U')
2430 2432                  return (first);
2431 2433  
2432 2434          if (first[1] != 't' && first[1] != 'l')
2433 2435                  return (first);
2434 2436  
2435 2437          const char *t1 = first + 2;
2436 2438          const char *t2 = NULL;
2437 2439  
2438 2440          if (first[1] == 't') {
2439      -                while (t1 != last && t1[0] != '_' && is_digit(t1[0]))
     2441 +                while (t1 != last && t1[0] != '_' &&
     2442 +                    isdigit_l(t1[0], db->cpp_loc))
2440 2443                          t1++;
2441 2444  
2442 2445                  if (t1[0] != '_')
2443 2446                          return (first);
2444 2447  
2445 2448                  if (t1 == first + 2)
2446 2449                          nadd_l(db, "", 0);
2447 2450                  else
2448 2451                          nadd_l(db, first + 2, (size_t)(t1 - first - 2));
2449 2452  
↓ open down ↓ 22 lines elided ↑ open up ↑
2472 2475                          return (first);
2473 2476          }
2474 2477  
2475 2478          njoin(db, NAMT(db, n), ", ");
2476 2479  
2477 2480          /* E */
2478 2481          t1++;
2479 2482  
2480 2483          t2 = t1;
2481 2484          while (t2 != last && t2[0] != '_') {
2482      -                if (!is_digit(*t2++))
     2485 +                if (!isdigit_l(*t2++, db->cpp_loc))
2483 2486                          return (first);
2484 2487          }
2485 2488  
2486 2489          if (t2[0] != '_')
2487 2490                  return (first);
2488 2491  
2489 2492          if (t2 - t1 > 0)
2490 2493                  nadd_l(db, t1, (size_t)(t2 - t1));
2491 2494          else
2492 2495                  nadd_l(db, "", 0);
↓ open down ↓ 72 lines elided ↑ open up ↑
2565 2568                                  }
2566 2569                                  break;
2567 2570                          case '>':
2568 2571                                  c++;
2569 2572                                  break;
2570 2573                          }
2571 2574                  }
2572 2575          }
2573 2576  
2574 2577  out:
2575      -        ASSERT3P(end, >=, start);
     2578 +        VERIFY3P(end, >=, start);
2576 2579  
2577 2580          if (end - start < 2) {
2578 2581                  nadd_l(db, "", 0);
2579 2582                  return;
2580 2583          }
2581 2584  
2582 2585          for (start = end - 1; start > s->str_s; start--) {
2583 2586                  if (start[0] == ':') {
2584 2587                          start++;
2585 2588                          break;
2586 2589                  }
2587 2590          }
2588 2591  
2589      -        ASSERT3P(end, >=, start);
     2592 +        VERIFY3P(end, >=, start);
2590 2593  
2591 2594          nadd_l(db, start, (size_t)(end - start));
2592 2595  }
2593 2596  
2594 2597  /*
2595 2598   * <ctor-dtor-name> ::= C1    # complete object constructor
2596 2599   *                  ::= C2    # base object constructor
2597 2600   *                  ::= C3    # complete object allocating constructor
2598 2601   *   extension      ::= C5    # ?
2599 2602   *                  ::= D0    # deleting destructor
2600 2603   *                  ::= D1    # complete object destructor
2601 2604   *                  ::= D2    # base object destructor
2602 2605   *   extension      ::= D5    # ?
2603 2606   */
2604 2607  static const char *
2605 2608  parse_ctor_dtor_name(const char *first, const char *last, cpp_db_t *db)
2606 2609  {
2607      -        ASSERT3P(first, <=, last);
     2610 +        VERIFY3P(first, <=, last);
2608 2611  
2609 2612          if (last - first < 2 || nempty(db) || str_length(TOP_L(db)) == 0)
2610 2613                  return (first);
2611 2614  
2612 2615          switch (first[0]) {
2613 2616          case 'C':
2614 2617                  switch (first[1]) {
2615 2618                  case '1':
2616 2619                  case '2':
2617 2620                  case '3':
↓ open down ↓ 22 lines elided ↑ open up ↑
2640 2643          }
2641 2644  
2642 2645          db->cpp_parsed_ctor_dtor_cv = B_TRUE;
2643 2646          return (first + 2);
2644 2647  }
2645 2648  
2646 2649  static const char *
2647 2650  parse_integer_literal(const char *first, const char *last, const char *fmt,
2648 2651      cpp_db_t *db)
2649 2652  {
2650      -        ASSERT3P(first, <=, last);
     2653 +        VERIFY3P(first, <=, last);
2651 2654  
2652      -        const char *t = parse_number(first, last);
     2655 +        const char *t = parse_number(first, last, db->cpp_loc);
2653 2656          const char *start = first;
2654 2657  
2655 2658          if (t == first || t == last || t[0] != 'E')
2656 2659                  return (first);
2657 2660  
2658 2661          if (first[0] == 'n')
2659 2662                  start++;
2660 2663  
2661 2664          nadd_l(db, start, (size_t)(t - start));
2662 2665          if (start != first)
↓ open down ↓ 10 lines elided ↑ open up ↑
2673 2676          char type;
2674 2677  } float_info[] = {
2675 2678          { "%af", 8, 24, 'f' },          /* float */
2676 2679          { "%a", 16, 32, 'd' },          /* double */
2677 2680          { "%LaL", 20, 40, 'e' }         /* long double */
2678 2681  };
2679 2682  
2680 2683  static const char *
2681 2684  parse_floating_literal(const char *first, const char *last, cpp_db_t *db)
2682 2685  {
2683      -        ASSERT3P(first, <=, last);
2684      -        ASSERT(first[0] == 'f' || first[0] == 'd' || first[0] == 'e');
     2686 +        VERIFY3P(first, <=, last);
     2687 +        VERIFY(first[0] == 'f' || first[0] == 'd' || first[0] == 'e');
2685 2688  
2686 2689          const struct float_data_s *fd = NULL;
2687 2690  
2688 2691          for (size_t i = 0; i < ARRAY_SIZE(float_info); i++) {
2689 2692                  if (float_info[i].type != first[0])
2690 2693                          continue;
2691 2694  
2692 2695                  fd = &float_info[i];
2693 2696                  break;
2694 2697          }
↓ open down ↓ 30 lines elided ↑ open up ↑
2725 2728                  e = conv.ld.buf;
2726 2729                  break;
2727 2730          }
2728 2731          last = first + fd->mangled_size + 1;
2729 2732  
2730 2733  #if defined(_BIG_ENDIAN)
2731 2734          for (t = first + 1; t != last; t++, e++) {
2732 2735                  if (!is_xdigit(t[0]))
2733 2736                          return (first);
2734 2737  
2735      -                unsigned d1 = is_digit(t[0]) ? t[0] - '0' : t[0] - 'a' + 10;
     2738 +                unsigned d1 = isdigit_l(t[0], db->cpp_loc) ? t[0] - '0' : t[0] - 'a' + 10;
2736 2739                  t++;
2737      -                unsigned d0 = is_digit(t[0]) ? t[0] - '0' : t[0] - 'a' + 10;
     2740 +                unsigned d0 = isdigit_l(t[0], db->cpp_loc) ? t[0] - '0' : t[0] - 'a' + 10;
2738 2741  
2739 2742                  *e = (d1 << 4) + d0;
2740 2743          }
2741 2744  #elif defined(_LITTLE_ENDIAN)
2742 2745          for (t = last - 1; t > first; t--, e++) {
2743 2746                  if (!is_xdigit(t[0]))
2744 2747                          return (first);
2745 2748  
2746      -                unsigned d0 = is_digit(t[0]) ? t[0] - '0' : t[0] - 'a' + 10;
     2749 +                unsigned d0 = isdigit_l(t[0], db->cpp_loc) ? t[0] - '0' : t[0] - 'a' + 10;
2747 2750                  t--;
2748      -                unsigned d1 = is_digit(t[0]) ? t[0] - '0' : t[0] - 'a' + 10;
     2751 +                unsigned d1 = isdigit_l(t[0], db->cpp_loc) ? t[0] - '0' : t[0] - 'a' + 10;
2749 2752  
2750 2753                  *e = (d1 << 4) + d0;
2751 2754          }
2752 2755          t = last;
2753 2756  #else
2754 2757  #error One of _BIG_ENDIAN or _LITTLE_ENDIAN must be defined
2755 2758  #endif
2756 2759  
2757 2760          if (t[0] != 'E')
2758 2761                  return (first);
↓ open down ↓ 60 lines elided ↑ open up ↑
2819 2822          { 's', "(short){0}" },
2820 2823          { 't', "(unsigned short){0}" },
2821 2824          { 'w', "(wchar_t){0}" },
2822 2825          { 'x', "{0}ll" },
2823 2826          { 'y', "{0}ull" }
2824 2827  };
2825 2828  
2826 2829  static const char *
2827 2830  parse_expr_primary(const char *first, const char *last, cpp_db_t *db)
2828 2831  {
2829      -        ASSERT3P(first, <=, last);
     2832 +        VERIFY3P(first, <=, last);
2830 2833  
2831 2834          if (last - first < 4 || first[0] != 'L')
2832 2835                  return (first);
2833 2836  
2834 2837          const char *t = NULL;
2835 2838  
2836 2839          for (size_t i = 0; i < ARRAY_SIZE(int_lits); i++) {
2837 2840                  if (first[1] == int_lits[i].c) {
2838 2841                          t = parse_integer_literal(first + 2, last,
2839 2842                              int_lits[i].fmt, db);
↓ open down ↓ 43 lines elided ↑ open up ↑
2883 2886                  return (t + 1);
2884 2887          default:
2885 2888                  t = parse_type(first + 1, last, db);
2886 2889                  if (t == first + 1 || t == last)
2887 2890                          return (first);
2888 2891  
2889 2892                  if (t[0] == 'E')
2890 2893                          return (t + 1);
2891 2894  
2892 2895                  const char *n;
2893      -                for (n = t; n != last && is_digit(n[0]); n++)
     2896 +                for (n = t; n != last && isdigit_l(n[0], db->cpp_loc); n++)
2894 2897                          ;
2895 2898                  if (n == last || nempty(db) || n[0] != 'E')
2896 2899                          return (first);
2897 2900                  if (n == t)
2898 2901                          return (t);
2899 2902  
2900 2903                  nadd_l(db, t, (size_t)(n - t));
2901 2904                  nfmt(db, "({1}){0}", NULL);
2902 2905  
2903 2906                  return (n + 1);
↓ open down ↓ 102 lines elided ↑ open up ↑
3006 3009          { "qu", "operator?" },
3007 3010          { "rm", "operator%" },
3008 3011          { "rM", "operator%=" },
3009 3012          { "rs", "operator>>" },
3010 3013          { "rS", "operator>>=" }
3011 3014  };
3012 3015  
3013 3016  static const char *
3014 3017  parse_operator_name(const char *first, const char *last, cpp_db_t *db)
3015 3018  {
3016      -        ASSERT3P(first, <=, last);
     3019 +        VERIFY3P(first, <=, last);
3017 3020  
3018 3021          if (last - first < 2)
3019 3022                  return (first);
3020 3023  
3021 3024          for (size_t i = 0; i < ARRAY_SIZE(op_tbl); i++) {
3022 3025                  if (strncmp(first, op_tbl[i].code, 2) != 0)
3023 3026                          continue;
3024 3027  
3025 3028                  nadd_l(db, op_tbl[i].op, 0);
3026 3029                  return (first + 2);
↓ open down ↓ 4 lines elided ↑ open up ↑
3031 3034          if (first[0] == 'l' && first[1] == 'i') {
3032 3035                  t = parse_source_name(first + 2, last, db);
3033 3036                  if (t == first + 2 || nempty(db))
3034 3037                          return (first);
3035 3038  
3036 3039                  nfmt(db, "operator\"\" {0}", NULL);
3037 3040                  return (t);
3038 3041          }
3039 3042  
3040 3043          if (first[0] == 'v') {
3041      -                if (!is_digit(first[1]))
     3044 +                if (!isdigit_l(first[1], db->cpp_loc))
3042 3045                          return (first);
3043 3046  
3044 3047                  t = parse_source_name(first + 2, last, db);
3045 3048                  if (t == first + 2)
3046 3049                          return (first);
3047 3050  
3048 3051                  nfmt(db, "operator {0}", NULL);
3049 3052                  return (t);
3050 3053          }
3051 3054  
↓ open down ↓ 52 lines elided ↑ open up ↑
3104 3107          { 'f', "decimal32" },
3105 3108          { 'h', "decimal16" },
3106 3109          { 'i', "char32_t" },
3107 3110          { 'n', "std::nullptr_t" },
3108 3111          { 's', "char16_t" }
3109 3112  };
3110 3113  
3111 3114  static const char *
3112 3115  parse_builtin_type(const char *first, const char *last, cpp_db_t *db)
3113 3116  {
3114      -        ASSERT3P(first, <=, last);
     3117 +        VERIFY3P(first, <=, last);
3115 3118  
3116 3119          if (first == last)
3117 3120                  return (first);
3118 3121  
3119 3122          size_t i;
3120 3123  
3121 3124          for (i = 0; i < ARRAY_SIZE(type_tbl1); i++) {
3122 3125                  if (first[0] == type_tbl1[i].code) {
3123 3126                          nadd_l(db, type_tbl1[i].name, 0);
3124 3127                          return (first + 1);
↓ open down ↓ 15 lines elided ↑ open up ↑
3140 3143                  const char *t = parse_source_name(first + 1, last, db);
3141 3144                  if (t == first + 1)
3142 3145                          return (first);
3143 3146                  return (t);
3144 3147          }
3145 3148  
3146 3149          return (first);
3147 3150  }
3148 3151  
3149 3152  static const char *
3150      -parse_base36(const char *first, const char *last, size_t *val)
     3153 +parse_base36(const char *first, const char *last, size_t *val, locale_t loc)
3151 3154  {
3152      -        ASSERT3P(first, <=, last);
     3155 +        VERIFY3P(first, <=, last);
3153 3156  
3154 3157          const char *t;
3155 3158  
3156 3159          for (t = first, *val = 0; t != last; t++) {
3157      -                if (!is_digit(t[0]) && !is_upper(t[0]))
     3160 +                if (!isdigit_l(t[0], loc) && !isupper_l(t[0], loc))
3158 3161                          return (t);
3159 3162  
3160 3163                  *val *= 36;
3161 3164  
3162      -                if (is_digit(t[0]))
     3165 +                if (isdigit_l(t[0], loc))
3163 3166                          *val += t[0] - '0';
3164 3167                  else
3165 3168                          *val += t[0] - 'A' + 10;
3166 3169          }
3167 3170          return (t);
3168 3171  }
3169 3172  
3170 3173  static struct type_tbl_s sub_tbl[] = {
3171 3174          { 'a', "std::allocator" },
3172 3175          { 'b', "std::basic_string" },
3173 3176          { 's', "std::string" },
3174 3177          { 'i', "std::istream" },
3175 3178          { 'o', "std::ostream" },
3176 3179          { 'd', "std::iostream" }
3177 3180  };
3178 3181  
3179 3182  static const char *
3180 3183  parse_substitution(const char *first, const char *last, cpp_db_t *db)
3181 3184  {
3182      -        ASSERT3P(first, <=, last);
     3185 +        VERIFY3P(first, <=, last);
3183 3186  
3184 3187          if (first == last || last - first < 2)
3185 3188                  return (first);
3186 3189  
3187 3190          if (first[0] != 'S')
3188 3191                  return (first);
3189 3192  
3190 3193          for (size_t i = 0; i < ARRAY_SIZE(sub_tbl); i++) {
3191 3194                  if (first[1] == sub_tbl[i].code) {
3192 3195                          nadd_l(db, sub_tbl[i].name, 0);
3193 3196                          return (first + 2);
3194 3197                  }
3195 3198          }
3196 3199  
3197 3200          const char *t = first + 1;
3198 3201          size_t n = 0;
3199 3202  
3200 3203          if (t[0] != '_') {
3201      -                t = parse_base36(first + 1, last, &n);
     3204 +                t = parse_base36(first + 1, last, &n, db->cpp_loc);
3202 3205                  if (t == first + 1 || t[0] != '_')
3203 3206                          return (first);
3204 3207  
3205 3208                  /*
3206 3209                   * S_ == substitution 0,
3207 3210                   * S0_ == substituion 1,
3208 3211                   * ...
3209 3212                   */
3210 3213                  n++;
3211 3214          }
3212 3215  
3213 3216          if (n >= sub_len(&db->cpp_subs))
3214 3217                  return (first);
3215 3218  
3216 3219          sub(db, n);
3217 3220  
3218 3221          /* skip _ */
3219      -        ASSERT3U(t[0], ==, '_');
     3222 +        VERIFY3U(t[0], ==, '_');
3220 3223  
3221 3224          return (t + 1);
3222 3225  }
3223 3226  
3224 3227  static const char *
3225 3228  parse_source_name(const char *first, const char *last, cpp_db_t *db)
3226 3229  {
3227      -        ASSERT3P(first, <=, last);
     3230 +        VERIFY3P(first, <=, last);
3228 3231  
3229 3232          if (first == last)
3230 3233                  return (first);
3231 3234  
3232 3235          const char *t = NULL;
3233 3236          size_t n = 0;
3234 3237  
3235      -        for (t = first; t != last && is_digit(t[0]); t++) {
     3238 +        for (t = first; t != last && isdigit_l(t[0], db->cpp_loc); t++) {
3236 3239                  /* make sure we don't overflow */
3237 3240                  size_t nn = n * 10;
3238 3241                  if (nn < n)
3239 3242                          return (first);
3240 3243  
3241 3244                  nn += t[0] - '0';
3242 3245                  if (nn < n)
3243 3246                          return (first);
3244 3247  
3245 3248                  n = nn;
↓ open down ↓ 15 lines elided ↑ open up ↑
3261 3264   * extension:
3262 3265   * <vector-type>           ::= Dv <positive dimension number> _
3263 3266   *                                    <extended element type>
3264 3267   *                         ::= Dv [<dimension expression>] _ <element type>
3265 3268   * <extended element type> ::= <element type>
3266 3269   *                         ::= p # AltiVec vector pixel
3267 3270   */
3268 3271  static const char *
3269 3272  parse_vector_type(const char *first, const char *last, cpp_db_t *db)
3270 3273  {
3271      -        ASSERT3P(first, <=, last);
     3274 +        VERIFY3P(first, <=, last);
3272 3275  
3273 3276          if (last - first < 3)
3274 3277                  return (first);
3275 3278  
3276      -        ASSERT3U(first[0], ==, 'D');
3277      -        ASSERT3U(first[1], ==, 'v');
     3279 +        VERIFY3U(first[0], ==, 'D');
     3280 +        VERIFY3U(first[1], ==, 'v');
3278 3281  
3279 3282          const char *t = first + 2;
3280 3283          const char *t1 = NULL;
3281 3284  
3282      -        if (is_digit(first[2]) && first[2] != '0') {
3283      -                t1 = parse_number(t, last);
     3285 +        if (isdigit_l(first[2], db->cpp_loc) && first[2] != '0') {
     3286 +                t1 = parse_number(t, last, db->cpp_loc);
3284 3287                  if (t1 == last || t1 + 1 == last || t1[0] != '_')
3285 3288                          return (first);
3286 3289  
3287 3290                  nadd_l(db, t, (size_t)(t1 - t));
3288 3291  
3289 3292                  /* skip _ */
3290 3293                  t = t1 + 1;
3291 3294  
3292 3295                  if (t[0] != 'p') {
3293 3296                          t1 = parse_type(t, last, db);
↓ open down ↓ 28 lines elided ↑ open up ↑
3322 3325  
3323 3326  /* BEGIN CSTYLED */
3324 3327  /*
3325 3328   * <decltype>  ::= Dt <expression> E  # decltype of an id-expression or class member access (C++0x)
3326 3329   *             ::= DT <expression> E  # decltype of an expression (C++0x)
3327 3330   */
3328 3331  /* END CSTYLED */
3329 3332  static const char *
3330 3333  parse_decltype(const char *first, const char *last, cpp_db_t *db)
3331 3334  {
3332      -        ASSERT3P(first, <=, last);
     3335 +        VERIFY3P(first, <=, last);
3333 3336  
3334 3337          if (last - first < 4)
3335 3338                  return (first);
3336 3339  
3337      -        ASSERT3U(first[0], ==, 'D');
     3340 +        VERIFY3U(first[0], ==, 'D');
3338 3341  
3339 3342          if (first[1] != 't' && first[1] != 'T')
3340 3343                  return (first);
3341 3344  
3342 3345          size_t n = nlen(db);
3343 3346          const char *t = parse_expression(first + 2, last, db);
3344 3347          if (NAMT(db, n) != 1 || t == first + 2 || t == last || t[0] != 'E')
3345 3348                  return (first);
3346 3349  
3347 3350          nfmt(db, "decltype({0})", NULL);
↓ open down ↓ 2 lines elided ↑ open up ↑
3350 3353          return (t + 1);
3351 3354  }
3352 3355  
3353 3356  /*
3354 3357   * <array-type> ::= A <positive dimension number> _ <element type>
3355 3358   *              ::= A [<dimension expression>] _ <element type>
3356 3359   */
3357 3360  static const char *
3358 3361  parse_array_type(const char *first, const char *last, cpp_db_t *db)
3359 3362  {
3360      -        ASSERT3P(first, <=, last);
3361      -        ASSERT3U(first[0], ==, 'A');
     3363 +        VERIFY3P(first, <=, last);
     3364 +        VERIFY3U(first[0], ==, 'A');
3362 3365  
3363 3366          if (last - first < 3)
3364 3367                  return (first);
3365 3368  
3366 3369          const char *t = first + 1;
3367 3370          const char *t1 = NULL;
3368 3371          size_t n = nlen(db);
3369 3372  
3370 3373          if (t[0] != '_') {
3371      -                if (is_digit(t[0]) && t[0] != '0') {
3372      -                        t1 = parse_number(t, last);
     3374 +                if (isdigit_l(t[0], db->cpp_loc) && t[0] != '0') {
     3375 +                        t1 = parse_number(t, last, db->cpp_loc);
3373 3376                          if (t1 == last)
3374 3377                                  return (first);
3375 3378  
3376 3379                          nadd_l(db, t, (size_t)(t1 - t));
3377 3380                  } else {
3378 3381                          t1 = parse_expression(t, last, db);
3379 3382                          if (t1 == last || t == t1)
3380 3383                                  return (first);
3381 3384                  }
3382 3385  
3383 3386                  if (t1[0] != '_')
3384 3387                          return (first);
3385 3388  
3386 3389                  t = t1;
3387 3390          } else {
3388 3391                  nadd_l(db, "", 0);
3389 3392          }
3390 3393  
3391      -        ASSERT3U(t[0], ==, '_');
     3394 +        VERIFY3U(t[0], ==, '_');
3392 3395  
3393 3396          t1 = parse_type(t + 1, last, db);
3394 3397          if (t1 == t + 1 || NAMT(db, n) != 2)
3395 3398                  return (first);
3396 3399  
3397 3400          /*
3398 3401           * if we have  " [xxx]" already, want new result to be
3399 3402           * " [yyy][xxx]"
3400 3403           */
3401 3404          str_t *r = &name_top(&db->cpp_name)->strp_r;
↓ open down ↓ 1 lines elided ↑ open up ↑
3403 3406                  str_erase(r, 0, 1);
3404 3407  
3405 3408          nfmt(db, "{0:L}", " [{1}]{0:R}");
3406 3409          return (t1);
3407 3410  }
3408 3411  
3409 3412  /* <pointer-to-member-type> ::= M <class type> <member type> */
3410 3413  static const char *
3411 3414  parse_pointer_to_member_type(const char *first, const char *last, cpp_db_t *db)
3412 3415  {
3413      -        ASSERT3P(first, <=, last);
     3416 +        VERIFY3P(first, <=, last);
3414 3417  
3415 3418          if (last - first < 3)
3416 3419                  return (first);
3417 3420  
3418      -        ASSERT3U(first[0], ==, 'M');
     3421 +        VERIFY3U(first[0], ==, 'M');
3419 3422  
3420 3423          const char *t1 = first + 1;
3421 3424          const char *t2 = NULL;
3422 3425          size_t n = nlen(db);
3423 3426  
3424 3427          t2 = parse_type(t1, last, db);
3425 3428          if (t1 == t2)
3426 3429                  return (first);
3427 3430  
3428 3431          t1 = t2;
↓ open down ↓ 23 lines elided ↑ open up ↑
3452 3455   *                                                                       # A::x, N::y, A<T>::z; "gs" means leading "::"
3453 3456   *                   ::= sr <unresolved-type> <base-unresolved-name>     # T::x / decltype(p)::x
3454 3457   *  extension        ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3455 3458   *                                                                       # T::N::x /decltype(p)::N::x
3456 3459   *  (ignored)        ::= srN <unresolved-type>  <unresolved-qualifier-level>+ E <base-unresolved-name>
3457 3460   */
3458 3461  /* END CSTYLED */
3459 3462  static const char *
3460 3463  parse_unresolved_name(const char *first, const char *last, cpp_db_t *db)
3461 3464  {
3462      -        ASSERT3P(first, <=, last);
     3465 +        VERIFY3P(first, <=, last);
3463 3466  
3464 3467          if (last - first < 2)
3465 3468                  return (first);
3466 3469  
3467 3470          const char *t = first;
3468 3471          const char *t2 = NULL;
3469 3472          boolean_t global = B_FALSE;
3470 3473          size_t n;
3471 3474  
3472 3475          if (t[0] == 'g' && t[1] == 's') {
↓ open down ↓ 27 lines elided ↑ open up ↑
3500 3503  
3501 3504                  t2 = parse_template_args(t, last, db);
3502 3505                  if (t2 != t) {
3503 3506                          if (NAMT(db, n) < 2 || t2 == last)
3504 3507                                  return (first);
3505 3508  
3506 3509                          nfmt(db, "{1:L}{0}", "{1:R}");
3507 3510                          t = t2;
3508 3511                  }
3509 3512  
3510      -                ASSERT3U(NAMT(db, n), ==, 1);
     3513 +                VERIFY3U(NAMT(db, n), ==, 1);
3511 3514  
3512 3515                  while (t[0] != 'E') {
3513 3516                          size_t nn = nlen(db);
3514 3517                          t2 = parse_unresolved_qualifier_level(t, last, db);
3515 3518                          if (t == t2 || t == last || NAMT(db, nn) != 1)
3516 3519                                  return (first);
3517 3520  
3518 3521                          t = t2;
3519 3522                  }
3520 3523  
↓ open down ↓ 51 lines elided ↑ open up ↑
3572 3575  
3573 3576          njoin(db, NAMT(db, n), "::");
3574 3577          return (t2);
3575 3578  }
3576 3579  
3577 3580  /* <unresolved-qualifier-level> ::= <simple-id> */
3578 3581  static const char *
3579 3582  parse_unresolved_qualifier_level(const char *first, const char *last,
3580 3583      cpp_db_t *db)
3581 3584  {
3582      -        ASSERT3P(first, <=, last);
     3585 +        VERIFY3P(first, <=, last);
3583 3586          return (parse_simple_id(first, last, db));
3584 3587  }
3585 3588  
3586 3589  /* BEGIN CSTYLED */
3587 3590  /*
3588 3591   * <base-unresolved-name> ::= <simple-id>                                # unresolved name
3589 3592   *          extension     ::= <operator-name>                            # unresolved operator-function-id
3590 3593   *          extension     ::= <operator-name> <template-args>            # unresolved operator template-id
3591 3594   *                        ::= on <operator-name>                         # unresolved operator-function-id
3592 3595   *                        ::= on <operator-name> <template-args>         # unresolved operator template-id
3593 3596   *                        ::= dn <destructor-name>                       # destructor or pseudo-destructor;
3594 3597   *                                                                       # e.g. ~X or ~X<N-1>
3595 3598   */
3596 3599  /* END CSTYLED */
3597 3600  static const char *
3598 3601  parse_base_unresolved_name(const char *first, const char *last, cpp_db_t *db)
3599 3602  {
3600      -        ASSERT3P(first, <=, last);
     3603 +        VERIFY3P(first, <=, last);
3601 3604  
3602 3605          if (last - first < 2)
3603 3606                  return (first);
3604 3607  
3605 3608          const char *t = NULL;
3606 3609          const char *t1 = NULL;
3607 3610  
3608 3611          if ((first[0] != 'o' && first[0] != 'd') || first[1] != 'n') {
3609 3612                  t = parse_simple_id(first, last, db);
3610 3613                  if (t != first)
↓ open down ↓ 28 lines elided ↑ open up ↑
3639 3642          return (t1);
3640 3643  }
3641 3644  
3642 3645  /*
3643 3646   * <destructor-name> ::= <unresolved-type>      # e.g., ~T or ~decltype(f())
3644 3647   *                   ::= <simple-id>            # e.g., ~A<2*N>
3645 3648   */
3646 3649  static const char *
3647 3650  parse_destructor_name(const char *first, const char *last, cpp_db_t *db)
3648 3651  {
3649      -        ASSERT3P(first, <=, last);
     3652 +        VERIFY3P(first, <=, last);
3650 3653  
3651 3654          if (first == last)
3652 3655                  return (first);
3653 3656  
3654 3657          const char *t = parse_unresolved_type(first, last, db);
3655 3658  
3656 3659          if (t == first)
3657 3660                  t = parse_simple_id(first, last, db);
3658 3661  
3659 3662          if (t == first)
↓ open down ↓ 5 lines elided ↑ open up ↑
3665 3668  
3666 3669  /*
3667 3670   *  <ref-qualifier> ::= R                   # & ref-qualifier
3668 3671   *  <ref-qualifier> ::= O                   # && ref-qualifier
3669 3672   *
3670 3673   * <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
3671 3674   */
3672 3675  static const char *
3673 3676  parse_function_type(const char *first, const char *last, cpp_db_t *db)
3674 3677  {
3675      -        ASSERT3P(first, <=, last);
     3678 +        VERIFY3P(first, <=, last);
3676 3679  
3677 3680          if (last - first < 2)
3678 3681                  return (first);
3679 3682  
3680      -        ASSERT3U(first[0], ==, 'F');
     3683 +        VERIFY3U(first[0], ==, 'F');
3681 3684  
3682 3685          const char *t = first + 1;
3683 3686  
3684 3687          /* extern "C" */
3685 3688          if (t[0] == 'Y')
3686 3689                  t++;
3687 3690  
3688 3691          const char *t1 = parse_type(t, last, db);
3689 3692          if (t1 == t)
3690 3693                  return (first);
↓ open down ↓ 50 lines elided ↑ open up ↑
3741 3744          return (t + 1);
3742 3745  }
3743 3746  
3744 3747  /*
3745 3748   * <template-param> ::= T_    # first template parameter
3746 3749   *                  ::= T <parameter-2 non-negative number> _
3747 3750   */
3748 3751  static const char *
3749 3752  parse_template_param(const char *first, const char *last, cpp_db_t *db)
3750 3753  {
3751      -        ASSERT3P(first, <=, last);
     3754 +        VERIFY3P(first, <=, last);
3752 3755  
3753 3756          if (last - first < 2 || first[0] != 'T')
3754 3757                  return (first);
3755 3758  
3756 3759          const char *t = first + 1;
3757 3760          size_t idx = 0;
3758 3761  
3759 3762          while (t != last && t[0] != '_') {
3760      -                if (!is_digit(t[0]))
     3763 +                if (!isdigit_l(t[0], db->cpp_loc))
3761 3764                          return (first);
3762 3765  
3763 3766                  idx *= 10;
3764 3767                  idx += t[0] - '0';
3765 3768                  t++;
3766 3769          }
3767 3770  
3768 3771          if (t == last)
3769 3772                  return (first);
3770 3773  
3771      -        ASSERT3U(t[0], ==, '_');
     3774 +        VERIFY3U(t[0], ==, '_');
3772 3775  
3773 3776          /*
3774 3777           * T_ -> idx 0
3775 3778           * T0 -> idx 1
3776 3779           * T1 -> idx 2
3777 3780           * ...
3778 3781           */
3779 3782          if (first[1] != '_')
3780 3783                  idx++;
3781 3784  
↓ open down ↓ 13 lines elided ↑ open up ↑
3795 3798          return (t);
3796 3799  }
3797 3800  
3798 3801  /*
3799 3802   * <template-args> ::= I <template-arg>* E
3800 3803   *     extension, the abi says <template-arg>+
3801 3804   */
3802 3805  static const char *
3803 3806  parse_template_args(const char *first, const char *last, cpp_db_t *db)
3804 3807  {
3805      -        ASSERT3P(first, <=, last);
     3808 +        VERIFY3P(first, <=, last);
3806 3809  
3807 3810          if (last - first < 2 || first[0] != 'I')
3808 3811                  return (first);
3809 3812  
3810 3813          if (db->cpp_tag_templates)
3811 3814                  sub_clear(templ_top(&db->cpp_templ));
3812 3815  
3813 3816          const char *t = first + 1;
3814 3817          size_t n = nlen(db);
3815 3818  
↓ open down ↓ 15 lines elided ↑ open up ↑
3831 3834  
3832 3835                  t = t1;
3833 3836          }
3834 3837  
3835 3838          /*
3836 3839           * ugly, but if the last thing pushed was an empty string,
3837 3840           * get rid of it so we dont get "<..., >"
3838 3841           */
3839 3842          if (NAMT(db, n) > 1 &&
3840 3843              str_pair_len(name_top(&db->cpp_name)) == 0)
3841      -                (void) name_pop(&db->cpp_name, NULL);
     3844 +                name_pop(&db->cpp_name, NULL);
3842 3845  
3843 3846          njoin(db, NAMT(db, n), ", ");
3844 3847  
3845      -        ASSERT3U(nlen(db), >, 0);
     3848 +        VERIFY3U(nlen(db), >, 0);
3846 3849  
3847 3850          /* make sure we don't bitshift ourselves into oblivion */
3848 3851          str_t *top = TOP_L(db);
3849 3852          if (str_length(top) > 0 &&
3850 3853              top->str_s[top->str_len - 1] == '>')
3851 3854                  nfmt(db, "<{0} >", NULL);
3852 3855          else
3853 3856                  nfmt(db, "<{0}>", NULL);
3854 3857  
3855 3858          /* skip E */
3856 3859          return (t + 1);
3857 3860  }
3858 3861  
3859 3862  /*
3860 3863   * <discriminator> := _ <non-negative number>      # when number < 10
3861 3864   *                 := __ <non-negative number> _   # when number >= 10
3862 3865   *  extension      := decimal-digit+               # at the end of string
3863 3866   */
3864 3867  static const char *
3865      -parse_discriminator(const char *first, const char *last)
     3868 +parse_discriminator(const char *first, const char *last, locale_t loc)
3866 3869  {
3867      -        ASSERT3P(first, <=, last);
     3870 +        VERIFY3P(first, <=, last);
3868 3871  
3869 3872          const char *t = NULL;
3870 3873  
3871 3874          if (first == last)
3872 3875                  return (first);
3873 3876  
3874      -        if (is_digit(first[0])) {
3875      -                for (t = first; t != last && is_digit(t[0]); t++)
     3877 +        if (isdigit_l(first[0], loc)) {
     3878 +                for (t = first; t != last && isdigit_l(t[0], loc); t++)
3876 3879                          ;
3877 3880  
3878 3881                  /* not at the end of the string */
3879 3882                  if (t != last)
3880 3883                          return (first);
3881 3884  
3882 3885                  return (t);
3883 3886          } else if (first[0] != '_' || first + 1 == last) {
3884 3887                  return (first);
3885 3888          }
3886 3889  
3887 3890          t = first + 1;
3888      -        if (is_digit(t[0]))
     3891 +        if (isdigit_l(t[0], loc))
3889 3892                  return (t + 1);
3890 3893  
3891 3894          if (t[0] != '_' || t + 1 == last)
3892 3895                  return (first);
3893 3896  
3894      -        for (t++; t != last && is_digit(t[0]); t++)
     3897 +        for (t++; t != last && isdigit_l(t[0], loc); t++)
3895 3898                  ;
3896 3899          if (t == last || t[0] != '_')
3897 3900                  return (first);
3898 3901  
3899 3902          return (t);
3900 3903  }
3901 3904  
3902 3905  /* <CV-qualifiers> ::= [r] [V] [K] */
3903 3906  const char *
3904 3907  parse_cv_qualifiers(const char *first, const char *last, unsigned *cv)
3905 3908  {
3906      -        ASSERT3P(first, <=, last);
     3909 +        VERIFY3P(first, <=, last);
3907 3910  
3908 3911          if (first == last)
3909 3912                  return (first);
3910 3913  
3911 3914          *cv = 0;
3912 3915          if (first[0] == 'r') {
3913 3916                  *cv |= CPP_QUAL_RESTRICT;
3914 3917                  first++;
3915 3918          }
3916 3919          if (first != last && first[0] == 'V') {
↓ open down ↓ 5 lines elided ↑ open up ↑
3922 3925                  first++;
3923 3926          }
3924 3927  
3925 3928          return (first);
3926 3929  }
3927 3930  
3928 3931  /*
3929 3932   * <number> ::= [n] <non-negative decimal integer>
3930 3933   */
3931 3934  static const char *
3932      -parse_number(const char *first, const char *last)
     3935 +parse_number(const char *first, const char *last, locale_t loc)
3933 3936  {
3934      -        ASSERT3P(first, <=, last);
     3937 +        VERIFY3P(first, <=, last);
3935 3938  
3936 3939          const char *t = first;
3937 3940  
3938      -        if (first == last || (first[0] != 'n' && !is_digit(first[0])))
     3941 +        if (first == last || (first[0] != 'n' && !isdigit_l(first[0], loc)))
3939 3942                  return (first);
3940 3943  
3941 3944          if (t[0] == 'n')
3942 3945                  t++;
3943 3946  
3944 3947          if (t[0] == '0')
3945 3948                  return (t + 1);
3946 3949  
3947      -        while (is_digit(t[0]))
     3950 +        while (isdigit_l(t[0], loc))
3948 3951                  t++;
3949 3952  
3950 3953          return (t);
3951 3954  }
3952 3955  
3953 3956  /*
3954      - * we only ever use ASCII versions of these
     3957 + * Like isxdigit(3C), except we can only accept lower case letters as
     3958 + * that's only what is allowed when [de]mangling floating point constants into
     3959 + * their hex representation.
3955 3960   */
3956 3961  static inline boolean_t
3957      -is_digit(int c)
3958      -{
3959      -        if (c < '0' || c > '9')
3960      -                return (B_FALSE);
3961      -        return (B_TRUE);
3962      -}
3963      -
3964      -static inline boolean_t
3965      -is_upper(int c)
3966      -{
3967      -        if (c < 'A' || c > 'Z')
3968      -                return (B_FALSE);
3969      -        return (B_TRUE);
3970      -}
3971      -
3972      -static inline boolean_t
3973 3962  is_xdigit(int c)
3974 3963  {
3975 3964          if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))
3976 3965                  return (B_TRUE);
3977 3966          return (B_FALSE);
3978 3967  }
3979 3968  
3980 3969  static boolean_t
3981 3970  nempty(cpp_db_t *db)
3982 3971  {
↓ open down ↓ 67 lines elided ↑ open up ↑
4050 4039  {
4051 4040          templ_pop(&db->cpp_templ);
4052 4041  }
4053 4042  
4054 4043  static void
4055 4044  tsave(cpp_db_t *db, size_t amt)
4056 4045  {
4057 4046          CK(templ_save(&db->cpp_name, amt, &db->cpp_templ));
4058 4047  }
4059 4048  
4060      -static void
     4049 +static boolean_t
4061 4050  db_init(cpp_db_t *db, sysdem_ops_t *ops)
4062 4051  {
4063 4052          (void) memset(db, 0, sizeof (*db));
4064 4053          db->cpp_ops = ops;
4065 4054          name_init(&db->cpp_name, ops);
4066 4055          sub_init(&db->cpp_subs, ops);
4067 4056          templ_init(&db->cpp_templ, ops);
4068 4057          db->cpp_tag_templates = B_TRUE;
4069 4058          db->cpp_try_to_parse_template_args = B_TRUE;
4070 4059          tpush(db);
     4060 +        db->cpp_loc = newlocale(LC_CTYPE_MASK, "C", 0);
     4061 +        return ((db->cpp_loc != NULL) ? B_TRUE : B_FALSE);
4071 4062  }
4072 4063  
4073 4064  static void
4074 4065  db_fini(cpp_db_t *db)
4075 4066  {
4076 4067          name_fini(&db->cpp_name);
4077 4068          sub_fini(&db->cpp_subs);
4078 4069          templ_fini(&db->cpp_templ);
     4070 +        freelocale(db->cpp_loc);
4079 4071          (void) memset(db, 0, sizeof (*db));
4080 4072  }
4081 4073  
4082 4074  static void
4083 4075  print_sp(const str_pair_t *sp, FILE *out)
4084 4076  {
4085 4077          (void) fprintf(out, "{%.*s#%.*s}",
4086 4078              (int)sp->strp_l.str_len, sp->strp_l.str_s,
4087 4079              (int)sp->strp_r.str_len, sp->strp_r.str_s);
4088 4080  }
↓ open down ↓ 11 lines elided ↑ open up ↑
4100 4092  
4101 4093          for (i = 0; i < n->nm_len; i++, sp--) {
4102 4094                  (void) fprintf(out, "  [%02zu] ", i);
4103 4095                  print_sp(sp, out);
4104 4096                  (void) fputc('\n', out);
4105 4097          }
4106 4098  
4107 4099          (void) fputc('\n', out);
4108 4100  }
4109 4101  
4110      -
     4102 +/* Print a base-36 number (for substitutions) */
4111 4103  static char *
4112 4104  base36(char *buf, size_t val)
4113 4105  {
4114 4106          char tmp[16] = { 0 };
4115 4107          char *p = tmp;
4116 4108  
4117 4109          if (val == 0) {
4118 4110                  buf[0] = '0';
4119 4111                  buf[1] = '\0';
4120 4112                  return (buf);
↓ open down ↓ 100 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX