LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   macro to repeat a token/string n number of times (https://www.linuxquestions.org/questions/programming-9/macro-to-repeat-a-token-string-n-number-of-times-325445/)

saravkrish 05-20-2005 02:06 PM

macro to repeat a token/string n number of times
 
Hi,

Does anyone know how write a macro that does something like this in C?

RPTSTR(str,3) expands to "str", "str", "str"
RPTSTR(str,5) expands to "str", "str", "str", "str", "str"

Or at the minimum,

RPTEMPTY(3) expands to "", "", ""

I want to use that macro to fill up an array of strings like this:

char *str[] = { "word1", "word2", RPTSTR("dummy string", 5), "word8" };

or

char *str[] = { "word1", "word2", RPTEMPTY(5), "word8" };

Thanks in advance for any help.

-Sarav

jonaskoelker 05-21-2005 11:47 AM

I don't think (correct me if I'm wrong) that cpp can do that (but I think m4 can).

but you can do:

Code:

#define repeat2(s) s, s
#define repeat3(s) s, repeat2(s)
...
#define repeat100(s) s, repeat99(s)

(which can be generated by a simple for loop in your favorite language)

LostSheepOfThePorn 05-21-2005 09:32 PM

Maybe go something like

int RPTSTR(char []. int n) {
//decrease the integer
//store (pointer to ?) string in an array
//repeat until n hits zero. Maybe use recursion? Dunno.
}

jonaskoelker 05-21-2005 10:41 PM

coding it as a function will fail the use case given as an example (try it).

saravkrish 05-22-2005 12:08 AM

Quote:

Originally posted by jonaskoelker
I don't think (correct me if I'm wrong) that cpp can do that (but I think m4 can).

but you can do:

Code:

#define repeat2(s) s, s
#define repeat3(s) s, repeat2(s)
...
#define repeat100(s) s, repeat99(s)

(which can be generated by a simple for loop in your favorite language)

What is m4 btw? I already thought about your suggestion, but there is no way my boss is gonna accept to that.

Thanks,
Sarav

LostSheepOfThePorn 05-22-2005 12:43 AM

I'm calling off sides on this one. The op wanted to use RPTSTR as

char *str[] = { "word1", "word2", RPTSTR("dummy string", 5), "word8" }

(Note in this context, we are using a function)

NOT

char *str[] = { "word1", "word2", RPTSTR, "word8" }
(In this context we are using a Macro)

The later would require using #define with RPTSTR(), which is not valid c.

jonaskoelker 05-22-2005 01:35 AM

saravkrish: m4 is a generic macro-processor; it's a lot more expressive that CPP.
see http://www.gnu.org/software/m4/

also useful:
#define REPEAT(str, n) RPT ## n (str)
// REPEAT("foo", 3) -> RPT3("foo") -> "foo", RPT2("foo") -> "foo", "foo", "foo";

LostSheepOfThePorn:
I tried using the identity function for const char* as RPTSTR; gcc -ansi -pedantic -Wall -W -O3 complained: `initializer element is not constant'.

if you have a .c-file where RPTSTR is implemented as a function in a way so that you can use it in initializers with a c89-compliant compiler, show us.

also, if you have an ansi-compliant compiler that rejects this program, let me know:
[code]
#define RPT2(str) str, str
#define RPT3(str) str, RPT2(str)
char* strings[] = {"foo", RPT3("bar"), "baz"};
int main(){return 0;}

eddiebaby1023 05-22-2005 02:14 PM

Quote:

The later would require using #define with RPTSTR(), which is not valid c.
Huh? Look at, eg, /usr/include/alloca.h at the #define for alloca. Have you been doing C for long?

LostSheepOfThePorn 05-22-2005 11:56 PM

I was thinking something along the lines like

#define hooker(y) y*y

eddiebaby1023 05-23-2005 05:21 PM

Quote:

Originally posted by LostSheepOfThePorn
I was thinking something along the lines like

#define hooker(y) y*y

#define hooker(y) ((y)*(y))

is safer. I obviously misunderstood your comment that doing this isn't valid C. Why do you assert that RPTSTR("dummy string", 5) has to be a function? What am I missing?

LostSheepOfThePorn 05-24-2005 12:49 AM

I don't think you are missing anything. I was probably suffering from terminal confusion at the time. Correct me if I'm wrong. You could write RPTSTR() using #define had it not been for the fact that you use pointers. This might be a crude hack, but you could maybe do something like this.

//Have RPTSTR() return an array of strings
//Have array of strings return by RPTSTR() stored in a buffer


Now everytime RPTSTR() has a different value, the value in the buffer would change. If buffer
was in a list, it would produce the corresponding expansion. Just an idea. Maybe I didn't fully understand the original question.

ta0kira 05-24-2005 01:31 AM

I think the idea is to have a compile-time constant; OP could obviously create an empty array of strings on the stack then fill it in at run-time, but if anything else in the code requires a compile-time constant value for the repeated data then having a buffer would not work. I really don't think this is possible with the C preprocessor.
ta0kira


All times are GMT -5. The time now is 04:08 AM.