POSIX enhancements to printf

J

jacob navia

I am implementing the POSIX enhancements to printf under lcc-win.

I had already implemented the ' modifier, that allows to group big
numbers sequences of 3 digits, i.e. instead of

File size is 633455543 bytes

to write

File size is 633 455 543 bytes.

MUCH more readable!

I am now starting to implement positional arguments

printf("%d %d %d\n", 1, 2, 3);
output:
1 2 3

printf("%3$d %2$d %1$d\n",1,2,3);
output:
3 2 1

These are really nice things to have, and it is a pity they aren't more
used. I tested the versions of gcc I have (linux Mint and Macintosh OS
X) and none of them implements that.

Anyone here has a compiler that implements those? How wide are the
implementations of that standard?

POSIX specs:

The Open Group Base Specifications Issue 7
IEEE Std 1003.1, 2013 Edition
 
N

Noob

jacob said:
I am implementing the POSIX enhancements to printf [...]

[Taking the bait. You're welcome.]
If you want to discuss POSIX-specific code, you can post
to comp.unix.programmer

Regards.
 
B

Ben Bacarisse

jacob navia said:
I am implementing the POSIX enhancements to printf under lcc-win.

I had already implemented the ' modifier, that allows to group big
numbers sequences of 3 digits
I am now starting to implement positional arguments
printf("%3$d %2$d %1$d\n",1,2,3);
output:
3 2 1

These are really nice things to have, and it is a pity they aren't
more used. I tested the versions of gcc I have (linux Mint and
Macintosh OS X) and none of them implements that.

Really? Mine does. The behaviour of ' is controlled by the locale
setting (for en_GB I get a comma), but the %n$ feature should not be
locale dependent.

gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9) but I seem to recall
these features working ages ago.
 
I

Ian Pilcher

Really? Mine does. The behaviour of ' is controlled by the locale
setting (for en_GB I get a comma), but the %n$ feature should not be
locale dependent.

gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9) but I seem to recall
these features working ages ago.

Off topic, but this is up to glibc, not gcc.
 
B

Ben Bacarisse

Ian Pilcher said:
Off topic, but this is up to glibc, not gcc.

Yes, silly of me: glibc-2.17.1 (one could work out a likely version from
the Ubuntu build, but you are quite right that's it's independent of
gcc).

Aside: Off topic is relative. We've had VM design discussions, a debate
about various machine architectures, and even a grand old ding-dong
about a divinely inspired programming language. I don't think a
discussion about a common extension to a core C function is beyond the
pale.
 
I

Ian Collins

jacob said:
I am implementing the POSIX enhancements to printf under lcc-win.

Anyone here has a compiler that implements those? How wide are the
implementations of that standard?

printf is implemented in your system's libC or whatever the C runtime is
called (remember printf is a run time interpreted language:) ). You
probably need to update yours, but this feature has been around on UNIX
systems fro several years now. The Solaris printf man page was last
updated in 2011.
 
K

Keith Thompson

Ian Collins said:
printf is implemented in your system's libC or whatever the C runtime is
called (remember printf is a run time interpreted language:) ). You
probably need to update yours, but this feature has been around on UNIX
systems fro several years now. The Solaris printf man page was last
updated in 2011.

If you're using a locale that doesn't define a grouping character, the
POSIX "%'d" format might not appear to work. And you have to call
setlocale() (for example `setlocale(LC_ALL, "")`) to initialize your
locale settings from environment variables; without that, you'll be
using the default "C" locale.

The C and POSIX locales don't define a grouping character.

On my system, the "en_IN" and "en_IN.utf8" locales cause 123456 to be
printed as "1,23,456". (POSIX specifies "thousands' grouping
characters", which raises some conformance questions that are best
discussed in comp.unix.programmer, or in comp.std.c if you're suggesting
a change to the C standard.)
 
J

jacob navia

