C language Linux kernel variable parameter implementation printf,sprintf

Source: Internet
Author: User
Tags define null goto sprintf

Yesterday, I published a fprintf function with variable parameters, in fact, it is not entirely variable parameter implementation, because the use of the file * Such a pointer, Need to include stdio.h this header file to implement this function, today we will see, how to abandon stdio.h, all 0 start to implement printf, sprintf, of course, this code is I get inside the Linux kernel, and then after I modify, transplant, in devc++ The test is passed in this compilation environment. Let's take a look at the code:

#include <stdarg.h> #define NULL 0//If the string is a number, it returns the number static int skip_atoi (const char **s) {int i = 0;while (IsDigit (**s )) i = i * + * ((*s) + +)-' 0 '; return i;}  static inline int isdigit (int ch) {return (ch >= ' 0 ') && (ch <= ' 9 ');//Returns the number extracted from the character 0-9} #define zeropad1/* pad With zero */#define sign2/* unsigned/signed long */#define PLUS4/* show Plus/#define space8/* space if plus */#define L eft16/* left Justified */#define small32/* must be + = 0x20/#define SPECIAL64/* 0x *///This macro is mainly used to determine what to convert into the number of #define _ _do_div (n, base) ({int __res; __res = ((unsigned long) n)% (unsigned) base; n = ((unsigned long) n)/(unsigned) base; _ _res; }) static char *number (char *str, long num, int base, int size, int precision, int type) {/* This string array holds 0-15 of these 16 numbers, which will be used for the binary Convert */static const char digits[16] = "0123456789ABCDEF"; Char Tmp[66];char c, sign, locase;int i;/*locase = 0 or 0x20, produces the same number or letter as Locase, perhaps the letter is lowercase */locase = (type & SMALL); (Type & left) type &= ~zeropad;if (BASe < 2 | | Base > Null;c) return = (type & zeropad)?  ' 0 ': '; sign = 0;if (type & sign) {if (num < 0) {sign = '-'; num =-num;size--;} else if (type & PLUS) {sign = ' + '; size--;} else if (type & SPACE) {sign = '; size--;}} Detection of the number of binary, whether to 2 or 8 or 16 if (type & special) {if (base = =) Size-= 2;else if (base = = 8) size--;} i = 0;if (num = = 0) tmp[i++] = ' 0 '; Elsewhile (num! = 0) tmp[i++] = (digits[__do_div (num, base)] | locase); if (i > Precisi ON) precision = i;size-= precision;if (!  Type & (Zeropad + left)) while (size--> 0) *str++ = "; if (sign) *str++ = sign;if (Type & special) {if (base = = 8) *str++ = ' 0 ', else if (base = =) {*str++ = ' 0 '; *str++ = (' X ' | locase);}} if (! ( Type & Left) (size--> 0) *str++ = c;while (i < precision--) *str++ = ' 0 ', while (i--> 0) *str++ = tmp[i]; while (size--> 0) *str++ = "; return str;} int vsprintf (char *buf, const char *fmt, va_list args) {int len;unsigned long num;int i, Base;char *str;const chaR *s;int flags;int field_width;/* bit wide output */int precision;int qualifier;//It is determined here that if the symbol is not present in the string fmt, then the string continues to traverse for the for (str = BUF ; *FMT; ++FMT) {if (*fmt! = '% ') {*str++ = *fmt;continue;}      Program set flag bit flags = 0; repeat:++fmt;/* This also skips first '% ' *///format control switch (*FMT) {case '-': Flags |= left;goto repeat;case ' + ': Flags |= PLU S;goto repeat;case ': Flags |= space;goto repeat;case ' # ': Flags |= special;goto repeat;case ' 0 ': Flags |= Zeropad;goto Rep Eat;} Get the width, here is primarily to implement printf's bit-width mechanism field_width = -1;if (IsDigit (*fmt)) Field_width = Skip_atoi (&AMP;FMT); else if (*fmt = = ' * ') {+ +) Fmt;field_width = Va_arg (args, int); if (Field_width < 0) {field_width =-field_width;flags |= left;}} Precision = -1;if (*fmt = = '. ') {++fmt;if (IsDigit (*fmt)) precision = Skip_atoi (&AMP;FMT); else if (*fmt = = ' * ') {++fmt;precision = Va_arg (args, int);} if (Precision < 0) precision = 0;} /* The resulting conversion qualifier */qualifier = -1;if (*fmt = = ' h ' | | *fmt = = ' L ' | | *fmt = ' l ') {qualifier = *fmt;++fmt;} /* The default binary is 10 binary */base = 10;//The following is primarily to implement printfFormat output For example:%d,%c,%u ... Wait for switch (*FMT) {case ' C '://Output as a character if (!) Flags & Left) while (--field_width > 0) *str++ = "; *str++ = (unsigned char) va_arg (args, int); while (--field_width > 0) *str++ = "; Continue;case ' s '://output in string form s = Va_arg (args, char *); len = Strnlen (s, precision); Flags & Left) while (Len < field_width--) *str++ = ", for (i = 0; i < len; ++i) *str++ = *s++;while (Len < fie ld_width--) *str++ = "; Continue;case ' P '://output in address form, that is, output if (field_width = =-1) {field_width = 2 * sizeof (void *) in 16 decimal digits); Flags |= Zeropad;} str = number (str, (unsigned long) va_arg (args, void *), field_width, precision, flags), Continue;case ' n ': if (qu Alifier = = ' L ') {Long *ip = Va_arg (args, long *); *ip = (STR-BUF);} else {int *ip = Va_arg (args, int *); *ip = (STR-BUF) ;} Continue;case '% '://Here indicates that the character is present in the string *str++ = '% '; continue;/* integer number Formats-set up the flags and "break" * /case ' O '://%o Represents 8 binary Output base = 8;break;case ' x '://%x or%x Represents 16 binary output flags |= small;case ' X ': base = 16;break;case ' d '://%d%i Shaping number output,%u unsigned case ' I ': Flags |= sign;case ' u ': Break ;d efault:*str++ = '% '; if (*fmt) *str++ = *fmt;else--fmt;continue;} if (qualifier = = ' l ')//unsigned long integer output num = va_arg (args, unsigned long); else if (qualifier = = ' h ') {num = (unsigned short) va_a RG (args, int); if (Flags & sign) num = (short) num;} else if (Flags & sign) num = va_arg (args, int); elsenum = Va_arg (args, unsigned int); str = number (str, NUM, base, Field_ width, precision, flags);}   *str = ' + '; The string is traversed to a place where there is a str-buf; Variable Parameter form implementation sprintf int mysprintf (char *buf, const char *FMT, ...) {va_list args;int i;va_start (args, FMT);//The FMT format string to be obtained is written to the BUF in this cache i = vsprintf (buf, FMT, args);//release args va_end (args); return i;} Variable parameter forms are implemented myprintf int myprintf (const char *FMT, ...) {Char printf_buf[1024];va_list args;int printed;va_start (args, fmt);p rinted = vsprintf (Printf_buf, FMT, args); Va_end ( args);p UTS (PRINTF_BUF); return printed;} int main (void) {myprintf ("Output string: Hello World!\n "); static int sum, a = 3, b = 4; sum = a + b; myprintf ("sum (decimal output):%d\n", sum), myprintf ("sum (16 output):%p\n", sum); char buffer[128] = {0};//saves a string into an array buffer. mysprintf (buffer, "output string: Hello world! \//To output the contents of this buffer in string format myprintf ("buffer:%s\n", buffer); return 0;}
Operation Result:

Read the code to know, our program does not contain stdio.h this header file, as well as the implementation of printf and sprintf these two functions. In this case, if you want to implement a printf function, this code can be called as a file, haha!



C language Linux kernel variable parameter implementation printf,sprintf

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.