Slightly better logging for font loading
[notion/jeffpc.git] / mod_query / history.c
blobeae5b87af4f00b27eadcf9239ebceda66523aafc
1 /*
2 * ion/mod_query/history.h
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <string.h>
11 #include <ioncore/common.h>
12 #include <libextl/extl.h>
14 #include "history.h"
17 #define HISTORY_SIZE 1024
20 static int hist_head=HISTORY_SIZE;
21 static int hist_count=0;
22 static char *hist[HISTORY_SIZE];
25 int get_index(int i)
27 if(i<0 || i>=hist_count)
28 return -1;
29 return (hist_head+i)%HISTORY_SIZE;
33 /*EXTL_DOC
34 * Push an entry into line editor history.
36 EXTL_EXPORT
37 bool mod_query_history_push(const char *str)
39 char *s=scopy(str);
41 if(s==NULL)
42 return FALSE;
44 mod_query_history_push_(s);
46 return TRUE;
50 void mod_query_history_push_(char *str)
52 int ndx=mod_query_history_search(str, 0, FALSE, TRUE);
54 if(ndx==0){
55 free(str);
56 return; /* First entry already */
57 }else if(ndx>0){
58 int i, j;
59 i=get_index(ndx);
60 free(hist[i]);
61 while(++ndx<hist_count){
62 j=get_index(ndx);
63 hist[i]=hist[j];
64 i=j;
66 hist_count--;
69 hist_head--;
70 if(hist_head<0)
71 hist_head=HISTORY_SIZE-1;
73 if(hist_count==HISTORY_SIZE)
74 free(hist[hist_head]);
75 else
76 hist_count++;
78 hist[hist_head]=str;
82 /*EXTL_DOC
83 * Get entry at index \var{n} in line editor history, 0 being the latest.
85 EXTL_SAFE
86 EXTL_EXPORT
87 const char *mod_query_history_get(int n)
89 int i=get_index(n);
90 return (i<0 ? NULL : hist[i]);
94 /*EXTL_DOC
95 * Clear line editor history.
97 EXTL_EXPORT
98 void mod_query_history_clear()
100 while(hist_count!=0){
101 free(hist[hist_head]);
102 hist_count--;
103 if(++hist_head==HISTORY_SIZE)
104 hist_head=0;
106 hist_head=HISTORY_SIZE;
111 static bool match(const char *h, const char *b, bool exact)
113 const char *h_;
115 if(b==NULL)
116 return TRUE;
118 /* Special case: search in any context. */
119 if(*b=='*' && *(b+1)==':'){
120 b=b+2;
121 h_=strchr(h, ':');
122 if(h_!=NULL)
123 h=h_+1;
126 return (exact
127 ? strcmp(h, b)==0
128 : strncmp(h, b, strlen(b))==0);
132 static const char *skip_colon(const char *s)
134 const char *p=strchr(s, ':');
135 return (p!=NULL ? p+1 : s);
139 /*EXTL_DOC
140 * Try to find matching history entry. Returns -1 if none was
141 * found. The parameter \var{from} specifies where to start
142 * searching from, and \var{bwd} causes backward search from
143 * that point. If \var{exact} is not set, \var{s} only required
144 * to be a prefix of the match.
146 EXTL_SAFE
147 EXTL_EXPORT
148 int mod_query_history_search(const char *s, int from, bool bwd, bool exact)
150 while(1){
151 int i=get_index(from);
152 if(i<0)
153 return -1;
154 if(match(hist[i], s, exact))
155 return from;
156 if(bwd)
157 from--;
158 else
159 from++;
164 uint mod_query_history_complete(const char *s, char ***h_ret)
166 char **h=ALLOC_N(char *, hist_count);
167 int i, n=0;
169 if(h==NULL)
170 return 0;
172 for(i=0; i<hist_count; i++){
173 int j=get_index(i);
174 if(j<0)
175 break;
176 if(match(hist[j], s, FALSE)){
177 h[n]=scopy(skip_colon(hist[j]));
178 if(h[n]!=NULL)
179 n++;
183 if(n==0)
184 free(h);
185 else
186 *h_ret=h;
188 return n;
192 /*EXTL_DOC
193 * Return table of history entries.
195 EXTL_SAFE
196 EXTL_EXPORT
197 ExtlTab mod_query_history_table()
199 ExtlTab tab=extl_create_table();
200 int i;
202 for(i=0; i<hist_count; i++){
203 int j=get_index(i);
204 extl_table_seti_s(tab, i+1, hist[j]);
207 return tab;