add libc testcase.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1061 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
bernard.xiong@gmail.com
2010-11-18 11:31:54 +00:00
parent 019b654201
commit d9cb84f484
15 changed files with 1575 additions and 0 deletions

8
examples/libc/SConscript Normal file
View File

@@ -0,0 +1,8 @@
Import('env')
src_local = Glob('*.c')
# The set of source files associated with this SConscript file.
obj = env.Object(src_local)
Return('obj')

56
examples/libc/dirent.c Normal file
View File

@@ -0,0 +1,56 @@
/*
* dirent.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
#include <dirent.h>
int libc_dirent()
{
DIR * dirp;
long int save3 = 0;
long int cur;
int i = 0;
int result = 0;
struct dirent *dp;
dirp = opendir("/");
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
{
/* save position 3 (after fourth entry) */
if (i++ == 3)
save3 = telldir(dirp);
printf("%s\n", dp->d_name);
/* stop at 400 (just to make sure dirp->__offset and dirp->__size are
scrambled */
if (i == 400)
break;
}
printf("going back past 4-th entry...\n");
/* go back to saved entry */
seekdir(dirp, save3);
/* Check whether telldir equals to save3 now. */
cur = telldir(dirp);
if (cur != save3)
{
printf("seekdir (d, %ld); telldir (d) == %ld\n", save3, cur);
result = 1;
}
/* print remaining files (3-last) */
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
printf("%s\n", dp->d_name);
closedir(dirp);
return result;
}
FINSH_FUNCTION_EXPORT(libc_dirent, dirent test for libc);

18
examples/libc/env.c Normal file
View File

@@ -0,0 +1,18 @@
/*
* env.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int libc_env()
{
printf("PATH=%s\n", getenv("PATH"));
putenv("foo=bar");
printf("foo=%s\n", getenv("foo"));
return 0;
}
FINSH_FUNCTION_EXPORT(libc_env, get/set_env test);

37
examples/libc/ex1.c Normal file
View File

@@ -0,0 +1,37 @@
/* Creates two threads, one printing 10000 "a"s, the other printing
10000 "b"s.
Illustrates: thread creation, thread joining. */
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include "pthread.h"
static void *process(void * arg)
{
int i;
printf("Starting process %s\n", (char *)arg);
for (i = 0; i < 10000; i++)
write(1, (char *) arg, 1);
return NULL;
}
#define sucfail(r) (r != 0 ? "failed" : "succeeded")
int libc_ex1(void)
{
int pret, ret = 0;
pthread_t th_a, th_b;
void *retval;
ret += (pret = pthread_create(&th_a, NULL, process, (void *)"a"));
printf("create a %s %d\n", sucfail(pret), pret);
ret += (pret = pthread_create(&th_b, NULL, process, (void *)"b"));
printf("create b %s %d\n", sucfail(pret), pret);
ret += (pret = pthread_join(th_a, &retval));
printf("join a %s %d\n", sucfail(pret), pret);
ret += (pret = pthread_join(th_b, &retval));
printf("join b %s %d\n", sucfail(pret), pret);
return ret;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex1, example 1 for libc);

114
examples/libc/ex2.c Normal file
View File

