/* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. ChibiOS/RT is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. ChibiOS/RT 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. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #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)))