示例#1
0
bool ph_vprintf_register(const char *name, void *formatter_arg,
    ph_vprintf_named_formatter_func func)
{
  struct formatter *f;
  bool res;
  ph_string_t *kptr;

  pthread_once(&once_init, init_vprintf);

  f = malloc(sizeof(*f));
  if (!f) {
    return false;
  }

  ph_string_init_claim(&f->namestr, PH_STRING_STATIC,
      f->name, 0, sizeof(f->name));
  f->func = func;
  f->farg = formatter_arg;
  ph_string_append_cstr(&f->namestr, name);
  kptr = &f->namestr;

  pthread_rwlock_wrlock(&formatter_lock);
  res = (ph_ht_replace(&formatters, &kptr, &f) == PH_OK);
  pthread_rwlock_unlock(&formatter_lock);

  if (res) {
    return true;
  }

  free(f);
  return false;
}
示例#2
0
ph_variant_t *ph_var_object_get_cstr(ph_variant_t *obj, const char *key)
{
  ph_string_t kstr;
  uint32_t len = strlen(key);

  ph_string_init_claim(&kstr, PH_STRING_STATIC, (char*)key, len, len);
  return ph_var_object_get(obj, &kstr);
}
示例#3
0
文件: hook.c 项目: 01BTC10/libphenom
ph_hook_point_t *ph_hook_point_get_cstr(const char *name, bool create)
{
  ph_string_t sstr, *str;
  ph_hook_point_t *hp;

  if (create) {
    str = ph_string_make_cstr(mt.string, name);
  } else {
    uint32_t len = strlen(name);
    ph_string_init_claim(&sstr, PH_STRING_STATIC, (char*)name, len, len);
    str = &sstr;
  }

  hp = ph_hook_point_get(str, create);

  if (str != &sstr) {
    ph_string_delref(str);
  }

  return hp;
}
示例#4
0
int
ph_vprintf_core(void *print_arg,
    const struct ph_vprintf_funcs *print_funcs,
    const char *fmt0, va_list ap)
{
  char *fmt;    /* format string */
  int ch;     /* character from fmt */
  int n, n2;    /* handy integers (short term usage) */
  char *cp;   /* handy char pointer (short term usage) */
  int flags;    /* flags as above */
  int ret;    /* return value accumulator */
  int width;    /* width from format (%8d), or 0 */
  int prec;   /* precision from format; <0 for N/A */
  char sign;    /* sign prefix (' ', '+', '-', or \0) */
  wchar_t wc;
  mbstate_t ps;
#ifdef FLOATING_POINT
  /*
   * We can decompose the printed representation of floating
   * point numbers into several parts, some of which may be empty:
   *
   * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
   *    A       B     ---C---      D       E   F
   *
   * A: 'sign' holds this value if present; '\0' otherwise
   * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
   * C: cp points to the string MMMNNN.  Leading and trailing
   *  zeros are not in the string and must be added.
   * D: expchar holds this character; '\0' if no exponent, e.g. %f
   * F: at least two digits for decimal, at least one digit for hex
   */
  const char *decimal_point =
#ifdef USE_LOCALE
    NULL
#else
    "."
#endif
    ;
  int signflag;   /* true if float is negative */
  union {     /* floating point arguments %[aAeEfFgG] */
    double dbl;
    long double ldbl;
  } fparg;
  int expt;   /* integer value of exponent */
  char expchar = 0;   /* exponent character: [eEpP\0] */
  char *dtoaend;    /* pointer to end of converted digits */
  int expsize = 0;    /* character count for expstr */
  int lead = 0;   /* sig figs before decimal or group sep */
  int ndig = 0;   /* actual number of digits returned by dtoa */
  char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
  char *dtoaresult = NULL;
#endif

  uintmax_t _umax;  /* integer arguments %[diouxX] */
  enum { OCT, DEC, HEX } base;  /* base for %[diouxX] conversion */
  int dprec;    /* a copy of prec if %[diouxX], 0 otherwise */
  int realsz;   /* field size expanded by dprec */
  int size;   /* size of converted field or string */
  const char *xdigs = xdigs_lower;  /* digits for %[xX] conversion */
  char buf[BUF];    /* buffer with space for digits of uintmax_t */
  char ox[2];   /* space for 0x; ox[1] is either x, X, or \0 */
  union arg *argtable;  /* args, built due to positional arg */
  union arg statargtable[STATIC_ARG_TBL_SIZE];
  size_t argtablesiz;
  int nextarg;    /* 1-based argument index */
  va_list orgap;    /* original argument pointer */
#ifdef PRINTF_WIDE_CHAR
  char *convbuf;    /* buffer for wide to multi-byte conversion */
#endif

  bool print_error = false;

  /*
   * BEWARE, these `goto error' on error, and PAD uses `n'.
   */
#define PRINT(ptr, len) do { \
  if (len > 0 && !print_funcs->print(print_arg, ptr, len)) { \
    print_error = true; \
    goto error; \
  } \
} while (0)
#define PAD(howmany, with) do { \
  if ((n = (howmany)) > 0) { \
    while (n > PADSIZE) { \
      PRINT(with, PADSIZE); \
      n -= PADSIZE; \
    } \
    PRINT(with, n); \
  } \
} while (0)
#define PRINTANDPAD(p, ep, len, with) do {  \
  n2 = (ep) - (p);            \
  if (n2 > (len))       \
    n2 = (len);     \
  if (n2 > 0)       \
    PRINT((p), n2);     \
  PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
} while(0)
#define FLUSH() do { \
  if (print_funcs->flush && !print_funcs->flush(print_arg)) { \
    print_error = true; \
    goto error; \
  } \
} while (0)

  /*
   * To extend shorts properly, we need both signed and unsigned
   * argument extraction methods.
   */
