]> git.proxmox.com Git - mirror_smartmontools-debian.git/blobdiff - utility.cpp
Refresh original patches with new upstream release
[mirror_smartmontools-debian.git] / utility.cpp
index 09a4f1f1bb45c86afe9c0b1b37113e0533df4354..5aabd26d8671aa801c850fdd9dbbbfeab25be443 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * utility.cpp
  *
- * Home page of code is: http://smartmontools.sourceforge.net
+ * Home page of code is: http://www.smartmontools.org
  *
- * Copyright (C) 2002-12 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2002-12 Bruce Allen
+ * Copyright (C) 2008-17 Christian Franke
  * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -52,7 +52,7 @@
 #include "atacmds.h"
 #include "dev_interface.h"
 
-const char * utility_cpp_cvsid = "$Id: utility.cpp 3937 2014-07-05 17:51:21Z chrfranke $"
+const char * utility_cpp_cvsid = "$Id: utility.cpp 4583 2017-11-03 21:10:09Z chrfranke $"
                                  UTILITY_H_CVSID INT64_H_CVSID;
 
 const char * packet_types[] = {
@@ -90,23 +90,20 @@ std::string format_version_info(const char * prog_name, bool full /*= false*/)
       "(build date " __DATE__ ")" // checkout without expansion of Id keywords
 #endif
       " [%s] " BUILD_INFO "\n"
-    "Copyright (C) 2002-14, Bruce Allen, Christian Franke, www.smartmontools.org\n",
+    "Copyright (C) 2002-17, Bruce Allen, Christian Franke, www.smartmontools.org\n",
     prog_name, smi()->get_os_version_str().c_str()
   );
   if (!full)
     return info;
 
-  info += strprintf(
-    "\n"
-    "%s comes with ABSOLUTELY NO WARRANTY. This is free\n"
+  info += "\n";
+  info += prog_name;
+  info += " comes with ABSOLUTELY NO WARRANTY. This is free\n"
     "software, and you are welcome to redistribute it under\n"
     "the terms of the GNU General Public License; either\n"
     "version 2, or (at your option) any later version.\n"
     "See http://www.gnu.org for further details.\n"
-    "\n",
-    prog_name
-  );
-  info +=
+    "\n"
     "smartmontools release " PACKAGE_VERSION
       " dated " SMARTMONTOOLS_RELEASE_DATE " at " SMARTMONTOOLS_RELEASE_TIME "\n"
 #ifdef SMARTMONTOOLS_SVN_REV
@@ -116,13 +113,24 @@ std::string format_version_info(const char * prog_name, bool full /*= false*/)
     "smartmontools SVN rev is unknown\n"
 #endif
     "smartmontools build host: " SMARTMONTOOLS_BUILD_HOST "\n"
+    "smartmontools build with: "
+#if   __cplusplus > 201402
+                               "C++17"
+#elif __cplusplus > 201103
+                               "C++14"
+#elif __cplusplus > 199711
+                               "C++11"
+#else
+                               "C++98"
+#endif
 #if defined(__GNUC__) && defined(__VERSION__) // works also with CLang
-    "smartmontools build with: GCC " __VERSION__ "\n"
+                                     ", GCC " __VERSION__
 #endif
-    "smartmontools configure arguments: "
+                                                          "\n"
+    "smartmontools configure arguments:"
   ;
   info += (sizeof(SMARTMONTOOLS_CONFIGURE_ARGS) > 1 ?
-           SMARTMONTOOLS_CONFIGURE_ARGS : "[no arguments given]");
+           SMARTMONTOOLS_CONFIGURE_ARGS : " [no arguments given]");
   info += '\n';
 
   return info;