@@ -0,0 +1,114 @@
/* The classic producer-consumer example.
Illustrates mutexes and conditions.
All integers between 0 and 9999 should be printed exactly twice,
once to the right of the arrow and once to the left. */
#include <stdio.h>
#include "pthread.h"
#define BUFFER_SIZE 16
/* Circular buffer of integers. */
struct prodcons {
int buffer[BUFFER_SIZE]; /* the actual data */
pthread_mutex_t lock; /* mutex ensuring exclusive access to buffer */
int readpos, writepos; /* positions for reading and writing */
pthread_cond_t notempty; /* signaled when buffer is not empty */
pthread_cond_t notfull; /* signaled when buffer is not full */
};
/* Initialize a buffer */
static void init(struct prodcons * b)
{
pthread_mutex_init(&b->lock, NULL);
pthread_cond_init(&b->notempty, NULL);
pthread_cond_init(&b->notfull, NULL);
b->readpos = 0;
b->writepos = 0;
}
/* Store an integer in the buffer */
static void put(struct prodcons * b, int data)
{
pthread_mutex_lock(&b->lock);
/* Wait until buffer is not full */
while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) {
pthread_cond_wait(&b->notfull, &b->lock);
/* pthread_cond_wait reacquired b->lock before returning */
}
/* Write the data and advance write pointer */
b->buffer[b->writepos] = data;
b->writepos++;
if (b->writepos >= BUFFER_SIZE) b->writepos = 0;
/* Signal that the buffer is now not empty */
pthread_cond_signal(&b->notempty);
pthread_mutex_unlock(&b->lock);
}
/* Read and remove an integer from the buffer */
static int get(struct prodcons * b)
{
int data;
pthread_mutex_lock(&b->lock);
/* Wait until buffer is not empty */
while (b->writepos == b->readpos) {
pthread_cond_wait(&b->notempty, &b->lock);
}
/* Read the data and advance read pointer */
data = b->buffer[b->readpos];
b->readpos++;
if (b->readpos >= BUFFER_SIZE) b->readpos = 0;
/* Signal that the buffer is now not full */
pthread_cond_signal(&b->notfull);
pthread_mutex_unlock(&b->lock);
return data;
}
/* A test program: one thread inserts integers from 1 to 10000,
the other reads them and prints them. */
#define OVER (-1)
struct prodcons buffer;
static void * producer(void * data)
{
int n;
for (n = 0; n < 10000; n++) {
printf("%d --->\n", n);
put(&buffer, n);
}
put(&buffer, OVER);
return NULL;
}
static void * consumer(void * data)
{
int d;
while (1) {
d = get(&buffer);
if (d == OVER) break;
printf("---> %d\n", d);
}
return NULL;
}
int libc_ex2(void)
{
pthread_t th_a, th_b;
void * retval;
init(&buffer);
/* Create the threads */
pthread_create(&th_a, NULL, producer, 0);
pthread_create(&th_b, NULL, consumer, 0);
/* Wait until producer and consumer finish. */
pthread_join(th_a, &retval);
pthread_join(th_b, &retval);
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex2, example 2 for libc);

154
examples/libc/ex3.c Normal file
View File

@@ -0,0 +1,154 @@
/* Multi-thread searching.
Illustrates: thread cancellation, cleanup handlers. */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
/* Defines the number of searching threads */
#define NUM_THREADS 5
/* Function prototypes */
void *search(void *);
void print_it(void *);
/* Global variables */
pthread_t threads[NUM_THREADS];
pthread_mutex_t lock;
int tries;
volatile int started;
int libc_ex3()
{
int i;
int pid;
/* create a number to search for */
pid = getpid();
printf("Searching for the number = %d...\n", pid);
/* Initialize the mutex lock */
pthread_mutex_init(&lock, NULL);
/* Create the searching threads */
for (started=0; started<NUM_THREADS; started++)
pthread_create(&threads[started], NULL, search, (void *)pid);
/* Wait for (join) all the searching threads */
for (i=0; i<NUM_THREADS; i++)
pthread_join(threads[i], NULL);
printf("It took %d tries to find the number.\n", tries);
/* Exit the program */
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex3, example 5 for libc);
/* This is the cleanup function that is called
when the threads are cancelled */
void print_it(void *arg)
{
int *try = (int *) arg;
pthread_t tid;
/* Get the calling thread's ID */
tid = pthread_self();
/* Print where the thread was in its search when it was cancelled */
printf("Thread %lx was canceled on its %d try.\n", tid, *try);
}
/* This is the search routine that is executed in each thread */
void *search(void *arg)
{
int num = (int) arg;
int i, j, ntries;
pthread_t tid;
/* get the calling thread ID */
tid = pthread_self();
/* use the thread ID to set the seed for the random number generator */
/* Since srand and rand are not thread-safe, serialize with lock */
/* Try to lock the mutex lock --
if locked, check to see if the thread has been cancelled
if not locked then continue */
while (pthread_mutex_trylock(&lock) == EBUSY)
pthread_testcancel();
srand((int)tid);
i = rand() & 0xFFFFFF;
pthread_mutex_unlock(&lock);
ntries = 0;
/* Set the cancellation parameters --
- Enable thread cancellation
- Defer the action of the cancellation */
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
while (started < NUM_THREADS)
sched_yield ();
/* Push the cleanup routine (print_it) onto the thread
cleanup stack. This routine will be called when the
thread is cancelled. Also note that the pthread_cleanup_push
call must have a matching pthread_cleanup_pop call. The
push and pop calls MUST be at the same lexical level
within the code */
/* Pass address of `ntries' since the current value of `ntries' is not
the one we want to use in the cleanup function */
pthread_cleanup_push(print_it, (void *)&ntries);
/* Loop forever */
while (1) {
i = (i + 1) & 0xFFFFFF;
ntries++;
/* Does the random number match the target number? */
if (num == i) {
/* Try to lock the mutex lock --
if locked, check to see if the thread has been cancelled
if not locked then continue */
while (pthread_mutex_trylock(&lock) == EBUSY)
pthread_testcancel();
/* Set the global variable for the number of tries */
tries = ntries;
printf("Thread %lx found the number!\n", tid);
/* Cancel all the other threads */
for (j=0; j<NUM_THREADS; j++)
if (threads[j] != tid) pthread_cancel(threads[j]);
/* Break out of the while loop */
break;
}
/* Every 100 tries check to see if the thread has been cancelled. */
if (ntries % 100 == 0) {
pthread_testcancel();
}
}
/* The only way we can get here is when the thread breaks out
of the while loop. In this case the thread that makes it here
has found the number we are looking for and does not need to run
the thread cleanup function. This is why the pthread_cleanup_pop
function is called with a 0 argument; this will pop the cleanup
function off the stack without executing it */
pthread_cleanup_pop(0);
return((void *)0);
}