Le 26/02/2014 17:23, Ben Bacarisse a écrit :
Really? Mine does. The behaviour of ' is controlled by the locale
setting (for en_GB I get a comma), but the %n$ feature should not be
locale dependent.

How would you setup gcc to activate that?

I have gcc and linux mint/Mac OS X
 
M

Mark Storkamp

jacob navia said:
Le 26/02/2014 17:23, Ben Bacarisse a écrit :

How would you setup gcc to activate that?

I have gcc and linux mint/Mac OS X

I'm using OS X 10.4.11, and just tried this and it worked:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main(void)
{
setlocale(LC_ALL, "en_US");
printf("%'d\n", 123456789);
return EXIT_SUCCESS;
}

I noticed in 'man 3 printf' it also supports positional arguments.
 
J

jacob navia

Le 26/02/2014 18:08, Ben Bacarisse a écrit :
Aside: Off topic is relative. We've had VM design discussions, a debate
about various machine architectures, and even a grand old ding-dong
about a divinely inspired programming language. I don't think a
discussion about a common extension to a core C function is beyond the
pale.

I would second that. printf is important and enhancements to it are
obviously on topic. Unless all I say is off topic by definition :)
 
J

jacob navia

Le 26/02/2014 21:06, Mark Storkamp a écrit :
I'm using OS X 10.4.11, and just tried this and it worked:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main(void)
{
setlocale(LC_ALL, "en_US");
printf("%'d\n", 123456789);
return EXIT_SUCCESS;
}

I noticed in 'man 3 printf' it also supports positional arguments.

Yes, that works but if you set it to the french locale

setlocale(LC_ALL, "fr"); or > setlocale(LC_ALL, "de"); (german)

it doesn't. It doesn't either if you set it to

setlocale(LC_ALL, "en_UK"); (United Kingdom I would guess).

So, gcc will accept thousands separators only in the U.S.

Go figure...

The positional arguments are supported in european locales however.
probably because they do not need any character.

Thanks for your answer.
 
J

jacob navia

Le 26/02/2014 21:34, jacob navia a écrit :
setlocale(LC_ALL, "en_UK"); (United Kingdom I would guess).

Wrong guess!

It should be en_GB, and then it works.

Sorry about this
 
I

Ian Collins

You shouldn't have to, as I (or was it you?) said, printf is a run time
interpreted language. Just make sure your C run time is up to date and
check your man pages.
I'm using OS X 10.4.11, and just tried this and it worked:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main(void)
{
setlocale(LC_ALL, "en_US");
printf("%'d\n", 123456789);
return EXIT_SUCCESS;
}

Works fine out of the box on latest OSX with xcode:

ian$ gcc -v

Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)

ian$ gcc /tmp/x.c; ./a.out
123,456,789

And on Ubuntu:

$ gcc -v

gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

$ gcc /tmp/x.c; ./a.out
123,456,789
 
I

Ian Collins

jacob said:
Le 26/02/2014 21:06, Mark Storkamp a écrit :


Yes, that works but if you set it to the french locale

setlocale(LC_ALL, "fr"); or > setlocale(LC_ALL, "de"); (german)

it doesn't. It doesn't either if you set it to

setlocale(LC_ALL, "en_UK"); (United Kingdom I would guess).

So, gcc will accept thousands separators only in the U.S.

Go figure...

Or go and read your man pages. Which locales did you install when you
installed your OS? On my Ubuntu VM, I have to use en_NZ.UTF-8 because
the en-US locale isn't installed.
 
J

jacob navia

Le 26/02/2014 21:39, Ian Collins a écrit :
You shouldn't have to, as I (or was it you?) said, printf is a run time
interpreted language. Just make sure your C run time is up to date and
check your man pages.


Works fine out of the box on latest OSX with xcode:

ian$ gcc -v

Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)

ian$ gcc /tmp/x.c; ./a.out
123,456,789

And on Ubuntu:

$ gcc -v

gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