#define SARG() \
  ((intmax_t)(flags&MAXINT ? GETARG(intmax_t) : \
      flags&LLONGINT ? GETARG(long long) : \
      flags&LONGINT ? GETARG(long) : \
      flags&PTRINT ? GETARG(ptrdiff_t) : \
      flags&SIZEINT ? GETARG(ssize_t) : \
      flags&SHORTINT ? (short)GETARG(int) : \
      flags&CHARINT ? (__signed char)GETARG(int) : \
      GETARG(int)))
#define UARG() \
  ((uintmax_t)(flags&MAXINT ? GETARG(uintmax_t) : \
      flags&LLONGINT ? GETARG(unsigned long long) : \
      flags&LONGINT ? GETARG(unsigned long) : \
      flags&PTRINT ? (uintptr_t)GETARG(ptrdiff_t) : /* XXX */ \
      flags&SIZEINT ? GETARG(size_t) : \
      flags&SHORTINT ? (unsigned short)GETARG(int) : \
      flags&CHARINT ? (unsigned char)GETARG(int) : \
      GETARG(unsigned int)))

  /*
   * Append a digit to a value and check for overflow.
   */
#define APPEND_DIGIT(val, dig) do { \
  if ((val) > INT_MAX / 10) \
    goto overflow; \
  (val) *= 10; \
  if ((val) > INT_MAX - to_digit((dig))) \
    goto overflow; \
  (val) += to_digit((dig)); \
} while (0)

   /*
    * Get * arguments, including the form *nn$.  Preserve the nextarg
    * that the argument can be gotten once the type is determined.
    */
#define GETASTER(val) \
  n2 = 0; \
  cp = fmt; \
  while (is_digit(*cp)) { \
    APPEND_DIGIT(n2, *cp); \
    cp++; \
  } \
  if (*cp == '$') { \
    int hold = nextarg; \
    if (argtable == NULL) { \
      argtable = statargtable; \
      __find_arguments(fmt0, orgap, &argtable, &argtablesiz); \
    } \
    nextarg = n2; \
    val = GETARG(int); \
    nextarg = hold; \
    fmt = ++cp; \
  } else { \
    val = GETARG(int); \
  }

/*
* Get the argument indexed by nextarg.   If the argument table is
* built, use it to get the argument.  If its not, get the next
* argument (and arguments must be gotten sequentially).
*/
#define GETARG(type) \
  ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
    (nextarg++, va_arg(ap, type)))

  fmt = (char *)fmt0;
  argtable = NULL;
  nextarg = 1;
  va_copy(orgap, ap);
  ret = 0;
#ifdef PRINTF_WIDE_CHAR
  convbuf = NULL;
#endif

  memset(&ps, 0, sizeof(ps));
  /*
   * Scan the format for conversions (`%' character).
   */
  for (;;) {
    cp = fmt;
    while ((n = mbrtowc(&wc, fmt, MB_CUR_MAX, &ps)) > 0) {
      fmt += n;
      if (wc == '%' || wc == '`') {
        fmt--;
        break;
      }
    }
    if (fmt != cp) {
      ptrdiff_t m = fmt - cp;
      if (m < 0 || m > INT_MAX - ret)
        goto overflow;
      PRINT(cp, m);
      ret += m;
    }
    if (n <= 0)
      goto done;

    flags = 0;
    dprec = 0;
    width = 0;
    prec = -1;
    sign = '\0';
    ox[1] = '\0';

    /* check for phenom specials */
    if (fmt[0] == '`') {
      if (fmt[1] == '`') {
        /* we just print a literal ` */
        PRINT(fmt, 1);
        fmt += 2;
        continue;
      }
      if (fmt[1] != 'P') {
        /* some regular backtick enclosed text */
        PRINT(fmt, 1);
        fmt++;
        continue;
      }
      switch (fmt[2]) {
        case '{':
          {
            char *term;
            void *object;
            struct formatter *f = NULL;
            ph_string_t key, *keyptr = &key;

            fmt += 3;
            term = strstr(fmt, ":%p}");
            if (!term) {
              break;
            }

            object = GETARG(void*);

            pthread_once(&once_init, init_vprintf);
            ph_string_init_claim(&key, PH_STRING_STATIC, fmt,
                term - fmt, term - fmt);

            pthread_rwlock_rdlock(&formatter_lock);
            ph_ht_lookup(&formatters, &keyptr, (void*)&f, false);
            pthread_rwlock_unlock(&formatter_lock);

            if (f && f->func) {
              ret += f->func(f->farg, object, print_arg, print_funcs);
            } else {
              PRINT("INVALID:", 8);
              PRINT(fmt, term - fmt);
              ret += 8 + (term - fmt);
            }

            fmt = term + 4;
            continue;
          }

        case 'e':
          /* "`Pe%d" errno formatted as string */
          if (fmt[3] == '%' && fmt[4] == 'd') {
            char ebuf[128];
            int err = GETARG(int);

            cp = (char*)ph_strerror_r(err, ebuf, sizeof(ebuf));

            size = strlen(cp);
            fmt += 5;
            PRINT(cp, size);
            ret += size;
            continue;
          }
          break;

        case 's': {
          uint32_t len;
          ph_string_t *str = NULL;

          if (!memcmp("%p", fmt + 3, 2)) {
            str = GETARG(void*);
            len = str->len;
            fmt += 5;
          } else if (!memcmp("%d%p", fmt + 3, 4)) {
            len = GETARG(int);
            str = GETARG(void*);
            len = MIN(len, str->len);
            fmt += 7;
          } else {
            // invalid
            break;