Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/tools/perf/util/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 9 kB image not shown  

Quelle  string.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
#include "string2.h"
#include <linux/kernel.h>
#include <linux/string.h>
#include <stdlib.h>

#include <linux/ctype.h>

const char *graph_dotted_line =
 "---------------------------------------------------------------------"
 "---------------------------------------------------------------------"
 "---------------------------------------------------------------------";
const char *dots =
 "....................................................................."
 "....................................................................."
 ".....................................................................";

/*
 * perf_atoll()
 * Parse (\d+)(b|B|kb|KB|mb|MB|gb|GB|tb|TB) (e.g. "256MB")
 * and return its numeric value
 */

s64 perf_atoll(const char *str)
{
 s64 length;
 char *p;
 char c;

 if (!isdigit(str[0]))
  goto out_err;

 length = strtoll(str, &p, 10);
 switch (c = *p++) {
  case 'b'case 'B':
   if (*p)
    goto out_err;

   fallthrough;
  case '\0':
   return length;
  default:
   goto out_err;
  /* two-letter suffices */
  case 'k'case 'K':
   length <<= 10;
   break;
  case 'm'case 'M':
   length <<= 20;
   break;
  case 'g'case 'G':
   length <<= 30;
   break;
  case 't'case 'T':
   length <<= 40;
   break;
 }
 /* we want the cases to match */
 if (islower(c)) {
  if (strcmp(p, "b") != 0)
   goto out_err;
 } else {
  if (strcmp(p, "B") != 0)
   goto out_err;
 }
 return length;

out_err:
 return -1;
}

