Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagn...@jcrosoft.com>
---
 apps/Kconfig           |    3 +
 apps/Makefile          |    5 ++
 apps/example/Makefile  |   14 +++
 apps/example/example.h |    7 ++
 apps/example/list.c    |   98 ++++++++++++++++++++
 apps/example/ls.c      |  127 ++++++++++++++++++++++++++
 apps/example/main.c    |  231 ++++++++++++++++++++++++++++++++++++++++++++++++
 apps/example/setjmp.c  |   24 +++++
 8 files changed, 509 insertions(+)
 create mode 100644 apps/example/Makefile
 create mode 100644 apps/example/example.h
 create mode 100644 apps/example/list.c
 create mode 100644 apps/example/ls.c
 create mode 100644 apps/example/main.c
 create mode 100644 apps/example/setjmp.c

diff --git a/apps/Kconfig b/apps/Kconfig
index 4805c50..324e14d 100644
--- a/apps/Kconfig
+++ b/apps/Kconfig
@@ -37,4 +37,7 @@ config APP_FILE_MAX
 
 endmenu
 
+config APP_EXAMPLE
+       bool "example"
+
 endif
diff --git a/apps/Makefile b/apps/Makefile
index 28efb0d..7f609e7 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -5,6 +5,8 @@ export APP_CPPFLAGS
 
 apps-$(CONFIG_APP_EXAMPLE) += example
 
+apps-$(CONFIG_APP_EXAMPLE) += example
+
 $(obj)/application: $(apps-lds) $(apps-y)
 
 APP_CPPFLAGS           += -fdata-sections -ffunction-sections
@@ -20,3 +22,6 @@ obj-y += utils/
 
 barebox-app-header += $(obj)/include/types.h
 barebox-app-header += $(obj)/include/barebox/syscalls.h
