Ejemplo n.º 1
0
static void TestMapping (const char* str)
{
#ifdef TEST_UNICODE_MAPPINGS
  csPrintf (" Upper:    %s\n Lower:    %s\n Fold:     %s\n",
    MapString (str, &csUnicodeTransform::MapToUpper).GetData(),
    MapString (str, &csUnicodeTransform::MapToLower).GetData(),
    MapString (str, &csUnicodeTransform::MapToFold).GetData());
#else
  (void) str; // unused except for the above block so silence the warning
#endif // TEST_UNICODE_MAPPINGS
}
Ejemplo n.º 2
0
// Look up tagname, generate one if necessary, and return a tag
LIBLOG_ABI_PUBLIC int android_lookupEventTagNum(EventTagMap* map,
                                                const char* tagname,
                                                const char* format, int prio) {
  const char* ep = endOfTag(tagname);
  size_t len = ep - tagname;
  if (!len || *ep) {
    errno = EINVAL;
    return -1;
  }

  if ((prio != ANDROID_LOG_UNKNOWN) && (prio < ANDROID_LOG_SILENT) &&
      !__android_log_is_loggable_len(prio, tagname, len,
                                     __android_log_is_debuggable()
                                         ? ANDROID_LOG_VERBOSE
                                         : ANDROID_LOG_DEBUG)) {
    errno = EPERM;
    return -1;
  }

  if (!format) format = "";
  ssize_t fmtLen = strlen(format);
  int ret = map->find(TagFmt(
      std::make_pair(MapString(tagname, len), MapString(format, fmtLen))));
  if (ret != -1) return ret;

  // call event tag service to arrange for a new tag
  char* buf = NULL;
  // Can not use android::base::StringPrintf, asprintf + free instead.
  static const char command_template[] = "getEventTag name=%s format=\"%s\"";
  ret = asprintf(&buf, command_template, tagname, format);
  if (ret > 0) {
    // Add some buffer margin for an estimate of the full return content.
    char* cp;
    size_t size =
        ret - strlen(command_template) +
        strlen("65535\n4294967295\t?\t\t\t?\t# uid=32767\n\n\f?success?");
    if (size > (size_t)ret) {
      cp = static_cast<char*>(realloc(buf, size));
      if (cp) {
        buf = cp;
      } else {
        size = ret;
      }
    } else {
      size = ret;
    }
    // Ask event log tag service for an allocation
    if (__send_log_msg(buf, size) >= 0) {
      buf[size - 1] = '\0';
      unsigned long val = strtoul(buf, &cp, 10);        // return size
      if ((buf != cp) && (val > 0) && (*cp == '\n')) {  // truncation OK
        val = strtoul(cp + 1, &cp, 10);                 // allocated tag number
        if ((val > 0) && (val < UINT32_MAX) && (*cp == '\t')) {
          free(buf);
          ret = val;
          // cache
          map->emplaceUnique(ret, TagFmt(std::make_pair(
                                      MapString(std::string(tagname, len)),
                                      MapString(std::string(format, fmtLen)))));
          return ret;
        }
      }
    }
    free(buf);
  }

  // Hail Mary
  ret = map->find(MapString(tagname, len));
  if (ret == -1) errno = ESRCH;
  return ret;
}
Ejemplo n.º 3
0
// Scan one tag line.
//
// "pData" should be pointing to the first digit in the tag number.  On
// successful return, it will be pointing to the last character in the
// tag line (i.e. the character before the start of the next line).
//
// lineNum = 0 removes verbose comments and requires us to cache the
// content rather than make direct raw references since the content
// will disappear after the call. A non-zero lineNum means we own the
// data and it will outlive the call.
//
// Returns 0 on success, nonzero on failure.
static int scanTagLine(EventTagMap* map, const char*& pData, int lineNum) {
  char* ep;
  unsigned long val = strtoul(pData, &ep, 10);
  const char* cp = ep;
  if (cp == pData) {
    if (lineNum) {
      fprintf(stderr, OUT_TAG ": malformed tag number on line %d\n", lineNum);
    }
    errno = EINVAL;
    return -1;
  }

  uint32_t tagIndex = val;
  if (tagIndex != val) {
    if (lineNum) {
      fprintf(stderr, OUT_TAG ": tag number too large on line %d\n", lineNum);
    }
    errno = ERANGE;
    return -1;
  }

  while ((*++cp != '\n') && isspace(*cp)) {
  }

  if (*cp == '\n') {
    if (lineNum) {
      fprintf(stderr, OUT_TAG ": missing tag string on line %d\n", lineNum);
    }
    errno = EINVAL;
    return -1;
  }

  const char* tag = cp;
  cp = endOfTag(cp);
  size_t tagLen = cp - tag;

  if (!isspace(*cp)) {
    if (lineNum) {
      fprintf(stderr, OUT_TAG ": invalid tag char %c on line %d\n", *cp,
              lineNum);
    }
    errno = EINVAL;
    return -1;
  }

  while (isspace(*cp) && (*cp != '\n')) ++cp;
  const char* fmt = NULL;
  size_t fmtLen = 0;
  if (*cp && (*cp != '#')) {
    fmt = cp;
    while (*cp && (*cp != '\n') && (*cp != '#')) ++cp;
    while ((cp > fmt) && isspace(*(cp - 1))) --cp;
    fmtLen = cp - fmt;
  }

  // KISS Only report identicals if they are global
  // Ideally we want to check if there are identicals
  // recorded for the same uid, but recording that
  // unused detail in our database is too burdensome.
  bool verbose = true;
  while (*cp && (*cp != '#') && (*cp != '\n')) ++cp;
  if (*cp == '#') {
    do {
      ++cp;
    } while (isspace(*cp) && (*cp != '\n'));
    verbose = !!fastcmp<strncmp>(cp, "uid=", strlen("uid="));
  }

  while (*cp && (*cp != '\n')) ++cp;
#ifdef DEBUG
  fprintf(stderr, "%d: %p: %.*s\n", lineNum, tag, (int)(cp - pData), pData);
#endif
  pData = cp;

  if (lineNum) {
    if (map->emplaceUnique(tagIndex,
                           TagFmt(std::make_pair(MapString(tag, tagLen),
                                                 MapString(fmt, fmtLen))),
                           verbose)) {
      return 0;
    }
  } else {
    // cache
    if (map->emplaceUnique(
            tagIndex,
            TagFmt(std::make_pair(MapString(std::string(tag, tagLen)),
                                  MapString(std::string(fmt, fmtLen)))))) {
      return 0;
    }
  }
  errno = EMLINK;
  return -1;
}