What is the preferred way to embed multi-line string in C source?

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

What is the preferred way to embed multi-line string in C source?

Pan, Shi Zhu
Hi all,

The question is probably more C-related rather than Lua-related.

I want to use Lua inside C program and sometimes it would be convenient if I can write lua source inside a C string.

As far as I know the ISO standard for C requires the quotation mark "" to be within one single line. (Though actually most C compilers allow multi-line string inside ""). May I ask if there's an ISO-compliant way to embed multi-line string in C program?

Regards,
Pan, Shi Zhu

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

hoelzro
"pan shizhu" <[hidden email]> wrote:

> Hi all,
> 
> The question is probably more C-related rather than Lua-related.
> 
> I want to use Lua inside C program and sometimes it would be
> convenient if I can write lua source inside a C string.
> 
> As far as I know the ISO standard for C requires the quotation mark
> "" to be within one single line. (Though actually most C compilers
> allow multi-line string inside ""). May I ask if there's an
> ISO-compliant way to embed multi-line string in C program?
> 
> Regards,
> Pan, Shi Zhu

I believe you can do the following:

char *luaCode = "function foo()\n"
    "  print('foo')\n"
    "end";

Not ideal, but hey, it works.

-Rob Hoelz

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

David Jones-2

On 19 Dec 2008, at 05:13, Rob Hoelz wrote:

I believe you can do the following:

char *luaCode = "function foo()\n"
    "  print('foo')\n"
    "end";

Not ideal, but hey, it works.

Yes, adjacent literal strings just get concatenated. The portable limit on the total length of the string as specified in the standard is 4095 characters (in C99). If you are generating C code with a program you can easily go past this.

drj

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

Jeff Pohlmeyer
On Fri, Dec 19, 2008 at 10:53 AM, David Jones <[hidden email]> wrote:

> The portable limit on the total length of the string as specified in
> the standard is 4095 characters (in C99).  If you are generating C code
> with a program you can easily go past this.

There is a note in the libcurl sources:
  http://curl.haxx.se/lxr/source/src/mkhelp.pl#L213

"gcc 2.96 claims ISO C89 only is required to support 509 letter strings"

I'm not sure how accurate that is, so please don't shoot the messenger :-)

But I guess you could even break the code up into smaller chunks
and re-assemble it at runtime...


 - Jeff

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

David Given
In reply to this post by David Jones-2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

David Jones wrote:
[...]
> Yes, adjacent literal strings just get concatenated.  The portable limit
> on the total length of the string as specified in the standard is 4095
> characters (in C99).  If you are generating C code with a program you
> can easily go past this.

...but don't forget that a string array initialiser (const char foo[] =
"...") is not the same as a string literal (const char* foo = "..."),
and the limits don't apply to initialisers.

(Yes, I did have to work with a compiler that would crash if you went
beyond the length limit for literals.)

- --
David Given
[hidden email]

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAklL5AsACgkQf9E0noFvlzjcmgCfdWB5GXCT8GQdIR8IUWpspUG6
gwwAn1OEjNTbe7hiNT0/0RoUpx1yq6pj
=+vez
-----END PGP SIGNATURE-----

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

Farmbuyer
In reply to this post by Jeff Pohlmeyer
On Fri, Dec 19, 2008 at 12:38 PM, Jeff Pohlmeyer
<[hidden email]> wrote:
> On Fri, Dec 19, 2008 at 10:53 AM, David Jones <[hidden email]> wrote:
>
>> The portable limit on the total length of the string as specified in
>> the standard is 4095 characters (in C99).  If you are generating C code
>> with a program you can easily go past this.
>
> There is a note in the libcurl sources:
>  http://curl.haxx.se/lxr/source/src/mkhelp.pl#L213
>
> "gcc 2.96 claims ISO C89 only is required to support 509 letter strings"
>
> I'm not sure how accurate that is, so please don't shoot the messenger :-)

It sounds about right.  But C89 is, after all, almost 20 years old.
Being constrained by small memory environments is one thing, but
arbitrary limits older than some of the programmers writing in Lua are
another thing entirely.  :-)  I would expect that any decent modern
C99 compiler should be able to handle much larger strings.


> But I guess you could even break the code up into smaller chunks
> and re-assemble it at runtime...

