thecodingidiot.com

The VoiceComplete tci_printf

Complete tci_printf

One specifier remains: %%. Then the tester confirms that all nine specifiers work together.

%%

%% prints a literal % character. No argument is consumed from the variadic list — va_arg is not called:

if (spec == '%')
    return (tci_putchar_fd('%', 1));  /* no va_arg: no argument consumed */

This is already in the dispatcher from page 03. If you added it then, nothing needs to change here.

%% exists because % is the delimiter of the specifier syntax — the only way to print a literal % inside a format string is to escape it. printf("100%% done\n") prints 100% done. printf("%d%%\n", score) prints the integer followed by %.

The argument count matters: va_arg is a cursor, and each call advances it by one argument. A spurious call inside %% would corrupt the position for every specifier that followed — silently, since format strings are not validated at compile time.

Complete tci_printf.c

At this point tci_printf.c should contain, in order:

  1. Includes: "libtci.h", <stdarg.h>, <unistd.h>, <stdint.h>
  2. Forward declarations for all static helpers
  3. tci_putchar_fd
  4. tci_putstr_fd
  5. tci_putnbr_base
  6. tci_print_signed
  7. tci_print_unsigned
  8. tci_print_ptr
  9. dispatch
  10. tci_printf

Run make re. Thirty object files, no warnings.

Run the tester

make re
bash test.sh

The tester compiles a small driver that calls both tci_printf and libc printf with the same format strings and captures the outputs. Any divergence in output or return value is reported as a failure.

Common failure points at this stage:

  • Return value wrong: a helper returns 0 when it should return a byte count. Check every path through tci_putstr_fd and tci_putnbr_base. The write call returns the number of bytes written — return that value, not a literal constant.
  • %p with NULL: returning 0 instead of writing (nil). Check the NULL branch in tci_print_ptr.
  • INT_MIN: %d with −2147483648. If this row fails, the intlong promotion before negation is missing in tci_print_signed.
  • Trailing %: a % at the very end of the format string with nothing after it. The format loop must handle fmt[i + 1] == '\0' and write the % as a literal character.

Fix any failures before proceeding to the flags page.