00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <assert.h>
00034 #include "../bigint.h"
00035 #include "../builtin.h"
00036 #include "../debug.h"
00037 #include "../mytypes.h"
00038 #include "../os/os.h"
00039 #include "../rdata.h"
00040 #include "../run.h"
00041 #include "../strtab.h"
00042
00043 #include "bi_string.h"
00044
00045 static void bi_string_length(run_t *run);
00046 static void bi_string_slice(run_t *run);
00047
00052 void bi_string_declare(builtin_t *bi)
00053 {
00054 (void) bi;
00055 }
00056
00061 void bi_string_bind(builtin_t *bi)
00062 {
00063 builtin_fun_bind(bi, "String", "get_length", bi_string_length);
00064 builtin_fun_bind(bi, "String", "Slice", bi_string_slice);
00065 }
00066
00071 static void bi_string_length(run_t *run)
00072 {
00073 rdata_var_t *self_value_var;
00074 const char *str;
00075 size_t str_l;
00076
00077 rdata_int_t *rint;
00078 rdata_var_t *rvar;
00079 rdata_value_t *rval;
00080 rdata_item_t *ritem;
00081
00082 run_proc_ar_t *proc_ar;
00083
00084
00085 self_value_var = builtin_get_self_mbr_var(run, "Value");
00086 assert(self_value_var->vc == vc_string);
00087 str = self_value_var->u.string_v->value;
00088 str_l = os_str_length(str);
00089
00090 #ifdef DEBUG_RUN_TRACE
00091 printf("Get length of string '%s'.\n", str);
00092 #endif
00093
00094
00095 rint = rdata_int_new();
00096 bigint_init(&rint->value, (int) str_l);
00097
00098 rvar = rdata_var_new(vc_int);
00099 rvar->u.int_v = rint;
00100 rval = rdata_value_new();
00101 rval->var = rvar;
00102
00103 ritem = rdata_item_new(ic_value);
00104 ritem->u.value = rval;
00105
00106 proc_ar = run_get_current_proc_ar(run);
00107 proc_ar->retval = ritem;
00108 }
00109
00114 static void bi_string_slice(run_t *run)
00115 {
00116 rdata_var_t *self_value_var;
00117 const char *str;
00118 const char *slice;
00119 size_t str_l;
00120
00121 rdata_var_t *start_var;
00122 int start;
00123
00124 rdata_var_t *length_var;
00125 int length;
00126
00127 int rc;
00128
00129
00130 self_value_var = builtin_get_self_mbr_var(run, "Value");
00131 assert(self_value_var->vc == vc_string);
00132 str = self_value_var->u.string_v->value;
00133 str_l = os_str_length(str);
00134
00135
00136 start_var = run_local_vars_lookup(run, strtab_get_sid("start"));
00137 assert(start_var);
00138 assert(start_var->vc == vc_int);
00139
00140 rc = bigint_get_value_int(&start_var->u.int_v->value, &start);
00141 if (rc != EOK || start < 0 || (size_t) start > str_l) {
00142 printf("Error: Parameter 'start' to Slice() out of range.\n");
00143 exit(1);
00144 }
00145
00146
00147 length_var = run_local_vars_lookup(run, strtab_get_sid("length"));
00148 assert(length_var);
00149 assert(length_var->vc == vc_int);
00150
00151 rc = bigint_get_value_int(&length_var->u.int_v->value, &length);
00152 if (rc != EOK || length < 0 || (size_t) (start + length) > str_l) {
00153 printf("Error: Parameter 'length' to Slice() out of range.\n");
00154 exit(1);
00155 }
00156
00157 #ifdef DEBUG_RUN_TRACE
00158 printf("Construct Slice(%d, %d) from string '%s'.\n",
00159 start, length, str);
00160 #endif
00161 slice = os_str_aslice(str, start, length);
00162
00163
00164 builtin_return_string(run, slice);
00165 }