Good thought.  Maybe an array of such strings, each limited to 4K?

Writing a small Lua program to read in text (say, Lua source) and spit
out such a C array would be a good exercise, I might go play with
that.

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

Roberto Ierusalimschy
In reply to this post by David Given
> ...but don't forget that a string array initialiser (const char foo[] =
> "...") is not the same as a string literal (const char* foo = "..."),
> and the limits don't apply to initialisers.

And it is easy to write a specific lua_Reader function to feed each
array element to lua_load without concatenating them.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

Luiz Henrique de Figueiredo
In reply to this post by Farmbuyer
> Writing a small Lua program to read in text (say, Lua source) and spit
> out such a C array would be a good exercise, I might go play with
> that.

See http://lua-users.org/wiki/BinToCee .

In Linux, try also "xxd -i".

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

Tony Finch
In reply to this post by Farmbuyer
On Fri, 19 Dec 2008, MFarm wrote:
>
> I would expect that any decent modern C99 compiler should be able to
> handle much larger strings.

C99 requires support for string literals containing 4095 characters (after
concatenation).

Tony.
-- 
f.anthony.n.finch  <[hidden email]>  http://dotat.at/
FAIR ISLE FAEROES: SOUTHWESTERLY VEERING WESTERLY, BUT CYCLONIC AT FIRST IN
FAEROES, SEVERE GALE 9 TO VIOLENT STORM 11, VEERING NORTHWESTERLY 6 TO GALE 8,
DECREASING 5 LATER IN FAEROES. HIGH OR VERY HIGH. SQUALLY SHOWERS. MODERATE OR
POOR.

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

Roberto Ierusalimschy
In reply to this post by Farmbuyer
> Good thought.  Maybe an array of such strings, each limited to 4K?

I guess this was David's suggestion. But you do not need to worry about
the 4K limit, unless you have really long lines:

char *prog[] = {
  "function foo ()",
  "  return x",
  "end"
};

As I said, with a proper lua_Reader, you can feed each line one by one
to lua_load, without concatenating them. (If you want, the lua_Reader
may also inser the newlines between lines.)

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

Pan, Shi Zhu

Thanks everyone, I found Lua mailing list really wonderful with all kinds of kindly help!

It seems that "xxd -i" is the best for me, I can add a step in my Makefile to do that.

xxd -i output a char array like the following, which is not a string literal.

unsigned char ltools_lua[] = {
  0x0a, 0x6c, 0x6f, 0x63, 0x61,
};

Is there any 4096 limit for xxd -i style output?

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

Eric Tetz
pan shizhu <[hidden email]> wrote:
> xxd -i output a char array like the following, which is not a string
> literal.
>
> unsigned char ltools_lua[] = {
>   0x0a, 0x6c, 0x6f, 0x63, 0x61,
> };

That's similar to what Dave was pointing out earlier:

   const char* s = "foo...bar";  /* string literal; limited to 4096 */
   const char s[] = "foo...bar"; /* initializer, NOT a string literal */

The latter is equivalent to:

   const char s[] = { 'f', 'o', 'o', ... 'b', 'a', 'r' };

Reply | Threaded
Open this post in threaded view
|

Re: What is the preferred way to embed multi-line string in C source?

James Dennett
On Sat, Dec 20, 2008 at 2:24 PM, Eric Tetz <[hidden email]> wrote:
> pan shizhu <[hidden email]> wrote:
>> xxd -i output a char array like the following, which is not a string
>> literal.
>>
>> unsigned char ltools_lua[] = {
>>   0x0a, 0x6c, 0x6f, 0x63, 0x61,
>> };
>
> That's similar to what Dave was pointing out earlier:
>
>   const char* s = "foo...bar";  /* string literal; limited to 4096 */
>   const char s[] = "foo...bar"; /* initializer, NOT a string literal */

Except that the initializer does come from a string literal, to which
the limit applies.  C (or C++) implementations don't even have to
accept tokens that are too long, however they may be used.

> The latter is equivalent to:
>
>   const char s[] = { 'f', 'o', 'o', ... 'b', 'a', 'r' };

Except for (a) the length limit on string literals and (b) trivially,
the missing NUL terminator.

-- James