C
This page curates a list of example ast-grep rules to check and to rewrite C code.
Rewrite Method to Function Call Has Fix
Description
In C, there is no built-in support for object-oriented programming, but some programmers use structs and function pointers to simulate classes and methods. However, this style can have some drawbacks, such as:
- extra memory allocation and deallocation for the struct and the function pointer.
- indirection overhead when calling the function pointer.
A possible alternative is to use a plain function call with the struct pointer as the first argument.
YAML
id: method_receiver
language: c
rule:
pattern: $R.$METHOD($$$ARGS)
transform:
MAYBE_COMMA:
replace:
source: $$$ARGS
replace: '^.+'
by: ', '
fix:
$METHOD(&$R$MAYBE_COMMA$$$ARGS)
Example
void test_func() {
some_struct->field.method();
some_struct->field.other_method(1, 2, 3);
}
Diff
void test_func() {
some_struct->field.method();
method(&some_struct->field);
some_struct->field.other_method(1, 2, 3);
other_method(&some_struct->field, 1, 2, 3);
}
Contributed by
Surma, adapted from the original tweet
Rewrite Check to Yoda Condition Has Fix
Description
In programming jargon, a Yoda condition is a style that places the constant portion of the expression on the left side of the conditional statement. It is used to prevent assignment errors that may occur in languages like C.
YAML
id: may-the-force-be-with-you
language: c
rule:
pattern: $A == $B # Find equality comparison
inside: # inside an if_statement
kind: parenthesized_expression
inside: {kind: if_statement}
constraints: # with the constraint that
B: { kind: number_literal } # right side is a number
fix: $B == $A
The rule targets an equality comparison, denoted by the pattern $A == $B
. This comparison must occur inside an if_statement
. Additionally, there’s a constraint that the right side of the comparison, $B
, must be a number_literal like 42
.
Example
if (myNumber == 42) { /* ... */}
if (notMatch == another) { /* ... */}
if (notMatch) { /* ... */}
Diff
if (myNumber == 42) { /* ... */}
if (42 == myNumber) { /* ... */}
if (notMatch == another) { /* ... */}
if (notMatch) { /* ... */}
Contributed by
Inspired by this thread