From 33714b14b95ab4826167fc317a53d11e10030917 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Thu, 17 Jan 2013 12:43:01 +0000 Subject: [PATCH] atom completion in readline --- H/dlocals.h | 3 ++ H/hlocals.h | 2 + H/ilocals.h | 2 + H/rlocals.h | 2 + library/dialect/swi/fli/swi.c | 97 ++++++++++++++++++++++++++++++++++- misc/LOCALS | 3 ++ 6 files changed, 108 insertions(+), 1 deletion(-) diff --git a/H/dlocals.h b/H/dlocals.h index 222fa65bd..9619d78ad 100644 --- a/H/dlocals.h +++ b/H/dlocals.h @@ -433,3 +433,6 @@ #define LOCAL_ibnds LOCAL->ibnds_ #define REMOTE_ibnds(wid) REMOTE(wid)->ibnds_ +#define LOCAL_search_atoms LOCAL->search_atoms_ +#define REMOTE_search_atoms(wid) REMOTE(wid)->search_atoms_ + diff --git a/H/hlocals.h b/H/hlocals.h index 842454563..0677d390d 100644 --- a/H/hlocals.h +++ b/H/hlocals.h @@ -243,4 +243,6 @@ typedef struct worker_local { Functor FunctorVar_; UInt ibnds_[256]; + + struct scan_atoms* search_atoms_; } w_local; diff --git a/H/ilocals.h b/H/ilocals.h index 4e564a40a..0496ecca9 100644 --- a/H/ilocals.h +++ b/H/ilocals.h @@ -243,4 +243,6 @@ static void InitWorker(int wid) { REMOTE_FunctorVar(wid) = FunctorVar; + + } diff --git a/H/rlocals.h b/H/rlocals.h index 652d98e32..f3e8e9701 100644 --- a/H/rlocals.h +++ b/H/rlocals.h @@ -243,4 +243,6 @@ static void RestoreWorker(int wid USES_REGS) { + + } diff --git a/library/dialect/swi/fli/swi.c b/library/dialect/swi/fli/swi.c index e6a9a445e..053f91551 100755 --- a/library/dialect/swi/fli/swi.c +++ b/library/dialect/swi/fli/swi.c @@ -2807,11 +2807,106 @@ X_API void PL_on_halt(void (*f)(int, void *), void *closure) Yap_HaltRegisterHook((HaltHookFunc)f,closure); } -X_API char *PL_atom_generator(const char *prefix, int state) +#define is_signalled() unlikely(LD && LD->signal.pending != 0) + +#ifdef O_PLMT +#include +static pthread_key_t atomgen_key; +#endif + +typedef struct scan_atoms { + Int pos; + Atom atom; +} scan_atoms_t; + +static inline int +str_prefix(const char *p0, char *s) { + char *p = (char *)p0; + while (*p && *p == *s) { p++; s++; } + return p[0] == '\0'; +} + +static int +atom_generator(const char *prefix, char **hit, int state) +{ + struct scan_atoms *index; + Atom catom; + Int i; + +#ifdef O_PLMT + if ( !atomgen_key ) { + pthread_key_create(&atomgen_key, NULL); + state = FALSE; + } +#endif + + if ( !state ) + { index = (struct scan_atoms *)malloc(sizeof(struct scan_atoms)); + i = 0; + catom = NIL; + } else + { +#ifdef O_PLMT + index = (struct scan_atoms *)pthread_getspecific(atomgen_key); +#else + index = LOCAL_search_atoms; +#endif + catom = index->atom; + i = index->pos; + } + + while (catom != NIL || i < AtomHashTableSize) { + // if ( is_signalled() ) /* Notably allow windows version */ + // PL_handle_signals(); /* to break out on ^C */ + AtomEntry *ap; + + if (catom == NIL) { + /* move away from current hash table line */ + READ_LOCK(HashChain[i].AERWLock); + catom = HashChain[i].Entry; + READ_UNLOCK(HashChain[i].AERWLock); + i++; + } else { + ap = RepAtom(catom); + READ_LOCK(ap->ARWLock); + if ( str_prefix(prefix, ap->StrOfAE) ) { + index->pos = i; + index->atom = ap->NextOfAE; +#ifdef O_PLMT + pthread_setspecific(atomgen_key,index); +#else + LOCAL_search_atoms = index; +#endif + *hit = ap->StrOfAE; + READ_UNLOCK(ap->ARWLock); + return TRUE; + } + catom = ap->NextOfAE; + READ_UNLOCK(ap->ARWLock); + } + } +#ifdef O_PLMT + pthread_setspecific(atomgen_key,NULL); +#else + LOCAL_search_atoms = NULL; +#endif + free(index); + return FALSE; +} + + +char * +PL_atom_generator(const char *prefix, int state) +{ + char * hit = NULL; + if (atom_generator(prefix, &hit, state)) { + return hit; + } return NULL; } + X_API pl_wchar_t *PL_atom_generator_w(const pl_wchar_t *pref, pl_wchar_t *buffer, size_t buflen, int state) { return NULL; diff --git a/misc/LOCALS b/misc/LOCALS index 0ffdb50cd..a973dbf21 100644 --- a/misc/LOCALS +++ b/misc/LOCALS @@ -274,4 +274,7 @@ Functor FunctorVar =FunctorVar // exo indexing UInt ibnds[256] void +// atom completion +struct scan_atoms* search_atoms void + END_WORKER_LOCAL