108
examples/libc/ex4.c Normal file
View File

@@ -0,0 +1,108 @@
/* Making a library function that uses static variables thread-safe.
Illustrates: thread-specific data, pthread_once(). */
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
/* This is a typical example of a library function that uses
static variables to accumulate results between calls.
Here, it just returns the concatenation of all string arguments
that were given to it. */
#if 0
char * str_accumulate(char * s)
{
static char accu[1024] = { 0 };
strcat(accu, s);
return accu;
}
#endif
/* Of course, this cannot be used in a multi-threaded program
because all threads store "accu" at the same location.
So, we'll use thread-specific data to have a different "accu"
for each thread. */
/* Key identifying the thread-specific data */
static pthread_key_t str_key;
/* "Once" variable ensuring that the key for str_alloc will be allocated
exactly once. */
static pthread_once_t str_alloc_key_once = PTHREAD_ONCE_INIT;
/* Forward functions */
static void str_alloc_key(void);
static void str_alloc_destroy_accu(void * accu);
/* Thread-safe version of str_accumulate */
char * str_accumulate(const char * s)
{
char * accu;
/* Make sure the key is allocated */
pthread_once(&str_alloc_key_once, str_alloc_key);
/* Get the thread-specific data associated with the key */
accu = (char *) pthread_getspecific(str_key);
/* It's initially NULL, meaning that we must allocate the buffer first. */
if (accu == NULL) {
accu = malloc(1024);
if (accu == NULL) return NULL;
accu[0] = 0;
/* Store the buffer pointer in the thread-specific data. */
pthread_setspecific(str_key, (void *) accu);
printf("Thread %lx: allocating buffer at %p\n", pthread_self(), accu);
}
/* Now we can use accu just as in the non thread-safe code. */
strcat(accu, s);
return accu;
}
/* Function to allocate the key for str_alloc thread-specific data. */
static void str_alloc_key(void)
{
pthread_key_create(&str_key, str_alloc_destroy_accu);
printf("Thread %lx: allocated key %d\n", pthread_self(), str_key);
}
/* Function to free the buffer when the thread exits. */
/* Called only when the thread-specific data is not NULL. */
static void str_alloc_destroy_accu(void * accu)
{
printf("Thread %lx: freeing buffer at %p\n", pthread_self(), accu);
free(accu);
}
/* Test program */
static void *process(void * arg)
{
char *res;
res = str_accumulate("Result of ");
res = str_accumulate((char *) arg);
res = str_accumulate(" thread");
printf("Thread %lx: \"%s\"\n", pthread_self(), res);
return NULL;
}
int libc_ex4()
{
char * res;
pthread_t th1, th2;
// res = str_accumulate("Result of ");
pthread_create(&th1, NULL, process, (void *) "first");
pthread_create(&th2, NULL, process, (void *) "second");
// res = str_accumulate("initial thread");
printf("Thread %lx: \"%s\"\n", pthread_self(), res);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex4, example 4 for libc);

