1/* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <stdio.h> 33#include <string.h> 34#include "option.h" 35#include "perf_list.h" 36 37static int ParseOption(char **argv, int *index, PerfOption *opts) 38{ 39 int ret = 0; 40 const char *str = NULL; 41 42 while ((opts->name != NULL) && (*opts->name != 0)) { 43 if (strcmp(argv[*index], opts->name) == 0) { 44 switch (opts->type) { 45 case OPTION_TYPE_UINT: 46 *opts->value = strtoul(argv[++(*index)], NULL, 0); 47 break; 48 case OPTION_TYPE_STRING: 49 *opts->str = argv[++(*index)]; 50 break; 51 case OPTION_TYPE_CALLBACK: 52 str = argv[++(*index)]; 53 if ((*opts->cb)(str) != 0) { 54 printf("parse error\n"); 55 ret = -1; 56 } 57 break; 58 default: 59 printf("invalid option\n"); 60 ret = -1; 61 break; 62 } 63 return ret; 64 } 65 opts++; 66 } 67 68 return -1; 69} 70 71int ParseOptions(int argc, char **argv, PerfOption *opts, SubCmd *cmd) 72{ 73 int i; 74 int index = 0; 75 76 while ((index < argc) && (argv[index] != NULL) && (*argv[index] == '-')) { 77 if (ParseOption(argv, &index, opts) != 0) { 78 return -1; 79 } 80 index++; 81 } 82 83 if ((index < argc) && (argv[index] != NULL)) { 84 cmd->path = argv[index]; 85 cmd->params[0] = argv[index]; 86 index++; 87 } else { 88 printf("no subcmd to execute\n"); 89 return -1; 90 } 91 92 for (i = 1; (index < argc) && (i < CMD_MAX_PARAMS); index++, i++) { 93 cmd->params[i] = argv[index]; 94 } 95 printf_debug("subcmd = %s\n", cmd->path); 96 for (int j = 0; j < i; j++) { 97 printf_debug("paras[%d]:%s\n", j, cmd->params[j]); 98 } 99 return 0; 100} 101 102int ParseIds(const char *argv, int *arr, unsigned int *len) 103{ 104 int res, ret; 105 unsigned int index = 0; 106 char *sp = NULL; 107 char *this = NULL; 108 char *list = strdup(argv); 109 110 if (list == NULL) { 111 printf("no memory for ParseIds\n"); 112 return -1; 113 } 114 115 sp = strtok_r(list, ",", &this); 116 while (sp) { 117 res = strtoul(sp, NULL, 0); 118 if (res < 0) { 119 ret = -1; 120 goto EXIT; 121 } 122 arr[index++] = res; 123 sp = strtok_r(NULL, ",", &this); 124 } 125 *len = index; 126 ret = 0; 127EXIT: 128 free(list); 129 return ret; 130} 131 132static inline const PerfEvent *StrToEvent(const char *str) 133{ 134 const PerfEvent *evt = &g_events[0]; 135 136 for (; evt->event != -1; evt++) { 137 if (strcmp(str, evt->name) == 0) { 138 return evt; 139 } 140 } 141 return NULL; 142} 143 144int ParseEvents(const char *argv, PerfEventConfig *eventsCfg, unsigned int *len) 145{ 146 int ret; 147 unsigned int index = 0; 148 const PerfEvent *event = NULL; 149 char *sp = NULL; 150 char *this = NULL; 151 char *list = strdup(argv); 152 153 if (list == NULL) { 154 printf("no memory for ParseEvents\n"); 155 return -1; 156 } 157 158 sp = strtok_r(list, ",", &this); 159 while (sp) { 160 event = StrToEvent(sp); 161 if (event == NULL) { 162 ret = -1; 163 goto EXIT; 164 } 165 166 if (index == 0) { 167 eventsCfg->type = event->type; 168 } else if (eventsCfg->type != event->type) { 169 printf("events type must be same\n"); 170 ret = -1; 171 goto EXIT; 172 } 173 eventsCfg->events[index].eventId = event->event; 174 sp = strtok_r(NULL, ",", &this); 175 index++; 176 } 177 *len = index; 178 ret = 0; 179EXIT: 180 free(list); 181 return ret; 182}