home *** CD-ROM | disk | FTP | other *** search
- Submitted-by: ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe)
-
- In article <1rro2qINNk3f@ftp.UU.NET>, davidm@cimshop.UUCP (David S. Masterson) writes:
- > Submitted-by: davidm@cimshop.UUCP (David S. Masterson)
- > Shouldn't 'printf "%c" 3' output a NULL byte? I would expect that the '3'
- > would be stored in as a 4 byte integer of which the first 3 bytes are '0'.
- > The '%c' should take the byte at the address of the argument to printf (not
- > what that argument points to) and output it as an ASCII character (in this
- > case NULL). Without testing it, I'm not sure -- is this not what happens?
-
- Recall that
- (1) The existing documentation for Chris Torek's printf(1) -- and the
- undocumented intent of mine, which unfortunately uses proprietary
- Quintus code for the underlying printf() engine -- has it that
-
- Printf duplicates (as far as possible) the standard C
- library routine of the same name
-
- In C, printf("%c", 3) writes a byte with value \003 (unless of course
- '\n' == '\003', in which case strange things might happen). It does
- not write a NUL byte.
-
- (2) There are at least _three_ languages in *IX which have printf():
- (A) C
- (B) AWK -- which is part of .2
- (C) SH -- the printf(1) command
- So we would expect that
- printf "%c" 3
- and
- awk -e 'END { printf("%c", 3) }' </dev/null
- would produce the same results.
-
- (3) Who said that the printf(1) command uses 4 byte integers?
-
- (4) "The '%c' should take the byte at the address of the argument to
- printf". WHAT address? In the C equivalent, namely
- printf("%c", 3)
- printf() receives the numeric value 3, not the address of anything.
- Certainly a command line notionally contains no addresses.
-
- (5) For what it's worth, the relevant part of the code in my printf(1)
- looks like this:
-
- long get_integer_arg(operands, size)
- char ***operands;
- int size;
- {
- char *arg = *++*operands;
- long result;
-
- if (!arg) insufficient_arguments();
- result = expr(arg); /* copied from PD M4's eval() */
- switch (size) {
- case BYTE_SIZE: return result & 255;
- case HALF_SIZE: return result & 65535;
- case LONG_SIZE: return result;
- }
- }
-
- case 'c':
- c = get_integer_arg(&operands, operand_size);
- /* drop through */
- default:
- literal: if (precision < 0) precision = 1;
- if ((field_width -= precision) <= 0) {
- PUTCHR(c, precision);
- } else
- if (justification == GAMMA_PADDING) {
- PUTCHR(c, precision);
- PUTCHR(padding_character, field_width);
- } else {
- PUTCHR(padding_character, field_width);
- PUTCHR(c, precision);
- }
- break;
-
- PUTCHAR(char, count) writes out count copies of the character (stored
- in) char. So, for my implementation, it would make exactly as much
- sense for 'printf %c 3' to write a NUL character as it would for
- 'printf "x"' to write a NUL character; the same code handles both.
- The only address here is operands, which is a pointer into argv[].
-
-
-
- Volume-Number: Volume 31, Number 50
-
-