$ gcc /tmp/x.c; ./a.out
123,456,789

Where you are? It should work "out of the box" in the US, but on the
french edition it doesn't.

For my linux mint machine I get

jacob@linux-mint ~ $ cat tf.c
#include <stdio.h>
int main(void) { printf("%'d\n",123456789); }

jacob@linux-mint ~ $ gcc tf.c && ./a.out
123456789

jacob@linux-mint ~ $ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro
4.8.1-10ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs
--enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.8 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib
--enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--enable-gnu-unique-object --enable-plugin --with-system-zlib
--disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre
--enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64
--with-arch-directory=amd64
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc
--enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64
--with-multilib-list=m32,m64,mx32 --with-tune=generic
--enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)

jacob@linux-mint ~ $ uname -a
Linux linux-mint 3.11.0-12-generic #19-Ubuntu SMP Wed Oct 9 16:20:46 UTC
2013 x86_64 x86_64 x86_64 GNU/Linux
 
I

Ian Collins

jacob said:
Le 26/02/2014 21:39, Ian Collins a écrit :

Where you are?
NZ.

It should work "out of the box" in the US, but on the
french edition it doesn't.

Straying into c.u.p territory a bit here..

I'm not an expert on locales by any means, but my understanding is in
POSIX land you have to call setlocale() before using any library
functions that depend on the locale (such as printf extensions). You
should be able to call "setlocale(LC_ALL, "")" to set the default locale
for your environment. Check that the environment variable "LANG" is set
in your shell, it should be.

It might be worth following up in c.u.p for the gory details.
 
K

Kenny McCormack

Ian Collins said:
should be able to call "setlocale(LC_ALL, "")" to set the default locale
for your environment. Check that the environment variable "LANG" is set

Or, more directly, if you feel (as I do) that the environment variables are
skeevy, just do:

setlocale(LC_ALL, "en_US"); /* Or whatever... */

--
Given Bush and his insanely expensive wars (*), that we will be paying for
for generations to come, the only possible response a sensible person need
ever give, when a GOPer/TeaBagger says anything about "deficits", is a
polite snicker.

(*) Obvious money transfers between the taxpayers and Bush's moneyed
interests. Someday, we'll actually figure out a way to have a war where the
money just gets moved around and nobody (on either side) gets injured or
killed. That will be an accomplishment of which we will be justly proud.
 
J

James Kuyper

On 02/26/2014 04:28 PM, Ian Collins wrote:
....
I'm not an expert on locales by any means, but my understanding is in
POSIX land you have to call setlocale() before using any library
functions that depend on the locale (such as printf extensions).

As I understand it, calling those functions without first calling
setlocale() is perfectly acceptable - calling setlocale() is required
only if you want to use a locale other than the "C" locale.
 
J

jacob navia

Le 26/02/2014 21:43, Ian Collins a écrit :
Or go and read your man pages. Which locales did you install when you
installed your OS?

Linux mint is in english and my LANG environment variable is:
LANG=en_US.UTF-8

and it doesn't work!

In the Macintosh (not a portable ut a tower Mac) with OS X 10.9.2
the most recent version downloaded 6 hours ago!)
~ $ uname -a
Darwin macpro.local 13.1.0 Darwin Kernel Version 13.1.0: Thu Jan 16
19:40:37 PST 2014; root:xnu-2422.90.20~2/RELEASE_X86_64 x86_64

the printf("%'d\n",123456789);

will NOT work out of the box without setting the locale to en_US
within the program.

This is really weird.

And please, "read the man pages" you tell me... WHICH "man pages"???
I have man installed and ALL manpages but normally I should be able to
use printf without contortions isn't it?

In my implementation I default to "," as thousand separator, and
probably you can use setlocale but I wouldn't be sure of that, my
implementation of all this stuff is probably not the best part of
lcc-win :)

In any case under lcc-win it works out of the box without any locale stuff.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top