Skip to content

Commit 989e5b8

Browse files
walaclenticularis39
authored andcommitted
rtla/actions: Simplify argument parsing
The actions_parse() function uses open-coded logic to extract arguments from a string. This includes manual length checks and strncmp() calls, which can be verbose and error-prone. To simplify and improve the robustness of argument parsing, introduce a new extract_arg() helper macro. This macro extracts the value from a "key=value" pair, making the code more concise and readable. Also, introduce STRING_LENGTH() and strncmp_static() macros to perform compile-time calculations of string lengths and safer string comparisons. Refactor actions_parse() to use these new helpers, resulting in cleaner and more maintainable code. Signed-off-by: Wander Lairson Costa <wander@redhat.com> Link: https://lore.kernel.org/r/20260309195040.1019085-4-wander@redhat.com Signed-off-by: Tomas Glozar <tglozar@redhat.com>
1 parent b8f7f49 commit 989e5b8

2 files changed

Lines changed: 52 additions & 15 deletions

File tree

tools/tracing/rtla/src/actions.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,29 @@ actions_add_continue(struct actions *self)
111111
action->type = ACTION_CONTINUE;
112112
}
113113

114+
static inline const char *__extract_arg(const char *token, const char *opt, size_t opt_len)
115+
{
116+
const size_t tok_len = strlen(token);
117+
118+
if (tok_len <= opt_len)
119+
return NULL;
120+
121+
if (strncmp(token, opt, opt_len))
122+
return NULL;
123+
124+
return token + opt_len;
125+
}
126+
127+
/*
128+
* extract_arg - extract argument value from option token
129+
* @token: option token (e.g., "file=trace.txt")
130+
* @opt: option name to match (e.g., "file")
131+
*
132+
* Returns pointer to argument value after "=" if token matches "opt=",
133+
* otherwise returns NULL.
134+
*/
135+
#define extract_arg(token, opt) __extract_arg(token, opt "=", STRING_LENGTH(opt "="))
136+
114137
/*
115138
* actions_parse - add an action based on text specification
116139
*/
@@ -120,6 +143,7 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
120143
enum action_type type = ACTION_NONE;
121144
const char *token;
122145
char trigger_c[strlen(trigger) + 1];
146+
const char *arg_value;
123147

124148
/* For ACTION_SIGNAL */
125149
int signal = 0, pid = 0;
@@ -152,12 +176,10 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
152176
if (token == NULL)
153177
trace_output = tracefn;
154178
else {
155-
if (strlen(token) > 5 && strncmp(token, "file=", 5) == 0) {
156-
trace_output = token + 5;
157-
} else {
179+
trace_output = extract_arg(token, "file");
180+
if (!trace_output)
158181
/* Invalid argument */
159182
return -1;
160-
}
161183

162184
token = strtok(NULL, ",");
163185
if (token != NULL)
@@ -169,17 +191,21 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
169191
case ACTION_SIGNAL:
170192
/* Takes two arguments, num (signal) and pid */
171193
while (token != NULL) {
172-
if (strlen(token) > 4 && strncmp(token, "num=", 4) == 0) {
173-
if (strtoi(token + 4, &signal))
174-
return -1;
175-
} else if (strlen(token) > 4 && strncmp(token, "pid=", 4) == 0) {
176-
if (strncmp(token + 4, "parent", 7) == 0)
177-
pid = -1;
178-
else if (strtoi(token + 4, &pid))
194+
arg_value = extract_arg(token, "num");
195+
if (arg_value) {
196+
if (strtoi(arg_value, &signal))
179197
return -1;
180198
} else {
181-
/* Invalid argument */
182-
return -1;
199+
arg_value = extract_arg(token, "pid");
200+
if (arg_value) {
201+
if (strncmp_static(arg_value, "parent") == 0)
202+
pid = -1;
203+
else if (strtoi(arg_value, &pid))
204+
return -1;
205+
} else {
206+
/* Invalid argument */
207+
return -1;
208+
}
183209
}
184210

185211
token = strtok(NULL, ",");
@@ -194,9 +220,10 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
194220
case ACTION_SHELL:
195221
if (token == NULL)
196222
return -1;
197-
if (strlen(token) > 8 && strncmp(token, "command=", 8))
223+
arg_value = extract_arg(token, "command");
224+
if (!arg_value)
198225
return -1;
199-
actions_add_shell(self, token + 8);
226+
actions_add_shell(self, arg_value);
200227
break;
201228
case ACTION_CONTINUE:
202229
/* Takes no argument */

tools/tracing/rtla/src/utils.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414
#define MAX_NICE 20
1515
#define MIN_NICE -19
1616

17+
#ifndef ARRAY_SIZE
18+
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
19+
#endif
20+
21+
/* Calculate string length at compile time (excluding null terminator) */
22+
#define STRING_LENGTH(s) (ARRAY_SIZE(s) - sizeof(*(s)))
23+
24+
/* Compare string with static string, length determined at compile time */
25+
#define strncmp_static(s1, s2) strncmp(s1, s2, ARRAY_SIZE(s2))
26+
1727
#define container_of(ptr, type, member)({ \
1828
const typeof(((type *)0)->member) *__mptr = (ptr); \
1929
(type *)((char *)__mptr - offsetof(type, member)) ; })

0 commit comments

Comments
 (0)