static foreign_t archive_property(term_t archive, term_t prop, term_t value) { archive_wrapper *ar; atom_t pn; const char *s; if ( !get_archive(archive, &ar) || !PL_get_atom_ex(prop, &pn) ) return FALSE; #ifdef HAVE_ARCHIVE_FILTER_COUNT if ( pn == ATOM_filter ) { int i, fcount = archive_filter_count(ar->archive); term_t tail = PL_copy_term_ref(value); term_t head = PL_new_term_ref(); for(i=0; i<fcount; i++) { s = archive_filter_name(ar->archive, i); if ( !s || strcmp(s, "none") == 0 ) continue; if ( !PL_unify_list(tail, head, tail) || !PL_unify_atom_chars(head, s) ) return FALSE; } return PL_unify_nil(tail); } #endif return FALSE; }
static int get_show_map(term_t t, int *map) { int rc; term_t tail = PL_copy_term_ref(t); term_t head = PL_new_term_ref(); *map = 0; while (PL_get_list(tail, head, tail)) { atom_t a; if (!(rc = PL_get_atom_ex(head, &a))) { goto out; } if (a == ATOM_atoms) { *map |= clingo_show_type_atoms; } else if (a == ATOM_terms) { *map |= clingo_show_type_terms; } else if (a == ATOM_shown) { *map |= clingo_show_type_shown; } else if (a == ATOM_csp) { *map |= clingo_show_type_csp; } else if (a == ATOM_comp) { *map |= clingo_show_type_complement; } else { rc = PL_domain_error("clingo_show", head); goto out; } } if (!(rc = PL_get_nil_ex(tail))) { goto out; } out: return rc; }
static int get_tz_arg(int i, term_t t, term_t a, atom_t *tz) { GET_LD atom_t name; _PL_get_arg(i, t, a); if ( !PL_is_variable(a) ) { if ( !PL_get_atom_ex(a, &name) ) fail; if ( name != ATOM_minus ) *tz = name; } succeed; }
static int dict_option(term_t key, term_t value, int last, void *closure) { dictopt_ctx *ctx = closure; PL_local_data_t *__PL_ld = ctx->ld; atom_t name; int n; const opt_spec *s; if ( !PL_get_atom_ex(key, &name) ) return -1; for( n=0, s = ctx->specs; s->name; n++, s++ ) { if ( s->name == name ) { if ( !get_optval(ctx->values[n], s, value PASS_LD) ) return -1; return 0; } } return 0; /* unprocessed key */ }
static int md5_options(term_t options, optval *result) { term_t opts = PL_copy_term_ref(options); term_t opt = PL_new_term_ref(); /* defaults */ memset(result, 0, sizeof(*result)); result->encoding = REP_UTF8; while(PL_get_list(opts, opt, opts)) { atom_t aname; size_t arity; if ( PL_get_name_arity(opt, &aname, &arity) && arity == 1 ) { term_t a = PL_new_term_ref(); _PL_get_arg(1, opt, a); if ( aname == ATOM_encoding ) { atom_t a_enc; if ( !PL_get_atom_ex(a, &a_enc) ) return FALSE; if ( a_enc == ATOM_utf8 ) result->encoding = REP_UTF8; else if ( a_enc == ATOM_octet ) result->encoding = REP_ISO_LATIN_1; else return PL_domain_error("encoding", a); } } else { return PL_type_error("option", opt); } } if ( !PL_get_nil(opts) ) return PL_type_error("list", opts); return TRUE; }
bool scan_options(term_t options, int flags, atom_t optype, const opt_spec *specs, ...) { GET_LD va_list args; const opt_spec *s; optvalue values[MAXOPTIONS]; term_t list = PL_copy_term_ref(options); term_t head = PL_new_term_ref(); term_t tmp = PL_new_term_ref(); term_t val = PL_new_term_ref(); int n; if ( truePrologFlag(PLFLAG_ISO) ) flags |= OPT_ALL; va_start(args, specs); for( n=0, s = specs; s->name; s++, n++ ) values[n].ptr = va_arg(args, void *); va_end(args); while ( PL_get_list(list, head, list) ) { atom_t name; int arity; if ( PL_get_name_arity(head, &name, &arity) ) { if ( name == ATOM_equals && arity == 2 ) { _PL_get_arg(1, head, tmp); if ( !PL_get_atom(tmp, &name) ) goto itemerror; _PL_get_arg(2, head, val); } else if ( arity == 1 ) { _PL_get_arg(1, head, val); } else if ( arity == 0 ) PL_put_atom(val, ATOM_true); } else if ( PL_is_variable(head) ) { return PL_error(NULL, 0, NULL, ERR_INSTANTIATION); } else { itemerror: return PL_error(NULL, 0, NULL, ERR_DOMAIN, optype, head); } for( n=0, s = specs; s->name; n++, s++ ) { if ( s->name == name ) { switch((s->type & OPT_TYPE_MASK)) { case OPT_BOOL: { int bval; if ( !PL_get_bool_ex(val, &bval) ) return FALSE; *values[n].b = bval; break; } case OPT_INT: { if ( !PL_get_integer_ex(val, values[n].i) ) return FALSE; break; } case OPT_LONG: { if ( (s->type & OPT_INF) && PL_is_inf(val) ) *values[n].l = LONG_MAX; else if ( !PL_get_long_ex(val, values[n].l) ) return FALSE; break; } case OPT_NATLONG: { if ( !PL_get_long_ex(val, values[n].l) ) return FALSE; if ( *(values[n].l) <= 0 ) return PL_error(NULL, 0, NULL, ERR_DOMAIN, ATOM_not_less_than_one, val); break; } case OPT_SIZE: { if ( (s->type & OPT_INF) && PL_is_inf(val) ) *values[n].sz = (size_t)-1; else if ( !PL_get_size_ex(val, values[n].sz) ) return FALSE; break; } case OPT_DOUBLE: { if ( !PL_get_float_ex(val, values[n].f) ) return FALSE; break; } case OPT_STRING: { char *str; if ( !PL_get_chars(val, &str, CVT_ALL|CVT_EXCEPTION) ) /* copy? */ return FALSE; *values[n].s = str; break; } case OPT_ATOM: { atom_t a; if ( !PL_get_atom_ex(val, &a) ) return FALSE; *values[n].a = a; break; } #ifdef O_LOCALE case OPT_LOCALE: { PL_locale *l; PL_locale **lp = values[n].ptr; if ( !getLocaleEx(val, &l) ) return FALSE; *lp = l; break; } #endif case OPT_TERM: { *values[n].t = val; val = PL_new_term_ref(); /* can't reuse anymore */ break; } default: assert(0); fail; } break; } } if ( !s->name && (flags & OPT_ALL) ) goto itemerror; } if ( !PL_get_nil(list) ) return PL_error(NULL, 0, NULL, ERR_TYPE, ATOM_list, list); succeed; }
static int get_optval(optvalue valp, const opt_spec *spec, term_t val ARG_LD) { switch((spec->type & OPT_TYPE_MASK)) { case OPT_BOOL: { int bval; if ( !PL_get_bool_ex(val, &bval) ) return FALSE; *valp.b = bval; return TRUE; } case OPT_INT: { if ( !PL_get_integer_ex(val, valp.i) ) return FALSE; return TRUE; } case OPT_LONG: { if ( (spec->type & OPT_INF) && PL_is_inf(val) ) *valp.l = LONG_MAX; else if ( !PL_get_long_ex(val, valp.l) ) return FALSE; return TRUE; } case OPT_NATLONG: { if ( !PL_get_long_ex(val, valp.l) ) return FALSE; if ( *(valp.l) <= 0 ) return PL_error(NULL, 0, NULL, ERR_DOMAIN, ATOM_not_less_than_one, val); return TRUE; } case OPT_SIZE: { if ( (spec->type & OPT_INF) && PL_is_inf(val) ) *valp.sz = (size_t)-1; else if ( !PL_get_size_ex(val, valp.sz) ) return FALSE; return TRUE; } case OPT_DOUBLE: { if ( !PL_get_float_ex(val, valp.f) ) return FALSE; return TRUE; } case OPT_STRING: { char *str; if ( !PL_get_chars(val, &str, CVT_ALL|CVT_EXCEPTION) ) /* copy? */ return FALSE; *valp.s = str; return TRUE; } case OPT_ATOM: { atom_t a; if ( !PL_get_atom_ex(val, &a) ) return FALSE; *valp.a = a; return TRUE; } #ifdef O_LOCALE case OPT_LOCALE: { PL_locale *l; PL_locale **lp = valp.ptr; if ( !getLocaleEx(val, &l) ) return FALSE; *lp = l; return TRUE; } #endif case OPT_TERM: { *valp.t = PL_copy_term_ref(val); /* can't reuse anymore */ return TRUE; } default: assert(0); } return FALSE; }
static foreign_t pl_uuid(term_t UUID, term_t options) { unsigned int mode = UUID_MAKE_V1; atom_t format = ATOM_atom; uuid_t *uuid; char *ns = NULL; char *str = NULL; int rc; uuid_rc_t urc; if ( !PL_get_nil(options) ) { term_t tail = PL_copy_term_ref(options); term_t head = PL_new_term_ref(); term_t arg = PL_new_term_ref(); while( PL_get_list(tail, head, tail) ) { atom_t name; size_t arity; if ( !PL_get_name_arity(head, &name, &arity) || arity != 1 ) return PL_type_error("option", head); _PL_get_arg(1, head, arg); if ( name == ATOM_version ) { int v; if ( !PL_get_integer_ex(arg, &v) ) return FALSE; switch(v) { case 1: mode = UUID_MAKE_V1; break; case 2: mode = UUID_MAKE_MC; break; case 3: mode = UUID_MAKE_V3; break; case 4: mode = UUID_MAKE_V4; break; case 5: mode = UUID_MAKE_V5; break; default: return PL_domain_error("uuid_version", arg); } } else if ( name == ATOM_format ) { if ( !PL_get_atom_ex(arg, &format) ) return FALSE; if ( format != ATOM_atom && format != ATOM_integer ) return PL_domain_error("uuid_format", arg); } else { char *newns = NULL; if ( name == ATOM_dns ) { newns = "ns:DNS"; } else if ( name == ATOM_url ) { newns = "ns:URL"; } else if ( name == ATOM_oid ) { newns = "ns:OID"; } else if ( name == ATOM_x500 ) { newns = "ns:X500"; } if ( newns ) { ns = newns; if ( !PL_get_chars(arg, &str, CVT_ATOM|CVT_EXCEPTION) ) return FALSE; if ( mode == UUID_MAKE_V1 ) mode = UUID_MAKE_V3; } } } if ( !PL_get_nil_ex(tail) ) return FALSE; } switch(mode) { case UUID_MAKE_V1: case UUID_MAKE_MC: case UUID_MAKE_V4: uuid_create(&uuid); if ( (urc=uuid_make(uuid, mode)) != UUID_RC_OK ) return PL_warning("UUID: make: %s\n", uuid_error(urc)); break; case UUID_MAKE_V3: case UUID_MAKE_V5: { uuid_t *uuid_ns; if ( !ns ) return PL_existence_error("uuid_context", options); uuid_create(&uuid); uuid_create(&uuid_ns); uuid_load(uuid_ns, ns); if ( (urc=uuid_make(uuid, mode, uuid_ns, str)) != UUID_RC_OK ) return PL_warning("UUID: make: %s\n", uuid_error(urc)); uuid_destroy(uuid_ns); break; } default: assert(0); return FALSE; } if ( format == ATOM_atom ) { char buf[UUID_LEN_STR+1]; void *ptr = buf; size_t datalen = sizeof(buf); if ( (urc=uuid_export(uuid, UUID_FMT_STR, &ptr, &datalen)) != UUID_RC_OK ) return PL_warning("UUID: export: %s\n", uuid_error(urc)); rc = PL_unify_chars(UUID, PL_ATOM|REP_ISO_LATIN_1, (size_t)-1, buf); } else if ( format == ATOM_integer ) { char buf[UUID_LEN_SIV+1]; void *ptr = buf; size_t datalen = sizeof(buf); term_t tmp = PL_new_term_ref(); if ( (urc=uuid_export(uuid, UUID_FMT_SIV, &ptr, &datalen)) != UUID_RC_OK ) return PL_warning("UUID: export: %s\n", uuid_error(urc)); rc = ( PL_chars_to_term(buf, tmp) && PL_unify(UUID, tmp) ); } else { assert(0); return FALSE; } uuid_destroy(uuid); return rc; }
static foreign_t archive_open_stream(term_t data, term_t handle, term_t options) { IOSTREAM *datas; archive_wrapper *ar; term_t tail = PL_copy_term_ref(options); term_t head = PL_new_term_ref(); term_t arg = PL_new_term_ref(); if ( !PL_get_stream_handle(data, &datas) ) return FALSE; if ( !(datas->flags & SIO_INPUT) ) { PL_release_stream(datas); return PL_domain_error("input_stream", data); } ar = PL_malloc(sizeof(*ar)); memset(ar, 0, sizeof(*ar)); ar->data = datas; ar->magic = ARCHIVE_MAGIC; if ( !PL_unify_blob(handle, ar, sizeof(*ar), &archive_blob) ) return FALSE; while( PL_get_list_ex(tail, head, tail) ) { atom_t name; int arity; if ( !PL_get_name_arity(head, &name, &arity) || !PL_get_arg(1, head, arg) ) return PL_type_error("option", head); if ( name == ATOM_compression || name == ATOM_filter ) { atom_t c; if ( !PL_get_atom_ex(arg, &c) ) return FALSE; if ( c == ATOM_all ) ar->type |= FILTER_ALL; #ifdef FILTER_BZIP2 else if ( c == ATOM_bzip2 ) ar->type |= FILTER_BZIP2; #endif #ifdef FILTER_COMPRESS else if ( c == ATOM_compress ) ar->type |= FILTER_COMPRESS; #endif #ifdef FILTER_GZIP else if ( c == ATOM_gzip ) ar->type |= FILTER_GZIP; #endif #ifdef FILTER_GRZIP else if ( c == ATOM_grzip ) ar->type |= FILTER_GRZIP; #endif #ifdef FILTER_LRZIP else if ( c == ATOM_lrzip ) ar->type |= FILTER_LRZIP; #endif #ifdef FILTER_LZIP else if ( c == ATOM_lzip ) ar->type |= FILTER_LZIP; #endif #ifdef FILTER_LZMA else if ( c == ATOM_lzma ) ar->type |= FILTER_LZMA; #endif #ifdef FILTER_LZOP else if ( c == ATOM_lzop ) ar->type |= FILTER_LZOP; #endif #ifdef FILTER_NONE else if ( c == ATOM_none ) ar->type |= FILTER_NONE; #endif #ifdef FILTER_RPM else if ( c == ATOM_rpm ) ar->type |= FILTER_RPM; #endif #ifdef FILTER_UU else if ( c == ATOM_uu ) ar->type |= FILTER_UU; #endif #ifdef FILTER_XZ else if ( c == ATOM_xz ) ar->type |= FILTER_XZ; #endif else return PL_domain_error("filter", arg); } else if ( name == ATOM_format ) { atom_t f; if ( !PL_get_atom_ex(arg, &f) ) return FALSE; if ( f == ATOM_all ) ar->type |= FORMAT_ALL; #ifdef FORMAT_7ZIP else if ( f == ATOM_7zip ) ar->type |= FORMAT_7ZIP; #endif #ifdef FORMAT_AR else if ( f == ATOM_ar ) ar->type |= FORMAT_AR; #endif #ifdef FORMAT_CAB else if ( f == ATOM_cab ) ar->type |= FORMAT_CAB; #endif #ifdef FORMAT_CPIO else if ( f == ATOM_cpio ) ar->type |= FORMAT_CPIO; #endif #ifdef FORMAT_EMPTY else if ( f == ATOM_empty ) ar->type |= FORMAT_EMPTY; #endif #ifdef FORMAT_GNUTAR else if ( f == ATOM_gnutar ) ar->type |= FORMAT_GNUTAR; #endif #ifdef FORMAT_ISO9960 else if ( f == ATOM_iso9960 ) ar->type |= FORMAT_ISO9960; #endif #ifdef FORMAT_LHA else if ( f == ATOM_lha ) ar->type |= FORMAT_LHA; #endif #ifdef FORMAT_MTREE else if ( f == ATOM_mtree ) ar->type |= FORMAT_MTREE; #endif #ifdef FORMAT_RAR else if ( f == ATOM_rar ) ar->type |= FORMAT_RAR; #endif #ifdef FORMAT_RAW else if ( f == ATOM_raw ) ar->type |= FORMAT_RAW; #endif #ifdef FORMAT_TAR else if ( f == ATOM_tar ) ar->type |= FORMAT_TAR; #endif #ifdef FORMAT_XAR else if ( f == ATOM_xar ) ar->type |= FORMAT_XAR; #endif #ifdef FORMAT_ZIP else if ( f == ATOM_zip ) ar->type |= FORMAT_ZIP; #endif else return PL_domain_error("format", arg); } else if ( name == ATOM_close_parent ) { if ( !PL_get_bool_ex(arg, &ar->close_parent) ) return FALSE; } } if ( !PL_get_nil_ex(tail) ) return FALSE; if ( !(ar->type & FILTER_ALL) ) ar->type |= FILTER_ALL; if ( !(ar->type & FORMAT_MASK) ) ar->type |= FORMAT_ALL; if ( !(ar->archive = archive_read_new()) ) return PL_resource_error("memory"); if ( (ar->type & FILTER_ALL) == FILTER_ALL ) { archive_read_support_filter_all(ar->archive); } else { #ifdef FILTER_BZIP2 enable_type(ar, FILTER_BZIP2, archive_read_support_filter_bzip2); #endif #ifdef FILTER_COMPRESS enable_type(ar, FILTER_COMPRESS, archive_read_support_filter_compress); #endif #ifdef FILTER_GZIP enable_type(ar, FILTER_GZIP, archive_read_support_filter_gzip); #endif #ifdef FILTER_GRZIP enable_type(ar, FILTER_GRZIP, archive_read_support_filter_grzip); #endif #ifdef FILTER_LRZIP enable_type(ar, FILTER_LRZIP, archive_read_support_filter_lrzip); #endif #ifdef FILTER_LZIP enable_type(ar, FILTER_LZIP, archive_read_support_filter_lzip); #endif #ifdef FILTER_LZMA enable_type(ar, FILTER_LZMA, archive_read_support_filter_lzma); #endif #ifdef FILTER_LZOP enable_type(ar, FILTER_LZOP, archive_read_support_filter_lzop); #endif #ifdef FILTER_NONE enable_type(ar, FILTER_NONE, archive_read_support_filter_none); #endif #ifdef FILTER_RPM enable_type(ar, FILTER_RPM, archive_read_support_filter_rpm); #endif #ifdef FILTER_UU enable_type(ar, FILTER_UU, archive_read_support_filter_uu); #endif #ifdef FILTER_XZ enable_type(ar, FILTER_XZ, archive_read_support_filter_xz); #endif } if ( (ar->type & FORMAT_ALL) == FORMAT_ALL ) { archive_read_support_format_all(ar->archive); #ifdef FORMAT_RAW enable_type(ar, FORMAT_RAW, archive_read_support_format_raw); #endif } else { #ifdef FORMAT_7ZIP enable_type(ar, FORMAT_7ZIP, archive_read_support_format_7zip); #endif #ifdef FORMAT_AR enable_type(ar, FORMAT_AR, archive_read_support_format_ar); #endif #ifdef FORMAT_CAB enable_type(ar, FORMAT_CAB, archive_read_support_format_cab); #endif #ifdef FORMAT_CPIO enable_type(ar, FORMAT_CPIO, archive_read_support_format_cpio); #endif #ifdef FORMAT_EMPTY enable_type(ar, FORMAT_EMPTY, archive_read_support_format_empty); #endif #ifdef FORMAT_GNUTAR enable_type(ar, FORMAT_GNUTAR, archive_read_support_format_gnutar); #endif #ifdef FORMAT_ISO9960 enable_type(ar, FORMAT_ISO9960, archive_read_support_format_iso9660); #endif #ifdef FORMAT_LHA enable_type(ar, FORMAT_LHA, archive_read_support_format_lha); #endif #ifdef FORMAT_MTREE enable_type(ar, FORMAT_MTREE, archive_read_support_format_mtree); #endif #ifdef FORMAT_RAR enable_type(ar, FORMAT_RAR, archive_read_support_format_rar); #endif #ifdef FORMAT_RAW enable_type(ar, FORMAT_RAW, archive_read_support_format_raw); #endif #ifdef FORMAT_TAR enable_type(ar, FORMAT_TAR, archive_read_support_format_tar); #endif #ifdef FORMAT_XAR enable_type(ar, FORMAT_XAR, archive_read_support_format_xar); #endif #ifdef FORMAT_ZIP enable_type(ar, FORMAT_ZIP, archive_read_support_format_zip); #endif } #ifdef HAVE_ARCHIVE_READ_OPEN1 archive_read_set_callback_data(ar->archive, ar); archive_read_set_open_callback(ar->archive, ar_open); archive_read_set_read_callback(ar->archive, ar_read); archive_read_set_skip_callback(ar->archive, ar_skip); archive_read_set_seek_callback(ar->archive, ar_seek); archive_read_set_close_callback(ar->archive, ar_close); if ( archive_read_open1(ar->archive) == ARCHIVE_OK ) { ar->status = AR_OPENED; return TRUE; } #else if ( archive_read_open2(ar->archive, ar, ar_open, ar_read, ar_skip, ar_close) == ARCHIVE_OK ) { ar->status = AR_OPENED; return TRUE; } #endif return archive_error(ar); }
static bool get_value(term_t t, clingo_symbol_t *val, int minus) { switch (PL_term_type(t)) { case PL_INTEGER: { int i; if (PL_get_integer(t, &i)) { clingo_symbol_create_number(i, val); return true; } return false; } case PL_ATOM: { char *s; size_t len; if (PL_get_nchars(t, &len, &s, CVT_ATOM | REP_UTF8 | CVT_EXCEPTION)) { return clingo_symbol_create_id(s, !minus, val); /* no sign */ } return false; } case PL_STRING: { char *s; size_t len; if (PL_get_nchars(t, &len, &s, CVT_STRING | REP_UTF8 | CVT_EXCEPTION)) { return clingo_symbol_create_string(s, val); } return false; } case PL_TERM: { bool rc; term_t arg; atom_t name; size_t arity; /* TBD: -atom, #const */ clingo_symbol_t *values = NULL; if (!(rc = get_name_arity(t, &name, &arity))) { clingo_set_error(clingo_error_runtime, "prolog error"); goto out_term; } arg = PL_new_term_ref(); if (name == ATOM_minus && arity == 1) { if (!(rc = get_value(arg, val, TRUE))) { goto out_term; } } else if (name == ATOM_hash && arity == 1) { atom_t a; _PL_get_arg(1, t, arg); if (!(rc = PL_get_atom_ex(arg, &a))) { clingo_set_error(clingo_error_runtime, "prolog error"); goto out_term; } if (a == ATOM_inf) { clingo_symbol_create_infimum(val); } else if (a == ATOM_sup) { clingo_symbol_create_supremum(val); } else { rc = false; clingo_set_error(clingo_error_runtime, "bad value"); goto out_term; } } else { const char *id = PL_atom_chars(name); /* TBD: errors */ size_t i; if (!(values = malloc(sizeof(*values) * arity))) { rc = false; clingo_set_error(clingo_error_bad_alloc, "memory"); goto out_term; } for (i = 0; i < arity; i++) { _PL_get_arg(i + 1, t, arg); if (!(rc = get_value(arg, &values[i], FALSE))) { goto out_term; } } PL_reset_term_refs(arg); if (!(rc = clingo_symbol_create_function(id, values, arity, !minus, val))) { goto out_term; } } out_term: if (values) { free(values); } return rc; } default: clingo_set_error(clingo_error_runtime, "bad value"); return false; } }