The tests are taken almost verbatim from the open source project PicoC. It can be found at https://code.google.com/p/picoc/. The tests range from very simple/trivial ones to more complicated. My view is that the more tests the better. Without tests like this I was very reluctant to make any changes to tcc for the fear of breaking things. The tests pass on Win32, OSX, Linux x86 and x86_64. One or two tests fail on each platform due to differences in the runtime library.
		
			
				
	
	
		
			266 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			266 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* example from http://barnyard.syr.edu/quickies/led.c */
 | |
| 
 | |
| /* led.c: print out number as if on 7 line led display. I.e., write integer
 | |
|    given on command line like this:  
 | |
|       _   _       _  
 | |
|    |  _|  _| |_| |_  
 | |
|    | |_   _|   |  _| etc.
 | |
| 
 | |
|    We assume the terminal behaves like a classical teletype. So the top
 | |
|    lines of all digits have to be printed first, then the middle lines of
 | |
|    all digits, etc.
 | |
| 
 | |
|    By Terry R. McConnell
 | |
| 
 | |
| compile: cc -o led led.c
 | |
| 
 | |
| If you just want to link in the subroutine print_led that does all the
 | |
| work, compile with -DNO_MAIN, and declare the following in any source file
 | |
| that uses the call:
 | |
| 
 | |
| extern void print_led(unsigned long x, char *buf);
 | |
| 
 | |
| Bug: you cannot call repeatedly to print more than one number to a line.
 | |
| That would require curses or some other terminal API that allows moving the
 | |
| cursor to a previous line.
 | |
| 
 | |
| */
 | |
| 
 | |
| 
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| 
 | |
| #define MAX_DIGITS 32
 | |
| #define NO_MAIN
 | |
| 
 | |
| 
 | |
| /* Print the top line of the digit d into buffer. 
 | |
|    Does not null terminate buffer. */
 | |
| 
 | |
| void topline(int d, char *p){
 | |
| 
 | |
|    *p++ = ' ';
 | |
|    switch(d){
 | |
| 
 | |
|       /* all these have _ on top line */
 | |
| 
 | |
|       case 0:
 | |
|       case 2:
 | |
|       case 3:
 | |
|       case 5:
 | |
|       case 7:
 | |
|       case 8:
 | |
|       case 9:
 | |
|          *p++ = '_';
 | |
|          break;
 | |
|       default:
 | |
|          *p++=' ';
 | |
| 
 | |
|    }
 | |
|    *p++=' ';
 | |
| }
 | |
| 
 | |
| /* Print the middle line of the digit d into the buffer. 
 | |
|    Does not null terminate. */
 | |
| 
 | |
| void midline(int d, char *p){
 | |
| 
 | |
|    switch(d){
 | |
| 
 | |
|       /* those that have leading | on middle line */
 | |
| 
 | |
|       case 0:
 | |
|       case 4:
 | |
|       case 5:
 | |
|       case 6:
 | |
|       case 8:
 | |
|       case 9:
 | |
|          *p++='|';
 | |
|          break;
 | |
|       default:
 | |
|          *p++=' ';	
 | |
|    }
 | |
|    switch(d){
 | |
| 
 | |
|       /* those that have _ on middle line */
 | |
| 
 | |
|       case 2:
 | |
|       case 3:
 | |
|       case 4:
 | |
|       case 5:
 | |
|       case 6:
 | |
|       case 8:
 | |
|       case 9:
 | |
|          *p++='_';
 | |
|          break;
 | |
|       default:
 | |
|          *p++=' ';
 | |
| 
 | |
|    }
 | |
|    switch(d){
 | |
| 
 | |
|       /* those that have closing | on middle line */
 | |
| 
 | |
|       case 0:
 | |
|       case 1:
 | |
|       case 2:
 | |
|       case 3:
 | |
|       case 4:
 | |
|       case 7:
 | |
|       case 8:
 | |
|       case 9:
 | |
|          *p++='|';
 | |
|          break;
 | |
|       default:
 | |
|          *p++=' ';
 | |
| 
 | |
|    }
 | |
| }
 | |
| 
 | |
| /* Print the bottom line of the digit d. Does not null terminate. */
 | |
| 
 | |
