/** assign a tuple to something: */ static foreign_t python_assign_tuple(term_t t_lhs, term_t t_rhs) { PyObject *e; Py_ssize_t sz; functor_t f; e = term_to_python(t_rhs, true); if (!e || !PyTuple_Check(e)) { return -1; } sz = PyTuple_Size(e); switch (PL_term_type(t_lhs)) { case PL_VARIABLE: return PL_unify(t_lhs, t_rhs); case PL_ATOM: return assign_python(py_Main, t_rhs, e); case PL_TERM: if (PL_get_functor(t_lhs, &f)) { term_t targ = PL_new_term_ref(); // assign a tuple to a tuple if (PL_functor_name(f) == ATOM_t && ((sz = PL_functor_arity(f)))) { Py_ssize_t i; for (i = 0; i < sz; i++) { PL_get_arg(i + 1, t_lhs, targ); assign_python(py_Main, targ, PyTuple_GetItem(e, i)); } } else if (PL_functor_name(f) == ATOM_comma) { int n = conj_size(t_lhs); if (n != sz) return -1; return conj_copy(t_lhs, e, 0); } else if (PL_functor_name(f) == ATOM_dot) { // vectors size_t len; term_t tail = PL_new_term_ref(); PL_skip_list(t_lhs, tail, &len); if (!PL_get_nil(tail)) return -1; term_t arg = tail; size_t i; for (i = 0; i < len; i++) { if (!PL_get_list(t_rhs, arg, t_rhs)) { return -1; } if (assign_python(py_Main, arg, PyTuple_GetItem(e, i)) < 0) return -1; } } } } return -1; }
word pl_dwim_predicate(term_t pred, term_t dwim, control_t h) { GET_LD functor_t fdef; Module module = (Module) NULL; Procedure proc; Symbol symb; term_t head = PL_new_term_ref(); TableEnum e; if ( ForeignControl(h) == FRG_CUTTED ) { e = ForeignContextPtr(h); freeTableEnum(e); succeed; } if ( !PL_strip_module(pred, &module, head) ) fail; if ( !PL_get_functor(head, &fdef) ) fail; /* silent: leave errors for later */ if ( ForeignControl(h) == FRG_FIRST_CALL ) e = newTableEnum(module->procedures); else e = ForeignContextPtr(h); while( (symb = advanceTableEnum(e)) ) { Definition def; char *name; proc = symb->value; def = proc->definition; name = stringAtom(def->functor->name); if ( dwimMatch(stringAtom(nameFunctor(fdef)), name) && isDefinedProcedure(proc) && (name[0] != '$' || SYSTEM_MODE) ) { if ( !PL_unify_functor(dwim, def->functor->functor) ) continue; ForeignRedoPtr(e); } } freeTableEnum(e); fail; }
foreign_t pl_reportViolation(term_t RuleT, term_t MsgT, term_t CulpritsT) { // FIXME: all 'return FALSE' should be PL_warning' const char *Rule; if ( !PL_get_atom_chars(RuleT, (char **) &Rule)) return FALSE; const char *Msg; if ( !PL_get_atom_chars(MsgT, (char **) &Msg)) return FALSE; // atom_t StmtA = PL_new_atom("stmt"); // functor_t StmtF = PL_new_functor(StmtA, 1); atom_t NamedDeclA = PL_new_atom("NamedDecl"); functor_t NamedDeclF = PL_new_functor(NamedDeclA, 2); // functor_t SortF; // if ( !PL_get_functor(LocT, &SortF)) return FALSE; // term_t ElemT = PL_new_term_ref(); // if ( !PL_get_arg(1, LocT, ElemT)) return FALSE; // SourceLocation SL; // if ( PL_unify_functor(LocT, StmtF)) { // Stmt *S; // if ( !PL_get_pointer(ElemT, (void **) &S)) return FALSE; // SL = S->getLocStart(); // } // // FIXME: same for Decl and other elems. const CompilerInstance &CI = getCompilationInfo()->getCompilerInstance(); DiagnosticsEngine &DE = CI.getDiagnostics(); Twine MsgWithRule = Twine(Rule) + Twine(": ") + Twine(Msg); unsigned DiagId = DE.getCustomDiagID(DiagnosticsEngine::Warning, MsgWithRule.str()); DiagnosticBuilder DB = DE.Report(DiagId); term_t HeadT = PL_new_term_ref(); term_t ListT = PL_copy_term_ref(CulpritsT); // copy as we need to write while(PL_get_list(ListT, HeadT, ListT)) { term_t ElemT = PL_new_term_ref(); if ( !PL_get_arg(1, HeadT, ElemT)) return FALSE; if ( PL_unify_functor(HeadT, NamedDeclF)) { const NamedDecl *ND; if ( !PL_get_pointer(ElemT, (void **) &ND)) return FALSE; DB << ND->getDeclName(); continue; } // FIXME: same for Type and other elems } DB.~DiagnosticBuilder(); // Emits the diagnostic ListT = PL_copy_term_ref(CulpritsT); while(PL_get_list(ListT, HeadT, ListT)) { functor_t SortF; if ( !PL_get_functor(HeadT, &SortF)) return FALSE; term_t ElemT = PL_new_term_ref(); if ( !PL_get_arg(1, HeadT, ElemT)) return FALSE; term_t MsgT = PL_new_term_ref(); if ( !PL_get_arg(2, HeadT, MsgT)) return FALSE; const char *Msg; if ( !PL_get_atom_chars(MsgT, (char **) &Msg)) return FALSE; if ( PL_unify_functor(HeadT, NamedDeclF)) { const NamedDecl *ND; if ( !PL_get_pointer(ElemT, (void **) &ND)) return FALSE; DiagId = DE.getCustomDiagID(DiagnosticsEngine::Note, Msg); DiagnosticBuilder DB = DE.Report(ND->getLocStart(), DiagId); DB << ND->getDeclName(); DB.~DiagnosticBuilder(); // Emits the diagnostic continue; } // FIXME: same for Type and other elems } return TRUE; }
static foreign_t archive_header_prop(term_t archive, term_t field) { archive_wrapper *ar; functor_t prop; if ( !get_archive(archive, &ar) ) return FALSE; if ( !PL_get_functor(field, &prop) ) return PL_type_error("compound", field); if ( ar->status != AR_NEW_ENTRY ) return PL_permission_error("access", "archive_entry", archive); if ( prop == FUNCTOR_filetype1 ) { __LA_MODE_T type = archive_entry_filetype(ar->entry); atom_t name; term_t arg = PL_new_term_ref(); _PL_get_arg(1, field, arg); switch(type&AE_IFMT) { case AE_IFREG: name = ATOM_file; break; case AE_IFLNK: name = ATOM_link; break; case AE_IFSOCK: name = ATOM_socket; break; case AE_IFCHR: name = ATOM_character_device; break; case AE_IFBLK: name = ATOM_block_device; break; case AE_IFDIR: name = ATOM_directory; break; case AE_IFIFO: name = ATOM_fifo; break; default: return PL_unify_integer(arg, (type&AE_IFMT)); } return PL_unify_atom(arg, name); } else if ( prop == FUNCTOR_mtime1 ) { time_t stamp = archive_entry_mtime(ar->entry); term_t arg = PL_new_term_ref(); _PL_get_arg(1, field, arg); return PL_unify_float(arg, (double)stamp); } else if ( prop == FUNCTOR_size1 ) { int64_t size = archive_entry_size(ar->entry); term_t arg = PL_new_term_ref(); _PL_get_arg(1, field, arg); return PL_unify_int64(arg, size); } else if ( prop == FUNCTOR_link_target1 ) { __LA_MODE_T type = archive_entry_filetype(ar->entry); const wchar_t *target = NULL; switch(type&AE_IFMT) { case AE_IFLNK: target = archive_entry_symlink_w(ar->entry); break; } if ( target ) { term_t arg = PL_new_term_ref(); _PL_get_arg(1, field, arg); return PL_unify_wchars(arg, PL_ATOM, (size_t)-1, target); } return FALSE; } else if ( prop == FUNCTOR_format1 ) { const char *s = archive_format_name(ar->archive); if ( s ) { char lwr[50]; char *o; term_t arg = PL_new_term_ref(); _PL_get_arg(1, field, arg); for(o=lwr; *s && o < lwr+sizeof(lwr); ) *o++ = tolower(*s++); *o = '\0'; return PL_unify_atom_chars(arg, lwr); } } return PL_domain_error("archive_header_property", field); }