@@ -291,9 +299,6 @@ void dateandtimezoneepoch(char *buffer, time_t tval){
   const char *timezonename;
   char datebuffer[DATEANDEPOCHLEN];
   int lenm1;
-#ifdef _WIN32
-  char tzfixbuf[6+1];
-#endif
 
   FixGlibcTimeZoneBug();
   
@@ -309,7 +314,12 @@ void dateandtimezoneepoch(char *buffer, time_t tval){
   // Remove newline
   lenm1=strlen(datebuffer)-1;
   datebuffer[lenm1>=0?lenm1:0]='\0';
-  
+
+#if defined(_WIN32) && defined(_MSC_VER)
+  // tzname is missing in MSVC14
+  #define tzname _tzname
+#endif
+
   // correct timezone name
   if (tmval->tm_isdst==0)
     // standard time zone
@@ -323,6 +333,8 @@ void dateandtimezoneepoch(char *buffer, time_t tval){
 
 #ifdef _WIN32
   // Fix long non-ascii timezone names
+    // cppcheck-suppress variableScope
+  char tzfixbuf[6+1] = "";
   if (!getenv("TZ"))
     timezonename=fixtzname(tzfixbuf, sizeof(tzfixbuf), timezonename);
 #endif
@@ -511,33 +523,6 @@ bool regular_expression::compile()
   return true;
 }
 
-// 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;
-}
-
 #ifndef HAVE_STRTOULL
 // Replacement for missing strtoull() (Linux with libc < 6, MSVC)
 // Functionality reduced to requirements of smartd and split_selective_arg().
@@ -644,73 +629,6 @@ int split_selective_arg(char *s, uint64_t *start,
   return 0;
 }
 
-#ifdef OLD_INTERFACE
-
-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;
-  }
-  throw std::runtime_error("Internal error in CheckFree()");
-}
-
-// A custom version of calloc() that tracks memory use
-void *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)
-      throw std::runtime_error("Internal error in CustomStrDup()");
-    else
-      return NULL;
-  }
-
-  // make a copy of the string...
-  tmp=strdup(ptr);
-  
-  if (!tmp)
-    throw std::bad_alloc();
-  
-  // and track memory usage
-  bytes+=1+strlen(ptr);
-  
-  return tmp;
-}
-
-#endif // OLD_INTERFACE
-
-
 // Returns true if region of memory contains non-zero entries
 bool nonempty(const void * data, int size)
 {
@@ -720,6 +638,31 @@ bool nonempty(const void * data, int size)
   return false;
 }
 
+// Copy not null terminated char array to null terminated string.
+// Replace non-ascii characters.  Remove leading and trailing blanks.
+const char * format_char_array(char * str, int strsize, const char * chr, int chrsize)
+{
+  int b = 0;
+  while (b < chrsize && chr[b] == ' ')
+    b++;
+  int n = 0;
+  while (b+n < chrsize && chr[b+n])
+    n++;
+  while (n > 0 && chr[b+n-1] == ' ')
+    n--;
+
+  if (n >= strsize)
+    n = strsize-1;
+
+  for (int i = 0; i < n; i++) {
+    char c = chr[b+i];
+    str[i] = (' ' <= c && c <= '~' ? c : '?');
+  }
+
+  str[n] = 0;
+  return str;
+}
+
 // Format integer with thousands separator
 const char * format_with_thousands_sep(char * str, int strsize, uint64_t val,
                                        const char * thousands_sep /* = 0 */)
@@ -795,7 +738,7 @@ const char * format_capacity(char * str, int strsize, uint64_t val,
 }
 
 // return (v)sprintf() formatted std::string
-
+__attribute_format_printf(1, 0)
 std::string vstrprintf(const char * fmt, va_list ap)
 {
   char buf[512];
@@ -844,7 +787,14 @@ int safe_snprintf(char *buf, int size, const char *fmt, ...)
   return i;
 }
 
-#else // HAVE_WORKING_SNPRINTF
+static void check_snprintf() {}
+
+#elif defined(__GNUC__) && (__GNUC__ >= 7)
+
+// G++ 7+: Assume sane implementation and avoid -Wformat-truncation warning
+static void check_snprintf() {}
+
+#else
 
 static void check_snprintf()
 {
@@ -852,8 +802,7 @@ static void check_snprintf()
   int n1 = snprintf(buf, 8, "123456789");
   int n2 = snprintf(buf, 0, "X");
   if (!(!strcmp(buf, "1234567") && n1 == 9 && n2 == 1))
-    throw std::logic_error("Function snprintf() does not conform to C99,\n"
-                           "please contact " PACKAGE_BUGREPORT);
+    throw std::logic_error("Function snprintf() does not conform to C99");
 }
 
 #endif // HAVE_WORKING_SNPRINTF
@@ -862,7 +811,5 @@ static void check_snprintf()
 void check_config()
 {
   check_endianness();
-#ifdef HAVE_WORKING_SNPRINTF
   check_snprintf();
-#endif
 }