I'm trying to understand the behavior of %d
encoding in terminfo's parameterized string parser. The relevant man page is here and states that -
%[[:]flags][width[.precision]][doxXs]
as in printf, flags are [-+#] and space. Use a ":" to allow the
next character to be a "-" flag, avoiding interpreting "%-" as an
operator.
but says nothing about from where the values are to be printed and what to do with edge cases. Are they from stack or from the arguments being passed to the parameterized string? Also what happens when extra arguments are passed(non equal %d
in parameterized string) or extra %d
are present(incorrect parameterized string?)? Is that undefined behavior or implementation-defined or defined by definition somewhere?
I tried to check some cases by manually writing some valid and invalid strings and verifying the output but everything till now is bit inconsistent so I cannot see a pattern here -
#include <iostream>
#include <curses.h>
#include <term.h>
using namespace std;
int main() {
// single %d prints single argument
// => 2
auto res = tparm("[%d]", 2);
cout << res << endl;
// single %d prints single argument and ignores additional
// => 2
res = tparm("[%d]", 2, 3, 4);
cout << res << endl;
// multiple %d prints 0 for absent additional arguments
// => 2-0-0-0
res = tparm("[%d-%d-%d-%d]", 2);
cout << res << endl;
// multiple %d prints with equal number of arguments prints
// first two correctly and rest 0
// => 2-3-0-0-0
res = tparm("[%d-%d-%d-%d-%d]", 2,3,4,5,6);
cout << res << endl;
// single value pushed to stack prints from stack
// => 2
res = tparm("[%p1%d]", 2);
cout << res << endl;
// single value pushed to stack prints from stack and ignores extra arguments
// => 2
res = tparm("[%p1%d]", 2,3,4);
cout << res << endl;
// single value pushed to stack prints from stack and additional prints are 0
// if no arguments are provided
// => 2-0-0
res = tparm("[%p1%d-%d-%d]", 2);
cout << res << endl;
// single value pushed to stack prints from stack and additional prints 0
// even if equal arguments are provided
// => 2-0-0
res = tparm("[%p1%d-%d-%d]", 2,3,4);
cout << res << endl;
// single value pushed to stack prints from stack after pop()?
// => 100-<garbage>
res = tparm("[%p1%d-%c]", 100);
cout << res << endl;
// pushed to stack via {} and equal arguments provided, prints all
// => 2-1-100-200
res = tparm("[%{1}%{2}%d-%d-%d-%d]", 100, 200);
cout << res << endl;
// pushed to stack via {} and %p1 equal arguments provided
// prints only stack and rest 0
// => 100-2-1-0
res = tparm("[%{1}%{2}%p1%d-%d-%d-%d]", 100, 200);
cout << res << endl;
}