105
examples/libc/ex5.c Normal file
View File

@@ -0,0 +1,105 @@
/* The classic producer-consumer example, implemented with semaphores.
All integers between 0 and 9999 should be printed exactly twice,
once to the right of the arrow and once to the left. */
#include <stdio.h>
#include "pthread.h"
#include "semaphore.h"
#define BUFFER_SIZE 16
/* Circular buffer of integers. */
struct prodcons {
int buffer[BUFFER_SIZE]; /* the actual data */
int readpos, writepos; /* positions for reading and writing */
sem_t sem_read; /* number of elements available for reading */
sem_t sem_write; /* number of locations available for writing */
};
/* Initialize a buffer */
void init(struct prodcons * b)
{
sem_init(&b->sem_write, 0, BUFFER_SIZE - 1);
sem_init(&b->sem_read, 0, 0);
b->readpos = 0;
b->writepos = 0;
}
/* Store an integer in the buffer */
void put(struct prodcons * b, int data)
{
/* Wait until buffer is not full */
sem_wait(&b->sem_write);
/* Write the data and advance write pointer */
b->buffer[b->writepos] = data;
b->writepos++;
if (b->writepos >= BUFFER_SIZE) b->writepos = 0;
/* Signal that the buffer contains one more element for reading */
sem_post(&b->sem_read);
}
/* Read and remove an integer from the buffer */
int get(struct prodcons * b)
{
int data;
/* Wait until buffer is not empty */
sem_wait(&b->sem_read);
/* Read the data and advance read pointer */
data = b->buffer[b->readpos];
b->readpos++;
if (b->readpos >= BUFFER_SIZE) b->readpos = 0;
/* Signal that the buffer has now one more location for writing */
sem_post(&b->sem_write);
return data;
}
/* A test program: one thread inserts integers from 1 to 10000,
the other reads them and prints them. */
#define OVER (-1)
struct prodcons buffer;
static void *producer(void * data)
{
int n;
for (n = 0; n < 10000; n++) {
printf("%d --->\n", n);
put(&buffer, n);
}
put(&buffer, OVER);
return NULL;
}
static void *consumer(void * data)
{
int d;
while (1) {
d = get(&buffer);
if (d == OVER) break;
printf("---> %d\n", d);
}
return NULL;
}
int libc_ex5(void)
{
pthread_t th_a, th_b;
void * retval;
init(&buffer);
/* Create the threads */
pthread_create(&th_a, NULL, producer, 0);
pthread_create(&th_b, NULL, consumer, 0);
/* Wait until producer and consumer finish. */
pthread_join(th_a, &retval);
pthread_join(th_b, &retval);
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex5, example 5 for libc);

37
examples/libc/ex6.c Normal file
View File

@@ -0,0 +1,37 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define usleep rt_thread_sleep
static void *test_thread(void *v_param) {
return NULL;
}
int libc_ex6(void) {
unsigned long count;
setvbuf(stdout, NULL, _IONBF, 0);
for (count = 0; count < 2000; ++count) {
pthread_t thread;
int status;
status = pthread_create(&thread, NULL, test_thread, NULL);
if (status != 0) {
printf("status = %d, count = %lu: %s\n", status, count, strerror(
errno));
return 1;
} else {
printf("count = %lu\n", count);
}
/* pthread_detach (thread); */
pthread_join(thread, NULL);
usleep(10);
}
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex6, example 6 for libc);

101
examples/libc/ex7.c Normal file
View File

