2 * ========================================================================
3 * Copyright 2013-2022 Eduardo Chappa
4 * Copyright 2006-2007 University of Washington
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
16 #include "../pith/headers.h"
17 #include "../pith/conf.h"
18 #include "../pith/hist.h"
22 init_hist(HISTORY_S
**history
, int histsize
)
30 l
= sizeof(**history
) + histsize
* sizeof(ONE_HIST_S
);
31 *history
= (HISTORY_S
*) fs_get(l
);
32 memset(*history
, 0, l
);
33 (*history
)->histsize
= histsize
;
34 (*history
)->origindex
= histsize
- 1;
35 add_to_histlist(history
);
38 (*history
)->curindex
= (*history
)->origindex
;
43 free_hist(HISTORY_S
**history
)
47 if(history
&& *history
){
48 for(i
= 0; i
< (*history
)->histsize
; i
++)
49 if((*history
)->hist
[i
]){
50 if((*history
)->hist
[i
]->str
)
51 fs_give((void **) &(*history
)->hist
[i
]->str
);
52 (*history
)->hist
[i
]->cntxt
= NULL
; /* taken care of elsewhere */
53 fs_give((void **) &(*history
)->hist
[i
]);
56 fs_give((void **) history
);
61 hist_in_pos(int pos
, char **list
, int llen
, HISTORY_S
*hist
, int n
)
63 if(pos
< 0 || pos
> llen
+ n
)
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
);
75 get_prev_hist(HISTORY_S
*history
, char *savethis
, unsigned saveflags
, void *cntxt
)
80 if(!(history
&& history
->histsize
> 0))
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]))
91 /* save what user typed */
92 if(history
->curindex
== history
->origindex
){
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';
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
);
124 get_next_hist(HISTORY_S
*history
, char *savethis
, unsigned saveflags
, void *cntxt
)
126 if(!(history
&& history
->histsize
> 0))
129 /* already at end (most recent) of history */
130 if(history
->curindex
== history
->origindex
)
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
);
141 save_hist(HISTORY_S
*history
, char *savethis
, unsigned saveflags
, void *cntxt
)
146 if(!(history
&& history
->histsize
> 0))
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';
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
)
194 if(history
&& history
->histsize
> 0)
195 for(i
= 0; i
< history
->histsize
; i
++)
196 if(history
->hist
[i
] && history
->hist
[i
]->str
)
203 static HISTORY_S
**histlist
[100];
206 add_to_histlist(HISTORY_S
**history
)
211 /* find empty slot */
212 for(i
= 0; i
< 100; i
++)
217 histlist
[i
] = history
;
227 for(i
= 0; i
< 100; i
++)
229 free_hist(histlist
[i
]);