📄 goodies.c
字号:
/*
* ApBUILDER CODE FILE - Intel Corporation
*
*
* Purpose: Contains source code for many routines commonly found in a 'C' run-time library.
* These routines are extra, and are provided here only as possible building blocks
* for your programs. On occasion, you may not want a standard routine from a run-time
* library. Here we provide you with some extra source code to modify as you see fit,
* or just to learn from.
*
* The Software is provided "AS IS."
*
* LIMITATION OF LIABILITY: NEITHER INTEL NOR ITS VENDORS OR AGENTS
* SHALL BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
* INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
* OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* While we have made every attempt to completely test this code, we highly recommend that
* you personally test it completely prior to actual inclusion in your project.
*
* Compiler: Developed using Compass251 from Production Languages corporation.
*
* Ext Packages: None
*
* Author: Brad B.
*
* Revisions:
*
*
*/
int abs(int arg)
{
return( arg<0 ? -arg : arg );
}
long labs(long arg)
{
return(arg<0 ? -arg : arg);
}
long atol(const char *p)
{
register long n = 0;
register char f = 0;
for(;;p++)
{
switch(*p)
{
case ' ':
case '\t':
continue;
case '-':
f++;
case '+':
p++;
}
break;
}
while(*p >= '0' && *p <= '9')
{
n = n*10 + *p++ - '0';
}
return(f? -n: n);
}
void int_to_string (char far * str, int d)
{
int t=d;
while (t > 0)
{
t /= 10;
str++;
}
*str = 0 ;
while (d > 0)
{
*(--str) = (char)(d % 10) + '0';
d /= 10;
}
}
int isalpha(int c)
{
if ((((c|=0x20)>='a') && (c<='z')))
{
return 1;
}
return 0;
}
int isalnum(int c)
{
if (((c>='0')&&(c<='9'))||(((c|=0x20)>='a') && (c<='z')))
{
return 1;
}
return 0;
}
int atoi(const char *p)
{
register int n = 0;
register char f = 0;
for(;;p++)
{
switch(*p)
{
case ' ':
case '\t':
continue;
case '-':
f++;
case '+':
p++;
}
break;
}
while(*p >= '0' && *p <= '9')
{
n = n*10 + *p++ - '0';
}
return(f? -n: n);
}
int isascii(int c)
{
return !(c & (~0x7f));
}
int iscntrl(int c)
{
if ((((unsigned int)c) < 0x20) || (c == 0x7f))
{
return 1;
}
return 0;
}
int isdigit(int c)
{
if ((c>='0')&&(c<='9'))
{
return 1;
}
return 0;
}
int isgraph(int c)
{
if ((c > 0x20) && (c < 0x7f))
{
return 1;
}
return 0;
}
int islower(int c)
{
if ((c>='a')&&(c<='z'))
{
return 1;
}
return 0;
}
int isupper(int c)
{
if ((c >= 'A') && (c <= 'Z'))
{
return 1;
}
return 0;
}
int isprint(int c)
{
if ((c >= 0x20) && (c < 0x7f))
{
return 1;
}
return 0;
}
int isspace(int c)
{
if (c == ' ' || ((c >= 9) && (c <= 13)))
{
return 1;
}
return 0;
}
int isxdigit(int c)
{
if (((c >= '0') && (c <= '9')) || (((c |= 0x20) >= 'a') && (c <= 'f')))
{
return 1;
}
return 0;
}
int tolower(int c)
{
if ((c >= 'A') && (c <= 'Z'))
{
return (c + 'a' - 'A');
}
return c;
}
int toupper(int c)
{
if ((c >= 'a') && (c <= 'z'))
{
return (c + 'A' - 'a');
}
return c;
}
int strlen( char *s)
{
int x = 0;
while ( *s != 0 )
{
s++;
x++;
}
return(x);
}
/* used for printf and sprintf by the format() function. */
#define MAXWIDTH 14
#define NUMWIDTH 14
void *fmtcvt( void *ap, int base, char *cp, int len)
{
long val;
static char digits[]="0123456789abcdef";
if ( len == sizeof(long) )
{
val = *(long *)ap;
}
else if ( base > 0 )
{
val = *(unsigned int *)ap;
}
else
{
val = *(int *)ap;
}
len = 0;
if ( base < 0 )
{
base = -base;
if ( val < 0L )
{
val = -val;
len = 1;
}
}
do
{
*--cp = digits[ (char)( val % base ) ];
} while ( ( val /= base ) != 0);
if ( len )
{
*--cp = '-';
}
return cp;
}
/*
Function: format()
Used for printf and sprintf.
This function does all the real work of parsing your format string.
You may need to change a couple things if your compiler doesn't support this
syntax.
*/
int format( void (*place_char)( int ), register char *fmt, void *ap)
{
register char c;
int charcount, rj, fillc, maxwidth, width, i, k;
char *cp; char s[MAXWIDTH+1];
charcount = 0;
while ( ( c = *fmt++ ) != 0 )
{
if ( c == '%' )
{
s[NUMWIDTH] = 0;
rj = 1;
fillc = ' ';
maxwidth = 10000;
if ( (c = *fmt++ ) == '-')
{
rj = 0;
c = *fmt++;
}
if ( c == '0' )
{
fillc = '0';
c = *fmt++;
}
if ( c == '*' )
{
width = *( (int *)ap );
ap = (int *)ap + 1;
c = *fmt++;
}
else
{
for ( width = 0 ; isdigit(c) ; c = *fmt++ )
{
width = width * 10 + c - '0';
}
}
if ( c == '.' )
{
if ( ( c = *fmt++ ) == '*' )
{
maxwidth = *( (int *)ap );
ap = (int *)ap + 1;
c = *fmt++;
}
else
{
for ( maxwidth = 0 ; isdigit(c) ; c = *fmt++ )
{
maxwidth = maxwidth * 10 + c - '0';
}
}
}
i = sizeof( int );
if ( c == 'l' )
{
c = *fmt++;
i = sizeof(long);
}
else if ( c == 'h' )
{
c = *fmt++;
}
switch ( c )
{
case 'o':
k = 8;
goto convert_it;
case 'u':
k = 10;
goto convert_it;
case 'x':
k = 16;
goto convert_it;
case 'd':
k = -10;
convert_it:
cp = (char *)fmtcvt( ap, k, s + NUMWIDTH, i );
ap = (char *)ap + i;
break;
case 's':
cp = *( ( char **) ap );
ap = (char **)ap + 1;
i = strlen( cp );
goto we_have_length;
case 'c':
c = *((char *)ap + 1);
ap = (int *)ap + 1;
default:
*( cp = s + NUMWIDTH - 1 ) = c;
break;
}
i = ( s + NUMWIDTH ) - cp;
we_have_length:
if ( i > maxwidth )
{
i = maxwidth;
}
if ( rj )
{
if ( ( *cp == '-' || *cp == '+') && fillc == '0' )
{
--width;
place_char( *cp++ );
}
for (; width-- > i ; ++charcount)
{
place_char( fillc );
}
}
for ( k = 0 ; *cp && k < maxwidth ; ++k )
{
place_char( *cp++ );
}
charcount += k;
if ( !rj )
{
for ( ; width-- > i ; ++charcount )
{
place_char( ' ' );
}
}
}
else
{
place_char( c );
++charcount;
}
}
return charcount; /* return amount of characters converted */
}
/* used for printf and sprintf */
void putchar(int c)
{
/* here's where you output your character to hardware.
This could be a screen, printer, modem, etc.. */
}
/*
Function: printf()
This function should closely mimic a standard C-runtime library printf routine.
Final ouput of characters is determined by the putchar() function, which has not
been filled in, since we do not know where you will be printing characters to...
*/
int printf( const char *fmt, ... )
{
void *ap;
ap = (void *)( (char *)( &fmt ) + sizeof( fmt ) );
return format( putchar, fmt, ap );
}
/*
Function: sprintf()
Works like printf(), but prints to a buffer of your choosing instead of a stream.
*/
static char *buff;
static int spsub( int c )
{
return ( *buff++ = c );
}
int sprintf( char *buf, const char *fmt, ... )
{
register int i; void *ap;
ap = (void *)( (char *)( &fmt ) + sizeof( fmt ) );
buff = buf;
i = format( spsub, fmt, ap );
*buff = '\0';
return i;
}
/* Pseudo Random number generation */
static unsigned long next = 1;
int rand(void)
{
next = next * 1103515245 + 12345;
return(unsigned int)(next/65536) % 32768;
}
void srand(unsigned int seed)
{
next = seed;
}
/* String to Long integer conversion */
long strtol(const char *str, char **ptr, int base)
{
long result = 0;
register int ch;
unsigned char neg = FALSE;
char *str1 = str;
short found = 0;
short x = 0;
while (isspace(*str1)) /* read all spaces */
{
str1++;
}
if (*str1 == '-') /* Look for negative number */
{
neg = TRUE;
str1++;
}
else if (*str1 == '+') /* Look for positive number */
{
str1++;
}
/* if base not specified, figure it out */
if (base <= 1 || base > 36)
{
/* is it a hex number ? */
if (*str1 == '0' && (str1[1]== 'x' || str1[1]== 'X'))
{
str1 += 2;
base = 16;
x = 1;
}
/* perhaps Octal */
else if (*str1 == '0')
{
base = 8;
}
/* guess its base 10 */
else
{
base = 10;
}
}
/* If hex base specified.. */
else if (base == 16)
{
if (*str1 == '0' && (str1[1]== 'x' || str1[1]== 'X'))
{
str1 += 2;
x = 1;
}
}
for (;;)
{
ch = *(str1++);
if (isdigit(ch))
{
if (ch - '0' >= base)
{
break;
}
ch -= '0';
found = 1;
}
else if (islower(ch))
{
if (ch - 'a' + 10 >= base)
{
break;
}
ch -= 'a' - 10;
found = 1;
}
else if (isupper(ch))
{
if (ch - 'A' + 10 >= base)
{
break;
}
ch -= 'A' - 10;
found = 1;
}
else
break;
result = base * result + ch;
if(result < 0)
{
/* out of range error here.. Do what you need to with it */
return(neg ? -2147483647 : 2147483647);
}
}
if (ptr != (char **)NULL) /* pointer to remaining characters */
{
if (found)
{
*ptr = str1 - 1;
}
else if (x)
{
*ptr = str1 - 2;
}
else
{
*ptr = str;
}
}
return(neg ? -(long)result : (long)result);
}
/* Quick Sorting Stuff */
typedef unsigned int size_t;
/* Swap two elements.. Used for qsort */
static void _swap(const void *base, size_t sizep, int first, int second)
{
register char temp;
register char *one;
register char *two;
register size_t size = sizep; /* To speed up access to the value */
one = (char *)(base) + first*size; /* pointer to 'first' element in 'base' array */
two = (char *)(base) + second*size; /* pointer to 'second' element in 'base' array */
while(size-- > 0)
{
temp = one[size];
one[size] = two[size];
two[size] = temp;
}
}
/*
Function: qsort()
Standard Quick-sort algorithm.
Sorts elements from 'base' array, of np elements in length, each of sizep size.
You must supply the comparison function for the elements.. Standard implementation.
*/
void qsort(const void *base, size_t np, size_t sizep, int (*cmp)(const void *, const void *))
{
register int i;
register size_t last;
register size_t size = sizep; /* To speed up access to the value */
register size_t n = np; /* To speed up access to the value */
if(n <= 1) /* Do nothing when array smaller than two elements */
{
return;
}
_swap(base, size, 0, n/2);
last = 0;
for(i=1; i<n; i++)
{
if(cmp(((char *)base)+i*size, (char *)base) < 0)
{
_swap(base, size, ++last, i);
}
}
_swap(base, size, 0, last);
qsort(base, last, size, cmp);
qsort((char *)(base)+size*(last+1), n-(last+1), size, cmp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -