1 /*
2  * Copyright 2008 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 
8 #include <stdarg.h>
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <time.h>
14 #include <unistd.h>
15 
16 #include "native_client/src/include/build_config.h"
17 
18 /*
19  * TODO(sehr): enable thread local storage.
20  */
21 #define THREAD
22 
23 char **environ;
24 
25 char    bss_buf[1024];  /* just to see ELF info */
26 int     bss_int;
27 
28 THREAD int  tls_bss_int;
29 THREAD char tls_bss_buf[8192];
30 
31 THREAD int  tls_data_int = 10;
32 THREAD char tls_data_buf[128] = "Hello world\n";
33 
34 
test_tls(void)35 void  test_tls(void)
36 {
37   printf("%s\n", tls_data_buf);
38 }
39 
40 
test_fmt(char * fmt,int val)41 void  test_fmt(char *fmt, int val)
42 {
43   fputs(fmt, stdout); putc(':', stdout);
44   printf(fmt, val);
45   putc('\n', stdout);
46 }
47 
test_fp_fmt(char * fmt,double val)48 void  test_fp_fmt(char  *fmt, double val)
49 {
50   fputs(fmt, stdout); putc(':', stdout);
51   printf(fmt, val);
52   putc('\n', stdout);
53 }
54 
test_fp_val(double val)55 void  test_fp_val(double  val)
56 {
57   printf("\n123456789012345678901234567890"
58          "123456789012345678901234567890\n");
59   test_fp_fmt("%e", val);
60   test_fp_fmt("%30.15e.", val);
61   test_fp_fmt("%-30.15e.", val);
62   test_fp_fmt("%f.", val);
63   test_fp_fmt("%30.15f.", val);
64   test_fp_fmt("%-30.15f.", val);
65 }
66 
test_fp(void)67 void  test_fp(void)
68 {
69   double d;
70 
71   printf("one half is %e\n", 0.5);
72   printf("one half is %f\n", 0.5);
73   printf("one third is %e\n", 1.0/3.0);
74   printf("one third is %f\n", 1.0/3.0);
75 
76   test_fp_val(0.0);
77   test_fp_fmt("%.500e", 1.0);
78   d = 1.234567e+10;
79   test_fp_val(d);
80   test_fp_val(-d);
81 
82   d = 1.234567e308;
83   test_fp_val(d);
84   test_fp_val(-d);
85 
86   d = 1.234567e-307;
87   test_fp_val(d);
88   test_fp_val(-d);
89 
90   d = 1.234567e-310;
91   test_fp_val(d);
92   test_fp_val(-d);
93 #if 0
94   /* TODO: the code below doesn't compile on Windows
95      NOTE(robertm): disabled this code for all platforms
96      to be able to do with one golden file */
97   d = 1.234567e+310;  /* inf */
98   test_fp_val(d);
99   test_fp_val(-d);
100   d = 1.234567e+310;  /* inf */
101   test_fp_val(d);
102   test_fp_val(-d);
103 
104   d = 0.0/0.0;  /* nan */
105   test_fp_val(d);
106 #endif  /*NACL_WINDOWS*/
107 }
108 
test_malloc(void)109 void  test_malloc(void)
110 {
111   char    *p;
112   printf("test_malloc: entered\n");
113   p = malloc(10);
114   fprintf(stderr, "# got 0x%08x\n", (unsigned int) p);
115   printf("test_malloc: leaving\n");
116 }
117 
test_time(void)118 void test_time(void)
119 {
120   time_t tval;
121   printf("test_time: entered\n");
122   tval = time(NULL);
123   fprintf(stderr, "# current time is %d \n", (int) tval);
124   printf("test_time: leaving\n");
125 }
126 
test_fopen(const char * fn)127 void  test_fopen(const char* fn)
128 {
129   FILE  *fp;
130   int   c;
131   char  line[1024];
132   char  *rv;
133 
134   printf("test_fopen: entered\n");
135   fp = fopen(fn, "rb");
136   if (NULL == fp) {
137     printf("could not open file %s!\n", fn);
138     exit(-1);
139   } else {
140     printf("reading file\n");
141     while (EOF != (c = fgetc(fp))) {
142       if ((int)c != 13)
143         /*
144           TODO(gregoryd): make sure the input files are identical
145           on all platforms, so we won't need the if.
146         */
147         putc(c, stdout);
148     }
149     fclose(fp);
150   }
151 
152   while (0 != (rv = (fputs("input: ", stdout),
153                      fflush(stdout),
154                      fgets(line, sizeof line, stdin)))) {
155     printf("Got line: <<%s>>, %d\n", rv, strlen(rv));
156   }
157   printf("test_fopen: done\n");
158 }
159 
160 
NaClMain(const char * fn)161 int NaClMain(const char* fn)
162 {
163   char const  *hello = "Hello world\n";
164   char const  *bye = "Goodbye cruel world";
165   int         r;
166 
167   r = write(1, hello, strlen(hello));
168 
169   printf("write returned %d.\n", r);
170   test_fmt("<%04d>", r);
171   test_fmt("<%-d>", r);
172   test_fmt("<%-04d>", r);
173   r = -r;
174   test_fmt("<%d>", r);
175   test_fmt("<%04d>", r);
176   test_fmt("<%-d>", r);
177   test_fmt("<%-04d>", r);
178 
179   printf("The message was \"%s\".\n", hello);
180 
181   printf("Bye message: \"%25s\".\n", bye);
182   printf("Bye message: \"%-25s\".\n", bye);
183 
184   test_fp();
185   test_malloc();
186   test_time();
187   test_fopen(fn);
188 
189   fflush(0);
190   fprintf(stderr, "# Hello is at address 0x%08lx\n", (long) hello);
191   fprintf(stderr, "# Hello is at address %p\n", (void *) hello);
192   {
193     short s = -1;
194     unsigned short us = (unsigned short) -1;
195 
196     printf("s = %hd\n", s);
197     printf("us = %hu\n", us);
198   }
199 
200   printf("Goodbye cruel world.  Really.\n");
201   fprintf(stderr, "My pid is %d\n", getpid());
202   fflush(0);
203   return 0;
204 }
205 
SimpleMain(void)206 int SimpleMain(void)
207 {
208   static char const  hello[] = "Hello from SimpleMain\n";
209 
210   write(1, hello, -1 + sizeof(hello));
211   return 0;
212 }
213 
main(int argc,char * argv[],char ** ep)214 int main(int argc, char *argv[], char **ep)
215 {
216   if (argc < 2) {
217     printf("you must specify a file to read\n");
218     exit(-1);
219   }
220 #if 1
221   return NaClMain(argv[1]);
222 #else
223   return SimpleMain();
224 #endif
225 }
226 
test_start(char * arg,...)227 void test_start(char *arg, ...)
228 {
229   int   argc;
230   char  **argv;
231   char  **envp;
232 
233   argv = &arg;
234   argc = *(int *)(argv-1);
235   envp = argv + argc + 1;
236 
237   environ = envp;
238 
239   exit(main(argc, argv, envp));
240 }
241