| void botline(int d, char *p){
 | |
| 
 | |
| 
 | |
|    switch(d){
 | |
| 
 | |
|       /* those that have leading | on bottom line */
 | |
| 
 | |
|       case 0:
 | |
|       case 2:
 | |
|       case 6:
 | |
|       case 8:
 | |
|          *p++='|';
 | |
|          break;
 | |
|       default:
 | |
|          *p++=' ';	
 | |
|    }
 | |
|    switch(d){
 | |
| 
 | |
|       /* those that have _ on bottom line */
 | |
| 
 | |
|       case 0:
 | |
|       case 2:
 | |
|       case 3:
 | |
|       case 5:
 | |
|       case 6:
 | |
|       case 8:
 | |
|          *p++='_';
 | |
|          break;
 | |
|       default:
 | |
|          *p++=' ';
 | |
| 
 | |
|    }
 | |
|    switch(d){
 | |
| 
 | |
|       /* those that have closing | on bottom line */
 | |
| 
 | |
|       case 0:
 | |
|       case 1:
 | |
|       case 3:
 | |
|       case 4:
 | |
|       case 5:
 | |
|       case 6:
 | |
|       case 7:
 | |
|       case 8:
 | |
|       case 9:
 | |
|          *p++='|';
 | |
|          break;
 | |
|       default:
 | |
|          *p++=' ';
 | |
| 
 | |
|    }
 | |
| }
 | |
| 
 | |
| /* Write the led representation of integer to string buffer. */
 | |
| 
 | |
| void print_led(unsigned long x, char *buf)
 | |
| {
 | |
| 
 | |
|    int i=0,n;
 | |
|    static int d[MAX_DIGITS];
 | |
| 
 | |
| 
 | |
|    /* extract digits from x */
 | |
| 
 | |
|    n = ( x == 0L ? 1 : 0 );  /* 0 is a digit, hence a special case */
 | |
| 
 | |
|    while(x){
 | |
|       d[n++] = (int)(x%10L);
 | |
|       if(n >= MAX_DIGITS)break;
 | |
|       x = x/10L;
 | |
|    }
 | |
| 
 | |
|    /* print top lines of all digits */
 | |
| 
 | |
|    for(i=n-1;i>=0;i--){
 | |
|       topline(d[i],buf);
 | |
|       buf += 3;
 | |
|       *buf++=' ';
 | |
|    }
 | |
|    *buf++='\n'; /* move teletype to next line */
 | |
| 
 | |
|    /* print middle lines of all digits */
 | |
| 
 | |
|    for(i=n-1;i>=0;i--){
 | |
|       midline(d[i],buf);
 | |
|       buf += 3;
 | |
|       *buf++=' ';
 | |
|    }
 | |
|    *buf++='\n';
 | |
| 
 | |
|    /* print bottom lines of all digits */
 | |
| 
 | |
|    for(i=n-1;i>=0;i--){
 | |
|       botline(d[i],buf);
 | |
|       buf += 3;
 | |
|       *buf++=' ';
 | |
|    }
 | |
|    *buf++='\n';
 | |
|    *buf='\0';
 | |
| }
 | |
| 
 | |
| int main()
 | |
| {
 | |
|    char buf[5*MAX_DIGITS];
 | |
|    print_led(1234567, buf);
 | |
|    printf("%s\n",buf);
 | |
| 
 | |
|    return 0;
 | |
| }
 | |
| 
 | |
| #ifndef NO_MAIN
 | |
| int main(int argc, char **argv)
 | |
| {
 | |
| 
 | |
|    int i=0,n;
 | |
|    long x;
 | |
|    static int d[MAX_DIGITS];
 | |
|    char buf[5*MAX_DIGITS];
 | |
| 
 | |
|    if(argc != 2){
 | |
|       fprintf(stderr,"led: usage: led integer\n");
 | |
|       return 1;
 | |
|    }
 | |
| 
 | |
|    /* fetch argument from command line */
 | |
| 
 | |
|    x = atol(argv[1]);
 | |
| 
 | |
|    /* sanity check */
 | |
| 
 | |
|    if(x<0){
 | |
|       fprintf(stderr,"led: %d must be non-negative\n",x);
 | |
|       return 1;
 | |
|    }
 | |
| 
 | |
|    print_led(x,buf);
 | |
|    printf("%s\n",buf);
 | |
| 
 | |
|    return 0;
 | |
| 
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
 |