string.format (formatstring, ···)
Returns a formatted version of its variable number of arguments following the description given in its first argument (which must be a string). The format string follows the same rules as the ISO C function sprintf. The only differences are that the options/modifiers *, h, L, l, n, and p are not supported and that there is an extra option, q.
Lua 5.3 doesn't support lld, how can I print lld in Lua 5.3?
Short answer: use %d.
In C sprintf, %lld is used to format a long long type, which is an integer type at least 64 bit.
In Lua 5.3, the type number has two internal representations, integer and float. Integer representation is 64-bit in standard Lua. You can use %d to print it no matter its internal representation:
print(string.format("%d", 2^62))
Output: 4611686018427387904
In Lua source file luaconf.h, you can see that Lua converts %d to the approapriate format:
#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
and LUA_INTEGER_FRMLEN is defined as "", "l" or "ll" if different internal representation for integer is used:
#if defined(LLONG_MAX) /* { */
/* use ISO C99 stuff */
#define LUA_INTEGER long long
#define LUA_INTEGER_FRMLEN "ll"
//...
Related
On the official LuaJIT website one can read the following:
The C parser complies to the C99 language standard plus the following extensions:
- The '\e' escape in character and string literals.
This should mean that LuaJIT C parser supports string literals!
Let's try:
ffi.cdef[[static const char * s = "foo";]]
ffi.cdef[[static const char s[] = "foo";]]
ffi.cdef[[static const char s[4] = "foo";]]
Unfortunately, none of the above works: the error invalid C type is raised on each ffi.cdef invocation.
Can you provide an example how to feed a string literal to the C parser integrated into LuaJIT?
P.S.
I should mention that I can successfully declare int and char variables the same way, but not strings.
ffi.cdef[[static const int k = 42;]]
print(ffi.C.k) --> 42
I'm new to llvm and was trying to do instrument. But I found LLVM API only has primitive types, like: getInt32Ty(Ctx).. What i want to do use getOrInsertFunction(),the function argument type is string type.As is known, when argument type is int, we can do it like is :
LLVMContext &Ctx = F.getContext();
Constant *logFunc = F.getParent()->getOrInsertFunction(
"logop", Type::getVoidTy(Ctx), Type::getInt32Ty(Ctx), NULL );
Type::getInt32Ty(Ctx) is the function argument type (int), what i want to do is:
getOrInsertFunction(
"logop", Type::getVoidTy(Ctx), string type, NULL);
The string type i don't know how to define it .In short, could you please tell me how to define it, thanks!
LLVM IR does not define any special string or char types.
Usually either [N x i8] or i8* are used, but it's really up to you - for example, Java-style strings will probably be a struct with some i32 for string length and an i16* for the UTF-16 code points.
LLVM IR does have a "string literal" which is typed as an i8 array - for example c"hello world\0A\00" is [13 x i8]. But that doesn't dictate what string form you should be using.
Keep in mind that if your function is supposed to interop with something, e.g. a hosting C++ application, then you need to use the same string type - in that case whatever std::string is compiling to. You can use Clang or this online demo to check what that type is.
Should Lua string.format( "%c", value ) be equivalent to string.char( value )?
It seems not when character value is zero.
string.format( "%c", 0 ):len()
returns 0
string.char( 0 ):len()
returns 1
Even stranger,
string.format( "%c%s", 0, "abc" ):len()
returns 3; where any other non-zero-modulo-256 value for %c returns 4, so string.format is not truncating the whole string at null byte like C sprintf, just collapsing %c field to empty string instead of one-byte string. Note that C sprintf writes the zero byte followed by the abc bytes in this case.
I couldn't find anything in the Lua docs describing expected behavior in this case. Most other string handling in Lua seems to treat zero byte as valid string character.
This is on Lua 5.1.4-8 on OpenWrt.
Idiosyncracy or bug?
I think this is a bug.
In Lua 5.1 and LuaJIT 2.0, string.format formats one item at a time (using the sprintf provided by the host C runtime.) It then calls strlen to update the length of the output string. Since strlen stops at the null character, this character will be overwritten.
This is documented behaviour for %s, but probably unintentional for %c
This is fixed in Lua 5.2. I wouldn't expect any more updates to 5.1.
In the book "programming in lua" 2nd edition. In the chapter 2.4, there are some context like below:
"Strings in Lua have the usual meaning: a sequence of characters. Lua is
eight-bit clean and its strings may contain characters with any numeric code,
including embedded zeros. This means that you can store any binary data into
a string.
"
So this is not a bug
The ShortNameLength member of FILE_BOTH_DIR_INFORMATION structure is declared as follows:
typedef struct FILE_BOTH_DIR_INFORMATION {
...
CCHAR ShortNameLength;
...
};
From the explanation of CCHAR type, CCHAR is a 8-bit Windows (ANSI) character. So, it is equivalent to AnsiChar in Delphi, right? However, the description of ShortNameLength member of FILE_BOTH_DIR_INFORMATION structure says,
“ShortNameLength specifies the length, in bytes, of the short file name string.”
The statement makes me think that the CCHAR equivalent is Byte in Delphi. Another example is the NumberOfProcessors member of SYSTEM_BASIC_INFORMATION which is declared in winternl.h as follows:
typedef struct _SYSTEM_BASIC_INFORMATION {
BYTE Reserved1[24];
PVOID Reserved2[4];
CCHAR NumberOfProcessors;
}
Once again, the CCHAR type seems to be used in a Byte context, rather than AnsiChar context.
Now, I confuse, whether to use AnsiChar or Byte as a CCHAR equivalent in Delphi.
Note
JwaWinType.pas of JEDI Windows API declares CCHAR as AnsiChar.
It's a byte, or at least, it is used as a 1 byte integer. In C, chars can be used for this purpose. In Delphi, you couldn't do that without typecasting. So you could use Char, but then you would need to give it the value 'A' or Chr(65) to indicate a string of 65 characters. Now, that would be silly. :-)
To be able to pass it to the API it must have the same size. Apart from that, the callee will not even know how it is declared, so declaring it as a Delphi byte is the most logical solution. A choice backed up by the other declaration you found.
I believe the explanation of CCHAR is wrong. The C prefix indicates that this is a count of characters so this is probably a simple copy-paste error done by Microsoft when writing the explanation.
It is stored in a byte and it is used to count the number of bytes of a string of characters. These characters may be wide characters but the CCHAR value still counts the number of bytes used to store the characters.
The natural translation for this type is Byte. If you marshal it to a character type like AnsiChar you will have to convert the character to an integer value (e.g. a byte) before using it.
How is it possible for F# to examine format strings at compile time to determine that x has type int in the following definition?
let foo x = sprintf "%d" x`?
Is this hard-coded into the language or could somebody write their own "my_print" function that uses format strings with a different syntax? For example:
let foo x = my_print "{integer}" x
You can read a bit about it in 6.4.17 ('printf' formats) here, but briefly
it's built into the language
string literals can effectively be 'coerced' into the weird 'Format' type
printf and friends expect a first argument of the Format type, making the coercion happen
The net result is that you can build your own printf-style functions, but must use the same %s formats, since that stuff is built-in.
Here is an example of how you can build your own printf-style functions in F#. You can't change the format specifiers (e.g. "%d"), but you can leverage the existing specifiers to build additional string formatting functions that the compiler will type check.