Search and replace in C source code, without touching comments - c

I have a lot of c code in which I would like to replace old syntax style with a new style. E.g. the following prefixes "si":
int siName;
should become "i":
int iName;
But the reg-expression or other find/replace tool, should not touch any source code comments.
Any solution?

You can try out coccinelle. It has a bit of a learning curve, but it parses the C code and executes the transformations given to it in a script. For example, for renaming a function from foo to bar, the script would look like this (from here):
##
##
-foo()
+bar()
It can probably rename variables based on regular expressions as well, I haven't yet found out a way though.

In vi use
:%s/\<Oldword\>/Newword/gc
This asks you whether or not to replace a particular occurrence of the whole word which you may happily neglect if it is a part of the comment.

With respect to the suggestion about Coccinelle, you can match using regular expressions using the following notation:
identifier foo =~ "xxx";
That is, foo will match any identifier that contains xxx. PCRE regular expressions are supported.
You can also use python to create a new identifier:
#a#
identifier x;
##
foo(x)
#script:python b#
x << a.x;
xx;
##
coccinelle.xx = "%s%s" % (x,x)
##
identifier a.x;
identifier b.xx;
##
foo(
- x
+ xx
)
For the program:
int main () {
foo(one);
}
This gives
int main () {
foo(oneone);
}

Related

Dynamic method of calling structures in C

