Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhistory.c
Go to the documentation of this file.
00001 /* 00002 * HISTORY.C - command line history. 00003 * 00004 * 00005 * History: 00006 * 00007 * 14/01/95 (Tim Norman) 00008 * started. 00009 * 00010 * 08/08/95 (Matt Rains) 00011 * i have cleaned up the source code. changes now bring this source 00012 * into guidelines for recommended programming practice. 00013 * 00014 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>) 00015 * added config.h include 00016 * 00017 * 25-Jan-1999 (Eric Kohl) 00018 * Cleanup! 00019 * Unicode and redirection safe! 00020 * 00021 * 25-Jan-1999 (Paolo Pantaleo <paolopan@freemail.it>) 00022 * Added lots of comments (beginning studying the source) 00023 * Added command.com's F3 support (see cmdinput.c) 00024 * 00025 */ 00026 00027 00028 00029 /* 00030 * HISTORY.C - command line history. Second version 00031 * 00032 * 00033 * History: 00034 * 00035 * 06/12/99 (Paolo Pantaleo <paolopan@freemail.it>) 00036 * started. 00037 * 00038 */ 00039 00040 #include <precomp.h> 00041 00042 #ifdef FEATURE_HISTORY 00043 00044 typedef struct tagHISTORY 00045 { 00046 struct tagHISTORY *prev; 00047 struct tagHISTORY *next; 00048 LPTSTR string; 00049 } HIST_ENTRY, * LPHIST_ENTRY; 00050 00051 static INT size, 00052 max_size=100; 00053 00054 00055 00056 static LPHIST_ENTRY Top; 00057 static LPHIST_ENTRY Bottom; 00058 00059 00060 static LPHIST_ENTRY curr_ptr=0; 00061 00062 00063 VOID InitHistory(VOID); 00064 VOID History_move_to_bottom(VOID); 00065 VOID History (INT dir, LPTSTR commandline); 00066 VOID CleanHistory(VOID); 00067 VOID History_del_current_entry(LPTSTR str); 00068 00069 /*service functions*/ 00070 static VOID del(LPHIST_ENTRY item); 00071 static VOID add_at_bottom(LPTSTR string); 00072 /*VOID add_before_last(LPTSTR string);*/ 00073 VOID set_size(INT new_size); 00074 00075 00076 00077 INT CommandHistory (LPTSTR param) 00078 { 00079 LPTSTR tmp; 00080 INT tmp_int; 00081 LPHIST_ENTRY h_tmp; 00082 TCHAR szBuffer[2048]; 00083 00084 tmp=_tcschr(param,_T('/')); 00085 00086 if (tmp) 00087 { 00088 param=tmp; 00089 switch (_totupper(param[1])) 00090 { 00091 case _T('F'):/*delete history*/ 00092 CleanHistory();InitHistory(); 00093 break; 00094 00095 case _T('R'):/*read history from standard in*/ 00096 //hIn=GetStdHandle (STD_INPUT_HANDLE); 00097 00098 for(;;) 00099 { 00100 ConInString(szBuffer,sizeof(szBuffer)/sizeof(TCHAR)); 00101 if (*szBuffer!=_T('\0')) 00102 History(0,szBuffer); 00103 else 00104 break; 00105 } 00106 break; 00107 00108 case _T('A'):/*add an antry*/ 00109 History(0,param+2); 00110 break; 00111 00112 case _T('S'):/*set history size*/ 00113 if ((tmp_int=_ttoi(param+2))) 00114 set_size(tmp_int); 00115 break; 00116 00117 default: 00118 return 1; 00119 } 00120 } 00121 else 00122 { 00123 for (h_tmp = Top->prev; h_tmp != Bottom; h_tmp = h_tmp->prev) 00124 ConErrPuts(h_tmp->string); 00125 } 00126 return 0; 00127 } 00128 00129 VOID set_size(INT new_size) 00130 { 00131 while (new_size<size) 00132 del(Top->prev); 00133 00134 max_size=new_size; 00135 } 00136 00137 00138 VOID InitHistory(VOID) 00139 { 00140 size=0; 00141 00142 Top = cmd_alloc(sizeof(HIST_ENTRY)); 00143 Bottom = cmd_alloc(sizeof(HIST_ENTRY)); 00144 00145 Top->prev = Bottom; 00146 Top->next = NULL; 00147 Top->string = NULL; 00148 00149 Bottom->prev = NULL; 00150 Bottom->next = Top; 00151 Bottom->string = NULL; 00152 00153 curr_ptr=Bottom; 00154 } 00155 00156 00157 00158 00159 VOID CleanHistory(VOID) 00160 { 00161 while (Bottom->next!=Top) 00162 del(Bottom->next); 00163 00164 cmd_free(Top); 00165 cmd_free(Bottom); 00166 } 00167 00168 00169 VOID History_del_current_entry(LPTSTR str) 00170 { 00171 LPHIST_ENTRY tmp; 00172 00173 if (size == 0) 00174 return; 00175 00176 if (curr_ptr == Bottom) 00177 curr_ptr=Bottom->next; 00178 00179 if (curr_ptr == Top) 00180 curr_ptr=Top->prev; 00181 00182 00183 tmp = curr_ptr; 00184 curr_ptr = curr_ptr->prev; 00185 del(tmp); 00186 History(-1, str); 00187 } 00188 00189 00190 static 00191 VOID del(LPHIST_ENTRY item) 00192 { 00193 if (item==NULL || item==Top || item==Bottom) 00194 { 00195 TRACE ("del in " __FILE__ ": returning\n" 00196 "item is 0x%08x (Bottom is0x%08x)\n", 00197 item, Bottom); 00198 return; 00199 } 00200 00201 00202 00203 /*free string's mem*/ 00204 if (item->string) 00205 cmd_free(item->string); 00206 00207 /*set links in prev and next item*/ 00208 item->next->prev=item->prev; 00209 item->prev->next=item->next; 00210 00211 cmd_free(item); 00212 00213 size--; 00214 } 00215 00216 static 00217 VOID add_at_bottom(LPTSTR string) 00218 { 00219 00220 00221 LPHIST_ENTRY tmp; 00222 00223 00224 /*delete first entry if maximum number of entries is reached*/ 00225 while(size>=max_size) 00226 del(Top->prev); 00227 00228 while (_istspace(*string)) 00229 string++; 00230 00231 if (*string==_T('\0')) 00232 return; 00233 00234 00235 /*if new entry is the same than the last do not add it*/ 00236 if(size) 00237 if(_tcscmp(string,Bottom->next->string)==0) 00238 return; 00239 00240 00241 /*fill bottom with string, it will become Bottom->next*/ 00242 Bottom->string=cmd_alloc((_tcslen(string)+1)*sizeof(TCHAR)); 00243 _tcscpy(Bottom->string,string); 00244 00245 /*save Bottom value*/ 00246 tmp=Bottom; 00247 00248 00249 /*create new void Bottom*/ 00250 Bottom=cmd_alloc(sizeof(HIST_ENTRY)); 00251 Bottom->next=tmp; 00252 Bottom->prev=NULL; 00253 Bottom->string=NULL; 00254 00255 tmp->prev=Bottom; 00256 00257 /*set new size*/ 00258 size++; 00259 00260 } 00261 00262 00263 00264 VOID History_move_to_bottom(VOID) 00265 { 00266 curr_ptr=Bottom; 00267 00268 } 00269 00270 LPCTSTR PeekHistory(INT dir) 00271 { 00272 LPHIST_ENTRY entry = curr_ptr; 00273 00274 if (dir == 0) 00275 return NULL; 00276 00277 if (dir < 0) 00278 { 00279 /* key up */ 00280 if (entry->next == Top || entry == Top) 00281 { 00282 #ifdef WRAP_HISTORY 00283 entry = Bottom; 00284 #else 00285 return NULL; 00286 #endif 00287 } 00288 entry = entry->next; 00289 } 00290 else 00291 { 00292 /* key down */ 00293 if (entry->next == Bottom || entry == Bottom) 00294 { 00295 #ifdef WRAP_HISTORY 00296 entry = Top; 00297 #else 00298 return NULL; 00299 #endif 00300 } 00301 entry = entry->prev; 00302 } 00303 00304 return entry->string; 00305 } 00306 00307 VOID History (INT dir, LPTSTR commandline) 00308 { 00309 00310 if(dir==0) 00311 { 00312 add_at_bottom(commandline); 00313 curr_ptr=Bottom; 00314 return; 00315 } 00316 00317 if (size==0) 00318 { 00319 commandline[0]=_T('\0'); 00320 return; 00321 } 00322 00323 00324 if(dir<0)/*key up*/ 00325 { 00326 if (curr_ptr->next==Top || curr_ptr==Top) 00327 { 00328 #ifdef WRAP_HISTORY 00329 curr_ptr=Bottom; 00330 #else 00331 curr_ptr=Top; 00332 commandline[0]=_T('\0'); 00333 return; 00334 #endif 00335 } 00336 00337 00338 curr_ptr = curr_ptr->next; 00339 if(curr_ptr->string) 00340 _tcscpy(commandline,curr_ptr->string); 00341 00342 } 00343 00344 00345 00346 00347 00348 if(dir>0) 00349 { 00350 00351 if (curr_ptr->prev==Bottom || curr_ptr==Bottom) 00352 { 00353 #ifdef WRAP_HISTORY 00354 curr_ptr=Top; 00355 #else 00356 curr_ptr=Bottom; 00357 commandline[0]=_T('\0'); 00358 return; 00359 #endif 00360 } 00361 00362 curr_ptr=curr_ptr->prev; 00363 if(curr_ptr->string) 00364 _tcscpy(commandline,curr_ptr->string); 00365 00366 } 00367 } 00368 00369 #endif //#if FEATURE_HISTORY Generated on Fri May 25 2012 04:15:23 for ReactOS by
1.7.6.1
|