2 * MISC.C - misc. functions.
11 * moved functions in here
13 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
14 * added config.h include
16 * 18-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
17 * Changed split() to accept quoted arguments.
18 * Removed parse_firstarg().
20 * 23-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
21 * Fixed an ugly bug in split(). In rare cases (last character
22 * of the string is a space) it ignored the NULL character and
23 * tried to add the following to the argument list.
25 * 28-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
26 * FileGetString() seems to be working now.
28 * 06-Nov-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
29 * Added PagePrompt() and FilePrompt().
45 * get a character out-of-band and honor Ctrl-Break characters
49 HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
50 INPUT_RECORD irBuffer;
55 ReadConsoleInput (hInput, &irBuffer, 1, &dwRead);
56 if ((irBuffer.EventType == KEY_EVENT) &&
57 (irBuffer.Event.KeyEvent.bKeyDown == TRUE))
59 if ((irBuffer.Event.KeyEvent.dwControlKeyState &
60 (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &
61 (irBuffer.Event.KeyEvent.wVirtualKeyCode == 'C'))
70 return irBuffer.Event.KeyEvent.uChar.AsciiChar;
72 return irBuffer.Event.KeyEvent.uChar.UnicodeChar;
78 * Check if Ctrl-Break was pressed during the last calls
81 BOOL CheckCtrlBreak (INT mode)
83 static BOOL bLeaveAll = FALSE; /* leave all batch files */
88 case BREAK_OUTOFBATCH:
99 /* we need to be sure the string arrives on the screen! */
101 ConOutPuts (_T("\r\nCtrl-Break pressed. Cancel batch file? (Yes/No/All) "));
102 while (!_tcschr ("YNA\3", c = _totupper (cgetchar())) || !c);
104 ConOutPuts (_T("\r\n"));
107 return bCtrlBreak = FALSE; /* ignore */
109 /* leave all batch files */
110 bLeaveAll = ((c == _T('A')) || (c == _T('\3')));
119 /* state processed */
124 /* add new entry for new argument */
125 static BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry)
130 q = malloc ((_tcslen(entry) + 1) * sizeof (TCHAR));
138 *arg = realloc (oldarg, (*ac + 2) * sizeof (LPTSTR));
147 (*arg)[++(*ac)] = NULL;
152 static BOOL expand (LPINT ac, LPTSTR **arg, LPCTSTR pattern)
155 WIN32_FIND_DATA FindData;
158 LPTSTR dirpart, fullname;
160 pathend = _tcsrchr (pattern, _T('\\'));
163 dirpart = malloc((pathend - pattern + 2) * sizeof(TCHAR));
168 memcpy(dirpart, pattern, pathend - pattern + 1);
169 dirpart[pathend - pattern + 1] = '\0';
175 hFind = FindFirstFile (pattern, &FindData);
176 if (INVALID_HANDLE_VALUE != hFind)
182 fullname = malloc((_tcslen(dirpart) + _tcslen(FindData.cFileName) + 1) * sizeof(TCHAR));
183 if (NULL == fullname)
189 _tcscat (_tcscpy (fullname, dirpart), FindData.cFileName);
190 ok = add_entry(ac, arg, fullname);
196 ok = add_entry(ac, arg, FindData.cFileName);
198 } while (FindNextFile (hFind, &FindData) && ok);
203 ok = add_entry(ac, arg, pattern);
215 * split - splits a line up into separate arguments, deliminators
216 * are spaces and slashes ('/').
219 LPTSTR *split (LPTSTR s, LPINT args, BOOL expand_wildcards)
226 BOOL bQuoted = FALSE;
228 arg = malloc (sizeof (LPTSTR));
236 /* skip leading spaces */
237 while (*s && (_istspace (*s) || _istcntrl (*s)))
240 /* if quote (") then set bQuoted */
249 /* the first character can be '/' */
253 /* skip to next word delimiter or start of next option */
256 while (_istprint (*s) && (*s != _T('\"')) && (*s != _T('/')))
261 while (_istprint (*s) && !_istspace (*s) && (*s != _T('/')))
265 /* a word was found */
268 q = malloc (((len = s - start) + 1) * sizeof (TCHAR));
273 memcpy (q, start, len * sizeof (TCHAR));
275 if (expand_wildcards && _T('/') != *start &&
276 (NULL != _tcschr(q, _T('*')) || NULL != _tcschr(q, _T('?'))))
278 if (! expand(&ac, &arg, q))
287 if (! add_entry(&ac, &arg, q))
297 /* adjust string pointer if quoted (") */
312 * freep -- frees memory used for a call to split
315 VOID freep (LPTSTR *p)
330 LPTSTR stpcpy (LPTSTR dest, LPTSTR src)
333 return (dest + _tcslen (src));
339 * Checks if a path is valid (accessible)
342 BOOL IsValidPathName (LPCTSTR pszPath)
344 TCHAR szOldPath[MAX_PATH];
347 GetCurrentDirectory (MAX_PATH, szOldPath);
348 bResult = SetCurrentDirectory (pszPath);
350 SetCurrentDirectory (szOldPath);
357 * Checks if a file exists (accessible)
360 BOOL IsValidFileName (LPCTSTR pszPath)
362 return (GetFileAttributes (pszPath) != 0xFFFFFFFF);
366 BOOL IsValidDirectory (LPCTSTR pszPath)
368 return (GetFileAttributes (pszPath) & FILE_ATTRIBUTE_DIRECTORY);
372 BOOL FileGetString (HANDLE hFile, LPTSTR lpBuffer, INT nBufferLength)
380 while ((--nBufferLength > 0) &&
381 ReadFile(hFile, &ch, 1, &dwRead, NULL) && dwRead)
386 ReadFile (hFile, &ch, 1, &dwRead, NULL);
392 if (!dwRead && lpString == lpBuffer)
395 *lpString++ = _T('\0');
402 * GetConsoleWindow - returns the handle to the current console window
404 HWND GetConsoleWindow (VOID)
413 GetConsoleTitle (original, sizeof(original));
415 _tcscpy (temp, original);
416 _tcscat (temp, _T("-xxx "));
418 if (FindWindow (0, temp) == NULL )
420 SetConsoleTitle (temp);
423 while(!(h = FindWindow (0, temp)))
426 SetConsoleTitle (original);
434 INT PagePrompt (VOID)
438 ConOutPrintf ("Press a key to continue...\n");
440 RemoveBreakHandler ();
447 while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
448 (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) ||
449 (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL));
454 if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
455 ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') &&
456 (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))))
463 INT FilePromptYN (LPTSTR szFormat, ...)
468 // LPTSTR szKeys = _T("yna");
473 va_start (arg_ptr, szFormat);
474 _vstprintf (szOut, szFormat, arg_ptr);
477 ConOutPrintf (szFormat);
479 /* preliminary fix */
480 ConInString (szIn, 10);
481 ConOutPrintf (_T("\n"));
484 for (p = szIn; _istspace (*p); p++)
489 else if (*p == _T('N'))
492 else if (*p == _T('\03'))
499 /* unfinished sollution */
501 RemoveBreakHandler ();
507 cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar);
508 if (_tcschr (szKeys, cKey[0]) == NULL)
513 while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
514 (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) ||
515 (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL));
520 if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
521 ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') &&
522 (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))))
530 INT FilePromptYNA (LPTSTR szFormat, ...)
535 // LPTSTR szKeys = _T("yna");
540 va_start (arg_ptr, szFormat);
541 _vstprintf (szOut, szFormat, arg_ptr);
544 ConOutPrintf (szFormat);
546 /* preliminary fix */
547 ConInString (szIn, 10);
548 ConOutPrintf (_T("\n"));
551 for (p = szIn; _istspace (*p); p++)
556 else if (*p == _T('N'))
561 else if (*p == _T('\03'))
568 /* unfinished sollution */
570 RemoveBreakHandler ();
576 cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar);
577 if (_tcschr (szKeys, cKey[0]) == NULL)
582 while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
583 (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) ||
584 (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL));
589 if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
590 ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') &&
591 (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))))