~jsvoboda/helenos/sysel

« back to all changes in this revision

Viewing changes to uspace/app/sbi/src/builtin/bi_string.c

  • Committer: Jiri Svoboda
  • Date: 2010-05-08 08:10:44 UTC
  • Revision ID: jiri@wiwaxia-20100508081044-5hvcjwu15rsfvgnv
Update SBI to rev. 244.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2010 Jiri Svoboda
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *
 
9
 * - Redistributions of source code must retain the above copyright
 
10
 *   notice, this list of conditions and the following disclaimer.
 
11
 * - Redistributions in binary form must reproduce the above copyright
 
12
 *   notice, this list of conditions and the following disclaimer in the
 
13
 *   documentation and/or other materials provided with the distribution.
 
14
 * - The name of the author may not be used to endorse or promote products
 
15
 *   derived from this software without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
/** @file String builtin binding. */
 
30
 
 
31
#include <stdio.h>
 
32
#include <stdlib.h>
 
33
#include <assert.h>
 
34
#include "../bigint.h"
 
35
#include "../builtin.h"
 
36
#include "../debug.h"
 
37
#include "../mytypes.h"
 
38
#include "../os/os.h"
 
39
#include "../rdata.h"
 
40
#include "../run.h"
 
41
#include "../strtab.h"
 
42
 
 
43
#include "bi_string.h"
 
44
 
 
45
static void bi_string_length(run_t *run);
 
46
static void bi_string_slice(run_t *run);
 
47
 
 
48
/** Declare String builtin.
 
49
 *
 
50
 * @param bi    Builtin object
 
51
 */
 
52
void bi_string_declare(builtin_t *bi)
 
53
{
 
54
        (void) bi;
 
55
}
 
56
 
 
57
/** Bind String builtin.
 
58
 *
 
59
 * @param bi    Builtin object
 
60
 */
 
61
void bi_string_bind(builtin_t *bi)
 
62
{
 
63
        builtin_fun_bind(bi, "String", "get_length", bi_string_length);
 
64
        builtin_fun_bind(bi, "String", "Slice", bi_string_slice);
 
65
}
 
66
 
 
67
/** Return length of the string.
 
68
 *
 
69
 * @param run   Runner object
 
70
 */
 
71
static void bi_string_length(run_t *run)
 
72
{
 
73
        rdata_var_t *self_value_var;
 
74
        const char *str;
 
75
        size_t str_l;
 
76
 
 
77
        rdata_int_t *rint;
 
78
        rdata_var_t *rvar;
 
79
        rdata_value_t *rval;
 
80
        rdata_item_t *ritem;
 
81
 
 
82
        run_proc_ar_t *proc_ar;
 
83
 
 
84
        /* Extract self.Value */
 
85
        self_value_var = builtin_get_self_mbr_var(run, "Value");
 
86
        assert(self_value_var->vc == vc_string);
 
87
        str = self_value_var->u.string_v->value;
 
88
        str_l = os_str_length(str);
 
89
 
 
90
#ifdef DEBUG_RUN_TRACE
 
91
        printf("Get length of string '%s'.\n", str);
 
92
#endif
 
93
 
 
94
        /* Construct return value. */
 
95
        rint = rdata_int_new();
 
96
        bigint_init(&rint->value, (int) str_l);
 
97
 
 
98
        rvar = rdata_var_new(vc_int);
 
99
        rvar->u.int_v = rint;
 
100
        rval = rdata_value_new();
 
101
        rval->var = rvar;
 
102
 
 
103
        ritem = rdata_item_new(ic_value);
 
104
        ritem->u.value = rval;
 
105
 
 
106
        proc_ar = run_get_current_proc_ar(run);
 
107
        proc_ar->retval = ritem;
 
108
}
 
109
 
 
110
/** Return slice (substring) of the string.
 
111
 *
 
112
 * @param run   Runner object
 
113
 */
 
114
static void bi_string_slice(run_t *run)
 
115
{
 
116
        rdata_var_t *self_value_var;
 
117
        const char *str;
 
118
        size_t str_l;
 
119
 
 
120
        rdata_var_t *start_var;
 
121
        int start;
 
122
 
 
123
        rdata_var_t *length_var;
 
124
        int length;
 
125
 
 
126
        int rc;
 
127
 
 
128
        rdata_string_t *rstring;
 
129
        rdata_var_t *rvar;
 
130
        rdata_value_t *rval;
 
131
        rdata_item_t *ritem;
 
132
 
 
133
        run_proc_ar_t *proc_ar;
 
134
 
 
135
        /* Extract self.Value */
 
136
        self_value_var = builtin_get_self_mbr_var(run, "Value");
 
137
        assert(self_value_var->vc == vc_string);
 
138
        str = self_value_var->u.string_v->value;
 
139
        str_l = os_str_length(str);
 
140
 
 
141
        /* Get argument @a start. */
 
142
        start_var = run_local_vars_lookup(run, strtab_get_sid("start"));
 
143
        assert(start_var);
 
144
        assert(start_var->vc == vc_int);
 
145
 
 
146
        rc = bigint_get_value_int(&start_var->u.int_v->value, &start);
 
147
        if (rc != EOK || start < 0 || (size_t) start > str_l) {
 
148
                printf("Error: Parameter 'start' to Slice() out of range.\n");
 
149
                exit(1);
 
150
        }
 
151
 
 
152
        /* Get argument @a length. */
 
153
        length_var = run_local_vars_lookup(run, strtab_get_sid("length"));
 
154
        assert(length_var);
 
155
        assert(length_var->vc == vc_int);
 
156
 
 
157
        rc = bigint_get_value_int(&length_var->u.int_v->value, &length);
 
158
        if (rc != EOK || length < 0 || (size_t) (start + length) > str_l) {
 
159
                printf("Error: Parameter 'length' to Slice() out of range.\n");
 
160
                exit(1);
 
161
        }
 
162
 
 
163
#ifdef DEBUG_RUN_TRACE
 
164
        printf("Construct Slice(%d, %d) from string '%s'.\n",
 
165
            start, length, str);
 
166
#endif
 
167
        /* Construct return value. */
 
168
        rstring = rdata_string_new();
 
169
        rstring->value = os_str_aslice(str, start, length);
 
170
 
 
171
        rvar = rdata_var_new(vc_string);
 
172
        rvar->u.string_v = rstring;
 
173
        rval = rdata_value_new();
 
174
        rval->var = rvar;
 
175
 
 
176
        ritem = rdata_item_new(ic_value);
 
177
        ritem->u.value = rval;
 
178
 
 
179
        proc_ar = run_get_current_proc_ar(run);
 
180
        proc_ar->retval = ritem;
 
181
}