xref: /kernel/liteos_a/apps/perf/src/option.c (revision 0d163575)
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}