I want to embed a bash script inside the c program.
How could you do the below bash snippet in "c"?:
cat > /tmp/foo <<\__EOD_
all kinds of nasty stuff in here including single and double quotes
and bashslashes ..
(note that the here doc delimiter is preceded by a "\"
__EOD_
Treating a chunk of text as a bash script once you've got it embedded
in your program is beyond the scope of this newsgroup (but why don't
you just create it as a separate file and use system() to ask bash to
run it?), but:
You can pack a big chunk of text nicely into a string literal by doing
something like this:
--------
const char *my_long_string=
"This is a nice long string.\n"
"Note that every line ends with a '\\n\"', and we're taking advantage\n"
"of the string-splicing feature.\n"
"Note that single quotes inside string literals don't need to be escaped.\n";
--------
You're not guaranteed to be able to embed arbitrarily long strings this
way (the Standard places a minimum on the maximum length compilers can
restrict you to, but a compiler is allowed to complain about or reject
anything beyond that minimum[1]), but in practice I'd be surprised to see
GCC (which I assume you're using) choke on any length of string literal.
Something not entirely unlike this snippet (typed directly into the editor
for my posting software, never seen a compiler, usual disclaimers apply)
might help you with escaping the double quotes and backslashes if you'd
rather not do it by hand:
--------
/*This code as posted is a demonstration-of-concept and has never seen a
compiler, let alone been tested. The usual disclaimers apply.
Output will need fixing up by hand at beginning (adding '"' at the
beginning of the first line) and end (removing '"' at the beginning of
the nonexistent just-past-last line), but should be appropriately
escaped for inclusion into C source as a big string literal otherwise.
Caller is responsible for checking ferror(in) and acting appropriately
on error.
*/
void convert_to_string_literal(FILE *in,FILE *out)
{
int c;
while(c=getc(in) != EOF)
{
switch(c)
{
case '\n':
fputs("\\n\"\n\"",out);
break;
case '"':
fputs("\\\"",out);
break;
case '\\':
fputs("\\\\",out);
break;
default:
putc(c,out);
break;
}
}
}
--------
dave
[1] Actually, it doesn't quite even guarantee this, but the intention
is clear enough that even the DS9k implementors had to try pretty
hard to get around it.