/* Character class matching */
static bool __match_charclass(const char *pat, char c, const char **npat)
{
 bool complement = false, ret = true;

 if (*pat == '!') {
  complement = true;
  pat++;
 }
 if (*pat++ == c) /* First character is special */
  goto end;

 while (*pat && *pat != ']') { /* Matching */
  if (*pat == '-' && *(pat + 1) != ']') { /* Range */
   if (*(pat - 1) <= c && c <= *(pat + 1))
    goto end;
   if (*(pat - 1) > *(pat + 1))
    goto error;
   pat += 2;
  } else if (*pat++ == c)
   goto end;
 }
 if (!*pat)
  goto error;
 ret = false;

end:
 while (*pat && *pat != ']'/* Searching closing */
  pat++;
 if (!*pat)
  goto error;
 *npat = pat + 1;
 return complement ? !ret : ret;

error:
 return false;
}

/* Glob/lazy pattern matching */
static bool __match_glob(const char *str, const char *pat, bool ignore_space,
   bool case_ins)
{
 while (*str && *pat && *pat != '*') {
  if (ignore_space) {
   /* Ignore spaces for lazy matching */
   if (isspace(*str)) {
    str++;
    continue;
   }
   if (isspace(*pat)) {
    pat++;
    continue;
   }
  }
  if (*pat == '?') { /* Matches any single character */
   str++;
   pat++;
   continue;
  } else if (*pat == '['/* Character classes/Ranges */
   if (__match_charclass(pat + 1, *str, &pat)) {
    str++;
    continue;
   } else
    return false;
  else if (*pat == '\\'/* Escaped char match as normal char */
   pat++;
  if (case_ins) {
   if (tolower(*str) != tolower(*pat))
    return false;
  } else if (*str != *pat)
   return false;
  str++;
  pat++;
 }
 /* Check wild card */
 if (*pat == '*') {
  while (*pat == '*')
   pat++;
  if (!*pat) /* Tail wild card matches all */
   return true;
  while (*str)
   if (__match_glob(str++, pat, ignore_space, case_ins))
    return true;
 }
 return !*str && !*pat;
}

/**
 * strglobmatch - glob expression pattern matching
 * @str: the target string to match
 * @pat: the pattern string to match
 *
 * This returns true if the @str matches @pat. @pat can includes wildcards
 * ('*','?') and character classes ([CHARS], complementation and ranges are
 * also supported). Also, this supports escape character ('\') to use special
 * characters as normal character.
 *
 * Note: if @pat syntax is broken, this always returns false.
 */

bool strglobmatch(const char *str, const char *pat)
{
 return __match_glob(str, pat, falsefalse);
}

bool strglobmatch_nocase(const char *str, const char *pat)
{
 return __match_glob(str, pat, falsetrue);
}

/**
 * strlazymatch - matching pattern strings lazily with glob pattern
 * @str: the target string to match
 * @pat: the pattern string to match
 *
 * This is similar to strglobmatch, except this ignores spaces in
 * the target string.
 */

bool strlazymatch(const char *str, const char *pat)
{
 return __match_glob(str, pat, truefalse);
}

/**
 * strtailcmp - Compare the tail of two strings
 * @s1: 1st string to be compared
 * @s2: 2nd string to be compared
 *
 * Return 0 if whole of either string is same as another's tail part.
 */

int strtailcmp(const char *s1, const char *s2)
{
 int i1 = strlen(s1);
 int i2 = strlen(s2);
 while (--i1 >= 0 && --i2 >= 0) {
  if (s1[i1] != s2[i2])
   return s1[i1] - s2[i2];
 }
 return 0;
}

char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints)
{
 /*
 * FIXME: replace this with an expression using log10() when we
 * find a suitable implementation, maybe the one in the dvb drivers...
 *
 * "%s == %d || " = log10(MAXINT) * 2 + 8 chars for the operators
 */

 size_t size = nints * 28 + 1; /* \0 */
 size_t i, printed = 0;
 char *expr = malloc(size);

 if (expr) {
  const char *or_and = "||", *eq_neq = "==";
  char *e = expr;

  if (!in) {
   or_and = "&&";
   eq_neq = "!=";
  }

  for (i = 0; i < nints; ++i) {
   if (printed == size)
    goto out_err_overflow;

   if (i > 0)
    printed += scnprintf(e + printed, size - printed, " %s ", or_and);
   printed += scnprintf(e + printed, size - printed,
          "%s %s %d", var, eq_neq, ints[i]);
  }
 }

 return expr;

out_err_overflow:
 free(expr);
 return NULL;
}

/* Like strpbrk(), but not break if it is right after a backslash (escaped) */
char *strpbrk_esc(char *str, const char *stopset)
{
 char *ptr;

 do {
  ptr = strpbrk(str, stopset);
  if (!ptr) {
   /* stopset not in str. */
   break;
  }
  if (ptr == str) {
   /* stopset character is first in str. */
   break;
  }
  if (ptr == str + 1 && str[0] != '\\') {
   /* stopset chacter is second and wasn't preceded by a '\'. */
   break;
  }
  str = ptr + 1;
 } while (ptr[-1] == '\\' && ptr[-2] != '\\');

 return ptr;
}

/* Like strpbrk_esc(), but not break if it is quoted with single/double quotes */
char *strpbrk_esq(char *str, const char *stopset)
{
 char *_stopset = NULL;
 char *ptr;
 const char *squote = "'";
 const char *dquote = "\"";

 if (asprintf(&_stopset, "%s%c%c", stopset, *squote, *dquote) < 0)
  return NULL;

 do {
  ptr = strpbrk_esc(str, _stopset);
  if (!ptr)
   break;
  if (*ptr == *squote)
   ptr = strpbrk_esc(ptr + 1, squote);
  else if (*ptr == *dquote)
   ptr = strpbrk_esc(ptr + 1, dquote);
  else
   break;
  str = ptr + 1;
 } while (ptr);

 free(_stopset);
 return ptr;
}

/* Like strdup, but do not copy a single backslash */
char *strdup_esc(const char *str)
{
 char *s, *d, *p, *ret = strdup(str);

 if (!ret)
  return NULL;

 d = strchr(ret, '\\');
 if (!d)
  return ret;

 s = d + 1;
 do {
  if (*s == '\0') {
   *d = '\0';
   break;
  }
  p = strchr(s + 1, '\\');
  if (p) {
   memmove(d, s, p - s);
   d += p - s;
   s = p + 1;
  } else
   memmove(d, s, strlen(s) + 1);
 } while (p);

 return ret;
}

/* Remove backslash right before quote and return next quote address. */
static char *remove_consumed_esc(char *str, int len, int quote)
{
 char *ptr = str, *end = str + len;

 while (*ptr != quote && ptr < end) {
  if (*ptr == '\\' && *(ptr + 1) == quote) {
   memmove(ptr, ptr + 1, end - (ptr + 1));
   /* now *ptr is `quote`. */
   end--;
  }
  ptr++;
 }

 return *ptr == quote ? ptr : NULL;
}

/*
 * Like strdup_esc, but keep quoted string as it is (and single backslash
 * before quote is removed). If there is no closed quote, return NULL.
 */

char *strdup_esq(const char *str)
{
 char *d, *ret;

 /* If there is no quote, return normal strdup_esc() */
 d = strpbrk_esc((char *)str, "\"'");
 if (!d)
  return strdup_esc(str);

 ret = strdup(str);
 if (!ret)
  return NULL;

 d = ret;
 do {
  d = strpbrk(d, "\\\"\'");
  if (!d)
   break;

  if (*d == '"' || *d == '\'') {
   /* This is non-escaped quote */
   int quote = *d;
   int len = strlen(d + 1) + 1;

   /*
 * Remove the start quote and remove consumed escape (backslash
 * before quote) and remove the end quote. If there is no end
 * quote, it is the input error.
 */

   memmove(d, d + 1, len);
   d = remove_consumed_esc(d, len, quote);
   if (!d)
    goto error;
   memmove(d, d + 1, strlen(d + 1) + 1);
  }
  if (*d == '\\') {
   memmove(d, d + 1, strlen(d + 1) + 1);
   if (*d == '\\') {
    /* double backslash -- keep the second one. */
    d++;
   }
  }
 } while (*d != '\0');

 return ret;

error:
 free(ret);
 return NULL;
}

unsigned int hex(char c)
{
 if (c >= '0' && c <= '9')
  return c - '0';
 if (c >= 'a' && c <= 'f')
  return c - 'a' + 10;
 return c - 'A' + 10;
}

/*
 * Replace all occurrences of character 'needle' in string 'haystack' with
 * string 'replace'
 *
 * The new string could be longer so a new string is returned which must be
 * freed.
 */

char *strreplace_chars(char needle, const char *haystack, const char *replace)
{
 int replace_len = strlen(replace);
 char *new_s, *to;
 const char *loc = strchr(haystack, needle);
 const char *from = haystack;
 int num = 0;

 /* Count occurrences */
 while (loc) {
  loc = strchr(loc + 1, needle);
  num++;
 }

 /* Allocate enough space for replacements and reset first location */
 new_s = malloc(strlen(haystack) + (num * (replace_len - 1) + 1));
 if (!new_s)
  return NULL;
 loc = strchr(haystack, needle);
 to = new_s;

 while (loc) {
  /* Copy original string up to found char and update positions */
  memcpy(to, from, 1 + loc - from);
  to += loc - from;
  from = loc + 1;

  /* Copy replacement string and update positions */
  memcpy(to, replace, replace_len);
  to += replace_len;

  /* needle next occurrence or end of string */
  loc = strchr(from, needle);
 }

 /* Copy any remaining chars + null */
 strcpy(to, from);

 return new_s;
}

Messung V0.5
C=95 H=89 G=91

¤ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.