Print this page
Address Robert's feedback

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libsysdemangle/common/cpp_util.c
          +++ new/usr/src/lib/libsysdemangle/common/cxx_util.c
↓ open down ↓ 11 lines elided ↑ open up ↑
  12   12  /*
  13   13   * Copyright 2017 Jason King
  14   14   */
  15   15  
  16   16  #include <sys/debug.h>
  17   17  #include <sys/sysmacros.h>
  18   18  #include <string.h>
  19   19  #include <errno.h>
  20   20  #include <stdlib.h>
  21   21  #include "sysdemangle_int.h"
  22      -#include "cpp.h"
       22 +#include "cxx.h"
  23   23  
  24   24  #define CHUNK_SIZE  (8U)
  25   25  
  26   26  /*
  27   27   * A name_t is essentially a stack of str_pair_t's.  Generally, the parsing
  28   28   * code will push (via name_add() or the like) portions of the demangled
  29   29   * name into a name_t, and periodically combine them via name_join().
  30   30   *
  31   31   * As such it should be noted that since items are added at the end of
  32   32   * name_t->nm_items, the numbering of name_at() starts at the end
↓ open down ↓ 111 lines elided ↑ open up ↑
 144  144                  sp.strp_r = *r;
 145  145                  (void) memset(r, 0, sizeof (*r));
 146  146          }
 147  147  
 148  148          n->nm_items[n->nm_len++] = sp;
 149  149  
 150  150          return (B_TRUE);
 151  151  }
 152  152  
 153  153  str_pair_t *
 154      -name_at(name_t *n, size_t idx)
      154 +name_at(const name_t *n, size_t idx)
 155  155  {
 156      -        if (n->nm_len == 0)
 157      -                return (NULL);
 158      -
 159      -        ASSERT3U(idx, <=, n->nm_len);
      156 +        VERIFY(!name_empty(n));
      157 +        VERIFY3U(idx, <, n->nm_len);
 160  158          return (&n->nm_items[n->nm_len - idx - 1]);
 161  159  }
 162  160  
 163  161  str_pair_t *
 164  162  name_top(name_t *n)
 165  163  {
 166  164          return (name_at(n, 0));
 167  165  }
 168  166  
 169      -str_pair_t *
      167 +void
 170  168  name_pop(name_t *n, str_pair_t *sp)
 171  169  {
 172  170          if (n->nm_len == 0)
 173      -                return (NULL);
      171 +                return;
 174  172  
 175  173          str_pair_t *top = name_top(n);
 176  174  
 177  175          if (sp != NULL) {
 178  176                  *sp = *top;
 179  177                  (void) memset(top, 0, sizeof (*top));
 180  178          } else {
 181  179                  str_pair_fini(top);
 182  180          }
 183  181  
 184  182          n->nm_len--;
 185      -        return (sp);
 186  183  }
 187  184  
 188  185  boolean_t
 189  186  name_join(name_t *n, size_t amt, const char *sep)
 190  187  {
 191  188          str_pair_t *sp = NULL;
 192  189          str_t res = { 0 };
 193  190          size_t seplen = strlen(sep);
 194  191  
 195      -        ASSERT3U(amt, <=, n->nm_len);
      192 +        VERIFY3U(amt, <=, n->nm_len);
 196  193  
 197  194          /*
 198  195           * A join of 0 elements places an empty string on the stack.  This
 199  196           * simplifies code that wants to do things like:
 200  197           *   name_join(...); name_fmt(.., "({0})", ...)
 201  198           */
 202  199          if (amt == 0) {
 203  200                  name_add(n, "", 0, "", 0);
 204  201                  return (B_TRUE);
 205  202          }
 206      -        
      203 +
 207  204          /* A join of 1 element just implies merging the top str_pair_t */
 208  205          if (amt == 1) {
 209      -                ASSERT3U(name_len(n), >, 0);
      206 +                VERIFY3U(name_len(n), >, 0);
 210  207                  return (str_pair_merge(name_top(n)));
 211  208          }
 212  209  
 213  210          (void) str_init(&res, n->nm_ops);
 214  211  
 215  212          sp = name_at(n, amt - 1);
 216  213          for (size_t i = 0; i < amt; i++) {
 217  214                  if (i > 0) {
 218  215                          if (!str_append(&res, sep, seplen))
 219  216                                  goto error;
↓ open down ↓ 1 lines elided ↑ open up ↑
 221  218  
 222  219                  if (!str_append_str(&res, &sp->strp_l))
 223  220                          goto error;
 224  221                  if (!str_append_str(&res, &sp->strp_r))
 225  222                          goto error;
 226  223  
 227  224                  sp++;
 228  225          }
 229  226  
 230  227          for (size_t i = 0; i < amt; i++)
 231      -                (void) name_pop(n, NULL);
      228 +                name_pop(n, NULL);
 232  229  
 233  230          /* since we've removed at least 1 entry, this should always succeed */
 234  231          VERIFY(name_add_str(n, &res, NULL));
 235  232          return (B_TRUE);
 236  233  
 237  234  error:
 238  235          str_fini(&res);
 239  236          return (B_FALSE);
 240  237  }
 241  238  