I have a project which involves writing a C program for some software used by my company. I want it to be as efficient as possible, but the way the software references the signals I'm working with is a little wonky. I'm working with 4 sets of 96 signals; these signals are grouped into 32 groups with 3 members each. Rather than generic functions to work with these signals (the generic functions exist, but there's no documentation on how they work), the auto-generated header file has defined a group of macros (I think) for each of these groups.
Each of the groups are defined as follows...
typedef struct {
//struct members
} AB_A_Group_A_Network
Each of those structures have a group of macros(?) defined like this...
void AB_A_Group_ZF_Network_Init(AB_A_Group_A_Network *pAbc)
{
double values[6]
...
pAbc->Member_1 = values[3] //array positions vary
pAbc->Member_2 = values[4]
pAbc->Member_3 = values[5]
}
The software's tech support suggested I do the following, but I was hoping there'd be a better way to do it. Of course this is a long method, but I can write it with a python script no problem, if need be. These 250+ lines of code will run every second in my application for each data set.
AB_A_Group_A_Network GroupA;
AB_A_Group_B_Network GroupB;
//...and so on
AB_A_Group_ZF_Network GroupZF;
AB_A_Group_A_Network_Init(&GroupA);
AB_A_Group_B_Network_Init(&GroupB);
//...and so on
AB_A_Group_ZF_Network_Init(&GroupZF);
CD_Array_Set(0,GroupA.Member_1); //a custom array function meant to interface with the software
CD_Array_Set(1,GroupA.Member_2);
//...and so on
CD_Array_Set(95,GroupZF.Member_96);
//...Repeat 3 times for 4 sets of data (Data sets A-D), with checks to see if that data exists
I thought of doing something like this, but I'm not sure you can use char arrays in this way. I'll add the disclaimer don't have much experience with C, so this might look/sound really stupid. This isn't working code, just a stream of consciousness. I'm also not sure if doing it in this way, if possible, would just end up losing efficiency. I'm completely open to other methods.
char groupName[70] = "AB_*_Group_*_Network";
char dataset = 'A';
char group = 'A';
char member = '1';
char groupInit[70]
//write a loop to increment dataset alphabetically
//check if dataset exists
groupName[3] = dataset;
//write a sub-loop to increment group alphabetically (each set has 32 groups)
groupName[27] = group;
//use groupName in place of struct name (not sure how or if this is possible with my current methods)
groupInit = strncat(groupName, "_Init", 5);
//use groupInit in place of _init macro name
//write a sub-loop to increment member numerically (each group has 3 members)
char member[10] = "Member_*";
member[7] = member;
CD_Array_Set(i,groupName.member);
Is the long method really the best way of doing this? Any advice you can offer is appreciated!
There's no way to refer to variables and type names dynamically from strings at runtime. But you can use token pasting in a macro to avoid all the repeated code.
#define INIT_GROUP(dataset, group) \
AB_ ## dataset ## _Group_ ## group ## _Network Group ## group; \
AB_ ## dataset ## _Group_ ## group ## _Network_Init(&Group ## group); \
CD_Array_Set(0,Group ## group .Member_1); \
CD_Array_Set(1,Group ## group .Member_2); \
...
CD_Array_Set(95,Group ## group .Member_96);
Unfortunately, there are no loops in the preprocessor, so you have to write all 96 CD_Array_Set lines in the macro.
With this macro, you can then write:
INIT_GROUP(A, A)
INIT_GROUP(A, B)
...
INIT_GROUP(A, ZF)
Auto generated C code
It is possible to do such things in C but it requires ugly Macros.
First thing i would look at is
An old Stackoverflow question: https://stackoverflow.com/a/12591965/8964221
And the mentioned gist in it: https://gist.github.com/epatel/3786323
BUT!
I would think about the time it would consume to have it bug free and working.
It won`t be that easy to transform it to ur needs.

Array of macros in c -- is it possible

I was wondering if it is possible to create something like an array of macros.
I've implemented the following code which works:
struct led_cmds_
{
ioport_pin_t *commands[LED_COUNT] ;
};
struct led_cmds_ the_led_cmd_ ;
void populate() {
the_led_cmd_.commands[0] = SPECIFICPIN(0);
}
and in main:
int main(void)
{
//.....
populate();
LED_On(the_led_cmd_.commands[0]);
}
SPECIFICPIN(x) is macro defined as:
#define SPECIFICPIN(X) (LED##X##_PIN)
What I was hoping for is a way to is a way to do something like this:
#define ioport_pin_t* ARR_LED[LED_COUNT] \
for (int j = 0; j < LED_COUNT; j++) ARR_LED[j] = SPECIFICPIN(j);
and then only need to call the following when I want to use the specific pin
LED_On(ARR_LED[some_number])
when I try to do that I get an ARR_LED undeclared (first use in this function) error.
When I try to call SPECIFICPIN(x) where x is an int iterator in a for loop for example, I get an error saying something like 'LEDx_PIN' undeclared...
You need to work on your terminology. An array of macros is not possible. Macros are no data type, but rather pure text replacement before your program is actually compiled.
I guess " populate an array using macros " is what you want to do. But it is not possible to do that in a compile-time loop - What you seem to want to achieve with your ioport_pin_t macro attempt. Macros do not have the capability to expand to more instances of text elements than you have initially given. There is no such feature as looping at compile time through macro expansions and do repetitive expansion of macros.
Your for loop loops at run-time, while the macro is being expanded at compile-time. Once you have made yourself aware what is done by the preprocessor what is done by the compiler, and what is done at run-time by the finished program, you will see that will not work.
Something like
#define P(X) {(LED##X##_PIN)}
ioport_pin_t *commands[LED_COUNT] = {
P(0), P(1), P(2),......}
#undefine P
Would be the closest thing possible to what you seem to want. Note the main use of the pre-processor is not to save you typing effort - You would be better off using copy & paste in your editor, achieve the same thing and have clearer code.
An array as tofro's answer is the way to go. However in cases that couldn't be solved simply with an array then there's another way with switch
#define SPECIFICPIN(X) (LED##X##_PIN)
void setpin(int pin, int value)
{
switch (pin)
{
case 1:
SPECIFICPIN(1) = value;
doSomething(); // if needed
break;
case x: ...
default: ...
}
}

Search and replace a string as shown below

I am reading a file say x.c and I have to find for the string "shared". Once the string like that has been found, the following has to be done.
Example:
shared(x,n)
Output has to be
*var = &x;
*var1 = &n;
Pointers can be of any name. Output has to be written to a different file. How to do this?
I'm developing a source to source compiler for concurrent platforms using lex and yacc. This can be a routine written in C or if u can using lex and yacc. Can anyone please help?
Thanks.
If, as you state, the arguments can only be variables and not any kind of other expressions, then there are a couple of simple solutions.
One is to use regular expressions, and do a simple search/replace on the whole file using a pretty simple regular expression.
Another is to simply load the entire source file into memory, search using strstr for "shared(", and use e.g. strtok to get the arguments. Copy everything else verbatim to the destination.
Take advantage of the C preprocessor.
Put this at the top of the file
#define shared(x,n) { *var = &(x); *var1 = &(n); }
and run in through cpp. This will include external resources also and replace all macros, but you can simply remove all #something lines from the code, convert using injected preprocessor rules and then re-add them.
By the way, why not a simple macro set in a header file for the developer to include?
A doubt: where do var and var1 come from?
EDIT: corrected as shown by johnchen902
When it comes to preprocessor, I'll do this:
#define shared(x,n) (*var=&(x),*var1=&(n))
Why I think it's better than esseks's answer?
Suppose this situation:
if( someBool )
shared(x,n);
else { /* something else */ }
In esseks's answer it will becomes to:
if( someBool )
{ *var = &x; *var1 = &n; }; // compile error
else { /* something else */ }
And in my answer it will becomes to:
if( someBool )
(*var=&(x),*var1=&(n)); // good!
else { /* something else */ }

Ruby C API `defined? SomeConstant` equivalent?

I'm trying to convert an if condition of:
unless defined? SomeConstant
# do some stuff
end
Into part of a native C extension. Does anybody know how to do the defined? predicate check in the C API?
EDIT | I guess I could invoke:
rb_funcall(rb_cObject, rb_intern("const_defined?"), 1, rb_intern("SomeConstant"))
Though this is obviously slightly different, semantically.
If you trace through the 1.9.3 source, you'll find that defined? is implemented in insns.def:
DEFINE_INSN
defined
(rb_num_t op_type, VALUE obj, VALUE needstr)
/* ... */
switch (type) {
/* ... */
case DEFINED_CONST:
klass = v;
if (vm_get_ev_const(th, GET_ISEQ(), klass, SYM2ID(obj), 1)) {
expr_type = "constant";
}
break;
So when you defined? SomeConstant, you trickle through that big switch and end up calling vm_get_ev_const. The function is defined in vm_insnhelper.c:
static inline VALUE
vm_get_ev_const(rb_thread_t *th, const rb_iseq_t *iseq,
VALUE orig_klass, ID id, int is_defined)
That function happens to be static so you can't get at it. Looks like vm_get_ev_const is defined in terms of rb_const_defined and rb_const_defined_from and both of those should be available in your C so you could try those; but you'd have to find the right klass for those.
Or you could go with your idea and just use Object.const_defined?. One problem with that is that it won't do The Right Thing with things like A::B, you'd have to say Object.const_defined? :A && A.const_defined? :B for that as Object.const_defined? :'A::B' will just throw an exception in your face. A general solution here would require iteration and class lookups. However, if the classes that you're looking at are all in the top level namespace, then a simple Object.const_defined? should do the trick.

Personal Preprocessor Directives

Being a C novice I would like to hear what Macro "define"s developers are using. I've been thinking about putting these in a header to skip verbosity I've become used to:
#define TS_ typedef struct {
#define _TS(x) } x;
#define I(x)_ { int i; for ( i = 1; i <= x; i++ ) {
#define _I } }
Can I add \n \t etc within these macros? As I would like to pass on my sourcecode minus the extra include:
#define TS_ typedef struct {\n
#define _TS(x) } x;\n
#define I(x)_ { int i;\n\tfor ( i = 1; i <= x; i++ ) {\n
#define _I \t}\n}\n
Would these work?
ie: Can I use the proprocessor to replace my sourcecode with my personal include to formatted source without the include ?
Links to good preprocessor tips and tricks also appreciated.
Before you get started, do not use macro names that begin with an underscore - these are reserved for compiler and standard library writers, and must not be used in your own code.
Additionally, I would say that the macros you suggest are all very bad ideas, because they hide from the reader what is going on. The only justification for them seems to be to save you a very small amount of typing. Generally, you should only be using macros when there is no sensible alternative. In this case there is one - simply write the code.
You can put whitespace in by escaping the newline
#define SOMETHING whatever\
This is part of the macro
But as others have said it's not really a great way to to do this.
It would be much better to look into editor macros so you could type the shortcut and have the editor expand it.
You are headed into a wrong path. DO NOT make up your own cpp directives that are unfamiliar to others - this will make your code hard to understand, and at some point maintain.
Try to find some good C code to read - good C code does not use these things, for a good reason.
DON'T DO IT. Nobody else will be able to read your code.
As a cautionary example, check out Steve Bourne's original sources for the Bourne shell, where he used macros to write the code in a kind of pidgin Algol style.
You could do this, but this sort of "personal language" is not generally used in the C world, especially if you expect anybody else to read your code in the future.
If you're doing this just for yourself, then feel free to #define whatever you want, but expect that once you start working with (or for) anybody else, you won't be able to continue using this sort of thing.
Using C macros unnecessarily can lead you into a world of pain, especially if you attempt to use it to expand code. There are uses for C macros, but this is not it.
Edit: I realize that my answer is tangential to your question, but I thought I should mention this since you say you are a C novice. Search for "C macro pitfalls" to get a full list of reasons why not to use macros. It's been previously discussed here.
In general, I strongly agree with the other respondents who tell you not to define your own macros purely for the sake of saving typing. The obfuscation is not worth it. Also, the particular macros you suggest are heinous. However, in Stroustrup's 1st Ed, he does something I rather like (sometimes):
#define Kase break; case
I became accustomed to the Python elif construct, so I often define the following:
#define elif(test) else if(test)
My purpose in doing this isn't to reduce typing, it's to keep indentation logical while maintaining consistent code width (I don't let my code go wider than 80 characters). I say this because to me this...
if(...) ...
else if(...) ...
else ...
...should be...
if(...)
{
...
}
else
if(...)
{
...
}
else
{
...
}
With my macro this becomes:
if(...)
{
...
}
elif(...)
{
...
}
else
{
...
}
It is always better to pass the loop variable to the macro.
A block - a macro has certain optimization problems. All compilers do not guarantee an optimized obj code for the "block scope" variables.
for example, the following code, when compiled with out any optimization options to gcc, prints two separate addresses for &i. And the same code when compiled with -O2 option will print the same address in both the blocks.
{
int i;
printf("address of i in first block is %u\n", &i);
}
{
int i;
printf("address of i in sec block is %u\n", &i);
}
Naming the language constructs appropriately makes the code more readable.
I like your idea, if you put it in the following way.
#define GREEN 1
#define YELLOW 2
#define RED 3
# define NUM_COLORS 3
#define COLOR_ITER (color,i) \
for(i=GREEN, color = colors[i]; \
i < NUM_COLORS; \
color = colors[++i])
int colors[3] = {GREEN, YELLOW, RED};
int
fun () {
int j;
color_t clr;
COLOR_ITER(clr, j) {
paint(clr);
}
}
Here, regardless of how it is written, the macro, COLOR_ITER, by its name, implies that you are looping for all available colors and doing "something" for each color. And this is a very easy-to-use macro.
And your quesion
Can I use the proprocessor to replace my sourcecode with my personal include to formatted source without the include ?
As everybody explained preprocessor will not help you in this case.
You can use your editor commands to automatically format your code, as you type it.

Resources