lzma-loader improvements * update LzmaDecode.[ch] to 4.16 * speed up decompressing from flash * uses printf from lzma-loader of generic-2.6 target * initial support for flash bank switching
SVN-Revision: 7975master
parent
57f4fc91ed
commit
93a7dd0956
@ -0,0 +1,350 @@ |
||||
/*
|
||||
* Copyright (C) 2001 MontaVista Software Inc. |
||||
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net |
||||
* |
||||
* This program 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 2 of the License, or (at your |
||||
* option) any later version. |
||||
* |
||||
*/ |
||||
|
||||
#include "printf.h" |
||||
|
||||
extern void board_putc(int ch); |
||||
|
||||
/* this is the maximum width for a variable */ |
||||
#define LP_MAX_BUF 256 |
||||
|
||||
/* macros */ |
||||
#define IsDigit(x) ( ((x) >= '0') && ((x) <= '9') ) |
||||
#define Ctod(x) ( (x) - '0') |
||||
|
||||
/* forward declaration */ |
||||
static int PrintChar(char *, char, int, int); |
||||
static int PrintString(char *, char *, int, int); |
||||
static int PrintNum(char *, unsigned long, int, int, int, int, char, int); |
||||
|
||||
/* private variable */ |
||||
static const char theFatalMsg[] = "fatal error in lp_Print!"; |
||||
|
||||
/* -*-
|
||||
* A low level printf() function. |
||||
*/ |
||||
static void |
||||
lp_Print(void (*output)(void *, char *, int), |
||||
void * arg, |
||||
char *fmt, |
||||
va_list ap) |
||||
{ |
||||
|
||||
#define OUTPUT(arg, s, l) \ |
||||
{ if (((l) < 0) || ((l) > LP_MAX_BUF)) { \
|
||||
(*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \
|
||||
} else { \
|
||||
(*output)(arg, s, l); \
|
||||
} \
|
||||
} |
||||
|
||||
char buf[LP_MAX_BUF]; |
||||
|
||||
char c; |
||||
char *s; |
||||
long int num; |
||||
|
||||
int longFlag; |
||||
int negFlag; |
||||
int width; |
||||
int prec; |
||||
int ladjust; |
||||
char padc; |
||||
|
||||
int length; |
||||
|
||||
for(;;) { |
||||
{ |
||||
/* scan for the next '%' */ |
||||
char *fmtStart = fmt; |
||||
while ( (*fmt != '\0') && (*fmt != '%')) { |
||||
fmt ++; |
||||
} |
||||
|
||||
/* flush the string found so far */ |
||||
OUTPUT(arg, fmtStart, fmt-fmtStart); |
||||
|
||||
/* are we hitting the end? */ |
||||
if (*fmt == '\0') break; |
||||
} |
||||
|
||||
/* we found a '%' */ |
||||
fmt ++; |
||||
|
||||
/* check for long */ |
||||
if (*fmt == 'l') { |
||||
longFlag = 1; |
||||
fmt ++; |
||||
} else { |
||||
longFlag = 0; |
||||
} |
||||
|
||||
/* check for other prefixes */ |
||||
width = 0; |
||||
prec = -1; |
||||
ladjust = 0; |
||||
padc = ' '; |
||||
|
||||
if (*fmt == '-') { |
||||
ladjust = 1; |
||||
fmt ++; |
||||
} |
||||
|
||||
if (*fmt == '0') { |
||||
padc = '0'; |
||||
fmt++; |
||||
} |
||||
|
||||
if (IsDigit(*fmt)) { |
||||
while (IsDigit(*fmt)) { |
||||
width = 10 * width + Ctod(*fmt++); |
||||
} |
||||
} |
||||
|
||||
if (*fmt == '.') { |
||||
fmt ++; |
||||
if (IsDigit(*fmt)) { |
||||
prec = 0; |
||||
while (IsDigit(*fmt)) { |
||||
prec = prec*10 + Ctod(*fmt++); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/* check format flag */ |
||||
negFlag = 0; |
||||
switch (*fmt) { |
||||
case 'b': |
||||
if (longFlag) { |
||||
num = va_arg(ap, long int); |
||||
} else { |
||||
num = va_arg(ap, int); |
||||
} |
||||
length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0); |
||||
OUTPUT(arg, buf, length); |
||||
break; |
||||
|
||||
case 'd': |
||||
case 'D': |
||||
if (longFlag) { |
||||
num = va_arg(ap, long int); |
||||
} else { |
||||
num = va_arg(ap, int); |
||||
} |
||||
if (num < 0) { |
||||
num = - num; |
||||
negFlag = 1; |
||||
} |
||||
length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0); |
||||
OUTPUT(arg, buf, length); |
||||
break; |
||||
|
||||
case 'o': |
||||
case 'O': |
||||
if (longFlag) { |
||||
num = va_arg(ap, long int); |
||||
} else { |
||||
num = va_arg(ap, int); |
||||
} |
||||
length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0); |
||||
OUTPUT(arg, buf, length); |
||||
break; |
||||
|
||||
case 'u': |
||||
case 'U': |
||||
if (longFlag) { |
||||
num = va_arg(ap, long int); |
||||
} else { |
||||
num = va_arg(ap, int); |
||||
} |
||||
length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0); |
||||
OUTPUT(arg, buf, length); |
||||
break; |
||||
|
||||
case 'x': |
||||
if (longFlag) { |
||||
num = va_arg(ap, long int); |
||||
} else { |
||||
num = va_arg(ap, int); |
||||
} |
||||
length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0); |
||||
OUTPUT(arg, buf, length); |
||||
break; |
||||
|
||||
case 'X': |
||||
if (longFlag) { |
||||
num = va_arg(ap, long int); |
||||
} else { |
||||
num = va_arg(ap, int); |
||||
} |
||||
length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1); |
||||
OUTPUT(arg, buf, length); |
||||
break; |
||||
|
||||
case 'c': |
||||
c = (char)va_arg(ap, int); |
||||
length = PrintChar(buf, c, width, ladjust); |
||||
OUTPUT(arg, buf, length); |
||||
break; |
||||
|
||||
case 's': |
||||
s = (char*)va_arg(ap, char *); |
||||
length = PrintString(buf, s, width, ladjust); |
||||
OUTPUT(arg, buf, length); |
||||
break; |
||||
|
||||
case '\0': |
||||
fmt --; |
||||
break; |
||||
|
||||
default: |
||||
/* output this char as it is */ |
||||
OUTPUT(arg, fmt, 1); |
||||
} /* switch (*fmt) */ |
||||
|
||||
fmt ++; |
||||
} /* for(;;) */ |
||||
|
||||
/* special termination call */ |
||||
OUTPUT(arg, "\0", 1); |
||||
} |
||||
|
||||
|
||||
/* --------------- local help functions --------------------- */ |
||||
static int |
||||
PrintChar(char * buf, char c, int length, int ladjust) |
||||
{ |
||||
int i; |
||||
|
||||
if (length < 1) length = 1; |
||||
if (ladjust) { |
||||
*buf = c; |
||||
for (i=1; i< length; i++) buf[i] = ' '; |
||||
} else { |
||||
for (i=0; i< length-1; i++) buf[i] = ' '; |
||||
buf[length - 1] = c; |
||||
} |
||||
return length; |
||||
} |
||||
|
||||
static int |
||||
PrintString(char * buf, char* s, int length, int ladjust) |
||||
{ |
||||
int i; |
||||
int len=0; |
||||
char* s1 = s; |
||||
while (*s1++) len++; |
||||
if (length < len) length = len; |
||||
|
||||
if (ladjust) { |
||||
for (i=0; i< len; i++) buf[i] = s[i]; |
||||
for (i=len; i< length; i++) buf[i] = ' '; |
||||
} else { |
||||
for (i=0; i< length-len; i++) buf[i] = ' '; |
||||
for (i=length-len; i < length; i++) buf[i] = s[i-length+len]; |
||||
} |
||||
return length; |
||||
} |
||||
|
||||
static int |
||||
PrintNum(char * buf, unsigned long u, int base, int negFlag, |
||||
int length, int ladjust, char padc, int upcase) |
||||
{ |
||||
/* algorithm :
|
||||
* 1. prints the number from left to right in reverse form. |
||||
* 2. fill the remaining spaces with padc if length is longer than |
||||
* the actual length |
||||
* TRICKY : if left adjusted, no "0" padding. |
||||
* if negtive, insert "0" padding between "0" and number. |
||||
* 3. if (!ladjust) we reverse the whole string including paddings |
||||
* 4. otherwise we only reverse the actual string representing the num. |
||||
*/ |
||||
|
||||
int actualLength =0; |
||||
char *p = buf; |
||||
int i; |
||||
|
||||
do { |
||||
int tmp = u %base; |
||||
if (tmp <= 9) { |
||||
*p++ = '0' + tmp; |
||||
} else if (upcase) { |
||||
*p++ = 'A' + tmp - 10; |
||||
} else { |
||||
*p++ = 'a' + tmp - 10; |
||||
} |
||||
u /= base; |
||||
} while (u != 0); |
||||
|
||||
if (negFlag) { |
||||
*p++ = '-'; |
||||
} |
||||
|
||||
/* figure out actual length and adjust the maximum length */ |
||||
actualLength = p - buf; |
||||
if (length < actualLength) length = actualLength; |
||||
|
||||
/* add padding */ |
||||
if (ladjust) { |
||||
padc = ' '; |
||||
} |
||||
if (negFlag && !ladjust && (padc == '0')) { |
||||
for (i = actualLength-1; i< length-1; i++) buf[i] = padc; |
||||
buf[length -1] = '-'; |
||||
} else { |
||||
for (i = actualLength; i< length; i++) buf[i] = padc; |
||||
} |
||||
|
||||
|
||||
/* prepare to reverse the string */ |
||||
{ |
||||
int begin = 0; |
||||
int end; |
||||
if (ladjust) { |
||||
end = actualLength - 1; |
||||
} else { |
||||
end = length -1; |
||||
} |
||||
|
||||
while (end > begin) { |
||||
char tmp = buf[begin]; |
||||
buf[begin] = buf[end]; |
||||
buf[end] = tmp; |
||||
begin ++; |
||||
end --; |
||||
} |
||||
} |
||||
|
||||
/* adjust the string pointer */ |
||||
return length; |
||||
} |
||||
|
||||
static void printf_output(void *arg, char *s, int l) |
||||
{ |
||||
int i; |
||||
|
||||
// special termination call
|
||||
if ((l==1) && (s[0] == '\0')) return; |
||||
|
||||
for (i=0; i< l; i++) { |
||||
board_putc(s[i]); |
||||
if (s[i] == '\n') board_putc('\r'); |
||||
} |
||||
} |
||||
|
||||
void printf(char *fmt, ...) |
||||
{ |
||||
va_list ap; |
||||
va_start(ap, fmt); |
||||
lp_Print(printf_output, 0, fmt, ap); |
||||
va_end(ap); |
||||
} |
@ -0,0 +1,18 @@ |
||||
/*
|
||||
* Copyright (C) 2001 MontaVista Software Inc. |
||||
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net |
||||
* |
||||
* This program 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 2 of the License, or (at your |
||||
* option) any later version. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef _printf_h_ |
||||
#define _printf_h_ |
||||
|
||||
#include <stdarg.h> |
||||
void printf(char *fmt, ...); |
||||
|
||||
#endif /* _printf_h_ */ |
Loading…
Reference in new issue