Tizen 2.0 Release
[framework/uifw/embryo.git] / src / lib / embryo_args.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #ifdef HAVE_ALLOCA_H
6 # include <alloca.h>
7 #elif defined __GNUC__
8 # define alloca __builtin_alloca
9 #elif defined _AIX
10 # define alloca __alloca
11 #elif defined _MSC_VER
12 # include <malloc.h>
13 # define alloca _alloca
14 #else
15 # include <stddef.h>
16 # ifdef  __cplusplus
17 extern "C"
18 # endif
19 void *alloca (size_t);
20 #endif
21
22 #include "Embryo.h"
23 #include "embryo_private.h"
24
25 #define STRSET(ep, par, str) { \
26    Embryo_Cell *___cptr; \
27    if ((___cptr = embryo_data_address_get(ep, par))) { \
28       embryo_data_string_set(ep, str, ___cptr); \
29    } }
30
31 /* exported args api */
32
33 static Embryo_Cell
34 _embryo_args_numargs(Embryo_Program *ep, Embryo_Cell *params __UNUSED__)
35 {
36    Embryo_Header *hdr;
37    unsigned char *data;
38    Embryo_Cell bytes;
39
40    hdr = (Embryo_Header *)ep->base;
41    data = ep->base + (int)hdr->dat;
42    bytes = *(Embryo_Cell *)(data + (int)ep->frm +
43                             (2 * sizeof(Embryo_Cell)));
44    return bytes / sizeof(Embryo_Cell);
45 }
46
47 static Embryo_Cell
48 _embryo_args_getarg(Embryo_Program *ep, Embryo_Cell *params)
49 {
50    Embryo_Header *hdr;
51    unsigned char *data;
52    Embryo_Cell val;
53
54    if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
55    hdr = (Embryo_Header *)ep->base;
56    data = ep->base + (int)hdr->dat;
57    val = *(Embryo_Cell *)(data + (int)ep->frm +
58                           (((int)params[1] + 3) * sizeof(Embryo_Cell)));
59    val += params[2] * sizeof(Embryo_Cell);
60    val = *(Embryo_Cell *)(data + (int)val);
61    return val;
62 }
63
64 static Embryo_Cell
65 _embryo_args_setarg(Embryo_Program *ep, Embryo_Cell *params)
66 {
67    Embryo_Header *hdr;
68    unsigned char *data;
69    Embryo_Cell val;
70
71    if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
72    hdr = (Embryo_Header *)ep->base;
73    data = ep->base + (int)hdr->dat;
74    val = *(Embryo_Cell *)(data + (int)ep->frm +
75                           (((int)params[1] + 3) * sizeof(Embryo_Cell)));
76    val += params[2] * sizeof(Embryo_Cell);
77    if ((val < 0) || ((val >= ep->hea) && (val < ep->stk))) return 0;
78    *(Embryo_Cell *)(data + (int)val) = params[3];
79    return 1;
80 }
81
82 static Embryo_Cell
83 _embryo_args_getsarg(Embryo_Program *ep, Embryo_Cell *params)
84 {
85    Embryo_Header *hdr;
86    unsigned char *data;
87    Embryo_Cell base_cell;
88    char *s;
89    int i = 0;
90
91    /* params[1] = arg_no */
92    /* params[2] = buf */
93    /* params[3] = buflen */
94    if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
95    if (params[3] <= 0) return 0; /* buflen must be > 0 */
96    hdr = (Embryo_Header *)ep->base;
97    data = ep->base + (int)hdr->dat;
98    base_cell = *(Embryo_Cell *)(data + (int)ep->frm +
99                           (((int)params[1] + 3) * sizeof(Embryo_Cell)));
100
101    s = alloca(params[3]);
102
103    while (i < params[3])
104      {
105         int offset = base_cell + (i * sizeof(Embryo_Cell));
106
107         s[i] = *(Embryo_Cell *)(data + offset);
108         if (!s[i++]) break;
109      }
110
111    s[i - 1] = 0;
112    STRSET(ep, params[2], s);
113
114    return i - 1; /* characters written minus terminator */
115 }
116
117 /* functions used by the rest of embryo */
118
119 void
120 _embryo_args_init(Embryo_Program *ep)
121 {
122    embryo_program_native_call_add(ep, "numargs",  _embryo_args_numargs);
123    embryo_program_native_call_add(ep, "getarg", _embryo_args_getarg);
124    embryo_program_native_call_add(ep, "setarg", _embryo_args_setarg);
125    embryo_program_native_call_add(ep, "getfarg", _embryo_args_getarg);
126    embryo_program_native_call_add(ep, "setfarg", _embryo_args_setarg);
127    embryo_program_native_call_add(ep, "getsarg", _embryo_args_getsarg);
128 }