import from github
This commit is contained in:
266
agbcc/libc/misc/dprintf.c
Normal file
266
agbcc/libc/misc/dprintf.c
Normal file
@ -0,0 +1,266 @@
|
||||
/* Debugging printf, for debugging the library itself.
|
||||
|
||||
We don't assume stdio is working.
|
||||
We do assume _write_r is working.
|
||||
*/
|
||||
|
||||
#include "ctype.h"
|
||||
#include "reent.h"
|
||||
#include "string.h"
|
||||
#include "unctrl.h"
|
||||
|
||||
#ifdef __STDC__
|
||||
#include "stdarg.h"
|
||||
#else
|
||||
#include "varargs.h"
|
||||
#endif
|
||||
|
||||
static char *parse_number ();
|
||||
static long get_number ();
|
||||
static void print_number ();
|
||||
static void write_char ();
|
||||
static void write_string ();
|
||||
|
||||
/* Non-zero for big-endian systems. */
|
||||
static int big_endian_p;
|
||||
|
||||
/* For now hardcode 2 (stderr) as the console file descriptor.
|
||||
May wish to let the caller pass in a file descriptor or some such but
|
||||
this is only for debugging purposes anyway. */
|
||||
#define CONSOLE_FD 2
|
||||
|
||||
/* Standalone printf routine.
|
||||
|
||||
The format string has been enhanced so that multiple values can be dumped
|
||||
without having to have a %-field for each one (say if you want to dump
|
||||
20 words at a certain address). A modifier of `N' says the next argument
|
||||
is a count, and the one after that is a pointer.
|
||||
|
||||
Example: __dprintf (stderr, "%Nx\n", 20, p); /-* print 20 ints at `p' *-/
|
||||
|
||||
Supported formats are: c d u x s p.
|
||||
|
||||
All ints are retrieved a byte at a time so alignment issues are not
|
||||
a problem.
|
||||
|
||||
This routine is used in situations where the only debugging capability
|
||||
is console output and was written to aid debugging newlib itself. We don't
|
||||
use printf ourselves as we may be debugging it. We do assume _write_r is
|
||||
working.
|
||||
*/
|
||||
|
||||
void
|
||||
#ifdef __STDC__
|
||||
__dprintf (char *fmt, ...)
|
||||
#else
|
||||
__dprintf (fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
/* Which endian are we? */
|
||||
{
|
||||
short tmp = 1;
|
||||
big_endian_p = *(char *) &tmp == 0;
|
||||
}
|
||||
|
||||
#ifdef __STDC__
|
||||
va_start (args, fmt);
|
||||
#else
|
||||
va_start (args);
|
||||
#endif
|
||||
|
||||
while (*fmt)
|
||||
{
|
||||
char c, *p;
|
||||
int count;
|
||||
long l;
|
||||
|
||||
if (*fmt != '%' || *++fmt == '%')
|
||||
{
|
||||
write_char (*fmt++);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*fmt == 'N')
|
||||
{
|
||||
count = va_arg (args, int);
|
||||
p = va_arg (args, char *);
|
||||
++fmt;
|
||||
c = *fmt++;
|
||||
|
||||
while (--count >= 0)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'c' :
|
||||
write_string (unctrl (*p++));
|
||||
break;
|
||||
case 'p' :
|
||||
print_number (16, 1, get_number (p, sizeof (char *), 1));
|
||||
p += sizeof (char *);
|
||||
break;
|
||||
case 'd' :
|
||||
case 'u' :
|
||||
case 'x' :
|
||||
print_number (c == 'x' ? 16 : 10, c != 'd',
|
||||
get_number (p, sizeof (int), c != 'd'));
|
||||
p += sizeof (int);
|
||||
break;
|
||||
case 's' :
|
||||
write_string (*(char **) p);
|
||||
p += sizeof (char *);
|
||||
break;
|
||||
}
|
||||
if (count > 0)
|
||||
write_char (' ');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c = *fmt++)
|
||||
{
|
||||
case 'c' :
|
||||
c = va_arg (args, int);
|
||||
write_string (unctrl (c));
|
||||
break;
|
||||
case 'p' :
|
||||
l = (_POINTER_INT) va_arg (args, char *);
|
||||
print_number (16, 1, l);
|
||||
break;
|
||||
case 'd' :
|
||||
case 'u' :
|
||||
case 'x' :
|
||||
l = va_arg (args, int);
|
||||
print_number (c == 'x' ? 16 : 10, c != 'd', l);
|
||||
break;
|
||||
case 's' :
|
||||
p = va_arg (args, char *);
|
||||
write_string (p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
/* Parse a positive decimal integer at S.
|
||||
FIXME: Was used in earlier version, but not currently used.
|
||||
Keep for now. */
|
||||
|
||||
static char *
|
||||
parse_number (s, p)
|
||||
char *s;
|
||||
long *p;
|
||||
{
|
||||
long x = 0;
|
||||
|
||||
while (isdigit (*s))
|
||||
{
|
||||
x = (x * 10) + (*s - '0');
|
||||
++s;
|
||||
}
|
||||
|
||||
*p = x;
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Fetch the number at S of SIZE bytes. */
|
||||
|
||||
static long
|
||||
get_number (s, size, unsigned_p)
|
||||
char *s;
|
||||
long size;
|
||||
int unsigned_p;
|
||||
{
|
||||
long x;
|
||||
unsigned char *p = (unsigned char *) s;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1 :
|
||||
x = *p;
|
||||
if (!unsigned_p)
|
||||
x = (x ^ 0x80) - 0x80;
|
||||
return x;
|
||||
case 2 :
|
||||
if (big_endian_p)
|
||||
x = (p[0] << 8) | p[1];
|
||||
else
|
||||
x = (p[1] << 8) | p[0];
|
||||
if (!unsigned_p)
|
||||
x = (x ^ 0x8000) - 0x8000;
|
||||
return x;
|
||||
case 4 :
|
||||
if (big_endian_p)
|
||||
x = ((long)p[0] << 24) | ((long)p[1] << 16) | (p[2] << 8) | p[3];
|
||||
else
|
||||
x = ((long)p[3] << 24) | ((long)p[2] << 16) | (p[1] << 8) | p[0];
|
||||
if (!unsigned_p)
|
||||
x = (x ^ 0x80000000L) - 0x80000000L;
|
||||
return x;
|
||||
#if 0 /* FIXME: Is there a standard mechanism for knowing if
|
||||
long longs exist? */
|
||||
case 8 :
|
||||
#endif
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print X in base BASE. */
|
||||
|
||||
static void
|
||||
print_number (base, unsigned_p, n)
|
||||
int base;
|
||||
int unsigned_p;
|
||||
long n;
|
||||
{
|
||||
static char chars[16] = "0123456789abcdef";
|
||||
char *p, buf[32];
|
||||
unsigned long x;
|
||||
|
||||
if (!unsigned_p && n < 0)
|
||||
{
|
||||
write_char ('-');
|
||||
x = -n;
|
||||
}
|
||||
else
|
||||
x = n;
|
||||
|
||||
p = buf + sizeof (buf);
|
||||
*--p = '\0';
|
||||
do
|
||||
{
|
||||
*--p = chars[x % base];
|
||||
x /= base;
|
||||
}
|
||||
while (x != 0);
|
||||
|
||||
write_string (p);
|
||||
}
|
||||
|
||||
/* Write C to the console.
|
||||
We go through the file descriptor directly because we can't assume
|
||||
stdio is working. */
|
||||
|
||||
static void
|
||||
write_char (c)
|
||||
char c;
|
||||
{
|
||||
_write_r (_REENT, CONSOLE_FD, &c, 1);
|
||||
}
|
||||
|
||||
/* Write S to the console.
|
||||
We go through the file descriptor directly because we can't assume
|
||||
stdio is working. */
|
||||
|
||||
static void
|
||||
write_string (s)
|
||||
char *s;
|
||||
{
|
||||
_write_r (_REENT, CONSOLE_FD, s, strlen (s));
|
||||
}
|
42
agbcc/libc/misc/ffs.c
Normal file
42
agbcc/libc/misc/ffs.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<ffs>>---find first bit set in a word
|
||||
|
||||
INDEX
|
||||
ffs
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
int ffs(int <[word]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
int ffs(<[word]>);
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
<<ffs>> returns the first bit set in a word.
|
||||
|
||||
RETURNS
|
||||
<<ffs>> returns 0 if <[c]> is 0, 1 if <[c]> is odd, 2 if <[c]> is a multiple of
|
||||
2, etc.
|
||||
|
||||
PORTABILITY
|
||||
<<ffs>> is not ANSI C.
|
||||
|
||||
No supporting OS subroutines are required. */
|
||||
|
||||
int
|
||||
ffs (word)
|
||||
int word;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!word)
|
||||
return 0;
|
||||
|
||||
i = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (((1 << i++) & word) != 0)
|
||||
return i;
|
||||
}
|
||||
}
|
146
agbcc/libc/misc/unctrl.c
Normal file
146
agbcc/libc/misc/unctrl.c
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<unctrl>>---translate characters to upper case
|
||||
|
||||
INDEX
|
||||
unctrl
|
||||
INDEX
|
||||
unctrllen
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <unctrl.h>
|
||||
char *unctrl(int <[c]>);
|
||||
int unctrllen(int <[c]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <unctrl.h>
|
||||
char *unctrl(<[c]>);
|
||||
int unctrllen(<[c]>);
|
||||
|
||||
DESCRIPTION
|
||||
<<unctrl>> is a macro which returns the printable representation of <[c]>
|
||||
as a string.
|
||||
<<unctrllen>> is a macro which returns the length of the printable
|
||||
representation of <[c]>.
|
||||
|
||||
RETURNS
|
||||
<<unctrl>> returns a string of the printable representation of <[c]>.
|
||||
|
||||
<<unctrllen>> returns the length of the string which is the printable
|
||||
representation of <[c]>.
|
||||
|
||||
PORTABILITY
|
||||
<<unctrl>> and <<unctrllen>> are not ANSI C.
|
||||
|
||||
No supporting OS subroutines are required.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1981, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <_ansi.h>
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)unctrl.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* not lint */
|
||||
|
||||
_CONST char * _CONST __unctrl[256] = {
|
||||
"^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G",
|
||||
"^H", "^I", "^J", "^K", "^L", "^M", "^N", "^O",
|
||||
"^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W",
|
||||
"^X", "^Y", "^Z", "^[", "^\\", "^]", "^~", "^_",
|
||||
" ", "!", "\"", "#", "$", "%", "&", "'",
|
||||
"(", ")", "*", "+", ",", "-", ".", "/",
|
||||
"0", "1", "2", "3", "4", "5", "6", "7",
|
||||
"8", "9", ":", ";", "<", "=", ">", "?",
|
||||
"@", "A", "B", "C", "D", "E", "F", "G",
|
||||
"H", "I", "J", "K", "L", "M", "N", "O",
|
||||
"P", "Q", "R", "S", "T", "U", "V", "W",
|
||||
"X", "Y", "Z", "[", "\\", "]", "^", "_",
|
||||
"`", "a", "b", "c", "d", "e", "f", "g",
|
||||
"h", "i", "j", "k", "l", "m", "n", "o",
|
||||
"p", "q", "r", "s", "t", "u", "v", "w",
|
||||
"x", "y", "z", "{", "|", "}", "~", "^?",
|
||||
|
||||
"0x80", "0x81", "0x82", "0x83", "0x84", "0x85", "0x86", "0x87",
|
||||
"0x88", "0x89", "0x8a", "0x8b", "0x8c", "0x8d", "0x8e", "0x8f",
|
||||
"0x90", "0x91", "0x92", "0x93", "0x94", "0x95", "0x96", "0x97",
|
||||
"0x98", "0x99", "0x9a", "0x9b", "0x9c", "0x9d", "0x9e", "0x9f",
|
||||
"0xa0", "0xa1", "0xa2", "0xa3", "0xa4", "0xa5", "0xa6", "0xa7",
|
||||
"0xa8", "0xa9", "0xaa", "0xab", "0xac", "0xad", "0xae", "0xaf",
|
||||
"0xb0", "0xb1", "0xb2", "0xb3", "0xb4", "0xb5", "0xb6", "0xb7",
|
||||
"0xb8", "0xb9", "0xba", "0xbb", "0xbc", "0xbd", "0xbe", "0xbf",
|
||||
"0xc0", "0xc1", "0xc2", "0xc3", "0xc4", "0xc5", "0xc6", "0xc7",
|
||||
"0xc8", "0xc9", "0xca", "0xcb", "0xcc", "0xcd", "0xce", "0xcf",
|
||||
"0xd0", "0xd1", "0xd2", "0xd3", "0xd4", "0xd5", "0xd6", "0xd7",
|
||||
"0xd8", "0xd9", "0xda", "0xdb", "0xdc", "0xdd", "0xde", "0xdf",
|
||||
"0xe0", "0xe1", "0xe2", "0xe3", "0xe4", "0xe5", "0xe6", "0xe7",
|
||||
"0xe8", "0xe9", "0xea", "0xeb", "0xec", "0xed", "0xee", "0xef",
|
||||
"0xf0", "0xf1", "0xf2", "0xf3", "0xf4", "0xf5", "0xf6", "0xf7",
|
||||
"0xf8", "0xf9", "0xfa", "0xfb", "0xfc", "0xfd", "0xfe", "0xff",
|
||||
};
|
||||
|
||||
_CONST char __unctrllen[256] = {
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 2,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
};
|
Reference in New Issue
Block a user