LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-20-2005, 02:06 PM   #1
saravkrish
Member
 
Registered: Mar 2004
Location: KY, USA
Distribution: Fedora Core 1
Posts: 190

Rep: Reputation: 30
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
 
Old 05-21-2005, 11:47 AM   #2
jonaskoelker
Senior Member
 
Registered: Jul 2004
Location: Denmark
Distribution: Ubuntu, Debian
Posts: 1,524

Rep: Reputation: 47
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)
 
Old 05-21-2005, 09:32 PM   #3
LostSheepOfThePorn
LQ Newbie
 
Registered: May 2005
Location: Berkeley, CA
Distribution: Linux
Posts: 8

Rep: Reputation: 0
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.
}
 
Old 05-21-2005, 10:41 PM   #4
jonaskoelker
Senior Member
 
Registered: Jul 2004
Location: Denmark
Distribution: Ubuntu, Debian
Posts: 1,524

Rep: Reputation: 47
coding it as a function will fail the use case given as an example (try it).
 
Old 05-22-2005, 12:08 AM   #5
saravkrish
Member
 
Registered: Mar 2004
Location: KY, USA
Distribution: Fedora Core 1
Posts: 190

Original Poster
Rep: Reputation: 30
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
 
Old 05-22-2005, 12:43 AM   #6
LostSheepOfThePorn
LQ Newbie
 
Registered: May 2005
Location: Berkeley, CA
Distribution: Linux
Posts: 8

Rep: Reputation: 0
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.

Last edited by LostSheepOfThePorn; 05-22-2005 at 12:47 AM.
 
Old 05-22-2005, 01:35 AM   #7
jonaskoelker
Senior Member
 
Registered: Jul 2004
Location: Denmark
Distribution: Ubuntu, Debian
Posts: 1,524

Rep: Reputation: 47
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;}
 
Old 05-22-2005, 02:14 PM   #8
eddiebaby1023
Member
 
Registered: May 2005
Posts: 378

Rep: Reputation: 33
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?
 
Old 05-22-2005, 11:56 PM   #9
LostSheepOfThePorn
LQ Newbie
 
Registered: May 2005
Location: Berkeley, CA
Distribution: Linux
Posts: 8

Rep: Reputation: 0
I was thinking something along the lines like

#define hooker(y) y*y
 
Old 05-23-2005, 05:21 PM   #10
eddiebaby1023
Member
 
Registered: May 2005
Posts: 378

Rep: Reputation: 33
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?
 
Old 05-24-2005, 12:49 AM   #11
LostSheepOfThePorn
LQ Newbie
 
Registered: May 2005
Location: Berkeley, CA
Distribution: Linux
Posts: 8

Rep: Reputation: 0
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.
 
Old 05-24-2005, 01:31 AM   #12
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
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
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
strip number from string (c code) alaios Programming 8 09-26-2005 12:47 AM
#defining a macro inside a macro? saravkrish Programming 1 05-24-2005 09:48 PM
daemon to count number of times programs are being run dizzutch Linux - Software 0 10-27-2004 08:41 AM
replace a string/number in a text file jpan Linux - General 3 10-22-2004 09:33 PM
iptables and limiting the number of times an event gets logged drexel Linux - Security 3 02-09-2004 08:59 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:01 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration