src/share/vm/services/diagnosticArgument.cpp

Thu, 13 Jun 2013 22:02:40 -0700

author
ccheung
date
Thu, 13 Jun 2013 22:02:40 -0700
changeset 5259
ef57c43512d6
parent 5237
f2110083203d
child 5751
1b03bed31241
permissions
-rw-r--r--

8014431: cleanup warnings indicated by the -Wunused-value compiler option on linux
Reviewed-by: dholmes, coleenp
Contributed-by: jeremymanson@google.com, calvin.cheung@oracle.com

     1 /*
     2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "memory/allocation.inline.hpp"
    27 #include "memory/resourceArea.hpp"
    28 #include "runtime/thread.hpp"
    29 #include "services/diagnosticArgument.hpp"
    31 void GenDCmdArgument::read_value(const char* str, size_t len, TRAPS) {
    32   /* NOTE:Some argument types doesn't require a value,
    33    * for instance boolean arguments: "enableFeatureX". is
    34    * equivalent to "enableFeatureX=true". In these cases,
    35    * str will be null. This is perfectly valid.
    36    * All argument types must perform null checks on str.
    37    */
    39   if (is_set() && !allow_multiple()) {
    40     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
    41             "Duplicates in diagnostic command arguments\n");
    42   }
    43   parse_value(str, len, CHECK);
    44   set_is_set(true);
    45 }
    47 void GenDCmdArgument::to_string(jlong l, char* buf, size_t len) {
    48   jio_snprintf(buf, len, INT64_FORMAT, l);
    49 }
    51 void GenDCmdArgument::to_string(bool b, char* buf, size_t len) {
    52   jio_snprintf(buf, len, b ? "true" : "false");
    53 }
    55 void GenDCmdArgument::to_string(NanoTimeArgument n, char* buf, size_t len) {
    56   jio_snprintf(buf, len, INT64_FORMAT, n._nanotime);
    57 }
    59 void GenDCmdArgument::to_string(MemorySizeArgument m, char* buf, size_t len) {
    60   jio_snprintf(buf, len, INT64_FORMAT, m._size);
    61 }
    63 void GenDCmdArgument::to_string(char* c, char* buf, size_t len) {
    64   jio_snprintf(buf, len, "%s", c);
    65 }
    67 void GenDCmdArgument::to_string(StringArrayArgument* f, char* buf, size_t len) {
    68   int length = f->array()->length();
    69   size_t written = 0;
    70   buf[0] = 0;
    71   for (int i = 0; i < length; i++) {
    72     char* next_str = f->array()->at(i);
    73     size_t next_size = strlen(next_str);
    74     //Check if there's room left to write next element
    75     if (written + next_size > len) {
    76       return;
    77     }
    78     //Actually write element
    79     strcat(buf, next_str);
    80     written += next_size;
    81     //Check if there's room left for the comma
    82     if (i < length-1 && len - written > 0) {
    83       strcat(buf, ",");
    84     }
    85   }
    86 }
    88 template <> void DCmdArgument<jlong>::parse_value(const char* str,
    89                                                   size_t len, TRAPS) {
    90   int scanned = -1;
    91   if (str == NULL
    92       || sscanf(str, JLONG_FORMAT"%n", &_value, &scanned) != 1
    93       || (size_t)scanned != len)
    94   {
    95     ResourceMark rm;
    97     char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
    98     strncpy(buf, str, len);
    99     buf[len] = '\0';
   100     Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(),
   101       "Integer parsing error in command argument '%s'. Could not parse: %s.", _name, buf);
   102   }
   103 }
   105 template <> void DCmdArgument<jlong>::init_value(TRAPS) {
   106   if (has_default()) {
   107     this->parse_value(_default_string, strlen(_default_string), THREAD);
   108     if (HAS_PENDING_EXCEPTION) {
   109       fatal("Default string must be parseable");
   110     }
   111   } else {
   112     set_value(0);
   113   }
   114 }
   116 template <> void DCmdArgument<jlong>::destroy_value() { }
   118 template <> void DCmdArgument<bool>::parse_value(const char* str,
   119                                                  size_t len, TRAPS) {
   120   // len is the length of the current token starting at str
   121   if (len == 0) {
   122     set_value(true);
   123   } else {
   124     if (len == strlen("true") && strncasecmp(str, "true", len) == 0) {
   125        set_value(true);
   126     } else if (len == strlen("false") && strncasecmp(str, "false", len) == 0) {
   127        set_value(false);
   128     } else {
   129       ResourceMark rm;
   131       char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
   132       strncpy(buf, str, len);
   133       buf[len] = '\0';
   134       Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(),
   135         "Boolean parsing error in command argument '%s'. Could not parse: %s.", _name, buf);
   136     }
   137   }
   138 }
   140 template <> void DCmdArgument<bool>::init_value(TRAPS) {
   141   if (has_default()) {
   142     this->parse_value(_default_string, strlen(_default_string), THREAD);
   143     if (HAS_PENDING_EXCEPTION) {
   144       fatal("Default string must be parsable");
   145     }
   146   } else {
   147     set_value(false);
   148   }
   149 }
   151 template <> void DCmdArgument<bool>::destroy_value() { }
   153 template <> void DCmdArgument<char*>::parse_value(const char* str,
   154                                                   size_t len, TRAPS) {
   155   if (str == NULL) {
   156     _value = NULL;
   157   } else {
   158     _value = NEW_C_HEAP_ARRAY(char, len+1, mtInternal);
   159     strncpy(_value, str, len);
   160     _value[len] = 0;
   161   }
   162 }
   164 template <> void DCmdArgument<char*>::init_value(TRAPS) {
   165   if (has_default() && _default_string != NULL) {
   166     this->parse_value(_default_string, strlen(_default_string), THREAD);
   167     if (HAS_PENDING_EXCEPTION) {
   168      fatal("Default string must be parsable");
   169     }
   170   } else {
   171     set_value(NULL);
   172   }
   173 }
   175 template <> void DCmdArgument<char*>::destroy_value() {
   176   if (_value != NULL) {
   177     FREE_C_HEAP_ARRAY(char, _value, mtInternal);
   178     set_value(NULL);
   179   }
   180 }
   182 template <> void DCmdArgument<NanoTimeArgument>::parse_value(const char* str,
   183                                                  size_t len, TRAPS) {
   184   if (str == NULL) {
   185     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   186               "Integer parsing error nanotime value: syntax error, value is null");
   187   }
   189   int argc = sscanf(str, JLONG_FORMAT, &_value._time);
   190   if (argc != 1) {
   191     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   192               "Integer parsing error nanotime value: syntax error");
   193   }
   194   size_t idx = 0;
   195   while(idx < len && isdigit(str[idx])) {
   196     idx++;
   197   }
   198   if (idx == len) {
   199     // only accept missing unit if the value is 0
   200     if (_value._time != 0) {
   201       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   202                 "Integer parsing error nanotime value: unit required");
   203     } else {
   204       _value._nanotime = 0;
   205       strcpy(_value._unit, "ns");
   206       return;
   207     }
   208   } else if(len - idx > 2) {
   209     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   210               "Integer parsing error nanotime value: illegal unit");
   211   } else {
   212     strncpy(_value._unit, &str[idx], len - idx);
   213     /*Write an extra null termination. This is safe because _value._unit
   214      * is declared as char[3], and length is checked to be not larger than
   215      * two above. Also, this is necessary, since length might be 1, and the
   216      * default value already in the string is ns, which is two chars.
   217      */
   218     _value._unit[len-idx] = '\0';
   219   }
   221   if (strcmp(_value._unit, "ns") == 0) {
   222     _value._nanotime = _value._time;
   223   } else if (strcmp(_value._unit, "us") == 0) {
   224     _value._nanotime = _value._time * 1000;
   225   } else if (strcmp(_value._unit, "ms") == 0) {
   226     _value._nanotime = _value._time * 1000 * 1000;
   227   } else if (strcmp(_value._unit, "s") == 0) {
   228     _value._nanotime = _value._time * 1000 * 1000 * 1000;
   229   } else if (strcmp(_value._unit, "m") == 0) {
   230     _value._nanotime = _value._time * 60 * 1000 * 1000 * 1000;
   231   } else if (strcmp(_value._unit, "h") == 0) {
   232     _value._nanotime = _value._time * 60 * 60 * 1000 * 1000 * 1000;
   233   } else if (strcmp(_value._unit, "d") == 0) {
   234     _value._nanotime = _value._time * 24 * 60 * 60 * 1000 * 1000 * 1000;
   235   } else {
   236      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   237                "Integer parsing error nanotime value: illegal unit");
   238   }
   239 }
   241 template <> void DCmdArgument<NanoTimeArgument>::init_value(TRAPS) {
   242   if (has_default()) {
   243     this->parse_value(_default_string, strlen(_default_string), THREAD);
   244     if (HAS_PENDING_EXCEPTION) {
   245       fatal("Default string must be parsable");
   246     }
   247   } else {
   248     _value._time = 0;
   249     _value._nanotime = 0;
   250     strcpy(_value._unit, "ns");
   251   }
   252 }
   254 template <> void DCmdArgument<NanoTimeArgument>::destroy_value() { }
   256 // WARNING StringArrayArgument can only be used as an option, it cannot be
   257 // used as an argument with the DCmdParser
   259 template <> void DCmdArgument<StringArrayArgument*>::parse_value(const char* str,
   260                                                   size_t len, TRAPS) {
   261   _value->add(str,len);
   262 }
   264 template <> void DCmdArgument<StringArrayArgument*>::init_value(TRAPS) {
   265   _value = new StringArrayArgument();
   266   _allow_multiple = true;
   267   if (has_default()) {
   268     fatal("StringArrayArgument cannot have default value");
   269   }
   270 }
   272 template <> void DCmdArgument<StringArrayArgument*>::destroy_value() {
   273   if (_value != NULL) {
   274     delete _value;
   275     set_value(NULL);
   276   }
   277 }
   279 template <> void DCmdArgument<MemorySizeArgument>::parse_value(const char* str,
   280                                                   size_t len, TRAPS) {
   281   if (str == NULL) {
   282     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   283               "Integer parsing error nanotime value: syntax error");
   284   }
   286   if (*str == '-') {
   287     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   288                "Parsing error memory size value: negative values not allowed");
   289   }
   290   int res = sscanf(str, UINT64_FORMAT "%c", &_value._val, &_value._multiplier);
   291   if (res == 2) {
   292      switch (_value._multiplier) {
   293       case 'k': case 'K':
   294          _value._size = _value._val * 1024;
   295          break;
   296       case 'm': case 'M':
   297          _value._size = _value._val * 1024 * 1024;
   298          break;
   299       case 'g': case 'G':
   300          _value._size = _value._val * 1024 * 1024 * 1024;
   301          break;
   302        default:
   303          _value._size = _value._val;
   304          _value._multiplier = ' ';
   305          //default case should be to break with no error, since user
   306          //can write size in bytes, or might have a delimiter and next arg
   307          break;
   308      }
   309    } else if (res == 1) {
   310      _value._size = _value._val;
   311    } else {
   312      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   313                "Parsing error memory size value: invalid value");
   314    }
   315 }
   317 template <> void DCmdArgument<MemorySizeArgument>::init_value(TRAPS) {
   318   if (has_default()) {
   319     this->parse_value(_default_string, strlen(_default_string), THREAD);
   320     if (HAS_PENDING_EXCEPTION) {
   321       fatal("Default string must be parsable");
   322     }
   323   } else {
   324     _value._size = 0;
   325     _value._val = 0;
   326     _value._multiplier = ' ';
   327   }
   328 }
   330 template <> void DCmdArgument<MemorySizeArgument>::destroy_value() { }

mercurial