-/* -------------------------------- Arctic Core ------------------------------
- * Arctic Core - the open source AUTOSAR platform http://arccore.com
- *
- * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
- *
- * This source code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by the
- * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
- *
- * This program 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.
- * -------------------------------- Arctic Core ------------------------------*/
-
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include "simple_printf.h"
-
-#define BUF_SIZE 60
-#define STD_OUT 1
-
-#if 0
-//char *
-int dbg_printf(const char *fmt, ...) {
- /* Guess we need no more than 100 bytes. */
- int n;
- va_list ap;
- char p[BUF_SIZE];
-
- /* Try to print in the allocated space. */
- va_start(ap, fmt);
- n = vsnprintf (p, BUF_SIZE, fmt, ap);
- puts(p);
- va_end(ap);
- return 0;
-}
-
-#endif
-/*
- Copyright 2001, 2002 Georges Menie (www.menie.org)
- stdarg version contributed by Christian Ettinger
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-
-/*
- putchar is the only external dependency for this file,
- if you have a working putchar, leave it commented out.
- If not, uncomment the define below and
- replace outbyte(c) by your own function call.
-
-#define putchar(c) outbyte(c)
-*/
-
-
-extern int arc_putchar(int fd, int c);
-
-static void printchar(int fd, char **str, int c)
-{
- if (str) {
- **str = c;
- ++(*str);
- }
- else {
- (void)arc_putchar(fd, c);
- }
-}
-
-#define PAD_RIGHT 1
-#define PAD_ZERO 2
-
-static int prints(int fd, char **out, const char *string, int width, int pad)
-{
- register int pc = 0, padchar = ' ';
-
- if (width > 0) {
- register int len = 0;
- register const char *ptr;
- for (ptr = string; *ptr; ++ptr) ++len;
- if (len >= width) width = 0;
- else width -= len;
- if (pad & PAD_ZERO) padchar = '0';
- }
- if (!(pad & PAD_RIGHT)) {
- for ( ; width > 0; --width) {
- printchar (fd, out, padchar);
- ++pc;
- }
- }
- for ( ; *string ; ++string) {
- printchar (fd, out, *string);
- ++pc;
- }
- for ( ; width > 0; --width) {
- printchar (fd, out, padchar);
- ++pc;
- }
-
- return pc;
-}
-
-
-
-/* the following should be enough for 32 bit int */
-#define PRINT_BUF_LEN 12
-
-static int printi(int fd, char **out, int i, int b, int sg, int width, int pad, int letbase)
-{
- char print_buf[PRINT_BUF_LEN];
- register char *s;
- register int t, neg = 0, pc = 0;
- register unsigned int u = i;
-
- if (i == 0) {
- print_buf[0] = '0';
- print_buf[1] = '\0';
- return prints (fd, out, print_buf, width, pad);
- }
-
- if (sg && b == 10 && i < 0) {
- neg = 1;
- u = -i;
- }
-
- s = print_buf + PRINT_BUF_LEN-1;
- *s = '\0';
-
- while (u) {
- t = u % b;
- if( t >= 10 )
- t += letbase - '0' - 10;
- *--s = t + '0';
- u /= b;
- }
-
- if (neg) {
- if( width && (pad & PAD_ZERO) ) {
- printchar (fd, out, '-');
- ++pc;
- --width;
- }
- else {
- *--s = '-';
- }
- }
-
- return pc + prints (fd, out, s, width, pad);
-}
-
-static int print(int fd, char **out, const char *format, va_list args )
-{
- int width, pad;
- int pc = 0;
- char scr[2];
-
- for (; *format != 0; ++format) {
- if (*format == '%') {
- ++format;
- width = pad = 0;
- if (*format == '\0') break;
- if (*format == '%') goto out;
- if (*format == '-') {
- ++format;
- pad = PAD_RIGHT;
- }
- while (*format == '0') {
- ++format;
- pad |= PAD_ZERO;
- }
- for ( ; *format >= '0' && *format <= '9'; ++format) {
- width *= 10;
- width += *format - '0';
- }
- if( *format == 's' ) {
- char *s = (char *)va_arg( args, int );
- pc += prints (fd, out, s?s:"(null)", width, pad);
- continue;
- }
- if( *format == 'd' ) {
- pc += printi (fd, out, va_arg( args, int ), 10, 1, width, pad, 'a');
- continue;
- }
- if( *format == 'x' ) {
- pc += printi (fd, out, va_arg( args, int ), 16, 0, width, pad, 'a');
- continue;
- }
- if( *format == 'X' ) {
- pc += printi (fd, out, va_arg( args, int ), 16, 0, width, pad, 'A');
- continue;
- }
- if( *format == 'u' ) {
- pc += printi (fd, out, va_arg( args, int ), 10, 0, width, pad, 'a');
- continue;
- }
- if( *format == 'c' ) {
- /* char are converted to int then pushed on the stack */
- scr[0] = (char)va_arg( args, int );
- scr[1] = '\0';
- pc += prints (fd, out, scr, width, pad);
- continue;
- }
- }
- else {
- out:
- printchar (fd, out, *format);
- ++pc;
- }
- }
- if (out) **out = '\0';
- va_end( args );
- return pc;
-}
-
-
-
-#if 0
-int arc_fprintf(FILE *fd, const char *format, ...);
-int arc_vfprintf(FILE *fp, const char *fmt, va_list list);
-#endif
-
-
-#if 0
-int simple_fprintf(FILE *fd, const char *format, ...)
-{
- va_list args;
-
- va_start( args, format );
- return fprint( &fd, format, args );
-}
-#endif
-
-int simple_printf(const char *format, ...)
-{
- va_list args;
-
- va_start( args, format );
- return print( STD_OUT, 0, format, args );
-}
-
-int simple_sprintf(char *out, const char *format, ...)
-{
- va_list args;
-
- va_start( args, format );
- return print(STD_OUT, &out, format, args );
-}
-
-int standard_simple_sprintf(int fd, char *out, const char *format, ...)
-{
- va_list args;
-
- va_start( args, format );
- return print(fd, &out, format, args );
-}
-
-#ifdef TEST_PRINTF
-int main(void)
-{
- char *ptr = "Hello world!";
- char *np = 0;
- int i = 5;
- unsigned int bs = sizeof(int)*8;
- int mi;
- char buf[80];
-
- mi = (1 << (bs-1)) + 1;
-dbg_printf("%s\n", ptr);
-dbg_printf("printf test\n");
-dbg_printf("%s is null pointer\n", np);
-dbg_printf("%d = 5\n", i);
-dbg_printf("%d = - max int\n", mi);
-dbg_printf("char %c = 'a'\n", 'a');
-dbg_printf("hex %x = ff\n", 0xff);
-dbg_printf("hex %02x = 00\n", 0);
-dbg_printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
-dbg_printf("%d %s(s)%", 0, "message");
-dbg_printf("\n");
-dbg_printf("%d %s(s) with %%\n", 0, "message");
- sprintf(buf, "justif: \"%-10s\"\n", "left");dbg_printf("%s", buf);
- sprintf(buf, "justif: \"%10s\"\n", "right");dbg_printf("%s", buf);
- sprintf(buf, " 3: %04d zero padded\n", 3);dbg_printf("%s", buf);
- sprintf(buf, " 3: %-4d left justif.\n", 3);dbg_printf("%s", buf);
- sprintf(buf, " 3: %4d right justif.\n", 3);dbg_printf("%s", buf);
- sprintf(buf, "-3: %04d zero padded\n", -3);dbg_printf("%s", buf);
- sprintf(buf, "-3: %-4d left justif.\n", -3);dbg_printf("%s", buf);
- sprintf(buf, "-3: %4d right justif.\n", -3);dbg_printf("%s", buf);
-
- return 0;
-}
-
-/*
- * if you compile this file with
- * gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -cdbg_printf.c
- * you will get a normal warning:
- * dbg_printf.c:214: warning: spurious trailing `%' in format
- * this line is testing an invalid % at the end of the format string.
- *
- * this should display (on 32bit int machine) :
- *
- * Hello world!
- *dbg_printf test
- * (null) is null pointer
- * 5 = 5
- * -2147483647 = - max int
- * char a = 'a'
- * hex ff = ff
- * hex 00 = 00
- * signed -3 = unsigned 4294967293 = hex fffffffd
- * 0 message(s)
- * 0 message(s) with %
- * justif: "left "
- * justif: " right"
- * 3: 0003 zero padded
- * 3: 3 left justif.
- * 3: 3 right justif.
- * -3: -003 zero padded
- * -3: -3 left justif.
- * -3: -3 right justif.
- */
-
-#endif
-
-
+/*\r
+ * Copyright ArcCore AB\r
+ *\r
+ * A simple implementation of all formatted xxprintf functionallity.\r
+ *\r
+ * DESIGN CRITERIA:\r
+ * - Reentrant\r
+ * - Use little stack\r
+ *\r
+ * What you normally would do is to print to a buffer of some kind and then\r
+ * call write(). However little stack indicates that we can't place buffers\r
+ * on the stack and reentrant tells us that we can't have a static buffer.\r
+ * That leaves us with printing characters as it is ready. From a speed\r
+ * point of view that is less than optimal, but that the way it's got to be.\r
+ * (Could make a 16 long char buffer??)\r
+ *\r
+ * This is just intended to be used as a replacement for newlibs implementation.\r
+ * Newlib porting interface have the following API:\r
+ * int write( int fd, char *buf, int nbytes)\r
+ *\r
+ *\r
+ * Note that puts(), putc() are still the newlib variants....\r
+ *\r
+ * printf() -> vfprintf(stdout,) -> vsnprintf(buf,)\r
+ * write()\r
+ * vprintf() -> vfprintf(stdout,) -> vsnprintf(buf,)\r
+ * write()\r
+ * sprintf(buf,) -> vsnprintf(buf,)\r
+ * snprintf(buf,) -> vsnprintf(buf,)\r
+ *\r
+ * IMPLEMENTATION NOTE:\r
+ * - If printing more than the limit, e.g. using vsnprintf() then\r
+ * the emit function will only stop printing, but not interrupted\r
+ * (The code will get more complicated that way)\r
+ * - ANSI-C and POSIX, streams and POSIX filenumbers.\r
+ * POSIX file-numbers exist in unistd.h and are only to be used by the porting\r
+ * newlib interface i.e. newlib_port.c.\r
+ *\r
+ *\r
+ * NEWLIB: File handles vs files\r
+ * This printf() family of functions does not use newlib at all.\r
+ * At this point the following can have happend:\r
+ * 1. A call to any of the file functions in newlib have been called.\r
+ * This then calls a number of functions (sbrk, __sinit(_impure_ptr), etc ).\r
+ * __sinit(_impure_ptr) initializes the standard files, stdin, stdout, stderr.\r
+ * file->_file is the actual posix file number (stdin=0, stdout=1, stderr=2)\r
+ * 2. No calls is done to newlib file functions. The impure_data is then empty and\r
+ * all fields are 0.\r
+ *\r
+ * Code for checking if the newlib have initialized (or we have explicitly called __sinit(_impure_ptr)\r
+ * if( _impure_ptr->__sdidinit == 1 ) {\r
+ * // We use the real filenumber\r
+ * arc_putchar((int)(file->_file), c);\r
+ * )\r
+ *\r
+ */\r
+\r
+#include <unistd.h>\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+#include <assert.h>\r
+#include <string.h>\r
+#if defined(USE_NEWLIB) && defined(__GNUC__)\r
+#include "reent.h"\r
+#endif\r
+//#define HOST_TEST 1\r
+\r
+int arc_putchar(int fd, int c);\r
+int print(FILE *file, char **buffer, size_t n, const char *format, va_list ap);\r
+static inline int emitChar( FILE *file, char **buf, char c, int *left );\r
+\r
+int fputs( const char *s, FILE *file ) {\r
+ int left = ~(size_t)0;\r
+ while(*s) {\r
+ emitChar(file,NULL,*s++,&left);\r
+ }\r
+ return 0;\r
+}\r
+\r
+\r
+int printf(const char *format, ...) {\r
+ va_list ap;\r
+ int rv;\r
+\r
+ va_start(ap, format);\r
+ rv = vfprintf((FILE *)STDOUT_FILENO, format, ap);\r
+ va_end(ap);\r
+ return rv;\r
+}\r
+\r
+int fprintf(FILE *file, const char *format, ...) {\r
+ va_list ap;\r
+ int rv;\r
+\r
+ va_start(ap, format);\r
+ rv = vfprintf(file, format, ap);\r
+ va_end(ap);\r
+ return rv;\r
+}\r
+\r
+int sprintf(char *buffer, const char *format, ...) {\r
+ va_list ap;\r
+ int rv;\r
+\r
+ va_start(ap, format);\r
+ rv = vsnprintf(buffer, ~(size_t)0, format, ap);\r
+ va_end(ap);\r
+\r
+ return rv;\r
+}\r
+\r
+int snprintf(char *buffer, size_t n, const char *format, ...) {\r
+ va_list ap;\r
+ int rv;\r
+\r
+ va_start(ap, format);\r
+ rv = vsnprintf(buffer, n, format, ap);\r
+ va_end(ap);\r
+ return rv;\r
+}\r
+\r
+int vprintf(const char *format, va_list ap) {\r
+ return vfprintf((FILE *)STDOUT_FILENO, format, ap);\r
+}\r
+\r
+int vsprintf(char *buffer, const char *format, va_list ap) {\r
+ return vsnprintf(buffer, ~(size_t)0, format, ap);\r
+}\r
+\r
+int vfprintf(FILE *file, const char *format, va_list ap) {\r
+ int rv;\r
+ /* Just print to stdout */\r
+ rv = print(file,NULL,~(size_t)0, format,ap);\r
+ return rv;\r
+}\r
+\r
+\r
+int vsnprintf(char *buffer, size_t n, const char *format, va_list ap) {\r
+ int rv;\r
+\r
+ rv = print(NULL, &buffer, n, format,ap);\r
+ return rv;\r
+}\r
+\r
+\r
+/*\r
+ * The integer only counterpart\r
+ */\r
+int iprintf(const char *format, ...) __attribute__ ((alias("printf")));\r
+int fiprintf(FILE *file, const char *format, ...) __attribute__ ((alias("fprintf")));\r
+int siprintf(char *buffer, const char *format, ...) __attribute__ ((alias("sprintf")));\r
+int sniprintf(char *buffer, size_t n, const char *format, ...) __attribute__ ((alias("snprintf")));\r
+int viprintf(const char *format, va_list ap) __attribute__ ((alias("vprintf")));\r
+int vsiprintf(char *buffer, const char *format, va_list ap) __attribute__ ((alias("vsprintf")));\r
+int vfiprintf(FILE *file, const char *format, va_list ap) __attribute__ ((alias("vfprintf")));\r
+\r
+/**\r
+ *\r
+ * @param file The file to print to\r
+ * @param buf The buffer to print to\r
+ * @param c The char to print\r
+ * @return\r
+ */\r
+static inline int emitChar( FILE *file, char **buf, char c, int *left ) {\r
+ if( (*left) == 1 ) {\r
+ return 1;\r
+ }\r
+ --(*left);\r
+ if( buf == NULL ) {\r
+#if HOST_TEST\r
+ putc(c, stdout);\r
+ fflush(stdout);\r
+#else\r
+#if 0\r
+#if defined(USE_NEWLIB) && defined(__GNUC__)\r
+ /* We are trying to print with newlib file descriptor.\r
+ * That's wrong since we are using the POSIX file numbers here instead\r
+ * Check stdout */\r
+ assert( file != _impure_ptr->_stdout );\r
+#endif\r
+#endif\r
+ if( (unsigned )file > 10UL ) {\r
+ arc_putchar((int)(file->_file), c);\r
+ } else {\r
+ arc_putchar((int)(file), c);\r
+ }\r
+\r
+#endif /* HOST_TEST */\r
+ } else {\r
+ **buf = c;\r
+ (*buf)++;\r
+ }\r
+ return 1;\r
+}\r
+\r
+\r
+#if defined(HOST_TEST)\r
+/**\r
+ * Convert a number to a string\r
+ *\r
+ * @param val The value to convert\r
+ * @param str Pointer to a space where to put the string\r
+ * @param base The base\r
+ * @param negative If negative or not.\r
+ */\r
+void xtoa( unsigned long val, char* str, int base, int negative) {\r
+ int i;\r
+ char *oStr = str;\r
+ char c;\r
+\r
+ if (negative) {\r
+ val = -val;\r
+ }\r
+\r
+ if( base < 10 && base > 16 ) {\r
+ *str = '0';\r
+ return;\r
+ }\r
+ i = 0;\r
+\r
+ do {\r
+ str[i++] = "0123456789abcdef"[ val % base ];\r
+ } while ((val /= base) > 0);\r
+\r
+\r
+ if (negative) {\r
+ str[i++] = '-';\r
+ }\r
+\r
+ str[i] = '\0';\r
+ str = &str[i]-1;\r
+ while(str > oStr) {\r
+ c = *str;\r
+ *str-- = *oStr;\r
+ *oStr++=c;\r
+ }\r
+}\r
+#else\r
+extern void xtoa( unsigned long val, char* str, int base, int negative);\r
+#endif\r
+\r
+\r
+#define FL_NONE (0<<0)\r
+#define FL_ZERO (1<<1)\r
+#define FL_HASH (1<<2)\r
+#define FL_SPACE (1<<3)\r
+#define FL_ALIGN_LEFT (1<<4)\r
+#define FL_TYPE_SIGNED_INT (1<<5)\r
+#define FL_TYPE_UNSIGNED_INT (1<<6)\r
+#define FL_TYPE_POINTER (1<<7)\r
+\r
+static void emitString( FILE *file, char **buffer, char *string, int width, int flags, int *left) {\r
+ char pad;\r
+ char *str = string;\r
+ int i;\r
+ int strLen;\r
+ /* padding: FL_ZERO or normal ' '\r
+ * align: FL_ALIGN_LEFT (left) or normal (right)\r
+ */\r
+ pad = (flags & FL_ZERO) ? '0' : ' ';\r
+\r
+\r
+ if( flags & FL_ALIGN_LEFT ) {\r
+ for(i=0;str[i]; i++) {\r
+ emitChar(file,buffer,str[i],left);\r
+ }\r
+\r
+ /* Pad the rest */\r
+ for(;i<width;i++) {\r
+ emitChar(file,buffer,pad,left);\r
+ }\r
+ } else {\r
+\r
+ strLen = strlen(string);\r
+\r
+ /* Pad first */\r
+ if( width > strLen ) {\r
+ for(i=0;i<(width-strLen);i++) {\r
+ emitChar(file,buffer,pad,left);\r
+ }\r
+ }\r
+\r
+ for(i=0;i<strLen; i++) {\r
+ emitChar(file,buffer,string[i],left);\r
+ }\r
+ }\r
+}\r
+\r
+void emitInt( FILE *file, char **buffer, int val, int base, int width, int flags, int *left )\r
+{\r
+ char lBuf[12]; // longest is base 10, 2^32\r
+ char *str = lBuf;\r
+\r
+ if( flags & FL_TYPE_SIGNED_INT ) {\r
+ xtoa(val,str,base ,(val < 0));\r
+ } else {\r
+ xtoa((unsigned)val,str,base ,0);\r
+ }\r
+\r
+ emitString(file,buffer,str,width,flags,left);\r
+}\r
+\r
+#define PRINT_CHAR(_c) *buffer++= (_c);\r
+\r
+\r
+/**\r
+ * Write formatted output to an array with a maximum number of characters.\r
+ *\r
+ * This is the mother of the formatted print family. The main goal here\r
+ * is to be very small and memory efficient.\r
+ *\r
+ * Support:\r
+ * Parameter: None\r
+ * Flags : '-' and '0'\r
+ * Width : Normal padding is supported, '*' is not.\r
+ * Precision: None\r
+ * Length : None\r
+ * C99 : None\r
+ * Type : d,u,x,s,and c\r
+ *\r
+ * @param file The file descriptor\r
+ * @param buffer A pointer to the place to store the output\r
+ * If NULL the output is instead\r
+ * @param n The maximum number of characters to write\r
+ * @param format The format string\r
+ * @param ap The va list\r
+ * @return\r
+ */\r
+int print(FILE *file, char **buffer, size_t n, const char *format, va_list ap)\r
+{\r
+ char ch;\r
+ int flags;\r
+ char *str;\r
+ int width;\r
+ int left = n;\r
+\r
+ while ( (ch = *format++) ) {\r
+\r
+ if (ch == '%') {\r
+ ch = *format++;\r
+\r
+ if( ch == '%') {\r
+ emitChar(file,buffer,ch,&left);\r
+ continue;\r
+ }\r
+\r
+ /* Find flags */\r
+ if (ch == '0')\r
+ {\r
+ flags = FL_ZERO;\r
+ }\r
+ else if (ch == ' ')\r
+ {\r
+ flags = FL_SPACE;\r
+ }\r
+ else if (ch == '-')\r
+ {\r
+ flags = FL_ALIGN_LEFT;\r
+ }\r
+ else\r
+ {\r
+ /* Not supported or no flag */\r
+ flags = FL_NONE;\r
+ format--;\r
+ }\r
+\r
+ ch = *format++;\r
+\r
+ /* Width */\r
+ if( (ch >= '0') && (ch <= '9') ) {\r
+ width = ch -'0';\r
+ ch = *format++;\r
+ } else {\r
+ width = 0;\r
+ }\r
+\r
+ /* Find type */\r
+ if (ch =='c')\r
+ {\r
+ emitChar(file,buffer,(char )va_arg( ap, int ),&left);\r
+ }\r
+ else if (ch == 'd')\r
+ {\r
+ flags |= FL_TYPE_SIGNED_INT;\r
+ emitInt(file,buffer,va_arg( ap, int ),10,width,flags,&left);\r
+ }\r
+ else if (ch == 'u')\r
+ {\r
+ flags |= FL_TYPE_UNSIGNED_INT;\r
+ emitInt(file,buffer,va_arg( ap, int ),10,width,flags,&left);\r
+ }\r
+ else if (ch == 'x')\r
+ {\r
+ flags |= FL_TYPE_UNSIGNED_INT;\r
+ emitInt(file,buffer,va_arg( ap, int ),16,width,flags,&left);\r
+ }\r
+ else if (ch == 'p')\r
+ {\r
+ flags |= FL_TYPE_POINTER;\r
+ emitInt(file,buffer,va_arg( ap, int ),16,width,flags,&left);\r
+ }\r
+ else if (ch == 's')\r
+ {\r
+ str = (char *)va_arg( ap, int );\r
+\r
+ if( str == NULL ) {\r
+ str = "(null)";\r
+ }\r
+\r
+ emitString(file,buffer,str,width,flags,&left);\r
+ }\r
+ else\r
+ {\r
+ assert(0); // oops\r
+ }\r
+ } else {\r
+ flags = FL_NONE;\r
+ emitChar(file,buffer,ch,&left);\r
+ }\r
+ }\r
+// va_end(ap); // Removed, TODO: Check the va_start/va_end handling (used in calling functions also).\r
+ if(buffer!=0) {\r
+ left = 0;\r
+ emitChar(file,buffer,'\0',&left);\r
+ }\r
+ return 0; // Wrong.. but for now.\r
+}\r
+\r
+#if 0\r
+int main(void) {\r
+ char *ptr = NULL;\r
+ char buff[30];\r
+\r
+ printf("char: %c %c = a B\n", 'a', 66);\r
+\r
+ printf("string: %s = (null)\n", (char *)ptr);\r
+\r
+ printf("string: %s = foobar \n", "foobar");\r
+\r
+ printf("string: %2s = foobar \n", "foobar");\r
+ printf("string: \"%8s\" = \" foobar\" \n", "foobar");\r
+ /* Left justify */\r
+ printf("string: \"%-8s\" = \"foobar \" \n", "foobar");\r
+\r
+ printf("decimal: 23 = %d \n", 23);\r
+ printf("hex: c23 = %x \n", 0xc23);\r
+ printf("hex: 0c23 = %04x \n", 0xc23);\r
+ printf("decimal with blanks: 23 = %6d \n", 23);\r
+ printf("decimal with zero: 000023 = %06d \n", 23);\r
+\r
+ /* negative and large numbers */\r
+ printf("decimal: -23 = %d \n", -23);\r
+ printf("decimal: 4294967273 = %u \n", -23);\r
+ printf("decimal: c0000000 = %x \n", 0xc0000000);\r
+\r
+ printf("decimal: 00c000 = %06x \n", 0xc000);\r
+\r
+ fprintf(stdout, "string: %s = foobar \n", "foobar");\r
+ sprintf(buff, "string: %s = foobar \n", "foobar");\r
+ printf("%s",buff);\r
+\r
+ snprintf(buff,10, "%s\n", "12345678901234567");\r
+ printf("\"123456789\" = \"%s\"\n",buff);\r
+\r
+ snprintf(buff,12, "%s\n", "abcdefghijklmn");\r
+ printf("\"abcdefghijkl\" = \"%s\"\n",buff);\r
+\r
+ return 0;\r
+}\r
+#endif\r
+\r
+\r