@@ -0,0 +1,101 @@
/* ex7
*
* Test case that illustrates a timed wait on a condition variable.
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#define usleep rt_thread_sleep
/* Our event variable using a condition variable contruct. */
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
int flag;
} event_t;
/* Global event to signal main thread the timeout of the child thread. */
event_t main_event;
static void *test_thread(void *ms_param) {
int status = 0;
event_t foo;
struct timespec time;
struct timeval now;
long ms = (long) ms_param;
/* initialize cond var */
pthread_cond_init(&foo.cond, NULL);
pthread_mutex_init(&foo.mutex, NULL);
foo.flag = 0;
/* set the time out value */
printf("waiting %ld ms ...\n", ms);
gettimeofday(&now, NULL);
time.tv_sec = now.tv_sec + ms / 1000 + (now.tv_usec + (ms % 1000) * 1000)
/ 1000000;
time.tv_nsec = ((now.tv_usec + (ms % 1000) * 1000) % 1000000) * 1000;
/* Just use this to test the time out. The cond var is never signaled. */
pthread_mutex_lock(&foo.mutex);
while (foo.flag == 0 && status != ETIMEDOUT) {
status = pthread_cond_timedwait(&foo.cond, &foo.mutex, &time);
}
pthread_mutex_unlock(&foo.mutex);
/* post the main event */
pthread_mutex_lock(&main_event.mutex);
main_event.flag = 1;
pthread_cond_signal(&main_event.cond);
pthread_mutex_unlock(&main_event.mutex);
/* that's it, bye */
return (void*) status;
}
int libc_ex7(void) {
unsigned long count;
setvbuf(stdout, NULL, _IONBF, 0);
/* initialize main event cond var */
pthread_cond_init(&main_event.cond, NULL);
pthread_mutex_init(&main_event.mutex, NULL);
main_event.flag = 0;
for (count = 0; count < 20; ++count) {
pthread_t thread;
int status;
/* pass down the milli-second timeout in the void* param */
status = pthread_create(&thread, NULL, test_thread, (void*) (count
* 100));
if (status != 0) {
printf("status = %d, count = %lu: %s\n", status, count, strerror(
errno));
return 1;
} else {
/* wait for the event posted by the child thread */
pthread_mutex_lock(&main_event.mutex);
while (main_event.flag == 0) {
pthread_cond_wait(&main_event.cond, &main_event.mutex);
}
main_event.flag = 0;
pthread_mutex_unlock(&main_event.mutex);
printf("count = %lu\n", count);
}
usleep(10);
}
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_ex7, example 7 for libc);

516
examples/libc/file.c Normal file

File diff suppressed because it is too large Load Diff

54
examples/libc/memory.c Normal file
View File

@@ -0,0 +1,54 @@
/*
* memory.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
#include <errno.h>
static int errors = 0;
static void merror(const char *msg)
{
++errors;
printf("Error: %s\n", msg);
}
int libc_mem(void)
{
void *p;
int save;
errno = 0;
p = malloc(-1);
save = errno;
if (p != NULL)
merror("malloc (-1) succeeded.");
if (p == NULL && save != ENOMEM)
merror("errno is not set correctly");
p = malloc(10);
if (p == NULL)
merror("malloc (10) failed.");
/* realloc (p, 0) == free (p). */
p = realloc(p, 0);
if (p != NULL)
merror("realloc (p, 0) failed.");
p = malloc(0);
if (p == NULL)
merror("malloc (0) failed.");
p = realloc(p, 0);
if (p != NULL)
merror("realloc (p, 0) failed.");
return errors != 0;
}
FINSH_FUNCTION_EXPORT(libc_mem, memory test for libc);

200
examples/libc/printf.c Normal file
View File