+
+$(apps-y): $(barebox-app-header) $(barebox-app-common)
+       $(Q)$(MAKE) $(build)=apps/$@ apps/$@/$@.app
diff --git a/apps/example/Makefile b/apps/example/Makefile
new file mode 100644
index 0000000..22f8d68
--- /dev/null
+++ b/apps/example/Makefile
@@ -0,0 +1,14 @@
+targets := example.map
+
+# Make sure files are removed during clean
+extra-y       += example.map
+
+app-y += main.o
+app-y += ls.o
+app-y += list.o
+app-y += setjmp.o
+app-final-y = example
+
+OBJCOPYFLAGS_example.app = -O binary
+LDFLAGS_apps   := -Map $(obj)/example.map
+LDFLAGS_apps   += -static --gc-sections
diff --git a/apps/example/example.h b/apps/example/example.h
new file mode 100644
index 0000000..34675b4
--- /dev/null
+++ b/apps/example/example.h
@@ -0,0 +1,7 @@
+
+#define LS_RECURSIVE   1
+#define LS_SHOWARG     2
+#define LS_COLUMN      4
+int ls(const char *path, ulong flags);
+void test_list(void);
+void test_setjmp(void);
diff --git a/apps/example/list.c b/apps/example/list.c
new file mode 100644
index 0000000..fd5662d
--- /dev/null
+++ b/apps/example/list.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plag...@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <appinfo.h>
+#include <utils/list.h>
+
+#define ARRAY_SIZE(arr)                (sizeof(arr) / sizeof((arr)[0]))
+
+static LIST_HEAD(test);
+
+struct data {
+       char *name;
+       struct list_entry list;
+};
+
+struct data data[] = {
+       [0] = { .name = "data0", },
+       [1] = { .name = "data1", },
+       [2] = { .name = "data2", },
+       [3] = { .name = "data3", },
+};
+
+static void dump_list(void)
+{
+       struct list_entry *pos;
+       struct data *d;
+       int i;
+
+       i = 0;
+       list_for_each(pos, test) {
+               printf("data[%d].list = %p\n", i, pos);
+               i++;
+       }
+
+       i = 0;
+       list_for_each_entry(d, &test, list) {
+               printf("data[%d].name = %s\n", i, d->name);
+               printf("data[%d].list = %p\n", i, &d->list);
+               i++;
+       }
+}
+
+static void empty_list(void)
+{
+       struct data *d, *tmp;
+       int i;
+
+       i = 0;
+       list_for_each_entry_safe(d, tmp, &test, list) {
+               printf("data[%d].name = %s\n", i, d->name);
+               printf("data[%d].list = %p\n", i, &d->list);
+               list_del(&d->list);
+               i++;
+       }
+}
+
+void test_list(void)
+{
+       int i;
+
+       puts("------ list test ------\n");
+
+       puts("fill list\n");
+
+       for (i = 0; i < ARRAY_SIZE(data); i++) {
+               printf("data[%d].name = %s\n", i, data[i].name);
+               printf("data[%d].list = %p\n", i, &data[i].list);
+               list_add(&data[i].list, &test);
+       }
+
+       puts("dump list\n");
+       dump_list();
+       puts("remove entry 2\n");
+       list_del(&data[2].list);
+       puts("dump list\n");
+       dump_list();
+       puts("empty list\n");
+       empty_list();
+       puts("dump list\n");
+       dump_list();
+       printf("list is %s\n", list_empty(&test) ? "empty" : "filled");
+
+       puts("fill list tail\n");
+       for (i = 0; i < ARRAY_SIZE(data); i++) {
+               printf("data[%d].name = %s\n", i, data[i].name);
+               printf("data[%d].list = %p\n", i, &data[i].list);
+               list_add_tail(&data[i].list, &test);
+       }
+       puts("dump list\n");
+       dump_list();
+
+       puts("------ end ------\n\n");
+}
diff --git a/apps/example/ls.c b/apps/example/ls.c
new file mode 100644
index 0000000..bad0ccb
--- /dev/null
+++ b/apps/example/ls.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2007 Sascha Hauer <s.ha...@pengutronix.de>, Pengutronix
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plag...@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "example.h"
+
+static char *mkmodestr(unsigned long mode, char *str)
+{
+       static const char *l = "xwr";
+       int mask = 1, i;
+       char c;
+
+       switch (mode & S_IFMT) {
+               case S_IFDIR:    str[0] = 'd'; break;
+               case S_IFBLK:    str[0] = 'b'; break;
+               case S_IFCHR:    str[0] = 'c'; break;
+               case S_IFIFO:    str[0] = 'f'; break;
+               case S_IFLNK:    str[0] = 'l'; break;
+               case S_IFSOCK:   str[0] = 's'; break;
+               case S_IFREG:    str[0] = '-'; break;
+               default:         str[0] = '?';
+       }
+
+       for(i = 0; i < 9; i++) {
+               c = l[i%3];
+               str[9-i] = (mode & mask)?c:'-';
+               mask = mask<<1;
+       }
+
+       if(mode & S_ISUID) str[3] = (mode & S_IXUSR)?'s':'S';
+       if(mode & S_ISGID) str[6] = (mode & S_IXGRP)?'s':'S';
+       if(mode & S_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T';
+       str[10] = '\0';
+       return str;
+}
+
+static void ls_one(const char *path, const char* fullname, struct stat *s)
+{
+       char modestr[11];
+       unsigned int namelen = strlen(path);
+
+       mkmodestr(s->st_mode, modestr);
+       printf("%s %10llu %*.*s", modestr, s->st_size, namelen, namelen, path);
+
+       if (S_ISLNK(s->st_mode)) {
+               char realname[PATH_MAX];
+
+               memset(realname, 0, PATH_MAX);
+
+               if (readlink(fullname, realname, PATH_MAX - 1) >= 0)
+                       printf(" -> %s", realname);
+       }
+
+       puts("\n");
+}
+
+int ls(const char *path, ulong flags)
+{
+       DIR *dir;
+       struct dirent *d;
+       char tmp[PATH_MAX];
+       struct stat s;
+
+       if (lstat(path, &s))
+               return -1;
+
+       if (flags & LS_SHOWARG && s.st_mode & S_IFDIR)
+               printf("%s:\n", path);
+
+       if (!(s.st_mode & S_IFDIR)) {
+               ls_one(path, path, &s);
+               return 0;
+       }
+
+       dir = opendir(path);
+       if (!dir)
+               return -1;
+
+       while ((d = readdir(dir))) {
+               sprintf(tmp, "%s/%s", path, d->d_name);
+               if (!strlen(d->d_name))
+                       break;
+               if (lstat(tmp, &s))
+                       goto out;
+               ls_one(d->d_name, tmp, &s);
+       }
+
+       closedir(dir);
+
+       if (!(flags & LS_RECURSIVE))
+               return 0;
+
+       dir = opendir(path);
+       if (!dir) 
+               return -ENOENT;
+
+       while ((d = readdir(dir))) {
+
+               if (!strcmp(d->d_name, "."))
+                       continue;
+               if (!strcmp(d->d_name, ".."))
+                       continue;
+               sprintf(tmp, "%s/%s", path, d->d_name);
+
+               if (lstat(tmp, &s))
+                       goto out;
+               if (s.st_mode & S_IFDIR)
+                       ls(tmp, flags);
+       }
+out:
+       closedir(dir);
+
+       return 0;
+}
diff --git a/apps/example/main.c b/apps/example/main.c
new file mode 100644
index 0000000..12fb7f0
--- /dev/null
+++ b/apps/example/main.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plag...@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#include <stdio.h>
+#include <malloc.h>
+#include <appinfo.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sections.h>
+#include <sys/stat.h>
+
+#include "example.h"
+
+# define PUTHEX_LL(value)  ({ unsigned long v = (unsigned long) (value); \
+                            int i; unsigned char ch; \
+                            for (i = 8; i--; ) {\
+                            ch = ((v >> (i*4)) & 0xf);\
+                            ch += (ch >= 10) ? 'a' - 10 : '0';\
+                            putchar(ch); }})
+static void test_ls(void)
+{
+       puts(
+               "------ test 1 ------ \n"
+               "coverage:\n"
+               " - opendir/readdir/closedir\n"
+               " - lstat\n"
+               " - readlink\n"
+               "------ start ------ \n");
+
+       puts("ls -l /env/config\n");
+       ls("/env/config", 0);
+       puts("ls -l /dev\n");
+       ls("/dev", 0);
+       puts("ls -l /env\n");
+       ls("/env", 0);
+       puts("------ end ------\n\n");
+}
+
+static void print_ok_failed(int ret)
+{
+       if (ret)
+               printf("failed (%d)\n", ret);
+       else
+               puts(" => OK\n");
+}
+
+static void test_mkdir(void)
+{
+       int fd;
+       int ret;
+       char *test = "/test";
+       char *test_tmp = "/test/tmp";
+       char *readme_txt = "/test/readme.txt";
+       char *readme = "/test/readme";
+       char *txt = "test barebox app\n";
+
+       puts(
+               "------ test 2 ------ \n"
+               "coverage:\n"
+               " - mkdir/rmdir\n"
+               " - open/write\n"
+               " - symlink/unlink\n"
+               "------ start ------ \n");
+
+       printf("mkdir %s ", test);
+       ret = mkdir(test, 0666);
+       print_ok_failed(ret);
+       if (ret)
+               return;
+
+       printf("create %s ", readme_txt);
+       fd = open(readme_txt, O_CREAT | O_WRONLY);
+       if (fd >= 0) {
+               puts(" => OK\n");
+               ret = write(fd, txt, strlen(txt) + 1);
+               if (!ret)
+                       printf("fprintf on fd=%d failer (%d)\n", fd, ret);
+               close(fd);
+       } else {
+               printf("failed (%d)\n", fd);
+       }
+
+       printf("ln -s %s %s ", readme_txt, readme);
+       ret = symlink(readme_txt, readme);
+       print_ok_failed(ret);
+
+       printf("mkdir %s ", test_tmp);
+       ret = mkdir(test_tmp, 0666);
+       print_ok_failed(ret);
+
+       printf("ls -l %s\n", test);
+       ls(test, 0);
+
+       if (!ret) {
+               printf("rmdir %s ", test_tmp);
+               ret = rmdir(test_tmp);
+               print_ok_failed(ret);
+       }
+
+       printf("unlink %s ", readme);
+       ret = unlink(readme);
+       print_ok_failed(ret);
+
+       printf("ls -l %s\n", test);
+       ls(test, 0);
+
+       puts("------ end ------\n\n");
+}
+
+static void test_printf(int argc, char **argv)
+{
+       int i;
+       char *test;
+
+       puts("hello world\n");
+       test = malloc(10);
+       puts("mallox of 10 => 0x");
+       PUTHEX_LL(test);
+       puts("\n");
+
+       puts("------ printf test ------\n");
+
+       for (i = 0; i < argc; i++)
+               printf("argv[%d] = %s\n", i, argv[i]);
+
+       printf("mallox of %d => %p\n", 10, test);
+       puts("------ end ------\n\n");
+}
+
+static void test_all(int argc, char **argv)
+{
+       test_printf(argc, argv);
+       test_ls();
+       test_mkdir();
+       test_list();
+       test_setjmp();
+}
+
+void usage(char *name)
+{
+       printf("%s: [-VplmLh]\n"
+       "-V             dump app info\n"
+       "-p             run printf test\n"
+       "-l             run ls test\n"
+       "-m             run mkdir test\n"
+       "-L             run list test\n"
+       "-j             run setjmp test\n"
+       "-h             print help\n", name);
+}
+
+int main(int argc, char** argv)
+{
+       int i;
+       int opt;
+       bool do_test_printf = false;
+       bool do_test_ls = false;
+       bool do_test_mkdir = false;
+       bool do_test_list = false;
+       bool do_test_setjmp = false;
+       bool do_test_all = true;
+
+       for (i = 0; i < argc; i++) {
+               puts("argv[0x");
+               PUTHEX_LL(i);
+               puts("] = ");
+               puts(argv[i]);
+               puts("\n");
+       }
+
+       while ((opt = getopt(argc, argv, "VplmLhj")) > 0) {
+               switch (opt) {
+               case 'V':
+                       print_appinfo();
+                       break;
+               case 'p':
+                       do_test_all = false;
+                       do_test_printf = true;
+                       break;
+               case 'l':
+                       do_test_all = false;
+                       do_test_ls = true;
+                       break;
+               case 'm':
+                       do_test_all = false;
+                       do_test_mkdir = true;
+                       break;
+               case 'L':
+                       do_test_all = false;
+                       do_test_list = true;
+                       break;
+               case 'j':
+                       do_test_all = false;
+                       do_test_setjmp = true;
+                       break;
+               case 'h':
+                       usage(argv[0]);
+                       return 0;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       puts("------ start ------\n\n");
+       if (do_test_all) {
+               test_all(argc, argv);
+               return 0;
+       }
+
+       if (do_test_printf)
+               test_printf(argc, argv);
+       if (do_test_ls)
+               test_ls();
+       if (do_test_ls)
+               test_mkdir();
+       if (do_test_list)
+               test_list();
+       if (do_test_setjmp)
+               test_setjmp();
+       puts("------ end ------\n\n");
+
+       return 0;
+}
+
+APP_LICENSE("GPL");
+APP_DESCRIPTION("barebox Application example");
+APP_AUTHOR("Jean-Chrristophe PLAGNIOL-VILLARD <plagn...@jcrosoft.com>");
diff --git a/apps/example/setjmp.c b/apps/example/setjmp.c
new file mode 100644
index 0000000..4dee83c
--- /dev/null
+++ b/apps/example/setjmp.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <setjmp.h>
+
+static jmp_buf buf;
+
+void second(void) {
+       printf("second\n");
+       longjmp(buf, 1);
+}
+
+void first(void) {
+       second();
+       printf("first not reach\n");
+}
+
+void test_setjmp(void)
+{
+       puts("------ setjmp/longjmp test ------\n");
+       if (!setjmp(buf))
+               first();
+       else
+               printf("main\n");
+       puts("------ end ------\n\n");
+}
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to