diff --git a/examples/test b/examples/test deleted file mode 100755 index 934d5a6..0000000 Binary files a/examples/test and /dev/null differ diff --git a/examples/test.cpp b/examples/test.cpp index a670062..a2abf1e 100644 --- a/examples/test.cpp +++ b/examples/test.cpp @@ -1,6 +1,9 @@ #include #include #include +#define printf cprintf + +using namespace pipecolors; int main(void) { @@ -10,6 +13,6 @@ int main(void) { cprintf("\n%s\n\n", name); cprintf("%s\n", str); if( isatty(fileno(stdout)) ) { - cprintf("Awesome!"); + printf("Awesome!"); } } diff --git a/libpipecolors.7 b/libpipecolors.7 new file mode 100644 index 0000000..7d15bb1 --- /dev/null +++ b/libpipecolors.7 @@ -0,0 +1,60 @@ +.\" Copyright (c) 2009 Linux Foundation, written by Michael Kerrisk +.\" +.\" +.\" %%%LICENSE_START(VERBATIM) +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of this +.\" manual under the conditions for verbatim copying, provided that the +.\" entire resulting derived work is distributed under the terms of a +.\" permission notice identical to this one. +.\" +.\" Since the Linux kernel and libraries are constantly changing, this +.\" manual page may be incorrect or out-of-date. The author(s) assume no +.\" responsibility for errors or omissions, or for damages resulting from +.\" the use of the information contained herein. The author(s) may not +.\" have taken the same level of care in the production of this manual, +.\" which is licensed free of charge, as they might when working +.\" professionally. +.\" +.\" Formatted or processed versions of this manual, if unaccompanied by +.\" the source, must acknowledge the copyright and authors of this work. +.\" %%%LICENSE_END +.\" +.TH LIBPIPECOLORS 7 2015-07-01 "Linux" "libpipecolors" +.SH NAME +libpipecolors \- print old bbs/renegade style pipecodes in c/c++ +.SH DESCRIPTION + +.I libpipecolors +is a library that parses a string with pipe color codes +.B |01 +and replaces them with ansi color codes for the linux terminal. +.SS Other C libraries +.UR http://www.uclibc.org/ +.I uClibc +.UE , +.UR http://www.fefe.de/dietlibc/ +.I dietlibc +.UE , +and +.UR http://www.musl-libc.org/ +.I "musl libc" +.UE . +Details of these libraries are covered by the +.I man-pages +project, where they are known. +.SH SEE ALSO +.BR pcprintf (3), +.BR pcsprintf (3), +.SH COLOPHON +This page is part of release 0.1 of +.I libpipecolors +. +A description of the project, +information about reporting bugs, +and the latest version of this page, +can be found at +\%https://github.com/sk-5/libpipecolors/. diff --git a/libpipecolors.cpp b/libpipecolors.cpp index b43fa53..37a5a63 100644 --- a/libpipecolors.cpp +++ b/libpipecolors.cpp @@ -18,8 +18,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -//#include -//#include + #include #include #include @@ -29,45 +28,45 @@ #include #include "pipecolors.h" +namespace pipecolors { + #define C_DEFAULT 0 #define C_BOLD 1 #define C_ITALIC 3 #define C_UNDERLINE 4 #define C_INVERT 7 -#define C_B0 "\033[1m" -#define C_B1 "\033[0m" +#define C_B0 "\x1b[1m" +#define C_B1 "\x1b[0m" -#define C_FG_BLACK "\033[0;30m" -#define C_FG_RED "\033[0;31m" -#define C_FG_GREEN "\033[0;32m" -#define C_FG_YELLOW "\033[0;33m" -#define C_FG_BLUE "\033[0;34m" -#define C_FG_MAGENTA "\033[0;35m" -#define C_FG_CYAN "\033[0;36m" -#define C_FG_GRAY "\033[0;37m" -#define C_FG_DEFAULT "\033[0;39m" +#define C_FG_BLACK "\x1b[0;30m" +#define C_FG_RED "\x1b[0;31m" +#define C_FG_GREEN "\x1b[0;32m" +#define C_FG_YELLOW "\x1b[0;33m" +#define C_FG_BLUE "\x1b[0;34m" +#define C_FG_MAGENTA "\x1b[0;35m" +#define C_FG_CYAN "\x1b[0;36m" +#define C_FG_GRAY "\x1b[0;37m" +#define C_FG_DEFAULT "\x1b[0;39m" -#define C_FG_GRAY_D "\033[0;90m" -#define C_FG_RED_L "\033[0;91m" -#define C_FG_GREEN_L "\033[0;92m" -#define C_FG_YELLOW_L "\033[0;93m" -#define C_FG_BLUE_L "\033[0;94m" -#define C_FG_MAGENTA_L "\033[0;95m" -#define C_FG_CYAN_L "\033[0;96m" -#define C_FG_WHITE "\033[0;97m" +#define C_FG_GRAY_D "\x1b[0;90m" +#define C_FG_RED_L "\x1b[0;91m" +#define C_FG_GREEN_L "\x1b[0;92m" +#define C_FG_YELLOW_L "\x1b[0;93m" +#define C_FG_BLUE_L "\x1b[0;94m" +#define C_FG_MAGENTA_L "\x1b[0;95m" +#define C_FG_CYAN_L "\x1b[0;96m" +#define C_FG_WHITE "\x1b[0;97m" #define C_BG_NONE "" -#define C_BG_RED "\033[1;41m" -#define C_BG_GREEN "\033[1;42m" -#define C_BG_BLUE "\033[1;44m" -#define C_BG_DEFAULT "\033[1;49m" +#define C_BG_RED "\x1b[1;41m" +#define C_BG_GREEN "\x1b[1;42m" +#define C_BG_BLUE "\x1b[1;44m" +#define C_BG_DEFAULT "\x1b[1;49m" std::map getColors() { std::map colors; - colors["|30"] = C_B0; - colors["|31"] = C_B1; colors["|00"] = C_FG_BLACK; colors["|01"] = C_FG_BLUE; colors["|02"] = C_FG_GREEN; @@ -92,27 +91,23 @@ colors["|21"] = C_BG_RED; // C_BG_MAGENTA colors["|22"] = C_FG_WHITE; //C_BG_BROWN colors["|23"] = C_BG_DEFAULT; // C_BG_WHITE - + colors["|30"] = C_B0; //Bold OFF + colors["|31"] = C_B1; // Bold ON return colors; } bool has_colors(void) { - - if( isatty(fileno(stdout)) ) { - return true; - } else { - return false; - } + return isatty(fileno(stdout)); } -void cprintf( const char * format, ... ) { +void pcprintf( const char * fmt, ... ) { char buffer[256]; std::map colors; va_list args; - va_start(args, format); - vsprintf(buffer, format, args); + va_start(args, fmt); + vasprintf(buffer, fmt, args); std::string text(buffer), s(buffer); va_end(args); std::size_t index; @@ -132,3 +127,4 @@ void cprintf( const char * format, ... ) { std::cout << s; } +} diff --git a/pcprintf.3 b/pcprintf.3 new file mode 100644 index 0000000..c3c8931 --- /dev/null +++ b/pcprintf.3 @@ -0,0 +1,1123 @@ +.\" Copyright (c) 1999 Andries Brouwer (aeb@cwi.nl) +.\" +.\" Earlier versions of this page influenced the present text. +.\" It was derived from a Berkeley page with version +.\" @(#)printf.3 6.14 (Berkeley) 7/30/91 +.\" converted for Linux by faith@cs.unc.edu, updated by +.\" Helmut.Geyer@iwr.uni-heidelberg.de, agulbra@troll.no and Bruno Haible. +.\" +.\" %%%LICENSE_START(GPLv2+_DOC_FULL) +.\" This is free documentation; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of +.\" the License, or (at your option) any later version. +.\" +.\" The GNU General Public License's references to "object code" +.\" and "executables" are to be interpreted as the output of any +.\" document formatting or typesetting system, including +.\" intermediate and printed output. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with this manual; if not, see +.\" . +.\" %%%LICENSE_END +.\" +.\" 1999-11-25 aeb - Rewritten, using SUSv2 and C99. +.\" 2000-07-26 jsm28@hermes.cam.ac.uk - three small fixes +.\" 2000-10-16 jsm28@hermes.cam.ac.uk - more fixes +.\" +.TH PRINTF 3 2014-07-08 "GNU" "Linux Programmer's Manual" +.SH NAME +printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, +vsnprintf \- formatted output conversion +.SH SYNOPSIS +.B #include +.sp +.BI "int printf(const char *" format ", ...);" +.br +.BI "int fprintf(FILE *" stream ", const char *" format ", ...);" +.br +.BI "int sprintf(char *" str ", const char *" format ", ...);" +.br +.BI "int snprintf(char *" str ", size_t " size ", const char *" format ", ...);" +.sp +.B #include +.sp +.BI "int vprintf(const char *" format ", va_list " ap ); +.br +.BI "int vfprintf(FILE *" stream ", const char *" format ", va_list " ap ); +.br +.BI "int vsprintf(char *" str ", const char *" format ", va_list " ap ); +.br +.BI "int vsnprintf(char *" str ", size_t " size ", const char *" format \ +", va_list " ap ); +.sp +.in -4n +Feature Test Macro Requirements for glibc (see +.BR feature_test_macros (7)): +.in +.sp +.ad l +.BR snprintf (), +.BR vsnprintf (): +.RS 4 +_BSD_SOURCE || _XOPEN_SOURCE\ >=\ 500 || _ISOC99_SOURCE || +_POSIX_C_SOURCE\ >=\ 200112L; +.br +or +.I "cc -std=c99" +.RE +.ad +.SH DESCRIPTION +The functions in the +.BR printf () +family produce output according to a +.I format +as described below. +The functions +.BR printf () +and +.BR vprintf () +write output to +.IR stdout , +the standard output stream; +.BR fprintf () +and +.BR vfprintf () +write output to the given output +.IR stream ; +.BR sprintf (), +.BR snprintf (), +.BR vsprintf () +and +.BR vsnprintf () +write to the character string +.IR str . +.PP +The functions +.BR snprintf () +and +.BR vsnprintf () +write at most +.I size +bytes (including the terminating null byte (\(aq\e0\(aq)) to +.IR str . +.PP +The functions +.BR vprintf (), +.BR vfprintf (), +.BR vsprintf (), +.BR vsnprintf () +are equivalent to the functions +.BR printf (), +.BR fprintf (), +.BR sprintf (), +.BR snprintf (), +respectively, except that they are called with a +.I va_list +instead of a variable number of arguments. +These functions do not call the +.I va_end +macro. +Because they invoke the +.I va_arg +macro, the value of +.I ap +is undefined after the call. +See +.BR stdarg (3). +.PP +These eight functions write the output under the control of a +.I format +string that specifies how subsequent arguments (or arguments accessed via +the variable-length argument facilities of +.BR stdarg (3)) +are converted for output. + +C99 and POSIX.1-2001 specify that the results are undefined if a call to +.BR sprintf (), +.BR snprintf (), +.BR vsprintf (), +or +.BR vsnprintf () +would cause copying to take place between objects that overlap +(e.g., if the target string array and one of the supplied input arguments +refer to the same buffer). +See NOTES. +.SS Return value +Upon successful return, these functions return the number of characters +printed (excluding the null byte used to end output to strings). + +The functions +.BR snprintf () +and +.BR vsnprintf () +do not write more than +.I size +bytes (including the terminating null byte (\(aq\e0\(aq)). +If the output was truncated due to this limit, then the return value +is the number of characters (excluding the terminating null byte) +which would have been written to the final string if enough space +had been available. +Thus, a return value of +.I size +or more means that the output was truncated. +(See also below under NOTES.) + +If an output error is encountered, a negative value is returned. +.SS Format of the format string +The format string is a character string, beginning and ending +in its initial shift state, if any. +The format string is composed of zero or more directives: ordinary +characters (not +.BR % ), +which are copied unchanged to the output stream; +and conversion specifications, each of which results in fetching zero or +more subsequent arguments. +Each conversion specification is introduced by +the character +.BR % , +and ends with a +.IR "conversion specifier" . +In between there may be (in this order) zero or more +.IR flags , +an optional minimum +.IR "field width" , +an optional +.I precision +and an optional +.IR "length modifier" . + +The arguments must correspond properly (after type promotion) with the +conversion specifier. +By default, the arguments are used in the order +given, where each \(aq*\(aq and each conversion specifier asks for the next +argument (and it is an error if insufficiently many arguments are given). +One can also specify explicitly which argument is taken, +at each place where an argument is required, by writing "%m$" instead +of \(aq%\(aq and "*m$" instead of \(aq*\(aq, +where the decimal integer m denotes +the position in the argument list of the desired argument, indexed starting +from 1. +Thus, +.in +4n +.nf + +printf("%*d", width, num); + +.fi +.in +and +.in +4n +.nf + +printf("%2$*1$d", width, num); + +.fi +.in +are equivalent. +The second style allows repeated references to the +same argument. +The C99 standard does not include the style using \(aq$\(aq, +which comes from the Single UNIX Specification. +If the style using +\(aq$\(aq is used, it must be used throughout for all conversions taking an +argument and all width and precision arguments, but it may be mixed +with "%%" formats which do not consume an argument. +There may be no +gaps in the numbers of arguments specified using \(aq$\(aq; for example, if +arguments 1 and 3 are specified, argument 2 must also be specified +somewhere in the format string. + +For some numeric conversions a radix character ("decimal point") or +thousands' grouping character is used. +The actual character used +depends on the +.B LC_NUMERIC +part of the locale. +The POSIX locale +uses \(aq.\(aq as radix character, and does not have a grouping character. +Thus, +.in +4n +.nf + + printf("%\(aq.2f", 1234567.89); + +.fi +.in +results in "1234567.89" in the POSIX locale, in "1234567,89" in the +nl_NL locale, and in "1.234.567,89" in the da_DK locale. +.SS The flag characters +The character % is followed by zero or more of the following flags: +.TP +.B # +The value should be converted to an "alternate form". +For +.B o +conversions, the first character of the output string is made zero +(by prefixing a 0 if it was not zero already). +For +.B x +and +.B X +conversions, a nonzero result has the string "0x" (or "0X" for +.B X +conversions) prepended to it. +For +.BR a , +.BR A , +.BR e , +.BR E , +.BR f , +.BR F , +.BR g , +and +.B G +conversions, the result will always contain a decimal point, even if no +digits follow it (normally, a decimal point appears in the results of those +conversions only if a digit follows). +For +.B g +and +.B G +conversions, trailing zeros are not removed from the result as they would +otherwise be. +For other conversions, the result is undefined. +.TP +.B \&0 +The value should be zero padded. +For +.BR d , +.BR i , +.BR o , +.BR u , +.BR x , +.BR X , +.BR a , +.BR A , +.BR e , +.BR E , +.BR f , +.BR F , +.BR g , +and +.B G +conversions, the converted value is padded on the left with zeros rather +than blanks. +If the +.B \&0 +and +.B \- +flags both appear, the +.B \&0 +flag is ignored. +If a precision is given with a numeric conversion +.RB ( d , +.BR i , +.BR o , +.BR u , +.BR x , +and +.BR X ), +the +.B \&0 +flag is ignored. +For other conversions, the behavior is undefined. +.TP +.B \- +The converted value is to be left adjusted on the field boundary. +(The default is right justification.) +The converted value is padded on the right with blanks, rather +than on the left with blanks or zeros. +A +.B \- +overrides a +.B \&0 +if both are given. +.TP +.B \(aq \(aq +(a space) A blank should be left before a positive number +(or empty string) produced by a signed conversion. +.TP +.B + +A sign (+ or \-) should always be placed before a number produced by a signed +conversion. +By default a sign is used only for negative numbers. +A +.B + +overrides a space if both are used. +.PP +The five flag characters above are defined in the C99 standard. +The Single UNIX Specification specifies one further flag character. +.TP +.B \(aq +For decimal conversion +.RB ( i , +.BR d , +.BR u , +.BR f , +.BR F , +.BR g , +.BR G ) +the output is to be grouped with thousands' grouping characters +if the locale information indicates any. +Note that many versions of +.BR gcc (1) +cannot parse this option and will issue a warning. +(SUSv2 did not +include \fI%\(aqF\fP, but SUSv3 added it.) +.PP +glibc 2.2 adds one further flag character. +.TP +.B I +For decimal integer conversion +.RB ( i , +.BR d , +.BR u ) +the output uses the locale's alternative output digits, if any. +For example, since glibc 2.2.3 this will give Arabic-Indic digits +in the Persian ("fa_IR") locale. +.\" outdigits keyword in locale file +.SS The field width +An optional decimal digit string (with nonzero first digit) specifying +a minimum field width. +If the converted value has fewer characters +than the field width, it will be padded with spaces on the left +(or right, if the left-adjustment flag has been given). +Instead of a decimal digit string one may write "*" or "*m$" +(for some decimal integer \fIm\fP) to specify that the field width +is given in the next argument, or in the \fIm\fP-th argument, respectively, +which must be of type +.IR int . +A negative field width is taken as a \(aq\-\(aq flag followed by a +positive field width. +In no case does a nonexistent or small field width cause truncation of a +field; if the result of a conversion is wider than the field width, the +field is expanded to contain the conversion result. +.SS The precision +An optional precision, in the form of a period (\(aq.\(aq) followed by an +optional decimal digit string. +Instead of a decimal digit string one may write "*" or "*m$" +(for some decimal integer m) to specify that the precision +is given in the next argument, or in the m-th argument, respectively, +which must be of type +.IR int . +If the precision is given as just \(aq.\(aq, the precision is taken to +be zero. +A negative precision is taken as if the precision were omitted. +This gives the minimum number of digits to appear for +.BR d , +.BR i , +.BR o , +.BR u , +.BR x , +and +.B X +conversions, the number of digits to appear after the radix character for +.BR a , +.BR A , +.BR e , +.BR E , +.BR f , +and +.B F +conversions, the maximum number of significant digits for +.B g +and +.B G +conversions, or the maximum number of characters to be printed from a +string for +.B s +and +.B S +conversions. +.SS The length modifier +Here, "integer conversion" stands for +.BR d , +.BR i , +.BR o , +.BR u , +.BR x , +or +.B X +conversion. +.TP +.B hh +A following integer conversion corresponds to a +.I signed char +or +.I unsigned char +argument, or a following +.B n +conversion corresponds to a pointer to a +.I signed char +argument. +.TP +.B h +A following integer conversion corresponds to a +.I short int +or +.I unsigned short int +argument, or a following +.B n +conversion corresponds to a pointer to a +.I short int +argument. +.TP +.B l +(ell) A following integer conversion corresponds to a +.I long int +or +.I unsigned long int +argument, or a following +.B n +conversion corresponds to a pointer to a +.I long int +argument, or a following +.B c +conversion corresponds to a +.I wint_t +argument, or a following +.B s +conversion corresponds to a pointer to +.I wchar_t +argument. +.TP +.B ll +(ell-ell). +A following integer conversion corresponds to a +.I long long int +or +.I unsigned long long int +argument, or a following +.B n +conversion corresponds to a pointer to a +.I long long int +argument. +.TP +.B L +A following +.BR a , +.BR A , +.BR e , +.BR E , +.BR f , +.BR F , +.BR g , +or +.B G +conversion corresponds to a +.I long double +argument. +(C99 allows %LF, but SUSv2 does not.) +.\" .TP +.\" .B q +.\" ("quad". 4.4BSD and Linux libc5 only. +.\" Don't use.) +This is a synonym for +.BR ll . +.TP +.B j +A following integer conversion corresponds to an +.I intmax_t +or +.I uintmax_t +argument, or a following +.B n +conversion corresponds to a pointer to an +.I intmax_t +argument. +.TP +.B z +A following integer conversion corresponds to a +.I size_t +or +.I ssize_t +argument, or a following +.B n +conversion corresponds to a pointer to a +.I size_t +argument. +.\" (Linux libc5 has +.\" .B Z +.\" with this meaning. +.\" Don't use it.) +.TP +.B t +A following integer conversion corresponds to a +.I ptrdiff_t +argument, or a following +.B n +conversion corresponds to a pointer to a +.I ptrdiff_t +argument. +.PP +SUSv3 specifies all of the above. +SUSv2 specified only the length modifiers +.B h +(in +.BR hd , +.BR hi , +.BR ho , +.BR hx , +.BR hX , +.BR hn ) +and +.B l +(in +.BR ld , +.BR li , +.BR lo , +.BR lx , +.BR lX , +.BR ln , +.BR lc , +.BR ls ) +and +.B L +(in +.BR Le , +.BR LE , +.BR Lf , +.BR Lg , +.BR LG ). +.SS The conversion specifier +A character that specifies the type of conversion to be applied. +The conversion specifiers and their meanings are: +.TP +.BR d ", " i +The +.I int +argument is converted to signed decimal notation. +The precision, if any, gives the minimum number of digits +that must appear; if the converted value requires fewer digits, it is +padded on the left with zeros. +The default precision is 1. +When 0 is printed with an explicit precision 0, the output is empty. +.TP +.BR o ", " u ", " x ", " X +The +.I "unsigned int" +argument is converted to unsigned octal +.RB ( o ), +unsigned decimal +.RB ( u ), +or unsigned hexadecimal +.RB ( x +and +.BR X ) +notation. +The letters +.B abcdef +are used for +.B x +conversions; the letters +.B ABCDEF +are used for +.B X +conversions. +The precision, if any, gives the minimum number of digits +that must appear; if the converted value requires fewer digits, it is +padded on the left with zeros. +The default precision is 1. +When 0 is printed with an explicit precision 0, the output is empty. +.TP +.BR e ", " E +The +.I double +argument is rounded and converted in the style +.RB [\-]d \&. ddd e \(+-dd +where there is one digit before the decimal-point character and the number +of digits after it is equal to the precision; if the precision is missing, +it is taken as 6; if the precision is zero, no decimal-point character +appears. +An +.B E +conversion uses the letter +.B E +(rather than +.BR e ) +to introduce the exponent. +The exponent always contains at least two +digits; if the value is zero, the exponent is 00. +.TP +.BR f ", " F +The +.I double +argument is rounded and converted to decimal notation in the style +.RB [\-]ddd \&. ddd, +where the number of digits after the decimal-point character is equal to +the precision specification. +If the precision is missing, it is taken as +6; if the precision is explicitly zero, no decimal-point character appears. +If a decimal point appears, at least one digit appears before it. + +(SUSv2 does not know about +.B F +and says that character string representations for infinity and NaN +may be made available. +SUSv3 adds a specification for +.BR F . +The C99 standard specifies "[\-]inf" or "[\-]infinity" +for infinity, and a string starting with "nan" for NaN, in the case of +.B f +conversion, and "[\-]INF" or "[\-]INFINITY" or "NAN*" in the case of +.B F +conversion.) +.TP +.BR g ", " G +The +.I double +argument is converted in style +.B f +or +.B e +(or +.B F +or +.B E +for +.B G +conversions). +The precision specifies the number of significant digits. +If the precision is missing, 6 digits are given; if the precision is zero, +it is treated as 1. +Style +.B e +is used if the exponent from its conversion is less than \-4 or greater +than or equal to the precision. +Trailing zeros are removed from the +fractional part of the result; a decimal point appears only if it is +followed by at least one digit. +.TP +.BR a ", " A +(C99; not in SUSv2, but added in SUSv3) +For +.B a +conversion, the +.I double +argument is converted to hexadecimal notation (using the letters abcdef) +in the style +.RB [\-] 0x h \&. hhhh p \(+-; +for +.B A +conversion the prefix +.BR 0X , +the letters ABCDEF, and the exponent separator +.B P +is used. +There is one hexadecimal digit before the decimal point, +and the number of digits after it is equal to the precision. +The default precision suffices for an exact representation of the value +if an exact representation in base 2 exists +and otherwise is sufficiently large to distinguish values of type +.IR double . +The digit before the decimal point is unspecified for nonnormalized +numbers, and nonzero but otherwise unspecified for normalized numbers. +.TP +.B c +If no +.B l +modifier is present, the +.I int +argument is converted to an +.IR "unsigned char" , +and the resulting character is written. +If an +.B l +modifier is present, the +.I wint_t +(wide character) argument is converted to a multibyte sequence by a call +to the +.BR wcrtomb (3) +function, with a conversion state starting in the initial state, and the +resulting multibyte string is written. +.TP +.B s +If no +.B l +modifier is present: The +.I "const char\ *" +argument is expected to be a pointer to an array of character type (pointer +to a string). +Characters from the array are written up to (but not +including) a terminating null byte (\(aq\\0\(aq); +if a precision is specified, no more than the number specified +are written. +If a precision is given, no null byte need be present; +if the precision is not specified, or is greater than the size of the +array, the array must contain a terminating null byte. + +If an +.B l +modifier is present: The +.I "const wchar_t\ *" +argument is expected to be a pointer to an array of wide characters. +Wide characters from the array are converted to multibyte characters +(each by a call to the +.BR wcrtomb (3) +function, with a conversion state starting in the initial state before +the first wide character), up to and including a terminating null +wide character. +The resulting multibyte characters are written up to +(but not including) the terminating null byte. +If a precision is +specified, no more bytes than the number specified are written, but +no partial multibyte characters are written. +Note that the precision +determines the number of +.I bytes +written, not the number of +.I wide characters +or +.IR "screen positions" . +The array must contain a terminating null wide character, unless a +precision is given and it is so small that the number of bytes written +exceeds it before the end of the array is reached. +.TP +.B C +(Not in C99 or C11, but in SUSv2, SUSv3, and SUSv4.) +Synonym for +.BR lc . +Don't use. +.TP +.B S +(Not in C99 or C11, but in SUSv2, SUSv3, and SUSv4.) +Synonym for +.BR ls . +Don't use. +.TP +.B p +The +.I "void\ *" +pointer argument is printed in hexadecimal (as if by +.B %#x +or +.BR %#lx ). +.TP +.B n +The number of characters written so far is stored into the integer +pointed to by the corresponding argument. +That argument shall be an +.I "int\ *", +or variant whose size matches the (optionally) +supplied integer length modifier. +No argument is converted. +The behavior is undefined if the conversion specification includes +any flags, a field width, or a precision. +.TP +.B m +(Glibc extension.) +Print output of +.IR strerror(errno) . +No argument is required. +.TP +.B % +A \(aq%\(aq is written. +No argument is converted. +The complete conversion +specification is \(aq%%\(aq. +.SH CONFORMING TO +The +.BR fprintf (), +.BR printf (), +.BR sprintf (), +.BR vprintf (), +.BR vfprintf (), +and +.BR vsprintf () +functions conform to C89 and C99. +The +.BR snprintf () +and +.BR vsnprintf () +functions conform to C99. +.PP +Concerning the return value of +.BR snprintf (), +SUSv2 and C99 contradict each other: when +.BR snprintf () +is called with +.IR size =0 +then SUSv2 stipulates an unspecified return value less than 1, +while C99 allows +.I str +to be NULL in this case, and gives the return value (as always) +as the number of characters that would have been written in case +the output string has been large enough. +SUSv3 and later align their specification of +.BR snprintf () +with C99. +.\" .PP +.\" Linux libc4 knows about the five C standard flags. +.\" It knows about the length modifiers \fBh\fP, \fBl\fP, \fBL\fP, +.\" and the conversions +.\" \fBc\fP, \fBd\fP, \fBe\fP, \fBE\fP, \fBf\fP, \fBF\fP, +.\" \fBg\fP, \fBG\fP, \fBi\fP, \fBn\fP, \fBo\fP, \fBp\fP, +.\" \fBs\fP, \fBu\fP, \fBx\fP, and \fBX\fP, +.\" where \fBF\fP is a synonym for \fBf\fP. +.\" Additionally, it accepts \fBD\fP, \fBO\fP, and \fBU\fP as synonyms +.\" for \fBld\fP, \fBlo\fP, and \fBlu\fP. +.\" (This is bad, and caused serious bugs later, when +.\" support for \fB%D\fP disappeared.) +.\" No locale-dependent radix character, +.\" no thousands' separator, no NaN or infinity, no "%m$" and "*m$". +.\" .PP +.\" Linux libc5 knows about the five C standard flags and the \(aq flag, +.\" locale, "%m$" and "*m$". +.\" It knows about the length modifiers \fBh\fP, \fBl\fP, \fBL\fP, +.\" \fBZ\fP, and \fBq\fP, but accepts \fBL\fP and \fBq\fP +.\" both for \fIlong double\fP and for \fIlong long int\fP (this is a bug). +.\" It no longer recognizes \fBF\fP, \fBD\fP, \fBO\fP, and \fBU\fP, +.\" but adds the conversion character +.\" .BR m , +.\" which outputs +.\" .IR strerror(errno) . +.\" .PP +.\" glibc 2.0 adds conversion characters \fBC\fP and \fBS\fP. +.PP +glibc 2.1 adds length modifiers \fBhh\fP, \fBj\fP, \fBt\fP, and \fBz\fP +and conversion characters \fBa\fP and \fBA\fP. +.PP +glibc 2.2 adds the conversion character \fBF\fP with C99 semantics, +and the flag character \fBI\fP. +.SH NOTES +Some programs imprudently rely on code such as the following + + sprintf(buf, "%s some further text", buf); + +to append text to +.IR buf . +However, the standards explicitly note that the results are undefined +if source and destination buffers overlap when calling +.BR sprintf (), +.BR snprintf (), +.BR vsprintf (), +and +.BR vsnprintf (). +.\" http://sourceware.org/bugzilla/show_bug.cgi?id=7075 +Depending on the version of +.BR gcc (1) +used, and the compiler options employed, calls such as the above will +.B not +produce the expected results. + +The glibc implementation of the functions +.BR snprintf () +and +.BR vsnprintf () +conforms to the C99 standard, that is, behaves as described above, +since glibc version 2.1. +Until glibc 2.0.6, they would return \-1 +when the output was truncated. +.\" .SH HISTORY +.\" UNIX V7 defines the three routines +.\" .BR printf (), +.\" .BR fprintf (), +.\" .BR sprintf (), +.\" and has the flag \-, the width or precision *, the length modifier l, +.\" and the conversions doxfegcsu, and also D,O,U,X as synonyms for ld,lo,lu,lx. +.\" This is still true for 2.9.1BSD, but 2.10BSD has the flags +.\" #, + and and no longer mentions D,O,U,X. +.\" 2.11BSD has +.\" .BR vprintf (), +.\" .BR vfprintf (), +.\" .BR vsprintf (), +.\" and warns not to use D,O,U,X. +.\" 4.3BSD Reno has the flag 0, the length modifiers h and L, +.\" and the conversions n, p, E, G, X (with current meaning) +.\" and deprecates D,O,U. +.\" 4.4BSD introduces the functions +.\" .BR snprintf () +.\" and +.\" .BR vsnprintf (), +.\" and the length modifier q. +.\" FreeBSD also has functions +.\" .BR asprintf () +.\" and +.\" .BR vasprintf (), +.\" that allocate a buffer large enough for +.\" .BR sprintf (). +.\" In glibc there are functions +.\" .BR dprintf () +.\" and +.\" .BR vdprintf () +.\" that print to a file descriptor instead of a stream. +.SH BUGS +Because +.BR sprintf () +and +.BR vsprintf () +assume an arbitrarily long string, callers must be careful not to overflow +the actual space; this is often impossible to assure. +Note that the length +of the strings produced is locale-dependent and difficult to predict. +Use +.BR snprintf () +and +.BR vsnprintf () +instead (or +.BR asprintf (3) +and +.BR vasprintf (3)). +.\" .PP +.\" Linux libc4.[45] does not have a +.\" .BR snprintf (), +.\" but provides a libbsd that contains an +.\" .BR snprintf () +.\" equivalent to +.\" .BR sprintf (), +.\" that is, one that ignores the +.\" .I size +.\" argument. +.\" Thus, the use of +.\" .BR snprintf () +.\" with early libc4 leads to serious security problems. +.PP +Code such as +.BI printf( foo ); +often indicates a bug, since +.I foo +may contain a % character. +If +.I foo +comes from untrusted user input, it may contain \fB%n\fP, causing the +.BR printf () +call to write to memory and creating a security hole. +.\" .PP +.\" Some floating-point conversions under early libc4 +.\" caused memory leaks. +.SH EXAMPLE +To print +.I Pi +to five decimal places: +.in +4n +.nf + +#include +#include +fprintf(stdout, "pi = %.5f\en", 4 * atan(1.0)); +.fi +.in +.PP +To print a date and time in the form "Sunday, July 3, 10:02", +where +.I weekday +and +.I month +are pointers to strings: +.in +4n +.nf + +#include +fprintf(stdout, "%s, %s %d, %.2d:%.2d\en", + weekday, month, day, hour, min); +.fi +.in +.PP +Many countries use the day-month-year order. +Hence, an internationalized version must be able to print +the arguments in an order specified by the format: +.in +4n +.nf + +#include +fprintf(stdout, format, + weekday, month, day, hour, min); + +.fi +.in +where +.I format +depends on locale, and may permute the arguments. +With the value: +.in +4n +.nf + +"%1$s, %3$d. %2$s, %4$d:%5$.2d\en" + +.fi +.in +one might obtain "Sonntag, 3. Juli, 10:02". +.PP +To allocate a sufficiently large string and print into it +(code correct for both glibc 2.0 and glibc 2.1): +.nf + +#include +#include +#include + +char * +make_message(const char *fmt, ...) +{ + int n; + int size = 100; /* Guess we need no more than 100 bytes */ + char *p, *np; + va_list ap; + + p = malloc(size); + if (p == NULL) + return NULL; + + while (1) { + + /* Try to print in the allocated space */ + + va_start(ap, fmt); + n = vsnprintf(p, size, fmt, ap); + va_end(ap); + + /* Check error code */ + + if (n < 0) { + free(p); + return NULL; + } + + /* If that worked, return the string */ + + if (n < size) + return p; + + /* Else try again with more space */ + + size = n + 1; /* Precisely what is needed */ + + + np = realloc(p, size); + if (np == NULL) { + free(p); + return NULL; + } else { + p = np; + } + } +} +.fi +.PP +If truncation occurs in glibc versions prior to 2.0.6, this is treated as an +error instead of being handled gracefully. +.SH SEE ALSO +.BR printf (1), +.BR asprintf (3), +.BR dprintf (3), +.BR scanf (3), +.BR setlocale (3), +.BR wcrtomb (3), +.BR wprintf (3), +.BR locale (5) +.SH COLOPHON +This page is part of release 3.74 of the Linux +.I man-pages +project. +A description of the project, +information about reporting bugs, +and the latest version of this page, +can be found at +\%http://www.kernel.org/doc/man\-pages/. diff --git a/pipecolors.h b/pipecolors.h index e7ef575..7708c78 100644 --- a/pipecolors.h +++ b/pipecolors.h @@ -4,15 +4,16 @@ #ifndef _PIPECOLORS_H #define _PIPECOLORS_H #endif - +namespace pipecolors { #ifdef __cplusplus extern "C" { #endif -void cprintf(const char* format, ...); -void csprintf(void); +void pcprintf(const char* fmt, ...); +void pcsprintf(char **strp, const char *fmt, va_list ap); #ifdef __cplusplus } #endif +}