diff --git a/README.md b/README.md index d3d01b39f..ddc2b0bef 100644 --- a/README.md +++ b/README.md @@ -762,6 +762,8 @@ A server *Goal* takes a single arg, the connection stream. Networking ##EXPERIMENTAL## ========== + parse_url/2 # parse_url(?atom,?list) + server/2 # server(+host,-stream) server/3 # server(+host,-stream,+list) accept/2 # accept(+stream,-stream) diff --git a/src/control.c b/src/control.c index 330a60265..fa7ee2ca4 100644 --- a/src/control.c +++ b/src/control.c @@ -759,8 +759,8 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c check_heap_error(tmp); pl_idx nbr_cells = 0; make_struct(tmp+nbr_cells++, g_error_s, NULL, 2, 2); - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, err_type)); - make_atom(tmp+nbr_cells, index_from_pool(q->pl, expected)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, err_type)); + make_atom(tmp+nbr_cells, new_atom(q->pl, expected)); } else if (!strcmp(err_type, "type_error") && !strcmp(expected, "var")) { err_type = "uninstantiation_error"; //printf("error(%s(%s),(%s)/%u).\n", err_type, C_STR(q, c), functor, goal->arity); @@ -768,12 +768,12 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c check_heap_error(tmp); pl_idx nbr_cells = 0; make_struct(tmp+nbr_cells++, g_error_s, NULL, 2, 5+(c->nbr_cells-1)); - make_struct(tmp+nbr_cells++, index_from_pool(q->pl, err_type), NULL, 1, 1+(c->nbr_cells-1)); + make_struct(tmp+nbr_cells++, new_atom(q->pl, err_type), NULL, 1, 1+(c->nbr_cells-1)); safe_copy_cells(tmp+nbr_cells, c, c->nbr_cells); nbr_cells += c->nbr_cells; make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); SET_OP(tmp+nbr_cells, OP_YFX); nbr_cells++; - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, functor)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, functor)); make_int(tmp+nbr_cells, !is_string(goal)?goal->arity:0); } else if (!strcmp(err_type, "type_error") && !strcmp(expected, "evaluable")) { //printf("error(%s(%s,(%s)/%u),(%s)/%u).\n", err_type, expected, C_STR(q, c), c->arity, functor, goal->arity); @@ -781,8 +781,8 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c check_heap_error(tmp); pl_idx nbr_cells = 0; make_struct(tmp+nbr_cells++, g_error_s, NULL, 2, 8); - make_struct(tmp+nbr_cells++, index_from_pool(q->pl, err_type), NULL, 2, 4); - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, expected)); + make_struct(tmp+nbr_cells++, new_atom(q->pl, err_type), NULL, 2, 4); + make_atom(tmp+nbr_cells++, new_atom(q->pl, expected)); make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); SET_OP(tmp+nbr_cells, OP_YFX); nbr_cells++; tmp[nbr_cells] = *c; @@ -792,7 +792,7 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c make_int(tmp+nbr_cells++, c->arity); make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); SET_OP(tmp+nbr_cells, OP_YFX); nbr_cells++; - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, functor)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, functor)); make_int(tmp+nbr_cells, !is_string(goal)?goal->arity:0); } else if (!strcmp(err_type, "permission_error") && is_structure(c) && CMP_STR_TO_CSTR(q, c, "/") && is_var(FIRST_ARG(c))) { //printf("error(%s(%s,(%s)/%u),(%s)/%u).\n", err_type, expected, tmpbuf, c->arity, functor, goal->arity); @@ -800,10 +800,10 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c check_heap_error(tmp); pl_idx nbr_cells = 0; make_struct(tmp+nbr_cells++, g_error_s, NULL, 2, 8+extra); - make_struct(tmp+nbr_cells++, index_from_pool(q->pl, err_type), NULL, 2+extra, 4+extra); + make_struct(tmp+nbr_cells++, new_atom(q->pl, err_type), NULL, 2+extra, 4+extra); if (!extra) - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, expected)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, expected)); else { char tmpbuf[1024*8]; strcpy(tmpbuf, expected); @@ -812,12 +812,12 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c if (*ptr2) *ptr2++ = '\0'; while (ptr2) { - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, ptr)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, ptr)); ptr = ptr2; ptr2 = strchr(ptr, ','); } - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, ptr)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, ptr)); } make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); @@ -829,7 +829,7 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c make_int(tmp+nbr_cells++, c->arity); make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); SET_OP(tmp+nbr_cells, OP_YFX); nbr_cells++; - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, functor)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, functor)); make_int(tmp+nbr_cells, !is_string(goal)?goal->arity:0); } else if (!strcmp(err_type, "permission_error") && (is_builtin || (is_op && c->arity)) && !is_abolish) { //printf("error(%s(%s,(%s)/%u),(%s)/%u).\n", err_type, expected, tmpbuf, c->arity, functor, goal->arity); @@ -837,10 +837,10 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c check_heap_error(tmp); pl_idx nbr_cells = 0; make_struct(tmp+nbr_cells++, g_error_s, NULL, 2, 8+extra); - make_struct(tmp+nbr_cells++, index_from_pool(q->pl, err_type), NULL, 2+extra, 4+extra); + make_struct(tmp+nbr_cells++, new_atom(q->pl, err_type), NULL, 2+extra, 4+extra); if (!extra) - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, expected)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, expected)); else { char tmpbuf[1024*8]; strcpy(tmpbuf, expected); @@ -849,12 +849,12 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c if (*ptr2) *ptr2++ = '\0'; while (ptr2) { - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, ptr)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, ptr)); ptr = ptr2; ptr2 = strchr(ptr, ','); } - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, ptr)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, ptr)); } make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); @@ -866,7 +866,7 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c make_int(tmp+nbr_cells++, c->arity); make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); SET_OP(tmp+nbr_cells, OP_YFX); nbr_cells++; - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, functor)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, functor)); make_int(tmp+nbr_cells, !is_string(goal)?goal->arity:0); } else if (!strcmp(err_type, "instantiation_error")) { //printf("error(%s,(%s)/%u).\n", err_type, functor, goal->arity); @@ -874,10 +874,10 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c check_heap_error(tmp); pl_idx nbr_cells = 0; make_struct(tmp+nbr_cells++, g_error_s, NULL, 2, 4); - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, err_type)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, err_type)); make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); SET_OP(tmp+nbr_cells, OP_YFX); nbr_cells++; - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, functor)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, functor)); make_int(tmp+nbr_cells, !is_string(goal)?goal->arity:0); } else if (!strcmp(err_type, "existence_error") && !strcmp(expected, "procedure") && is_callable(c)) { //printf("error(%s(%s,(%s)/%u),(%s)/%u).\n", err_type, expected, tmpbuf, c->arity, functor, goal->arity); @@ -885,15 +885,15 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c check_heap_error(tmp); pl_idx nbr_cells = 0; make_struct(tmp+nbr_cells++, g_error_s, NULL, 2, 8); - make_struct(tmp+nbr_cells++, index_from_pool(q->pl, err_type), NULL, 2, 4); - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, expected)); + make_struct(tmp+nbr_cells++, new_atom(q->pl, err_type), NULL, 2, 4); + make_atom(tmp+nbr_cells++, new_atom(q->pl, expected)); make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); SET_OP(tmp+nbr_cells, OP_YFX); nbr_cells++; - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, C_STR(q, c))); + make_atom(tmp+nbr_cells++, new_atom(q->pl, C_STR(q, c))); make_int(tmp+nbr_cells++, c->arity); make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); SET_OP(tmp+nbr_cells, OP_YFX); nbr_cells++; - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, functor)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, functor)); make_int(tmp+nbr_cells, !is_string(goal)?goal->arity:0); } else if (!strcmp(err_type, "representation_error") || !strcmp(err_type, "evaluation_error") @@ -904,11 +904,11 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c check_heap_error(tmp); pl_idx nbr_cells = 0; make_struct(tmp+nbr_cells++, g_error_s, NULL, 2, 5); - make_struct(tmp+nbr_cells++, index_from_pool(q->pl, err_type), NULL, 1, 1); - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, expected)); + make_struct(tmp+nbr_cells++, new_atom(q->pl, err_type), NULL, 1, 1); + make_atom(tmp+nbr_cells++, new_atom(q->pl, expected)); make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); SET_OP(tmp+nbr_cells, OP_YFX); nbr_cells++; - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, functor)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, functor)); make_int(tmp+nbr_cells, !is_string(goal)?goal->arity:0); } else { //printf("error(%s(%s,(%s)),(%s)/%u).\n", err_type, expected, C_STR(q, c), functor, goal->arity); @@ -916,10 +916,10 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c check_heap_error(tmp); pl_idx nbr_cells = 0; make_struct(tmp+nbr_cells++, g_error_s, NULL, 2, 6+(c->nbr_cells-1)+extra); - make_struct(tmp+nbr_cells++, index_from_pool(q->pl, err_type), NULL, 2+extra, 2+(c->nbr_cells-1)+extra); + make_struct(tmp+nbr_cells++, new_atom(q->pl, err_type), NULL, 2+extra, 2+(c->nbr_cells-1)+extra); if (!extra) { - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, expected)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, expected)); } else { char tmpbuf[1024*8]; strcpy(tmpbuf, expected); @@ -928,18 +928,18 @@ bool throw_error3(query *q, cell *c, pl_idx c_ctx, const char *err_type, const c if (*ptr2) *ptr2++ = '\0'; while (ptr2) { - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, ptr)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, ptr)); ptr = ptr2; ptr2 = strchr(ptr, ','); } - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, ptr)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, ptr)); } nbr_cells += safe_copy_cells(tmp+nbr_cells, c, c->nbr_cells); make_struct(tmp+nbr_cells, g_slash_s, NULL, 2, 2); SET_OP(tmp+nbr_cells, OP_YFX); nbr_cells++; - make_atom(tmp+nbr_cells++, index_from_pool(q->pl, functor)); + make_atom(tmp+nbr_cells++, new_atom(q->pl, functor)); make_int(tmp+nbr_cells, !is_string(goal)?goal->arity:0); } diff --git a/src/heap.c b/src/heap.c index 0b1dbf65a..9b16fedb0 100644 --- a/src/heap.c +++ b/src/heap.c @@ -667,7 +667,7 @@ void allocate_structure(query *q, const char *functor, const cell *c) if (!tmp) return; tmp->tag = TAG_INTERNED; tmp->nbr_cells = 1; - tmp->val_off = index_from_pool(q->pl, functor); + tmp->val_off = new_atom(q->pl, functor); tmp->arity = 0; tmp->flags = 0; append_structure(q, c); diff --git a/src/module.c b/src/module.c index 07cd1c406..aed9e6312 100644 --- a/src/module.c +++ b/src/module.c @@ -296,7 +296,7 @@ static predicate *find_predicate_(module *m, cell *c, bool abolished) tmp.nbr_cells = 1; if (is_cstring(c)) { - tmp.val_off = index_from_pool(m->pl, C_STR(m, c)); + tmp.val_off = new_atom(m->pl, C_STR(m, c)); } sliter *iter = sl_find_key(m->index, &tmp); @@ -596,7 +596,7 @@ void set_discontiguous_in_db(module *m, const char *name, unsigned arity) { cell tmp = (cell){0}; tmp.tag = TAG_INTERNED; - tmp.val_off = index_from_pool(m->pl, name); + tmp.val_off = new_atom(m->pl, name); ensure(tmp.val_off != ERR_IDX); tmp.arity = arity; predicate *pr = find_predicate(m, &tmp); @@ -613,7 +613,7 @@ void set_multifile_in_db(module *m, const char *name, pl_idx arity) { cell tmp = (cell){0}; tmp.tag = TAG_INTERNED; - tmp.val_off = index_from_pool(m->pl, name); + tmp.val_off = new_atom(m->pl, name); ensure(tmp.val_off != ERR_IDX); tmp.arity = arity; predicate *pr = find_predicate(m, &tmp); @@ -630,7 +630,7 @@ void set_dynamic_in_db(module *m, const char *name, unsigned arity) { cell tmp = (cell){0}; tmp.tag = TAG_INTERNED; - tmp.val_off = index_from_pool(m->pl, name); + tmp.val_off = new_atom(m->pl, name); ensure(tmp.val_off != ERR_IDX); tmp.arity = arity; predicate *pr = find_predicate(m, &tmp); @@ -649,7 +649,7 @@ void set_meta_predicate_in_db(module *m, cell *c) unsigned arity = c->arity; cell tmp = (cell){0}; tmp.tag = TAG_INTERNED; - tmp.val_off = index_from_pool(m->pl, name); + tmp.val_off = new_atom(m->pl, name); ensure(tmp.val_off != ERR_IDX); tmp.arity = arity; predicate *pr = find_predicate(m, &tmp); @@ -953,7 +953,7 @@ bool do_use_foreign_module(module *m, cell *p) void convert_to_literal(module *m, cell *c) { char *src = DUP_STR(m, c); - pl_idx off = index_from_pool(m->pl, src); + pl_idx off = new_atom(m->pl, src); unshare_cell(c); c->tag = TAG_INTERNED; c->val_off = off; @@ -971,7 +971,7 @@ predicate *find_functor(module *m, const char *name, unsigned arity) { cell tmp = (cell){0}; tmp.tag = TAG_INTERNED; - tmp.val_off = index_from_pool(m->pl, name); + tmp.val_off = new_atom(m->pl, name); tmp.arity = arity; return find_predicate(m, &tmp); } diff --git a/src/parser.c b/src/parser.c index ce1326635..fa60f440d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -580,7 +580,7 @@ static bool directives(parser *p, cell *d) if (d->arity != 1) return false; - d->val_off = index_from_pool(p->pl, "$directive"); + d->val_off = new_atom(p->pl, "$directive"); CLR_OP(d); if (!strcmp(dirname, "initialization") && (c->arity == 1)) { @@ -1611,7 +1611,7 @@ static bool dcg_expansion(parser *p) cell *c = p->cl->cells; cell *tmp = alloc_on_heap(q, 1+c->nbr_cells+1+1); - make_struct(tmp, index_from_pool(p->pl, "dcg_translate"), NULL, 2, c->nbr_cells+1); + make_struct(tmp, new_atom(p->pl, "dcg_translate"), NULL, 2, c->nbr_cells+1); safe_copy_cells(tmp+1, p->cl->cells, c->nbr_cells); make_ref(tmp+1+c->nbr_cells, g_anon_s, p->cl->nbr_vars, 0); make_end(tmp+1+c->nbr_cells+1); @@ -3051,7 +3051,7 @@ static bool process_term(parser *p, cell *p1) } if (is_cstring(h)) { - pl_idx off = index_from_pool(p->m->pl, C_STR(p, h)); + pl_idx off = new_atom(p->m->pl, C_STR(p, h)); if (off == ERR_IDX) { p->error = true; return false; @@ -3709,7 +3709,7 @@ unsigned tokenize(parser *p, bool args, bool consing) if (p->is_quoted) c->flags |= FLAG_CSTR_QUOTED; - c->val_off = index_from_pool(p->m->pl, SB_cstr(p->token)); + c->val_off = new_atom(p->m->pl, SB_cstr(p->token)); ensure(c->val_off != ERR_IDX); } else { c->tag = TAG_CSTR; diff --git a/src/predicates.c b/src/predicates.c index f85e6cd45..d3fee8906 100644 --- a/src/predicates.c +++ b/src/predicates.c @@ -2359,7 +2359,7 @@ static void do_term_assign_vars(parser *p) else snprintf(tmpbuf, sizeof(tmpbuf), "%c%d", ch, n); - c->val_off = index_from_pool(p->m->pl, tmpbuf); + c->val_off = new_atom(p->m->pl, tmpbuf); c->flags = 0; } } @@ -2516,7 +2516,7 @@ static bool fn_iso_functor_3(query *q) tmp[0].nbr_cells = 1 + arity; if (is_cstring(p2)) { - tmp[0].val_off = index_from_pool(q->pl, C_STR(q, p2)); + tmp[0].val_off = new_atom(q->pl, C_STR(q, p2)); } else tmp[0].val_off = p2->val_off; @@ -2594,7 +2594,7 @@ static bool fn_iso_current_rule_1(query *q) cell tmp = (cell){0}; tmp.tag = TAG_INTERNED; - tmp.val_off = index_from_pool(q->pl, functor); + tmp.val_off = new_atom(q->pl, functor); tmp.arity = arity; if (search_predicate(q->st.m, &tmp, NULL)) @@ -2698,7 +2698,7 @@ static bool fn_iso_current_predicate_1(query *q) cell tmp = (cell){0}; tmp.tag = TAG_INTERNED; - tmp.val_off = is_interned(p1) ? p1->val_off : index_from_pool(q->pl, C_STR(q, p1)); + tmp.val_off = is_interned(p1) ? p1->val_off : new_atom(q->pl, C_STR(q, p1)); tmp.arity = get_smallint(p2); bool is_prebuilt = false; bool ok = search_predicate(q->st.m, &tmp, &is_prebuilt) != NULL; @@ -2726,11 +2726,11 @@ static bool fn_iso_current_prolog_flag_2(query *q) cell tmp; if (q->st.m->flags.double_quote_atom) - make_atom(&tmp, index_from_pool(q->pl, "atom")); + make_atom(&tmp, new_atom(q->pl, "atom")); else if (q->st.m->flags.double_quote_codes) - make_atom(&tmp, index_from_pool(q->pl, "codes")); + make_atom(&tmp, new_atom(q->pl, "codes")); else if (q->st.m->flags.double_quote_chars) - make_atom(&tmp, index_from_pool(q->pl, "chars")); + make_atom(&tmp, new_atom(q->pl, "chars")); return unify(q, p2, p2_ctx, &tmp, q->st.curr_frame); } else if (!CMP_STR_TO_CSTR(q, p1, "char_conversion")) { @@ -2758,12 +2758,12 @@ static bool fn_iso_current_prolog_flag_2(query *q) else if (q->st.m->flags.occurs_check == OCCURS_CHECK_FALSE) make_atom(&tmp, g_false_s); else - make_atom(&tmp, index_from_pool(q->pl, "error")); + make_atom(&tmp, new_atom(q->pl, "error")); return unify(q, p2, p2_ctx, &tmp, q->st.curr_frame); } else if (!CMP_STR_TO_CSTR(q, p1, "encoding")) { cell tmp; - make_atom(&tmp, index_from_pool(q->pl, "UTF-8")); + make_atom(&tmp, new_atom(q->pl, "UTF-8")); return unify(q, p2, p2_ctx, &tmp, q->st.curr_frame); } else if (!CMP_STR_TO_CSTR(q, p1, "strict_iso")) { cell tmp; @@ -2794,11 +2794,11 @@ static bool fn_iso_current_prolog_flag_2(query *q) return unify(q, p2, p2_ctx, &tmp, q->st.curr_frame); } else if (!CMP_STR_TO_CSTR(q, p1, "dialect")) { cell tmp; - make_atom(&tmp, index_from_pool(q->pl, "trealla")); + make_atom(&tmp, new_atom(q->pl, "trealla")); return unify(q, p2, p2_ctx, &tmp, q->st.curr_frame); } else if (!CMP_STR_TO_CSTR(q, p1, "integer_rounding_function")) { cell tmp; - make_atom(&tmp, index_from_pool(q->pl, "toward_zero")); + make_atom(&tmp, new_atom(q->pl, "toward_zero")); return unify(q, p2, p2_ctx, &tmp, q->st.curr_frame); } else if (!CMP_STR_TO_CSTR(q, p1, "bounded")) { cell tmp; @@ -2827,7 +2827,7 @@ static bool fn_iso_current_prolog_flag_2(query *q) sscanf(g_version, "v%u.%u.%u", &v1, &v2, &v3); cell *tmp = alloc_on_heap(q, 5); check_heap_error(tmp); - make_atom(&tmp[0], index_from_pool(q->pl, "trealla")); + make_atom(&tmp[0], new_atom(q->pl, "trealla")); make_int(&tmp[1], v1); make_int(&tmp[2], v2); make_int(&tmp[3], v3); @@ -2837,7 +2837,7 @@ static bool fn_iso_current_prolog_flag_2(query *q) return unify(q, p2, p2_ctx, tmp, q->st.curr_frame); } else if (!CMP_STR_TO_CSTR(q, p1, "version_git")) { cell tmp; - make_atom(&tmp, index_from_pool(q->pl, g_version)); + make_atom(&tmp, new_atom(q->pl, g_version)); return unify(q, p2, p2_ctx, &tmp, q->st.curr_frame); } else if (!CMP_STR_TO_CSTR(q, p1, "argv")) { if (g_avc >= g_ac) @@ -2859,10 +2859,10 @@ static bool fn_iso_current_prolog_flag_2(query *q) } else if (!CMP_STR_TO_CSTR(q, p1, "unknown")) { cell tmp; make_atom(&tmp, - q->st.m->flags.unknown == UNK_ERROR ? index_from_pool(q->pl, "error") : - q->st.m->flags.unknown == UNK_WARNING ? index_from_pool(q->pl, "warning") : - q->st.m->flags.unknown == UNK_CHANGEABLE ? index_from_pool(q->pl, "changeable") : - index_from_pool(q->pl, "fail")); + q->st.m->flags.unknown == UNK_ERROR ? new_atom(q->pl, "error") : + q->st.m->flags.unknown == UNK_WARNING ? new_atom(q->pl, "warning") : + q->st.m->flags.unknown == UNK_CHANGEABLE ? new_atom(q->pl, "changeable") : + new_atom(q->pl, "fail")); return unify(q, p2, p2_ctx, &tmp, q->st.curr_frame); } else if (!CMP_STR_TO_CSTR(q, p1, "generate_debug_info")) { } @@ -3921,7 +3921,7 @@ static bool fn_listing_1(query *q) if (!is_integer(p3)) return throw_error(q, p3, p1_ctx, "type_error", "integer"); - name = index_from_pool(q->pl, C_STR(q, p2)); + name = new_atom(q->pl, C_STR(q, p2)); arity = get_smallint(p3); if (!CMP_STR_TO_CSTR(q, p1, "//")) @@ -4023,10 +4023,10 @@ static bool fn_source_info_2(query *q) for (db_entry *dbe = pr->head; dbe; dbe = dbe->next) { cell tmp[8]; make_struct(tmp+0, g_dot_s, NULL, 2, 7); - make_struct(tmp+1, index_from_pool(q->pl, "filename"), NULL, 1, 1); + make_struct(tmp+1, new_atom(q->pl, "filename"), NULL, 1, 1); make_cstring(tmp+2, dbe->filename); make_struct(tmp+3, g_dot_s, NULL, 2, 4); - make_struct(tmp+4, index_from_pool(q->pl, "lines"), NULL, 2, 2); + make_struct(tmp+4, new_atom(q->pl, "lines"), NULL, 2, 2); make_uint(tmp+5, dbe->line_nbr_start); make_uint(tmp+6, dbe->line_nbr_end); make_atom(tmp+7, g_nil_s); @@ -5672,7 +5672,7 @@ static bool fn_crypto_data_hash_3(query *q) if (!CMP_STR_TO_CSTR(q, h, "algorithm")) { if (is_var(arg)) { cell tmp; - make_atom(&tmp, index_from_pool(q->pl, "sha256")); + make_atom(&tmp, new_atom(q->pl, "sha256")); unify(q, arg, arg_ctx, &tmp, q->st.curr_frame); is_sha384 = is_sha512 = false; is_sha256 = true; @@ -5786,14 +5786,17 @@ static bool fn_base64_3(query *q) return throw_error(q, p1, p1_ctx, "instantiation_error", "atom"); } -static char *url_encode(const char *src, int len, char *dstbuf) +char *url_encode(const char *src, int len, char *dstbuf) { char *dst = dstbuf; // As per RFC3986 (2005) while (len-- > 0) { - if (!isalnum(*src) && (*src != '-') && (*src != '_') && (*src != '.') && (*src != '~')) + if (*src == ' ') { + *dst++ = '+'; + src++; + } else if (!isalnum(*src) && (*src != '-') && (*src != '_') && (*src != '.') && (*src != '~')) dst += sprintf(dst, "%%%02X", *src++); else *dst++ = *src++; @@ -6398,17 +6401,17 @@ static bool fn_sys_legacy_predicate_property_2(query *q) if (evaluable) return false; - make_atom(&tmp, index_from_pool(q->pl, "built_in")); + make_atom(&tmp, new_atom(q->pl, "built_in")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; - make_atom(&tmp, index_from_pool(q->pl, "static")); + make_atom(&tmp, new_atom(q->pl, "static")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; - make_atom(&tmp, index_from_pool(q->pl, "dynamic")); + make_atom(&tmp, new_atom(q->pl, "dynamic")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return false; @@ -6422,58 +6425,58 @@ static bool fn_sys_legacy_predicate_property_2(query *q) return false; if (!pr->is_dynamic && !is_var(p2)) { - make_atom(&tmp, index_from_pool(q->pl, "built_in")); + make_atom(&tmp, new_atom(q->pl, "built_in")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; } if (!pr->is_dynamic) { - make_atom(&tmp, index_from_pool(q->pl, "static")); + make_atom(&tmp, new_atom(q->pl, "static")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; } if (pr->is_dynamic) { - make_atom(&tmp, index_from_pool(q->pl, "dynamic")); + make_atom(&tmp, new_atom(q->pl, "dynamic")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; } if (pr->is_multifile) { - make_atom(&tmp, index_from_pool(q->pl, "multifile")); + make_atom(&tmp, new_atom(q->pl, "multifile")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; } if (pr->is_public) { - make_atom(&tmp, index_from_pool(q->pl, "public")); + make_atom(&tmp, new_atom(q->pl, "public")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; } if (pr->is_public) { - make_atom(&tmp, index_from_pool(q->pl, "exported")); + make_atom(&tmp, new_atom(q->pl, "exported")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; } - make_atom(&tmp, index_from_pool(q->pl, "static")); + make_atom(&tmp, new_atom(q->pl, "static")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; - make_atom(&tmp, index_from_pool(q->pl, "meta_predicate")); + make_atom(&tmp, new_atom(q->pl, "meta_predicate")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; - make_atom(&tmp, index_from_pool(q->pl, "visible")); + make_atom(&tmp, new_atom(q->pl, "visible")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; @@ -6499,22 +6502,22 @@ static bool fn_sys_legacy_evaluable_property_2(query *q) if (!evaluable) return false; - make_atom(&tmp, index_from_pool(q->pl, "built_in")); + make_atom(&tmp, new_atom(q->pl, "built_in")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; - make_atom(&tmp, index_from_pool(q->pl, "static")); + make_atom(&tmp, new_atom(q->pl, "static")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return true; - make_atom(&tmp, index_from_pool(q->pl, "dynamic")); + make_atom(&tmp, new_atom(q->pl, "dynamic")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return false; - make_atom(&tmp, index_from_pool(q->pl, "foreign")); + make_atom(&tmp, new_atom(q->pl, "foreign")); if (unify(q, p2, p2_ctx, &tmp, q->st.curr_frame)) return false; @@ -6872,7 +6875,7 @@ static bool fn_sys_list_attributed_1(query *q) continue; cell v; - make_ref(&v, index_from_pool(q->pl, p->vartab.var_name[i]), i, q->st.curr_frame); + make_ref(&v, new_atom(q->pl, p->vartab.var_name[i]), i, q->st.curr_frame); if (first) { allocate_list(q, &v); @@ -7247,7 +7250,7 @@ static bool fn_current_module_1(query *q) check_heap_error(push_choice(q)); module *m = q->current_m = q->pl->modules; cell tmp; - make_atom(&tmp, index_from_pool(q->pl, m->name)); + make_atom(&tmp, new_atom(q->pl, m->name)); return unify(q, p1, p1_ctx, &tmp, q->st.curr_frame); } @@ -7261,7 +7264,7 @@ static bool fn_current_module_1(query *q) check_heap_error(push_choice(q)); cell tmp; - make_atom(&tmp, index_from_pool(q->pl, m->name)); + make_atom(&tmp, new_atom(q->pl, m->name)); return unify(q, p1, p1_ctx, &tmp, q->st.curr_frame); } @@ -7296,7 +7299,7 @@ static bool fn_attribute_3(query *q) while (m) { if ((arity == m->arity) && !strcmp(name, m->name)) { cell tmp; - make_atom(&tmp, index_from_pool(q->pl, m->orig->name)); + make_atom(&tmp, new_atom(q->pl, m->orig->name)); return unify(q, p1, p1_ctx, &tmp, q->st.curr_frame); } @@ -7304,7 +7307,7 @@ static bool fn_attribute_3(query *q) } cell tmp; - make_atom(&tmp, index_from_pool(q->pl, q->st.m->name)); + make_atom(&tmp, new_atom(q->pl, q->st.m->name)); return unify(q, p1, p1_ctx, &tmp, q->st.curr_frame); } @@ -7317,7 +7320,7 @@ static bool fn_prolog_load_context_2(query *q) return false; cell tmp; - make_atom(&tmp, index_from_pool(q->pl, q->st.prev_m->name)); + make_atom(&tmp, new_atom(q->pl, q->st.prev_m->name)); return unify(q, p2, p2_ctx, &tmp, q->st.curr_frame); } @@ -7327,7 +7330,7 @@ static bool fn_module_1(query *q) if (is_var(p1)) { cell tmp; - make_atom(&tmp, index_from_pool(q->pl, q->st.m->name)); + make_atom(&tmp, new_atom(q->pl, q->st.m->name)); return unify(q, p1, p1_ctx, &tmp, q->st.curr_frame); } @@ -8004,7 +8007,7 @@ static void load_properties(module *m) static void load_flags(query *q) { cell tmp; - make_atom(&tmp, index_from_pool(q->pl, "$current_prolog_flag")); + make_atom(&tmp, new_atom(q->pl, "$current_prolog_flag")); tmp.arity = 2; if (do_abolish(q, &tmp, &tmp, false) != true) diff --git a/src/prolog.c b/src/prolog.c index 21628d9eb..f8ec9a775 100644 --- a/src/prolog.c +++ b/src/prolog.c @@ -45,7 +45,7 @@ bool is_multifile_in_db(prolog *pl, const char *mod, const char *name, unsigned cell tmp = (cell){0}; tmp.tag = TAG_INTERNED; - tmp.val_off = index_from_pool(m->pl, name); + tmp.val_off = new_atom(m->pl, name); if (tmp.val_off == ERR_IDX) return false; tmp.arity = arity; predicate *pr = find_predicate(m, &tmp); @@ -77,7 +77,7 @@ static pl_idx add_to_pool(prolog *pl, const char *name) return (pl_idx)offset; } -pl_idx index_from_pool(prolog *pl, const char *name) +pl_idx new_atom(prolog *pl, const char *name) { const void *val; @@ -399,61 +399,61 @@ static bool g_init(prolog *pl) CHECK_SENTINEL(pl->symtab = sl_create((void*)fake_strcmp, (void*)keyfree, NULL), NULL); sl_allow_dups(pl->symtab, false); - CHECK_SENTINEL(index_from_pool(pl, "dummy"), ERR_IDX); - CHECK_SENTINEL(g_false_s = index_from_pool(pl, "false"), ERR_IDX); - CHECK_SENTINEL(g_true_s = index_from_pool(pl, "true"), ERR_IDX); - CHECK_SENTINEL(g_at_s = index_from_pool(pl, "@"), ERR_IDX); - CHECK_SENTINEL(g_conjunction_s = index_from_pool(pl, ","), ERR_IDX); - CHECK_SENTINEL(g_disjunction_s = index_from_pool(pl, ";"), ERR_IDX); - CHECK_SENTINEL(g_if_then_s = index_from_pool(pl, "->"), ERR_IDX); - CHECK_SENTINEL(g_soft_cut_s = index_from_pool(pl, "*->"), ERR_IDX); - CHECK_SENTINEL(g_negation_s = index_from_pool(pl, "\\+"), ERR_IDX); - CHECK_SENTINEL(g_dot_s = index_from_pool(pl, "."), ERR_IDX); - CHECK_SENTINEL(g_plus_s = index_from_pool(pl, "+"), ERR_IDX); - CHECK_SENTINEL(g_minus_s = index_from_pool(pl, "-"), ERR_IDX); - CHECK_SENTINEL(g_empty_s = index_from_pool(pl, ""), ERR_IDX); - CHECK_SENTINEL(g_anon_s = index_from_pool(pl, "_"), ERR_IDX); - CHECK_SENTINEL(g_dcg_s = index_from_pool(pl, "-->"), ERR_IDX); - CHECK_SENTINEL(g_call_s = index_from_pool(pl, "call"), ERR_IDX); - CHECK_SENTINEL(g_syscall_s = index_from_pool(pl, "$call"), ERR_IDX); - CHECK_SENTINEL(g_braces_s = index_from_pool(pl, "braces"), ERR_IDX); - CHECK_SENTINEL(g_unify_s = index_from_pool(pl, "="), ERR_IDX); - CHECK_SENTINEL(g_on_s = index_from_pool(pl, "on"), ERR_IDX); - CHECK_SENTINEL(g_off_s = index_from_pool(pl, "off"), ERR_IDX); - CHECK_SENTINEL(g_cut_s = index_from_pool(pl, "!"), ERR_IDX); - CHECK_SENTINEL(g_nil_s = index_from_pool(pl, "[]"), ERR_IDX); - CHECK_SENTINEL(g_braces_s = index_from_pool(pl, "{}"), ERR_IDX); - CHECK_SENTINEL(g_fail_s = index_from_pool(pl, "fail"), ERR_IDX); - CHECK_SENTINEL(g_neck_s = index_from_pool(pl, ":-"), ERR_IDX); - CHECK_SENTINEL(g_eof_s = index_from_pool(pl, "end_of_file"), ERR_IDX); - CHECK_SENTINEL(g_lt_s = index_from_pool(pl, "<"), ERR_IDX); - CHECK_SENTINEL(g_gt_s = index_from_pool(pl, ">"), ERR_IDX); - CHECK_SENTINEL(g_eq_s = index_from_pool(pl, "="), ERR_IDX); - CHECK_SENTINEL(g_once_s = index_from_pool(pl, "once"), ERR_IDX); - CHECK_SENTINEL(g_throw_s = index_from_pool(pl, "throw"), ERR_IDX); - CHECK_SENTINEL(g_error_s = index_from_pool(pl, "error"), ERR_IDX); - CHECK_SENTINEL(g_slash_s = index_from_pool(pl, "/"), ERR_IDX); - CHECK_SENTINEL(g_goal_expansion_s = index_from_pool(pl, "goal_expansion"), ERR_IDX); - CHECK_SENTINEL(g_term_expansion_s = index_from_pool(pl, "term_expansion"), ERR_IDX); - CHECK_SENTINEL(g_tm_s = index_from_pool(pl, "tm"), ERR_IDX); - CHECK_SENTINEL(g_float_s = index_from_pool(pl, "float"), ERR_IDX); - - CHECK_SENTINEL(g_sys_elapsed_s = index_from_pool(pl, "$elapsed"), ERR_IDX); - CHECK_SENTINEL(g_sys_queue_s = index_from_pool(pl, "$queue"), ERR_IDX); - CHECK_SENTINEL(g_sys_var_s = index_from_pool(pl, "$VAR"), ERR_IDX); - CHECK_SENTINEL(g_sys_stream_property_s = index_from_pool(pl, "$stream_property"), ERR_IDX); - CHECK_SENTINEL(g_post_unify_hook_s = index_from_pool(pl, "$post_unify_hook"), ERR_IDX); - CHECK_SENTINEL(g_sys_record_key_s = index_from_pool(pl, "$record_key"), ERR_IDX); - CHECK_SENTINEL(g_sys_ne_s = index_from_pool(pl, "$ne"), ERR_IDX); - CHECK_SENTINEL(g_sys_incr_s = index_from_pool(pl, "$incr"), ERR_IDX); - CHECK_SENTINEL(g_sys_block_catcher_s = index_from_pool(pl, "$block_catcher"), ERR_IDX); - CHECK_SENTINEL(g_sys_drop_barrier_s = index_from_pool(pl, "$drop_barrier"), ERR_IDX); - CHECK_SENTINEL(g_sys_cleanup_if_det_s = index_from_pool(pl, "$cleanup_if_det"), ERR_IDX); - CHECK_SENTINEL(g_sys_cut_if_det_s = index_from_pool(pl, "$cut_if_det"), ERR_IDX); - CHECK_SENTINEL(g_sys_table_s = index_from_pool(pl, "$table"), ERR_IDX); - CHECK_SENTINEL(g_as_s = index_from_pool(pl, "as"), ERR_IDX); - CHECK_SENTINEL(g_colon_s = index_from_pool(pl, ":"), ERR_IDX); - CHECK_SENTINEL(g_caret_s = index_from_pool(pl, "^"), ERR_IDX); + CHECK_SENTINEL(new_atom(pl, "dummy"), ERR_IDX); + CHECK_SENTINEL(g_false_s = new_atom(pl, "false"), ERR_IDX); + CHECK_SENTINEL(g_true_s = new_atom(pl, "true"), ERR_IDX); + CHECK_SENTINEL(g_at_s = new_atom(pl, "@"), ERR_IDX); + CHECK_SENTINEL(g_conjunction_s = new_atom(pl, ","), ERR_IDX); + CHECK_SENTINEL(g_disjunction_s = new_atom(pl, ";"), ERR_IDX); + CHECK_SENTINEL(g_if_then_s = new_atom(pl, "->"), ERR_IDX); + CHECK_SENTINEL(g_soft_cut_s = new_atom(pl, "*->"), ERR_IDX); + CHECK_SENTINEL(g_negation_s = new_atom(pl, "\\+"), ERR_IDX); + CHECK_SENTINEL(g_dot_s = new_atom(pl, "."), ERR_IDX); + CHECK_SENTINEL(g_plus_s = new_atom(pl, "+"), ERR_IDX); + CHECK_SENTINEL(g_minus_s = new_atom(pl, "-"), ERR_IDX); + CHECK_SENTINEL(g_empty_s = new_atom(pl, ""), ERR_IDX); + CHECK_SENTINEL(g_anon_s = new_atom(pl, "_"), ERR_IDX); + CHECK_SENTINEL(g_dcg_s = new_atom(pl, "-->"), ERR_IDX); + CHECK_SENTINEL(g_call_s = new_atom(pl, "call"), ERR_IDX); + CHECK_SENTINEL(g_syscall_s = new_atom(pl, "$call"), ERR_IDX); + CHECK_SENTINEL(g_braces_s = new_atom(pl, "braces"), ERR_IDX); + CHECK_SENTINEL(g_unify_s = new_atom(pl, "="), ERR_IDX); + CHECK_SENTINEL(g_on_s = new_atom(pl, "on"), ERR_IDX); + CHECK_SENTINEL(g_off_s = new_atom(pl, "off"), ERR_IDX); + CHECK_SENTINEL(g_cut_s = new_atom(pl, "!"), ERR_IDX); + CHECK_SENTINEL(g_nil_s = new_atom(pl, "[]"), ERR_IDX); + CHECK_SENTINEL(g_braces_s = new_atom(pl, "{}"), ERR_IDX); + CHECK_SENTINEL(g_fail_s = new_atom(pl, "fail"), ERR_IDX); + CHECK_SENTINEL(g_neck_s = new_atom(pl, ":-"), ERR_IDX); + CHECK_SENTINEL(g_eof_s = new_atom(pl, "end_of_file"), ERR_IDX); + CHECK_SENTINEL(g_lt_s = new_atom(pl, "<"), ERR_IDX); + CHECK_SENTINEL(g_gt_s = new_atom(pl, ">"), ERR_IDX); + CHECK_SENTINEL(g_eq_s = new_atom(pl, "="), ERR_IDX); + CHECK_SENTINEL(g_once_s = new_atom(pl, "once"), ERR_IDX); + CHECK_SENTINEL(g_throw_s = new_atom(pl, "throw"), ERR_IDX); + CHECK_SENTINEL(g_error_s = new_atom(pl, "error"), ERR_IDX); + CHECK_SENTINEL(g_slash_s = new_atom(pl, "/"), ERR_IDX); + CHECK_SENTINEL(g_goal_expansion_s = new_atom(pl, "goal_expansion"), ERR_IDX); + CHECK_SENTINEL(g_term_expansion_s = new_atom(pl, "term_expansion"), ERR_IDX); + CHECK_SENTINEL(g_tm_s = new_atom(pl, "tm"), ERR_IDX); + CHECK_SENTINEL(g_float_s = new_atom(pl, "float"), ERR_IDX); + + CHECK_SENTINEL(g_sys_elapsed_s = new_atom(pl, "$elapsed"), ERR_IDX); + CHECK_SENTINEL(g_sys_queue_s = new_atom(pl, "$queue"), ERR_IDX); + CHECK_SENTINEL(g_sys_var_s = new_atom(pl, "$VAR"), ERR_IDX); + CHECK_SENTINEL(g_sys_stream_property_s = new_atom(pl, "$stream_property"), ERR_IDX); + CHECK_SENTINEL(g_post_unify_hook_s = new_atom(pl, "$post_unify_hook"), ERR_IDX); + CHECK_SENTINEL(g_sys_record_key_s = new_atom(pl, "$record_key"), ERR_IDX); + CHECK_SENTINEL(g_sys_ne_s = new_atom(pl, "$ne"), ERR_IDX); + CHECK_SENTINEL(g_sys_incr_s = new_atom(pl, "$incr"), ERR_IDX); + CHECK_SENTINEL(g_sys_block_catcher_s = new_atom(pl, "$block_catcher"), ERR_IDX); + CHECK_SENTINEL(g_sys_drop_barrier_s = new_atom(pl, "$drop_barrier"), ERR_IDX); + CHECK_SENTINEL(g_sys_cleanup_if_det_s = new_atom(pl, "$cleanup_if_det"), ERR_IDX); + CHECK_SENTINEL(g_sys_cut_if_det_s = new_atom(pl, "$cut_if_det"), ERR_IDX); + CHECK_SENTINEL(g_sys_table_s = new_atom(pl, "$table"), ERR_IDX); + CHECK_SENTINEL(g_as_s = new_atom(pl, "as"), ERR_IDX); + CHECK_SENTINEL(g_colon_s = new_atom(pl, ":"), ERR_IDX); + CHECK_SENTINEL(g_caret_s = new_atom(pl, "^"), ERR_IDX); return error; } diff --git a/src/prolog.h b/src/prolog.h index 731f84f98..bf5284f93 100644 --- a/src/prolog.h +++ b/src/prolog.h @@ -6,7 +6,7 @@ builtins *get_builtin(prolog *pl, const char *name, size_t len, unsigned arity, builtins *get_help(prolog *pl, const char *name, unsigned arity, bool *found, bool *evaluable); module *find_module(prolog *pl, const char *name); module *find_next_module(prolog *pl, module *m); -pl_idx index_from_pool(prolog *pl, const char *name); +pl_idx new_atom(prolog *pl, const char *name); bool is_multifile_in_db(prolog *pl, const char *mod, const char *name, unsigned arity); void load_builtins(prolog *pl); void uuid_gen(prolog *pl, uuid *u); diff --git a/src/query.c b/src/query.c index 470ab6b90..a2d78f85b 100644 --- a/src/query.c +++ b/src/query.c @@ -471,7 +471,7 @@ static bool expand_meta_predicate(query *q, predicate *pr) else if (m->val_off == g_colon_s) { make_struct(tmp, g_colon_s, NULL, 2, 1+k->nbr_cells); SET_OP(tmp, OP_XFY); tmp++; - make_atom(tmp++, index_from_pool(q->pl, pr->m->name)); + make_atom(tmp++, new_atom(q->pl, pr->m->name)); } tmp += safe_copy_cells(tmp, k, k->nbr_cells); diff --git a/src/query.h b/src/query.h index a03dd1a0b..a81ac62c6 100644 --- a/src/query.h +++ b/src/query.h @@ -23,6 +23,8 @@ bool do_read_term(query *q, stream *str, cell *p1, pl_idx p1_ctx, cell *p2, pl_i bool do_yield(query *q, int msecs); void do_yield_at(query *q, unsigned int time_in_ms); +char *url_encode(const char *src, int len, char *dstbuf); +char *url_decode(const char *src, char *dstbuf); cell *do_term_variables(query *q, cell *p1, pl_idx p1_ctx); bool query_redo(query *q); bool has_next_key(query *q); diff --git a/src/streams.c b/src/streams.c index 9e0fc637d..647c2cea9 100644 --- a/src/streams.c +++ b/src/streams.c @@ -726,13 +726,13 @@ static bool do_stream_property(query *q) cell tmp; if (str->eof_action == eof_action_eof_code) - make_atom(&tmp, index_from_pool(q->pl, "eof_code")); + make_atom(&tmp, new_atom(q->pl, "eof_code")); else if (str->eof_action == eof_action_error) - make_atom(&tmp, index_from_pool(q->pl, "error")); + make_atom(&tmp, new_atom(q->pl, "error")); else if (str->eof_action == eof_action_reset) - make_atom(&tmp, index_from_pool(q->pl, "reset")); + make_atom(&tmp, new_atom(q->pl, "reset")); else - make_atom(&tmp, index_from_pool(q->pl, "none")); + make_atom(&tmp, new_atom(q->pl, "none")); return unify(q, c, c_ctx, &tmp, q->st.curr_frame); } @@ -764,11 +764,11 @@ static bool do_stream_property(query *q) cell tmp; if (str->at_end_of_file) - make_atom(&tmp, index_from_pool(q->pl, "past")); + make_atom(&tmp, new_atom(q->pl, "past")); else if (at_end_of_file) - make_atom(&tmp, index_from_pool(q->pl, "at")); + make_atom(&tmp, new_atom(q->pl, "at")); else - make_atom(&tmp, index_from_pool(q->pl, "not")); + make_atom(&tmp, new_atom(q->pl, "not")); return unify(q, c, c_ctx, &tmp, q->st.curr_frame); } @@ -6195,6 +6195,275 @@ static bool fn_accept_2(query *q) return unify(q, p1, p1_ctx, &tmp, q->st.curr_frame); } +static bool do_parse_parts(query *q, bool full) +{ + GET_FIRST_ARG(p1,atom_or_var); + GET_NEXT_ARG(p2,iso_list); + char protocol[256], host[1024], path[8192], search[8192], fragment[8192]; + protocol[0] = host[0] = path[0] = search[0] = fragment[0] = '\0'; + int port = 0; + LIST_HANDLER(p2); + + while (is_iso_list(p2)) { + cell *h = LIST_HEAD(p2); + h = deref(q, h, p2_ctx); + pl_idx h_ctx = q->latest_ctx; + + if (!strcmp(C_STR(q, h), "protocol")) { + if (!is_atom(h+1)) + return throw_error(q, h+1, p2_ctx, "type_error", "atom"); + + sprintf(protocol, C_STR(q, h+1)); + } else if (!strcmp(C_STR(q, h), "host")) { + if (!is_atom(h+1)) + return throw_error(q, h+1, p2_ctx, "type_error", "atom"); + + sprintf(host, C_STR(q, h+1)); + } else if (!strcmp(C_STR(q, h), "port")) { + if (!is_smallint(h+1)) + return throw_error(q, h+1, p2_ctx, "type_error", "integer"); + + port = get_smallint(h+1); + } else if (!strcmp(C_STR(q, h), "path")) { + if (!is_atom(h+1)) + return throw_error(q, h+1, p2_ctx, "type_error", "atom"); + + sprintf(path, C_STR(q, h+1)); + } else if (!strcmp(C_STR(q, h), "search")) { + cell *h1 = h + 1; + h1 = deref(q, h1, h_ctx); + pl_idx h1_ctx = q->latest_ctx; + + if (!is_iso_list(h1)) + return throw_error(q, h1, h_ctx, "type_error", "list"); + + char *dst = search; + LIST_HANDLER(h1); + + while (is_iso_list(h1)) { + cell *c = LIST_HEAD(h1); + c = deref(q, c, h1_ctx); + + if (!is_structure(c)) + return throw_error(q, c, h1_ctx, "type_error", "compound"); + + if (!is_atom(c+1)) + return throw_error(q, c+1, h1_ctx, "type_error", "atom"); + + if (!is_atom(c+2)) + return throw_error(q, c+2, h1_ctx, "type_error", "atom"); + + size_t len2 = C_STRLEN(q, c+2); + char *dstbuf2 = malloc(len2+1); + check_heap_error(dstbuf2); + url_encode(C_STR(q, c+2), len2, dstbuf2); + dst += sprintf(dst, "%s=%s", C_STR(q, c+1), dstbuf2); + free(dstbuf2); + + h1 = LIST_TAIL(h1); + h1 = deref(q, h1, h1_ctx); + h1_ctx = q->latest_ctx; + + if (!is_nil(h1)) + dst += sprintf(dst, "&"); + } + } else if (!strcmp(C_STR(q, h), "fragment")) { + if (!is_atom(h+1)) + return throw_error(q, h+1, p2_ctx, "type_error", "atom"); + + sprintf(fragment, C_STR(q, h+1)); + } + + p2 = LIST_TAIL(p2); + p2 = deref(q, p2, p2_ctx); + p2_ctx = q->latest_ctx; + } + + SB(pr); + SB_sprintf(pr, "%s://%s", protocol, host); + if (port) SB_sprintf(pr, "%d", port); + if (path[0]) SB_sprintf(pr, "%s", path); + if (search[0]) SB_sprintf(pr, "?%s", search); + if (fragment[0]) SB_sprintf(pr, "#%s", fragment); + cell tmp; + make_cstring(&tmp, SB_cstr(pr)); + return unify(q, p1, p1_ctx, &tmp, q->st.curr_frame); +} + +static bool do_parse_url(query *q, bool full) +{ + GET_FIRST_ARG(p1,atom); + GET_NEXT_ARG(p2,iso_list_or_var); + + const char *src = C_STR(q, p1); + char protocol[256], host[1024], path[8192], search[8192], fragment[8192]; + protocol[0] = host[0] = path[0] = search[0] = fragment[0] = '\0'; + + if (full) + sscanf(src, "%255[^:\r\n]://%1023[^/\r\n]%8191[^?\r\n]?%8191[^#\r\n]#%8191[^\r\n]", protocol, host, path, search, fragment); + else + sscanf(src, "%8191[^?\r\n]?%8191[^#\r\n]#%8191[^\r\n]", path, search, fragment); + + protocol[255] = host[1023] = path[8191] = search[8191] = fragment[8191] = '\0'; + char *dstbuf; + size_t len; + cell tmp[3]; + + if (search[0]) { + allocate_list(q, tmp); + char key[8192], search2[8192]; + key[0] = search2[0] = '\0'; + char *src2 = search, *dst2 = key; + bool first = true; + + while (*src2) { + if (*src2 == '=') { + src2++; + dst2 = search2; + *dst2 = '\0'; + } else if (*src2 == '&') { + make_struct(tmp, new_atom(q->pl, "="), NULL, 2, 2); + SET_OP(tmp, OP_YFX); + + len = strlen(key); + dstbuf = malloc(len+1); + check_heap_error(dstbuf); + url_decode(key, dstbuf); + make_cstring(tmp+1, dstbuf); + free(dstbuf); + + len = strlen(search2); + dstbuf = malloc(len+1); + check_heap_error(dstbuf); + url_decode(search2, dstbuf); + make_cstring(tmp+2, dstbuf); + free(dstbuf); + + if (first) { + allocate_list(q, tmp); + first = false; + } else + append_list(q, tmp); + + src2++; + dst2 = key; + *dst2 = '\0'; + } + + *dst2++ = *src2++; + *dst2 = '\0'; + } + + make_struct(tmp, new_atom(q->pl, "="), NULL, 2, 2); + SET_OP(tmp, OP_YFX); + + len = strlen(key); + dstbuf = malloc(len+1); + check_heap_error(dstbuf); + url_decode(key, dstbuf); + make_cstring(tmp+1, dstbuf); + free(dstbuf); + + len = strlen(search2); + dstbuf = malloc(len+1); + check_heap_error(dstbuf); + url_decode(search2, dstbuf); + make_cstring(tmp+2, dstbuf); + free(dstbuf); + append_list(q, tmp); + + cell *l = end_list(q); + cell *tmp2 = alloc_on_heap(q, 1 + l->nbr_cells); + make_struct(tmp2, new_atom(q->pl, "search"), NULL, 1, l->nbr_cells); + safe_copy_cells(tmp2+1, l, l->nbr_cells); + allocate_list(q, tmp2); + } + + if (protocol[0]) { + make_struct(tmp, new_atom(q->pl, "protocol"), NULL, 1, 1); + make_cstring(tmp+1, protocol); + + if (search[0]) + append_list(q, tmp); + else + allocate_list(q, tmp); + } + + if (host[0]) { + char host2[256]; host2[0] = '\0'; + int port = 0; + sscanf(host, "%255[^:]:%d", host2, &port); + host2[255] = '\0'; + + make_struct(tmp, new_atom(q->pl, "host"), NULL, 1, 1); + make_cstring(tmp+1, host2); + append_list(q, tmp); + + if (port) { + make_struct(tmp, new_atom(q->pl, "port"), NULL, 1, 1); + make_int(tmp+1, port); + append_list(q, tmp); + } + } + + if (!path[0]) + strcpy(path, "/"); + + if (path[0]) { + len = strlen(path); + dstbuf = malloc(len+1); + check_heap_error(dstbuf); + url_decode(path, dstbuf); + src = dstbuf; + make_struct(tmp, new_atom(q->pl, "path"), NULL, 1, 1); + make_cstring(tmp+1, path); + append_list(q, tmp); + free(dstbuf); + } + + if (fragment[0]) { + len = strlen(fragment); + dstbuf = malloc(len+1); + check_heap_error(dstbuf); + url_decode(path, dstbuf); + src = dstbuf; + make_struct(tmp, new_atom(q->pl, "fragment"), NULL, 1, 1); + make_cstring(tmp+1, fragment); + append_list(q, tmp); + free(dstbuf); + } + + return unify(q, p2, p2_ctx, end_list(q), q->st.curr_frame); +} + +static bool fn_parse_url_2(query *q) +{ + GET_FIRST_ARG(p1,atom_or_var); + GET_NEXT_ARG(p2,iso_list_or_var); + + if (is_var(p1) && is_var(p2)) + return throw_error2(q, p1, p1_ctx, "uninstantiation_error", "not_sufficiently_instantiated", p2); + + if (is_var(p2)) + return do_parse_url(q, true); + else + return do_parse_parts(q, true); +} + +static bool fn_parse_location_2(query *q) +{ + GET_FIRST_ARG(p1,atom_or_var); + GET_NEXT_ARG(p2,iso_list_or_var); + + if (is_var(p1) && is_var(p2)) + return throw_error2(q, p1, p1_ctx, "uninstantiation_error", "not_sufficiently_instantiated", p2); + + if (is_var(p2)) + return do_parse_url(q, false); + else + return do_parse_parts(q, false); +} + static bool fn_client_5(query *q) { GET_FIRST_ARG(p1,atom); @@ -7343,6 +7612,8 @@ builtins g_files_bifs[] = {"read_line_to_string", 2, fn_read_line_to_string_2, "+stream,-character_list", false, false, BLAH}, {"read_file_to_string", 3, fn_read_file_to_string_3, "+atom,-string,+options", false, false, BLAH}, + {"parse_location", 2, fn_parse_location_2, "?atom,?list", false, false, BLAH}, + {"parse_url", 2, fn_parse_url_2, "?atom,?list", false, false, BLAH}, {"client", 5, fn_client_5, "+atom,-atom,-atom,-atom,+list", false, false, BLAH}, {"server", 3, fn_server_3, "+atom,--stream,+list", false, false, BLAH}, {"accept", 2, fn_accept_2, "+stream,--stream", false, false, BLAH}, diff --git a/src/toplevel.c b/src/toplevel.c index 9208dabb7..35dab736a 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -509,7 +509,7 @@ void dump_vars(query *q, bool partial) q->variable_names_ctx = 0; q->tab_idx = 0; cell p1; - make_atom(&p1, index_from_pool(q->pl, "dump_attvars")); + make_atom(&p1, new_atom(q->pl, "dump_attvars")); cell *tmp = prepare_call(q, false, &p1, q->st.curr_frame, 1); pl_idx nbr_cells = NOPREFIX_LEN + p1.nbr_cells; make_end(tmp+nbr_cells);