return 0;
}
+/*
+ ***************************************************************************
+ * Parse string containing a single value or a range of values
+ * (e.g. "0,2-5,10-").
+ *
+ * IN:
+ * @t String to parse.
+ * @max_val Upper limit that value should not reach.
+ *
+ * OUT:
+ * @val_low Low value in range
+ * @val High value in range. @val_low and @val are the same if it's
+ * a single value.
+ *
+ * RETURNS:
+ * 0 on success, 1 otherwise.
+ ***************************************************************************
+ */
+int parse_range_values(char *t, int max_val, int *val_low, int *val)
+{
+ char *s, *valstr, range[16];
+
+ /* Parse value or range of values */
+ strncpy(range, t, 16);
+ range[15] = '\0';
+ valstr = t;
+
+ if ((s = strchr(range, '-')) != NULL) {
+ /* Possible range of values */
+ *s = '\0';
+ if (parse_valstr(range, max_val, val_low) || (*val_low < 0))
+ return 1;
+ valstr = s + 1;
+ }
+ if (parse_valstr(valstr, max_val, val))
+ return 1;
+ if (s && *val < 0) {
+ /* Range of values with no upper limit (e.g. "3-") */
+ *val = max_val - 1;
+ }
+ if ((!s && (*val < 0)) || (s && (*val < *val_low)))
+ /*
+ * Individual value: string cannot be empty.
+ * Range of values: n-m: m can be empty (e.g. "3-") but
+ * cannot be lower than n.
+ */
+ return 1;
+ if (!s) {
+ *val_low = *val;
+ }
+ return 0;
+}
+
/*
***************************************************************************
* Parse string containing a set of coma-separated values or ranges of
int parse_values(char *strargv, unsigned char bitmap[], int max_val, const char *__K_VALUE0)
{
int i, val_low, val;
- char *t, *s, *valstr, range[16];
+ char *t;
if (!strcmp(strargv, K_ALL)) {
/* Set bit for every possible values (CPU, IRQ, etc.) */
}
else {
/* Parse value or range of values */
- strncpy(range, t, 16);
- range[15] = '\0';
- valstr = t;
- if ((s = strchr(range, '-')) != NULL) {
- /* Possible range of values */
- *s = '\0';
- if (parse_valstr(range, max_val, &val_low) || (val_low < 0))
- return 1;
- valstr = s + 1;
- }
- if (parse_valstr(valstr, max_val, &val))
+ if (parse_range_values(t, max_val, &val_low, &val))
return 1;
- if (s && val < 0) {
- /* Range of values with no upper limit (e.g. "3-") */
- val = max_val - 1;
- }
- if ((!s && (val < 0)) || (s && (val < val_low)))
- /*
- * Individual value: string cannot be empty.
- * Range of values: n-m: m can be empty (e.g. "3-") but
- * cannot be lower than n.
- */
- return 1;
- if (!s) {
- val_low = val;
- }
+
for (i = val_low; i <= val; i++) {
bitmap[(i + 1) >> 3] |= 1 << ((i + 1) & 0x07);
}
#define C_ALWAYS "always"
#define DIGITS "0123456789"
+#define XDIGITS "0123456789-"
/*
***************************************************************************
(unsigned long long, unsigned long long, unsigned long long);
int is_iso_time_fmt
(void);
+int parse_range_values
+ (char *t, int, int *, int *);
int parse_values
(char *, unsigned char[], int, const char *);
int print_gal_header
#define NO_TM_START 0
#define NO_TM_END 0
#define NO_RESET 0
+#define NO_RANGE 0
#define NON_FATAL 0
#define FATAL 1
#define C_SAR 0
int next_slice
(unsigned long long, unsigned long long, int, long);
void parse_sa_devices
- (char *, struct activity *, int, int *, int);
+ (char *, struct activity *, int, int *, int, int);
int parse_sar_opt
(char * [], int *, struct activity * [], uint64_t *, int);
int parse_sa_P_opt
* @max_len Max length of a device name.
* @opt Index in list of arguments.
* @pos Position is string where is located the first device.
+ * @max_val If > 0 then ranges of values are allowed (e.g. 3-5,9-, etc.)
+ * Values are in range [0..@max_val].
*
* OUT:
* @opt Index on next argument.
***************************************************************************
*/
-void parse_sa_devices(char *argv, struct activity *a, int max_len, int *opt, int pos)
+void parse_sa_devices(char *argv, struct activity *a, int max_len, int *opt, int pos,
+ int max_val)
{
+ int i, val_low, val;
char *t;
+ char svalue[9];
for (t = strtok(argv + pos, ","); t; t = strtok(NULL, ",")) {
+
+ /* Test ranges of values, if allowed */
+ if ((max_val > 0) && (strlen(t) <= 16) && (strspn(t, XDIGITS) == strlen(t))) {
+ if (parse_range_values(t, max_val, &val_low, &val) == 0) {
+ /* This is a real range of values: Save each if its values */
+ for (i = val_low; i <= val; i++) {
+ snprintf(svalue, sizeof(svalue), "%d", i);
+ svalue[sizeof(svalue) - 1] = '\0';
+ a->item_list_sz += add_list_item(&(a->item_list), svalue, max_len);
+ }
+ continue;
+ }
+ }
a->item_list_sz += add_list_item(&(a->item_list), t, max_len);
}
if (a->item_list_sz) {
fprintf(stderr, _("Options are:\n"
"[ -C ] [ -c | -d | -g | -j | -l | -p | -r | -x ] [ -H ] [ -h ] [ -T | -t | -U ] [ -V ]\n"
"[ -O <opts> [,...] ] [ -P { <cpu> [,...] | ALL } ]\n"
- "[ --dev=<dev_list> ] [ --fs=<fs_list> ] [ --iface=<iface_list> ]\n"
+ "[ --dev=<dev_list> ] [ --fs=<fs_list> ] [ --iface=<iface_list> ] [ --int=<int_list> ]\n"
"[ -s [ <hh:mm[:ss]> ] ] [ -e [ <hh:mm[:ss]> ] ]\n"
"[ -- <sar_options> ]\n"));
exit(1);
else if (!strncmp(argv[opt], "--dev=", 6)) {
/* Parse devices entered on the command line */
p = get_activity_position(act, A_DISK, EXIT_IF_NOT_FOUND);
- parse_sa_devices(argv[opt], act[p], MAX_DEV_LEN, &opt, 6);
+ parse_sa_devices(argv[opt], act[p], MAX_DEV_LEN, &opt, 6, NO_RANGE);
}
else if (!strncmp(argv[opt], "--fs=", 5)) {
/* Parse devices entered on the command line */
p = get_activity_position(act, A_FS, EXIT_IF_NOT_FOUND);
- parse_sa_devices(argv[opt], act[p], MAX_FS_LEN, &opt, 5);
+ parse_sa_devices(argv[opt], act[p], MAX_FS_LEN, &opt, 5, NO_RANGE);
}
else if (!strncmp(argv[opt], "--iface=", 8)) {
/* Parse devices entered on the command line */
p = get_activity_position(act, A_NET_DEV, EXIT_IF_NOT_FOUND);
- parse_sa_devices(argv[opt], act[p], MAX_IFACE_LEN, &opt, 8);
+ parse_sa_devices(argv[opt], act[p], MAX_IFACE_LEN, &opt, 8, NO_RANGE);
q = get_activity_position(act, A_NET_EDEV, EXIT_IF_NOT_FOUND);
act[q]->item_list = act[p]->item_list;
act[q]->item_list_sz = act[p]->item_list_sz;
act[q]->options |= AO_LIST_ON_CMDLINE;
}
+ else if (!strncmp(argv[opt], "--int=", 6)) {
+ /* Parse interrupts names entered on the command line */
+ p = get_activity_position(act, A_IRQ, EXIT_IF_NOT_FOUND);
+ parse_sa_devices(argv[opt], act[p], MAX_SA_IRQ_LEN, &opt, 6, NR_IRQS);
+ }
+
else if (!strcmp(argv[opt], "-s")) {
/* Get time start */
if (parse_timestamp(argv, &opt, &tm_start, DEF_TMSTART)) {
"[ -I { <int_list> | SUM | ALL } ] [ -P { <cpu_list> | ALL } ]\n"
"[ -m { <keyword> [,...] | ALL } ] [ -n { <keyword> [,...] | ALL } ]\n"
"[ -q [ <keyword> [,...] | ALL ] ]\n"
- "[ --dev=<dev_list> ] [ --fs=<fs_list> ] [ --iface=<iface_list> ]\n"
+ "[ --dev=<dev_list> ] [ --fs=<fs_list> ] [ --iface=<iface_list> ] "
+ "[ --int=<int_list> ]\n"
"[ --dec={ 0 | 1 | 2 } ] [ --help ] [ --human ] [ --pretty ] [ --sadc ]\n"
"[ -j { SID | ID | LABEL | PATH | UUID | ... } ]\n"
"[ -f [ <filename> ] | -o [ <filename> ] | -[0-9]+ ]\n"
else if (!strncmp(argv[opt], "--dev=", 6)) {
/* Parse devices entered on the command line */
p = get_activity_position(act, A_DISK, EXIT_IF_NOT_FOUND);
- parse_sa_devices(argv[opt], act[p], MAX_DEV_LEN, &opt, 6);
+ parse_sa_devices(argv[opt], act[p], MAX_DEV_LEN, &opt, 6, NO_RANGE);
}
else if (!strncmp(argv[opt], "--fs=", 5)) {
/* Parse devices entered on the command line */
p = get_activity_position(act, A_FS, EXIT_IF_NOT_FOUND);
- parse_sa_devices(argv[opt], act[p], MAX_FS_LEN, &opt, 5);
+ parse_sa_devices(argv[opt], act[p], MAX_FS_LEN, &opt, 5, NO_RANGE);
}
else if (!strncmp(argv[opt], "--iface=", 8)) {
/* Parse devices entered on the command line */
p = get_activity_position(act, A_NET_DEV, EXIT_IF_NOT_FOUND);
- parse_sa_devices(argv[opt], act[p], MAX_IFACE_LEN, &opt, 8);
+ parse_sa_devices(argv[opt], act[p], MAX_IFACE_LEN, &opt, 8, NO_RANGE);
q = get_activity_position(act, A_NET_EDEV, EXIT_IF_NOT_FOUND);
act[q]->item_list = act[p]->item_list;
act[q]->item_list_sz = act[p]->item_list_sz;
act[q]->options |= AO_LIST_ON_CMDLINE;
}
+ else if (!strncmp(argv[opt], "--int=", 6)) {
+ /* Parse interrupts names entered on the command line */
+ p = get_activity_position(act, A_IRQ, EXIT_IF_NOT_FOUND);
+ parse_sa_devices(argv[opt], act[p], MAX_SA_IRQ_LEN, &opt, 6, NR_IRQS);
+ }
+
else if (!strcmp(argv[opt], "--help")) {
/* Display help message */
display_help(argv[0]);