⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utility.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    else      pout("%s\n",errormessage);  }  else if (message && *message)    pout("%s\n",message);    return;}// Prints a warning message for a failed regular expression compilation from// regcomp().void printregexwarning(int errcode, regex_t *compiled){  size_t length = regerror(errcode, compiled, NULL, 0);  char *buffer = (char*)malloc(length);  if (!buffer){    pout("Out of memory in printregexwarning()\n");    return;  }  regerror(errcode, compiled, buffer, length);  pout("%s\n", buffer);  free(buffer);  return;}// POSIX extended regular expressions interpret unmatched ')' ordinary:// "The close-parenthesis shall be considered special in this context//  only if matched with a preceding open-parenthesis."//// Actual '(...)' nesting errors remain undetected on strict POSIX// implementations (glibc) but an error is reported on others (Cygwin).// // The check below is rather incomplete because it does not handle// e.g. '\)' '[)]'.// But it should work for the regex subset used in drive database.static int check_regex_nesting(const char * pattern){  int level = 0, i;  for (i = 0; pattern[i] && level >= 0; i++) {    switch (pattern[i]) {      case '(': level++; break;      case ')': level--; break;    }  }  return level;}// A wrapper for regcomp().  Returns zero for success, non-zero otherwise.int compileregex(regex_t *compiled, const char *pattern, int cflags){   int errorcode;  if (   (errorcode = regcomp(compiled, pattern, cflags))      || check_regex_nesting(pattern) < 0                ) {    pout("Internal error: unable to compile regular expression \"%s\" ", pattern);    if (errorcode)      printregexwarning(errorcode, compiled);    else      pout("Unmatched ')'\n");    pout("Please inform smartmontools developers at " PACKAGE_BUGREPORT "\n");    return 1;  }  return 0;}// Splits an argument to the -r option into a name part and an (optional) // positive integer part.  s is a pointer to a string containing the// argument.  After the call, s will point to the name part and *i the// integer part if there is one or 1 otherwise.  Note that the string s may// be changed by this function.  Returns zero if successful and non-zero// otherwise.int split_report_arg(char *s, int *i){  if ((s = strchr(s, ','))) {    // Looks like there's a name part and an integer part.    char *tailptr;    *s++ = '\0';    if (*s == '0' || !isdigit((int)*s))  // The integer part must be positive      return 1;    errno = 0;    *i = (int) strtol(s, &tailptr, 10);    if (errno || *tailptr != '\0')      return 1;  } else {    // There's no integer part.    *i = 1;  }  return 0;}// same as above but sets *i to -1 if missing , argumentint split_report_arg2(char *s, int *i){  char *tailptr;  s+=6;  if (*s=='\0' || !isdigit((int)*s)) {     // What's left must be integer    *i=-1;    return 1;  }  errno = 0;  *i = (int) strtol(s, &tailptr, 10);  if (errno || *tailptr != '\0') {    *i=-1;    return 1;  }  return 0;}#ifndef HAVE_STRTOULL// Replacement for missing strtoull() (Linux with libc < 6, MSVC 6.0)// Functionality reduced to split_selective_arg()'s requirements.static uint64_t strtoull(const char * p, char * * endp, int base){  uint64_t result, maxres;  int i = 0;  char c = p[i++];  // assume base == 0  if (c == '0') {    if (p[i] == 'x' || p[i] == 'X') {      base = 16; i++;    }    else      base = 8;    c = p[i++];  }  else    base = 10;  result = 0;  maxres = ~(uint64_t)0 / (unsigned)base;  for (;;) {    unsigned digit;    if ('0' <= c && c <= '9')      digit = c - '0';    else if ('A' <= c && c <= 'Z')      digit = c - 'A' + 10;    else if ('a' <= c && c <= 'z')      digit = c - 'a' + 10;    else      break;    if (digit >= (unsigned)base)      break;    if (!(   result < maxres          || (result == maxres && digit <= ~(uint64_t)0 % (unsigned)base))) {      result = ~(uint64_t)0; errno = ERANGE; // return on overflow      break;    }    result = result * (unsigned)base + digit;    c = p[i++];  }  *endp = (char *)p + i - 1;  return result;}#endif // HAVE_STRTOLL// Splits an argument to the -t option that is assumed to be of the form// "selective,%lld-%lld" (prefixes of "0" (for octal) and "0x"/"0X" (for hex)// are allowed).  The first long long int is assigned to *start and the second// to *stop.  Returns zero if successful and non-zero otherwise.int split_selective_arg(char *s, uint64_t *start,                        uint64_t *stop, int *mode){  char *tailptr;  if (!(s = strchr(s, ',')))    return 1;  bool add = false;  if (!isdigit((int)(*++s))) {    *start = *stop = 0;    if (!strncmp(s, "redo", 4))      *mode = SEL_REDO;    else if (!strncmp(s, "next", 4))      *mode = SEL_NEXT;    else if (!strncmp(s, "cont", 4))      *mode = SEL_CONT;    else      return 1;    s += 4;    if (!*s)      return 0;    if (*s != '+')      return 1;  }  else {    *mode = SEL_RANGE;    errno = 0;    // Last argument to strtoull (the base) is 0 meaning that decimal is assumed    // unless prefixes of "0" (for octal) or "0x"/"0X" (for hex) are used.    *start = strtoull(s, &tailptr, 0);    s = tailptr;    add = (*s == '+');    if (!(!errno && (add || *s == '-')))      return 1;    if (!strcmp(s, "-max")) {      *stop = ~(uint64_t)0; // replaced by max LBA later      return 0;    }  }  *stop = strtoull(s+1, &tailptr, 0);  if (errno || *tailptr != '\0')    return 1;  if (add) {    if (*stop > 0)      (*stop)--;    *stop += *start; // -t select,N+M => -t select,N,(N+M-1)  }  return 0;}int64_t bytes = 0;// Helps debugging.  If the second argument is non-negative, then// decrement bytes by that amount.  Else decrement bytes by (one plus)// length of null terminated string.void *FreeNonZero1(void *address, int size, int line, const char* file){  if (address) {    if (size<0)      bytes-=1+strlen((char*)address);    else      bytes-=size;    return CheckFree1(address, line, file);  }  return NULL;}// To help with memory checking.  Use when it is known that address is// NOT null.void *CheckFree1(void *address, int whatline, const char* file){  if (address){    free(address);    return NULL;  }    PrintOut(LOG_CRIT, "Internal error in CheckFree() at line %d of file %s\n%s",            whatline, file, reportbug);  EXIT(EXIT_BADCODE);}// A custom version of calloc() that tracks memory usevoid *Calloc(size_t nmemb, size_t size) {   void *ptr=calloc(nmemb, size);    if (ptr)    bytes+=nmemb*size;  return ptr;}// A custom version of strdup() that keeps track of how much memory is// being allocated. If mustexist is set, it also throws an error if we// try to duplicate a NULL string.char *CustomStrDup(const char *ptr, int mustexist, int whatline, const char* file){  char *tmp;  // report error if ptr is NULL and mustexist is set  if (ptr==NULL){    if (mustexist) {      PrintOut(LOG_CRIT, "Internal error in CustomStrDup() at line %d of file %s\n%s",                whatline, file, reportbug);      EXIT(EXIT_BADCODE);    }    else      return NULL;  }  // make a copy of the string...  tmp=strdup(ptr);    if (!tmp) {    PrintOut(LOG_CRIT, "No memory to duplicate string %s at line %d of file %s\n", ptr, whatline, file);    EXIT(EXIT_NOMEM);  }    // and track memory usage  bytes+=1+strlen(ptr);    return tmp;}// Returns nonzero if region of memory contains non-zero entriesint nonempty(unsigned char *testarea,int n){  int i;  for (i=0;i<n;i++)    if (testarea[i])      return 1;  return 0;}// This routine converts an integer number of milliseconds into a test// string of the form Xd+Yh+Zm+Ts.msec.  The resulting text string is// written to the array.void MsecToText(unsigned int msec, char *txt){  int start=0;  unsigned int days, hours, min, sec;  days       = msec/86400000U;  msec      -= days*86400000U;  hours      = msec/3600000U;   msec      -= hours*3600000U;  min        = msec/60000U;  msec      -= min*60000U;  sec        = msec/1000U;  msec      -= sec*1000U;  if (days) {    txt += sprintf(txt, "%2dd+", (int)days);    start=1;  }  sprintf(txt, "%02d:%02d:%02d.%03d", (int)hours, (int)min, (int)sec, (int)msec);    return;}#ifndef HAVE_WORKING_SNPRINTF// Some versions of (v)snprintf() don't append null char on overflow (MSVCRT.DLL),// and/or return -1 on overflow (old Linux).// Below are sane replacements substituted by #define in utility.h.#undef vsnprintf#if defined(_WIN32) && defined(_MSC_VER)#define vsnprintf _vsnprintf#endifint safe_vsnprintf(char *buf, int size, const char *fmt, va_list ap){  int i;  if (size <= 0)    return 0;  i = vsnprintf(buf, size, fmt, ap);  if (0 <= i && i < size)    return i;  buf[size-1] = 0;  return strlen(buf); // Note: cannot detect for overflow, not necessary here.}int safe_snprintf(char *buf, int size, const char *fmt, ...){  int i; va_list ap;  va_start(ap, fmt);  i = safe_vsnprintf(buf, size, fmt, ap);  va_end(ap);  return i;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -