* New version 2.21
[alpine.git] / pith / hist.c
blobded26ff3e21197945c344080c81ad5eaf822db99
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: hist.c 807 2007-11-09 01:21:33Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2013-2017 Eduardo Chappa
8 * Copyright 2006-2007 University of Washington
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
20 #include "../pith/headers.h"
21 #include "../pith/conf.h"
22 #include "../pith/hist.h"
25 void
26 init_hist(HISTORY_S **history, int histsize)
28 size_t l;
30 if(!history)
31 return;
33 if(!*history){
34 l = sizeof(**history) + histsize * sizeof(ONE_HIST_S);
35 *history = (HISTORY_S *) fs_get(l);
36 memset(*history, 0, l);
37 (*history)->histsize = histsize;
38 (*history)->origindex = histsize - 1;
39 add_to_histlist(history);
42 (*history)->curindex = (*history)->origindex;
46 void
47 free_hist(HISTORY_S **history)
49 int i;
51 if(history && *history){
52 for(i = 0; i < (*history)->histsize; i++)
53 if((*history)->hist[i] && (*history)->hist[i]->str)
54 fs_give((void **) &(*history)->hist[i]->str);
56 fs_give((void **) history);
60 char *
61 hist_in_pos(int pos, char **list, int llen, HISTORY_S *hist, int n)
63 if(pos < 0 || pos > llen + n)
64 return NULL;
66 if(pos < llen)
67 return list[pos];
69 hist->curindex = (hist->origindex + n - pos + llen) % hist->histsize;
70 return((hist->hist[hist->curindex] && hist->hist[hist->curindex]->str)
71 ? hist->hist[hist->curindex]->str : NULL);
74 char *
75 get_prev_hist(HISTORY_S *history, char *savethis, unsigned saveflags, void *cntxt)
77 int nextcurindex;
78 size_t l;
80 if(!(history && history->histsize > 0))
81 return NULL;
83 nextcurindex = (history->curindex + 1) % history->histsize;
85 /* already at start of history */
86 if(nextcurindex == history->origindex
87 || !(history->hist[nextcurindex] && history->hist[nextcurindex]->str
88 && history->hist[nextcurindex]->str[0]))
89 return NULL;
91 /* save what user typed */
92 if(history->curindex == history->origindex){
93 if(!savethis)
94 savethis = "";
96 if(!history->hist[history->origindex]){
97 history->hist[history->origindex] = (ONE_HIST_S *) fs_get(sizeof(ONE_HIST_S));
98 memset(history->hist[history->origindex], 0, sizeof(ONE_HIST_S));
101 if(history->hist[history->origindex]->str){
102 if(strlen(history->hist[history->origindex]->str) < (l=strlen(savethis)))
103 fs_resize((void **) &history->hist[history->origindex]->str, l+1);
105 strncpy(history->hist[history->origindex]->str, savethis, l+1);
106 history->hist[history->origindex]->str[l] = '\0';
108 else
109 history->hist[history->origindex]->str = cpystr(savethis);
111 history->hist[history->origindex]->flags = saveflags;
113 history->hist[history->origindex]->cntxt = cntxt;
116 history->curindex = nextcurindex;
118 return((history->hist[history->curindex] && history->hist[history->curindex]->str)
119 ? history->hist[history->curindex]->str : NULL);
123 char *
124 get_next_hist(HISTORY_S *history, char *savethis, unsigned saveflags, void *cntxt)
126 if(!(history && history->histsize > 0))
127 return NULL;
129 /* already at end (most recent) of history */
130 if(history->curindex == history->origindex)
131 return NULL;
133 history->curindex = (history->curindex + history->histsize - 1) % history->histsize;
135 return((history->hist[history->curindex] && history->hist[history->curindex]->str)
136 ? history->hist[history->curindex]->str : NULL);
140 void
141 save_hist(HISTORY_S *history, char *savethis, unsigned saveflags, void *cntxt)
143 size_t l;
144 int plusone;
146 if(!(history && history->histsize > 0))
147 return;
149 plusone = (history->origindex + 1) % history->histsize;
151 if(!history->hist[history->origindex]){
152 history->hist[history->origindex] = (ONE_HIST_S *) fs_get(sizeof(ONE_HIST_S));
153 memset(history->hist[history->origindex], 0, sizeof(ONE_HIST_S));
156 if(savethis && savethis[0]
157 && (!history->hist[history->origindex]->str
158 || strcmp(history->hist[history->origindex]->str, savethis)
159 || history->hist[history->origindex]->flags != saveflags
160 || history->hist[history->origindex]->cntxt != cntxt)
161 && !(history->hist[plusone] && history->hist[plusone]->str
162 && !strcmp(history->hist[plusone]->str, savethis)
163 && history->hist[history->origindex]->flags == saveflags
164 && history->hist[history->origindex]->cntxt == cntxt)){
165 if(history->hist[history->origindex]->str){
166 if(strlen(history->hist[history->origindex]->str) < (l=strlen(savethis)))
167 fs_resize((void **) &history->hist[history->origindex]->str, l+1);
169 strncpy(history->hist[history->origindex]->str, savethis, l+1);
170 history->hist[history->origindex]->str[l] = '\0';
172 else{
173 history->hist[history->origindex]->str = cpystr(savethis);
176 history->hist[history->origindex]->flags = saveflags;
177 history->hist[history->origindex]->cntxt = cntxt;
179 history->origindex = (history->origindex + history->histsize - 1) % history->histsize;
180 if(history->hist[history->origindex] && history->hist[history->origindex]->str)
181 history->hist[history->origindex]->str[0] = '\0';
187 * Returns count of items entered into history.
190 items_in_hist(HISTORY_S *history)
192 int i, cnt = 0;
194 if(history && history->histsize > 0)
195 for(i = 0; i < history->histsize; i++)
196 if(history->hist[i] && history->hist[i]->str)
197 cnt++;
199 return(cnt);
203 static HISTORY_S **histlist[100];
205 void
206 add_to_histlist(HISTORY_S **history)
208 int i;
210 if(history){
211 /* find empty slot */
212 for(i = 0; i < 100; i++)
213 if(!histlist[i])
214 break;
216 if(i < 100)
217 histlist[i] = history;
222 void
223 free_histlist(void)
225 int i;
227 for(i = 0; i < 100; i++)
228 if(histlist[i])
229 free_hist(histlist[i]);