@@ -0,0 +1,200 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/fcntl.h>
#include <finsh.h>
char * format[] = {
"%",
"%0.",
"%.0",
"%+0.",
"%+.0",
"%.5",
"%+.5",
"%2.5",
"%22.5",
"%022.5",
"%#022.5",
"%-#022.5",
"%+#022.5",
"%-22.5",
"%+22.5",
"%--22.5",
"%++22.5",
"%+-22.5",
"%-+22.5",
"%-#022.5",
"%-#22.5",
"%-2.22",
"%+2.22",
"%-#02.22",
"%-#2.22",
"%-1.5",
"%1.5",
"%-#01.5",
"%-#1.5",
"%-#.5",
"%-#1.",
"%-#.",
NULL
};
static void
intchk (const char *fmt)
{
(void) printf("%15s :, \"", fmt);
(void) printf(fmt, 0);
(void) printf("\", \"");
(void) printf(fmt, 123);
(void) printf("\", \"");
(void) printf(fmt, -18);
(void) printf("\"\n");
}
static void
fltchk (const char *fmt)
{
(void) printf("%15s :, \"", fmt);
(void) printf(fmt, 0.0);
(void) printf("\", \"");
(void) printf(fmt, 123.0001);
(void) printf("\", \"");
(void) printf(fmt, -18.0002301);
(void) printf("\"\n");
}
int printf_test()
{
char buf[256];
int i;
printf("%s\n\n", "# vim:syntax=off:");
/* integers */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "d");
intchk(buf);
}
/* floats */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "f");
fltchk(buf);
}
/* hexa */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "x");
intchk(buf);
}
printf("#%.4x %4x#\n", 4, 88);
printf("#%4x#\n",4);
printf("#%#22.8x#\n",1234567);
printf("#%+2i#\n",18);
printf("#%i#\n",18);
printf("#%llu#\n",4294967297ULL);
printf("#%#x#\n",44444);
printf("#%-8i#\n",33);
printf("#%i#\n",18);
printf("#%d#\n",18);
printf("#%u#\n",18);
printf("#%lu#\n",18);
printf("#%li#\n",18);
printf("#%-+#06d#\n", -123);
printf("#%-+#6d#\n", -123);
printf("#%+#06d#\n", -123);
printf("#%06d#\n", -123);
printf("#%+15s#\n","ABCDEF");
/* from ncurses make_keys */
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1");
printf("%*.*f\n", 0, 16, 0.0);
printf("%*.*f\n", 16, 16, 0.0);
printf("%*.*f\n", 2, 2, -0.0);
printf("%*.*f\n", 20, 0, -123.123);
printf("%*.*f\n", 10, 0, +123.123);
i = printf("\"%s\"\n","A");
printf("%i\n", i);
/* from glibc's tst-printf.c */
{
char buf[20];
char buf2[512];
int i;
printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n",
snprintf (buf, sizeof (buf), "%30s", "foo"), (int) sizeof (buf),
buf);
memset(buf2,0,sizeof(buf));
i=snprintf(buf2, 256, "%.9999u", 10);
printf("%i %i\n",i,strlen(buf2));
printf ("snprintf (\"%%.999999u\", 10) == %d\n",
snprintf(buf2, sizeof(buf2), "%.999999u", 10));
}
return 0;
}
void libc_printf()
{
printf("stdout test!!\n");
fprintf(stdout, "fprintf test!!\n");
fprintf(stderr, "fprintf test!!\n");
puts("puts test!!\n");
putc('1', stderr);
putc('2', stderr);
putc('\n', stderr);
printf_test();
}
FINSH_FUNCTION_EXPORT(libc_printf, printf test in libc);
void libc_dprintf()
{
int fd;
fd = open("/dev/console", O_WRONLY, 0);
if (fd >0)
{
dprintf(fd, "fd:%d printf test!!\n", fd);
close(fd);
}
}
FINSH_FUNCTION_EXPORT(libc_dprintf, dprintf test);
void libc_fdopen()
{
int fd;
FILE* fp;
fd = open("/dev/console", O_WRONLY, 0);
if (fd >0)
{
fp = fdopen(fd, "w");
fprintf(fp, "fdopen test, fd %d!!\n", fileno(fp));
fclose(fp);
}
}
FINSH_FUNCTION_EXPORT(libc_fdopen, fdopen test);

43
examples/libc/rand.c Normal file
View File

@@ -0,0 +1,43 @@
/*
* rand.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int libc_rand(void)
{
int i1, i2;
int j1, j2;
/* The C standard says that "If rand is called before any calls to
srand have been made, the same sequence shall be generated as
when srand is first called with a seed value of 1." */
i1 = rand();
i2 = rand();
srand(1);
j1 = rand();
j2 = rand();
if (i1 < 0 || i2 < 0 || j1 < 0 || j2 < 0)
{
puts("Test FAILED!");
}
if (j1 == i1 && j2 == i2)
{
puts("Test succeeded.");
return 0;
}
else
{
if (j1 != i1)
printf("%d != %d\n", j1, i1);
if (j2 != i2)
printf("%d != %d\n", j2, i2);
puts("Test FAILED!");
return 1;
}
}
FINSH_FUNCTION_EXPORT(libc_rand, rand test for libc);

24
examples/libc/time.c Normal file
View File

@@ -0,0 +1,24 @@
/*
* time.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int speed()
{
int i;
time_t t;
printf("%d\n", time(0));
for (i = 0; i < 10000000; ++i)
t = time(0);
printf("%d\n", time(0));
return 0;
}
FINSH_FUNCTION_EXPORT(speed, speed test);