On 3 Sep, 08:33, Ron Ford <r...@example.invalidwrote:
Quote:
On Wed, 03 Sep 2008 07:16:54 +0000, Richard Heathfield posted:
Quote:
Ron Ford said:
Quote:
On Wed, 03 Sep 2008 06:15:59 +0000, Richard Heathfield posted:
>raashid bhatt said:
>>On Sep 2, 7:43 pm, Jrdman <ahmed.bo...@gmail.comwrote:
|
|
|
Quote:
Quote:
Quote:
|
>>>someone has an idea on how the *printf *function is programmed ?
|
|
>
Quote:
Quote:
|
>>unser windows itz a function call
|
|
>
Quote:
Quote:
>It's a function call in *any* environment. And the rest of your answer
>is unnecessarily platform-specific - the printf function can be written
>portably.
|
|
>>>
I see the syntax here in §7.2.
>
What I think a person might call this is an internal write. *In fortran, we
go so far as to speak of "internal files," when what we really mean is the
character variable that we write to. *I/O need not apply.
|
is english your first language? (I suspect "yes" as a non-native
speaker
wouldn't write such convoluted sentences) I often have difficulty
understanding you.
Quote:
|
I'd be curious to see a useful snippet
|
snippet of what? At the end is a very basic printf (for instance no
floating
point). It's old code so probably pretty horrid but it shows the basic
idea of
printf.
<snip>
/*
* MPRINTF.H
* Version 1.0
* (c) N.J.Keighley 1991
*/
/*
* This header file provides acces to a "mini-printf()" facility.
*/
/* history */
/*
Issue Date Who Auth Comment
----- ---- ---- ---- -------
00.00A 20-10-91 NJK : - CREATED
*/
#include <stdio.h>
#include <stdarg.h>
/* pointer to function returning void */
typedef void (*Func_vvc) (void *s, char c);
/* functions corresponding to those in the ANSI-C library */
int m_printf (const char *fmt, ...);
int m_sprintf (char *str, const char *fmt, ...);
/*
int m_fprintf (FILE *stream, const char fmt, ...);
int m_vprintf (const char *fmt, va_list arg);
int m_vsprintf (char *str, const char *fmt, va_list arg);
int m_vfprintf (FILE *stream, const char fmt, va_list arg);
*/
/* utility functions used to implement the above */
/*
* Printf() formatter used by the above functions.
* Uses FMT string and ARG list to produce an output string.
* DOCHAR is a function to process each character.
* STREAM specifies where the output is to go.
*
* This function does not support the following format
specifications:-
* %f, %e, %E, %g, %G, %p, %n
* or the following flags:-
* +, <space>, #
* or the length modifier:-
* h
*
* %x and %X both produce upper case letters (only %X does in ANSI-C)
*
*/
void m_format (const char *fmt, va_list arg, Func_vvc dochar, void
*stream);
void int_to_str (int n, char *s);
void radix_int_to_str (unsigned n, char *s, int radix);
/*
* MPRINTF.C
* Version 2.0
* (c) N.J.Keighley 1996
*/
/*
* This module implements printf()
*
* References: Comer,D. "Operating System Design- The XINU Approach"
* Hendrix,J. and Payne,E. "Dr. Dobb's Toolbook of C"
* Perez,C. "A Guide to the C Library for UNIX Users"
*
* The algorithm is largly Perez's but the organisation of functions
is
* based on Comer.
* Changes:-
* -code optimised for code size rather than speed
* -switches
* -improved compatability with ANSI-C library
*/
/* history */
/*
Issue Date Who Auth Comment
----- ---- ---- ---- -------
02.00 14-10-96 NJK : - removed depenency on "csdtypes.h"
- tided layout
00.00A 20-10-91 NJK : - CREATED
*/
#include <stdio.h>
#include <stdarg.h>
#include "mprintf.h"
#define TRUE 1
#define FALSE 0
/* defines */
#define MAX_DIGIT 20 /* size of largest number */
typedef int Bool;
void int_to_str(int n, char *s)
{
int sign;
int i;
char temp[MAX_DIGIT]; /* need this as digits
generated in reverse */
if ((sign = n) < 0)
n = -n;
i = 1;
temp[0] = '\0';
do
{
temp[i++] = (char) (n % 10 + '0');
n /= 10;
}
while (n 0);
if (sign < 0)
temp[i] = '-';
else
i--;
while (i >= 0)
*s++ = temp[i--];
}
void long_to_str(long n, char *s)
{
long sign;
int i;
char temp[MAX_DIGIT]; /* need this as digits
generated in reverse */
if ((sign = n) < 0)
n = -n;
temp[0] = '\0';
i = 1;
do
{
temp[i++] = (char) (n % 10 + '0');
n /= 10;
}
while (n 0);
if (sign < 0)
temp[i++] = '-';
else
i--;
while (i >= 0)
*s++ = temp[i--];
}
void radix_int_to_str(unsigned n, char *s, int radix)
{
int i;
char temp[MAX_DIGIT]; /* need this as digits
generated in reverse */
char d;
i = 1;
temp[0] = '\0';
do
{
d = (char) (n % radix);
temp[i++] = (d <= 9) ? (char) (d + '0') : (char) (d - 10 +
'A');
n /= radix;
}
while (n 0);
i--;
while (i >= 0)
*s++ = temp[i--];
}
void radix_long_to_str(unsigned long n, char *s, int radix)
{
int i;
char temp[MAX_DIGIT]; /* need this as digits
generated in reverse */
char d;
i = 1;
temp[0] = '\0';
do
{
d = (char) (n % radix);
temp[i++] = (d <= 9) ? (char) (d + '0') : (char) (d - 10 +
'A');
n /= radix;
}
while (n 0);
i--;
while (i >= 0)
*s++ = temp[i--];
}
void m_format(const char *fmt, va_list arg_ptr, Func_vvc dochar,
void *stream)
{
char c;
int i;
char f; /* format character (after %)
*/
char *str; /* pointer to string */
char string[MAX_DIGIT]; /* result of number conversion
*/
int length; /* string length */
char fill; /* ' ' or '0' */
Bool leftjust;
Bool longflag;
int fmax, fmin; /* field spec. %<min>.<max>f
*/
int leading; /* number of leading/trailing
fill chars */
char sign; /* '-' for negative numbers */
char digit1; /* offset to first numeric
digit */
long longarg;
int intarg;
int radix;
radix = radix;
for (;;)
{
/* echo until '%' */
while ((c = *fmt++) != '%')
{
if (c == '\0')
return;
dochar(stream, c);
}
leftjust = (*fmt == '-');
if (leftjust)
fmt++;
/* allow for zero filled numeric output eg. "%08d" */
if (*fmt == '0')
fill = *fmt++;
else
fill = ' ';
fmin = 0;
if (*fmt == '*')
{
/* variable width "%0*" */
fmin = va_arg(arg_ptr, int);
fmt++;
}
else
{
/* min field width "%10d" */
while ('0' <= *fmt && *fmt <= '9')
{
/* convert digits into a number */
fmin = fmin * 10 + *fmt++ - '0';
}
}
fmax = 0;
if (*fmt == '.')
{
if (*(++fmt) == '*')
{
/* variable field "%4.*s" */
fmax = va_arg(arg_ptr, int);
fmt++;
}
else
{
/* max field width "%4.10s" */
while ('0' <= *fmt && *fmt <= '9')
{
/* convert digits into a number */
fmax = fmax * 10 + *fmt++ - '0';
}
}
}
/* long flag */
longflag = (*fmt == 'l');
if (longflag)
fmt++;
str = &string[0];
if ((f = *fmt++) == '\0')
{
dochar(stream, '%');
return;
}
sign = '\0';
switch (f)
{
case 'c':
#ifdef MSDOS /* MS-C bug */
string[0] = (char) va_arg(arg_ptr, int);
#else
string[0] = va_arg(arg_ptr, char);
#endif
string[1] = '\0';
fmax = 0;
fill = ' ';
break;
case 's':
str = va_arg(arg_ptr, char *);
fill = ' ';
break;
case 'D':
case 'd':
case 'i':
if (longflag)
{
longarg = va_arg(arg_ptr, long);
if (longarg < 0)
{
sign = '-';
longarg = -longarg;
}
long_to_str(longarg, str);
}
else
{
intarg = va_arg(arg_ptr, int);
if (intarg < 0)
{
sign = '-';
intarg = -intarg;
}
int_to_str(intarg, str);
}
break;
case 'O':
case 'o':
if (longflag)
{
longarg = va_arg(arg_ptr, long);
radix_long_to_str(longarg, str, 8);
}
else
{
intarg = va_arg(arg_ptr, int);
radix_int_to_str(intarg, str, 8);
}
fmax = 0;
break;
case 'X':
case 'x':
if (longflag)
{
longarg = va_arg(arg_ptr, long);
radix_long_to_str(longarg, str, 16);
}
else
{
intarg = va_arg(arg_ptr, int);
radix_int_to_str(intarg, str, 16);
}
fmax = 0;
break;
case 'U':
case 'u':
if (longflag)
{
longarg = va_arg(arg_ptr, long);
digit1 = '\0';
/*
* "negative" longs in unsigned format can't be
computed by long division. Convert to positive. DIGIT1
* is how much to add back afterwards.
*/
while (longarg < 0)
{
longarg -= 1000000000L;
digit1++;
}
long_to_str(longarg, str);
str[0] += digit1;
}
else
{
intarg = va_arg(arg_ptr, int);
int_to_str(intarg, str);
}
fmax = 0;
break;
default:
/* this covers "%%" as well */
dochar(stream, f);
str[0] = '\0';
} /* end switch */
for (length = 0; str[length] != '\0'; length++)
;
if (fmin < 0)
fmin = 0;
if (fmax < 0)
fmax = 0;
leading = 0;
if (fmax != 0 || fmin != 0)
{
if (fmax != 0)
if (length fmax)
length = fmax;
if (fmin != 0)
leading = fmin - length;
if (sign == '-')
leading--;
}
if (sign == '-' && fill == '0')
dochar(stream, sign);
if (!leftjust)
for (i = 0; i < leading; i++)
dochar(stream, fill);
if (sign == '-' && fill == ' ')
dochar(stream, sign);
for (i = 0; i < length; i++)
dochar(stream, str[i]);
if (leftjust)
for (i = 0; i < leading; i++)
dochar(stream, fill);
} /* for */
} /* m_format() */
void print(void *stream, char c)
{
putc(c, (FILE *) stream);
}
int m_printf(const char *fmt,...)
{
va_list arg_ptr;
va_start(arg_ptr, fmt);
m_format(fmt, arg_ptr, print, stdout);
va_end(arg_ptr);
return 0;
}
void strput (void *stream, char c)
{
char *strptr;
strptr = (char*)stream;
*strptr++ = c;
}
int m_sprintf(char *str, const char *fmt,...)
{
va_list arg_ptr;
va_start(arg_ptr, fmt);
m_format(fmt, arg_ptr, strput, str);
va_end(arg_ptr);
return 0;
}
--
Nick Keighley