#include "ch.h"
#define MAX_FILLER 11
static char *ltoa(char *p, long num, unsigned radix) {
int i;
char *q;
q = p + MAX_FILLER;
do {
i = (int)(num % radix);
i += '0';
if (i > '9')
i += 'A' - '0' - 10;
*--q = i;
} while ((num /= radix) != 0);
i = (int)(p + MAX_FILLER - q);
do
*p++ = *q++;
while (--i);
return p;
}
/**
* @brief System formatted output function.
* @details This function implements a minimal @p printf() like functionality
* with output on a @p BaseChannel.
* The general parameters format is: %[.][width|*][l|L]p.
* The following parameter types (p) are supported:
* - x hexadecimal integer.
* - X hexadecimal long.
* - o octal integer.
* - O octal long.
* - d decimal signed integer.
* - D decimal signed long.
* - u decimal unsigned integer.
* - U decimal unsigned long.
* - c character.
* - s string.
* .
* @note Floating point types are not implemented, this function is meant
* as a system utility and not a full implementation.
*
* @param[in] chp pointer to a @p BaseChannel implementing object
* @param[in] fmt formatting string
*/
void chprintf(BaseChannel *chp, const char *fmt, ...) {
va_list ap;
char buf[MAX_FILLER + 1];
char *p, *s, c, filler;
int i, n, width;
bool_t lflag, ljust;
long l;
va_start(ap, fmt);
while (TRUE) {
c = *fmt++;
if (c == 0) {
va_end(ap);
return;
}
if (c != '%') {
chIOPut(chp, (uint8_t)c);
continue;
}
p = buf;
s = buf;
ljust = FALSE;
if (*fmt == '-') {
fmt++;
ljust = TRUE;
}
filler = ' ';
if (*fmt == '.') {
fmt++;
filler = '0';
}
for (width = 0;;) {
c = *fmt++;
if (c >= '0' && c <= '9')
c -= '0';
else if (c == '*')
c = va_arg(ap, int);
else
break;
width = width * 10 + c;
}
n = 0;
if (c == '.') {
for (;;) {
c = *fmt++;
if (c >= '0' && c <= '9')
c -= '0';
else if (c == '*')
c = va_arg(ap, int);
else
break;
n *= 10;
n += c;
}
}
lflag = FALSE;
if (c == 'l' || c == 'L') {
lflag++;
if (*fmt)
c = *fmt++;
}
switch (c) {
case 'X':
lflag = TRUE;
case 'x':
c = 16;
goto oxu;
case 'U':
lflag = TRUE;
case 'u':
c = 10;
goto oxu;
case 'O':
lflag = TRUE;
case 'o':
c = 8;
oxu:
if (lflag)
l = va_arg(ap, long);
else
l = va_arg(ap, int);
p = ltoa(p, l, c);
break;
case 'D':
lflag = TRUE;
case 'd':
if (lflag)
l = va_arg(ap, long);
else
l = va_arg(ap, int);
if (l < 0) {
*p++ = '-';
l = -l;
}
p = ltoa(p, l, 10);
break;
case 'c':
filler = ' ';
*p++ = va_arg(ap, int);
break;
case 's':
filler = ' ';
if ((s = va_arg(ap, char *)) == 0)
s = "(null)";
if (n == 0)
n = 32767;
for (p = s; *p && --n >= 0; p++)
;
break;
default:
*p++ = c;
break;
}
i = (int)(p - s);
if ((width -= i) < 0)
width = 0;
if (ljust == FALSE)
width = -width;
if (width < 0) {
if (*s == '-' && filler == '0') {
chIOPut(chp, (uint8_t)*s++);
i--;
}
do
chIOPut(chp, (uint8_t)filler);
while (++width != 0);
}
while (--i >= 0)
chIOPut(chp, (uint8_t)*s++);
while (width) {
chIOPut(chp, (uint8_t)filler);
width--;
}
}
}
ef='#n39'>39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#
# Copyright (C) 2007-2009 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
# Main makefile for the toolchain
#
# Steps:
# 1) toolchain/binutils/compile
# build & install binutils
# 2) toolchain/gcc/minimal/compile
# build & install a minimal gcc, needed for steps 3 & 4
# 3) toolchain/kernel-headers/compile
# install kernel headers, needed for step 4
# 4) toolchain/libc/headers/compile
# build & install libc headers & support files, needed for step 5
# 5) toolchain/gcc/initial/compile
# build & install an initial gcc, needed for step 6
# 6) toolchain/libc/compile
# build & install the final libc
# 7) toolchain/gcc/final/compile
# build & install the final gcc
# 8) toolchain/libc/utils/compile
# build & install libc utilities
#
# For musl, steps 2 and 4 are skipped, and step 3 is done after 5
curdir:=toolchain
# subdirectories to descend into
$(curdir)/builddirs := $(if $(CONFIG_GDB),gdb) $(if $(CONFIG_EXTERNAL_TOOLCHAIN),wrapper,kernel-headers binutils gcc/initial gcc/final $(LIBC) fortify-headers) $(if $(CONFIG_YASM),yasm)
ifdef CONFIG_USE_UCLIBC
$(curdir)/builddirs += $(LIBC)/utils
endif
# builddir dependencies
ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
ifdef CONFIG_USE_MUSL
$(curdir)/kernel-headers/compile:=$(curdir)/gcc/initial/compile
$(curdir)/$(LIBC)/compile:=$(curdir)/kernel-headers/compile
else
$(curdir)/builddirs += $(LIBC)/headers gcc/minimal
$(curdir)/gcc/minimal/compile:=$(curdir)/binutils/compile
$(curdir)/kernel-headers/compile:=$(curdir)/gcc/minimal/compile
$(curdir)/$(LIBC)/headers/compile:=$(curdir)/kernel-headers/compile
$(curdir)/gcc/initial/compile:=$(curdir)/$(LIBC)/headers/compile
endif
$(curdir)/gcc/initial/compile+=$(curdir)/binutils/compile
$(curdir)/$(LIBC)/compile:=$(curdir)/gcc/initial/compile
$(curdir)/gcc/final/compile:=$(curdir)/$(LIBC)/compile
$(curdir)/$(LIBC)/utils/compile:=$(curdir)/gcc/final/compile
endif
ifndef DUMP_TARGET_DB
ifneq ($(ARCH),)
$(TOOLCHAIN_DIR)/info.mk: .config
@for dir in $(TOOLCHAIN_DIR); do ( \
$(if $(QUIET),,set -x;) \
mkdir -p "$$dir"; \
cd "$$dir"; \
ln -nsf lib lib64; \
ln -nsf lib lib32; \
mkdir -p stamp lib usr/include usr/lib ; \
); done
@grep GCC_VERSION $@ >/dev/null 2>&1 || $(INSTALL_DATA) $(TOPDIR)/toolchain/info.mk $@
@touch $@
endif
endif
ifdef CONFIG_BUILDBOT
$(TOOLCHAIN_DIR)/stamp/.ver_check: $(TMP_DIR)/.build
cd "$(TOPDIR)"; git log --format=%h -1 toolchain > $(TMP_DIR)/.ver_check
cmp -s $(TMP_DIR)/.ver_check $@ || { \
rm -rf $(BUILD_DIR) $(STAGING_DIR) $(TOOLCHAIN_DIR) $(BUILD_DIR_TOOLCHAIN); \
mkdir -p $(TOOLCHAIN_DIR)/stamp; \
mv $(TMP_DIR)/.ver_check $@; \
}
$(TOOLCHAIN_DIR)/info.mk $(STAGING_DIR)/.prepared: $(TOOLCHAIN_DIR)/stamp/.ver_check
endif
# prerequisites for the individual targets
$(curdir)/ := .config prereq
$(curdir)//compile = $(STAGING_DIR)/.prepared $(TOOLCHAIN_DIR)/info.mk $(tools/stamp-compile)
ifndef DUMP_TARGET_DB
$(TOOLCHAIN_DIR)/stamp/.gcc-initial_installed:
endif
$(curdir)/install: $(curdir)/compile
$(eval $(call stampfile,$(curdir),toolchain,compile,$(TOOLCHAIN_DIR)/stamp/.gcc-initial_installed,,$(TOOLCHAIN_DIR)))
$(eval $(call stampfile,$(curdir),toolchain,check,$(TMP_DIR)/.build))
$(eval $(call subdir,$(curdir)))
|