↓ open down ↓ 9 lines elided ↑ open up ↑
 251  248          for (p = fmt; *p != '\0'; p++) {
 252  249                  if (*p != '{') {
 253  250                          str_append_c(s, *p);
 254  251                          continue;
 255  252                  }
 256  253  
 257  254                  errno = 0;
 258  255                  char *q = NULL;
 259  256                  long val = strtol(p + 1, &q, 10);
 260  257  
 261      -                ASSERT(val != 0 || errno == 0);
 262      -                ASSERT3U(val, <, n->nm_len);
      258 +                VERIFY(val != 0 || errno == 0);
      259 +                VERIFY3U(val, <, n->nm_len);
 263  260  
 264  261                  str_pair_t *sp = name_at(n, val);
 265  262  
 266  263                  if (val > max)
 267  264                          max = val;
 268  265  
 269  266                  switch (q[0]) {
 270  267                  case '}':
 271  268                          if (!str_append_str(s, &sp->strp_l))
 272  269                                  return (B_FALSE);
↓ open down ↓ 19 lines elided ↑ open up ↑
 292  289                  }
 293  290          }
 294  291  
 295  292          if (*maxp < max)
 296  293                  *maxp = max;
 297  294  
 298  295          return (B_TRUE);
 299  296  }
 300  297  
 301  298  /*
 302      - * replace a number of elements in the name stack with a formatted string
      299 + * Replace a number of elements in the name stack with a formatted string
 303  300   * for format is a plain string with optional {nnn} or {nnn:L|R} substitutions
 304  301   * where nnn is the stack position of an element and it's contents (both
 305  302   * left and right pieces) are inserted.  Optionally, only the left or
 306  303   * right piece can specified using :L|R e.g. {2:L}{3}{2:R} would insert
 307  304   * the left piece of element 2, all of element 3, then the right piece of
 308  305   * element 2.
 309  306   *
 310  307   * Once complete, all elements up to the deepest one references are popped
 311  308   * off the stack, and the resulting formatted string is pushed into n.
 312  309   *
↓ open down ↓ 11 lines elided ↑ open up ↑
 324  321          if (!name_reserve(n, 1))
 325  322                  return (B_FALSE);
 326  323  
 327  324          if (!name_fmt_s(n, &res.strp_l, fmt_l, &max))
 328  325                  goto error;
 329  326          if (!name_fmt_s(n, &res.strp_r, fmt_r, &max))
 330  327                  goto error;
 331  328  
 332  329          if (max >= 0) {
 333  330                  for (size_t i = 0; i <= max; i++)
 334      -                        (void) name_pop(n, NULL);
      331 +                        name_pop(n, NULL);
 335  332          }
 336  333  
 337  334          n->nm_items[n->nm_len++] = res;
 338  335          return (B_TRUE);
 339  336  
 340  337  error:
 341  338          str_pair_fini(&res);
 342  339          return (B_FALSE);
 343  340  }
 344  341  
↓ open down ↓ 77 lines elided ↑ open up ↑
 422  419  
 423  420          name_t *dest = &sub->sub_items[sub->sub_len++];
 424  421          name_init(dest, sub->sub_ops);
 425  422  
 426  423          if (!name_reserve(dest, depth)) {
 427  424                  name_fini(dest);
 428  425                  sub->sub_len--;
 429  426                  return (B_FALSE);
 430  427          }
 431  428  
 432      -        const str_pair_t *src_sp = name_at((name_t *)n, depth - 1);
      429 +        const str_pair_t *src_sp = name_at(n, depth - 1);
 433  430  
 434  431          for (size_t i = 0; i < depth; i++, src_sp++) {
 435  432                  str_pair_t copy = { 0 };
 436  433                  str_pair_init(&copy, n->nm_ops);
 437  434                  if (!str_pair_copy(src_sp, &copy)) {
 438  435                          str_pair_fini(&copy);
 439  436                          name_fini(dest);
 440  437                          return (B_FALSE);
 441  438                  }
 442  439  
 443  440                  VERIFY(name_add_str(dest, &copy.strp_l, &copy.strp_r));
 444  441          }
 445  442  
 446  443          return (B_TRUE);
 447  444  }
 448  445  
 449  446  /* push substitution idx onto n */
 450  447  boolean_t
 451  448  sub_substitute(const sub_t *sub, size_t idx, name_t *n)
 452  449  {
 453      -        ASSERT3U(idx, <, sub->sub_len);
      450 +        VERIFY3U(idx, <, sub->sub_len);
 454  451  
 455  452          const name_t *src = &sub->sub_items[idx];
 456  453          const str_pair_t *sp = src->nm_items;
 457  454          size_t save = name_len(n);
 458  455  
 459  456          for (size_t i = 0; i < src->nm_len; i++, sp++) {
 460  457                  str_pair_t copy = { 0 };
 461  458  
 462  459                  if (!str_pair_copy(sp, &copy))
 463  460                          goto fail;
 464  461  
 465  462                  if (!name_add_str(n, &copy.strp_l, &copy.strp_r))
 466  463                          goto fail;
 467  464          }
 468  465  
 469  466          return (B_TRUE);
 470  467  
 471  468  fail:
 472  469          for (size_t i = 0; i < name_len(n) - save; i++)
 473      -                (void) name_pop(n, NULL);
      470 +                name_pop(n, NULL);
 474  471          return (B_FALSE);
 475  472  }
 476  473  
 477  474  void
 478  475  sub_pop(sub_t *sub)
 479  476  {
 480  477          name_t *top = &sub->sub_items[--sub->sub_len];
 481  478          name_fini(top);
 482  479  }
 483  480  
