2 * HISTORY.C - command line history.
7 * 14/01/95 (Tim Norman)
10 * 08/08/95 (Matt Rains)
11 * i have cleaned up the source code. changes now bring this source
12 * into guidelines for recommended programming practice.
14 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
15 * added config.h include
17 * 25-Jan-1999 (Eric Kohl)
19 * Unicode and redirection safe!
21 * 25-Jan-1999 (Paolo Pantaleo <paolopan@freemail.it>)
22 * Added lots of comments (beginning studying the source)
23 * Added command.com's F3 support (see cmdinput.c)
30 * HISTORY.C - command line history. Second version
35 * 06/12/99 (Paolo Pantaleo <paolopan@freemail.it>)
42 #ifdef FEATURE_HISTORY
44 typedef struct tagHISTORY
46 struct tagHISTORY
*prev
;
47 struct tagHISTORY
*next
;
49 } HIST_ENTRY
, * LPHIST_ENTRY
;
51 static INT size
, max_size
= 100;
53 static LPHIST_ENTRY Top
= NULL
;
54 static LPHIST_ENTRY Bottom
= NULL
;
56 static LPHIST_ENTRY curr_ptr
= NULL
;
58 VOID
InitHistory(VOID
);
59 VOID
History_move_to_bottom(VOID
);
60 VOID
History(INT dir
, LPTSTR commandline
);
61 VOID
CleanHistory(VOID
);
62 VOID
History_del_current_entry(LPTSTR str
);
65 static VOID
del(LPHIST_ENTRY item
);
66 static VOID
add_at_bottom(LPTSTR string
);
67 /*VOID add_before_last(LPTSTR string);*/
68 VOID
set_size(INT new_size
);
71 INT
CommandHistory(LPTSTR param
)
78 tmp
=_tcschr(param
,_T('/'));
83 switch (_totupper(param
[1]))
85 case _T('F'):/*delete history*/
86 CleanHistory();InitHistory();
89 case _T('R'):/*read history from standard in*/
92 ConInString(szBuffer
,sizeof(szBuffer
)/sizeof(TCHAR
));
93 if (*szBuffer
!=_T('\0'))
100 case _T('A'):/*add an antry*/
104 case _T('S'):/*set history size*/
105 if ((tmp_int
=_ttoi(param
+2)))
115 for (h_tmp
= Top
->prev
; h_tmp
!= Bottom
; h_tmp
= h_tmp
->prev
)
116 ConErrPuts(h_tmp
->string
);
121 VOID
set_size(INT new_size
)
123 ASSERT(Top
&& Bottom
);
125 while (new_size
<size
)
132 VOID
InitHistory(VOID
)
136 Top
= cmd_alloc(sizeof(HIST_ENTRY
));
139 WARN("Cannot allocate memory for Top!\n");
142 Bottom
= cmd_alloc(sizeof(HIST_ENTRY
));
145 WARN("Cannot allocate memory for Bottom!\n");
157 Bottom
->string
= NULL
;
163 VOID
CleanHistory(VOID
)
165 ASSERT(Top
&& Bottom
);
167 while (Bottom
->next
!= Top
)
175 VOID
History_del_current_entry(LPTSTR str
)
179 ASSERT(Top
&& Bottom
);
184 if (curr_ptr
== Bottom
)
185 curr_ptr
= Bottom
->next
;
188 curr_ptr
= Top
->prev
;
192 curr_ptr
= curr_ptr
->prev
;
199 VOID
del(LPHIST_ENTRY item
)
201 ASSERT(Top
&& Bottom
);
203 if (item
==NULL
|| item
==Top
|| item
==Bottom
)
205 TRACE ("del in " __FILE__
": returning\n"
206 "item is 0x%08x (Bottom is0x%08x)\n",
211 /*free string's mem*/
213 cmd_free(item
->string
);
215 /*set links in prev and next item*/
216 item
->next
->prev
=item
->prev
;
217 item
->prev
->next
=item
->next
;
225 VOID
add_at_bottom(LPTSTR string
)
229 ASSERT(Top
&& Bottom
);
231 /*delete first entry if maximum number of entries is reached*/
232 while (size
>=max_size
)
235 while (_istspace(*string
))
238 if (*string
==_T('\0'))
241 /*if new entry is the same than the last do not add it*/
244 if (_tcscmp(string
,Bottom
->next
->string
)==0)
248 /*create new empty Bottom*/
249 tmp
= cmd_alloc(sizeof(HIST_ENTRY
));
252 WARN("Cannot allocate memory for new Bottom!\n");
256 /*fill old bottom with string, it will become new Bottom->next*/
257 Bottom
->string
= cmd_alloc((_tcslen(string
)+1)*sizeof(TCHAR
));
260 WARN("Cannot allocate memory for Bottom->string!\n");
264 _tcscpy(Bottom
->string
,string
);
272 /*save the new Bottom value*/
280 VOID
History_move_to_bottom(VOID
)
282 ASSERT(Top
&& Bottom
);
287 LPCTSTR
PeekHistory(INT dir
)
289 LPHIST_ENTRY entry
= curr_ptr
;
291 ASSERT(Top
&& Bottom
);
299 if (entry
->next
== Top
|| entry
== Top
)
312 if (entry
->next
== Bottom
|| entry
== Bottom
)
323 return entry
->string
;
326 VOID
History(INT dir
, LPTSTR commandline
)
328 ASSERT(Top
&& Bottom
);
332 add_at_bottom(commandline
);
339 commandline
[0]=_T('\0');
345 if (curr_ptr
->next
==Top
|| curr_ptr
==Top
)
351 commandline
[0]=_T('\0');
356 curr_ptr
= curr_ptr
->next
;
357 if (curr_ptr
->string
)
358 _tcscpy(commandline
,curr_ptr
->string
);
363 if (curr_ptr
->prev
==Bottom
|| curr_ptr
==Bottom
)
369 commandline
[0]=_T('\0');
374 curr_ptr
= curr_ptr
->prev
;
375 if (curr_ptr
->string
)
376 _tcscpy(commandline
,curr_ptr
->string
);
380 #endif //#if FEATURE_HISTORY