↓ open down ↓ 51 lines elided ↑ open up ↑
 535  532                  return (B_FALSE);
 536  533  
 537  534          sub_t *sub = &tpl->tpl_items[tpl->tpl_len++];
 538  535          sub_init(sub, tpl->tpl_ops);
 539  536          return (B_TRUE);
 540  537  }
 541  538  
 542  539  void
 543  540  templ_pop(templ_t *tpl)
 544  541  {
 545      -        ASSERT(!templ_empty(tpl));
      542 +        VERIFY(!templ_empty(tpl));
 546  543  
 547  544          sub_t *sub = &tpl->tpl_items[--tpl->tpl_len];
 548  545          sub_fini(sub);
 549  546  }
 550  547  
 551  548  sub_t *
 552  549  templ_top(templ_t *tpl)
 553  550  {
 554  551          if (tpl->tpl_len == 0)
 555  552                  return (NULL);
↓ open down ↓ 18 lines elided ↑ open up ↑
 574  571  templ_sub(const templ_t *tpl, size_t idx, name_t *n)
 575  572  {
 576  573          const sub_t *sub = templ_top((templ_t *)tpl);
 577  574  
 578  575          return (sub_substitute(sub, idx, n));
 579  576  }
 580  577  
 581  578  boolean_t
 582  579  templ_save(const name_t *n, size_t amt, templ_t *tpl)
 583  580  {
 584      -        ASSERT3U(tpl->tpl_len, >, 0);
      581 +        VERIFY3U(tpl->tpl_len, >, 0);
 585  582  
 586  583          sub_t *s = templ_top(tpl);
 587  584          boolean_t res = B_TRUE;
 588  585  
 589  586          /* a bit of a hack -- want an 'empty' entry when saving 0 params */
 590  587          if (amt == 0) {
 591  588                  name_t name = { 0 };
 592  589  
 593  590                  name_init(&name, tpl->tpl_ops);
 594  591                  res &= name_add(&name, "", 0, "", 0);
 595  592                  if (res)
 596  593                          res &= sub_save(s, &name, 1);
 597  594                  name_fini(&name);
 598  595          } else {
 599  596                  res &= sub_save(s, n, amt);
 600  597          }
 601  598  
 602  599          return (res);
 603  600  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX