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 (_T("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)
379 lpString = alloca(nBufferLength);
384 while ((--nBufferLength > 0) &&
385 ReadFile(hFile, &ch, 1, &dwRead, NULL) && dwRead)
390 ReadFile (hFile, &ch, 1, &dwRead, NULL);
393 lpString[len++] = ch;
399 lpString[len++] = '\0';
401 MultiByteToWideChar(CP_ACP, 0, lpString, len, lpBuffer, len);
408 * GetConsoleWindow - returns the handle to the current console window
410 HWND GetConsoleWindow (VOID)
419 GetConsoleTitle (original, sizeof(original) / sizeof(TCHAR));
421 _tcscpy (temp, original);
422 _tcscat (temp, _T("-xxx "));
424 if (FindWindow (0, temp) == NULL )
426 SetConsoleTitle (temp);
429 while(!(h = FindWindow (0, temp)))
432 SetConsoleTitle (original);
440 INT PagePrompt (VOID)
444 ConOutPrintf (_T("Press a key to continue...\n"));
446 RemoveBreakHandler ();
453 while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
454 (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) ||
455 (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL));
460 if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
461 ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') &&
462 (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))))
469 INT FilePromptYN (LPTSTR szFormat, ...)
474 // LPTSTR szKeys = _T("yna");
479 va_start (arg_ptr, szFormat);
480 _vstprintf (szOut, szFormat, arg_ptr);
483 ConOutPrintf (szFormat);
485 /* preliminary fix */
486 ConInString (szIn, 10);
487 ConOutPrintf (_T("\n"));
490 for (p = szIn; _istspace (*p); p++)
495 else if (*p == _T('N'))
498 else if (*p == _T('\03'))
505 /* unfinished sollution */
507 RemoveBreakHandler ();
513 cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar);
514 if (_tcschr (szKeys, cKey[0]) == NULL)
519 while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
520 (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) ||
521 (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL));
526 if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
527 ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') &&
528 (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))))
536 INT FilePromptYNA (LPTSTR szFormat, ...)
541 // LPTSTR szKeys = _T("yna");
546 va_start (arg_ptr, szFormat);
547 _vstprintf (szOut, szFormat, arg_ptr);
550 ConOutPrintf (szFormat);
552 /* preliminary fix */
553 ConInString (szIn, 10);
554 ConOutPrintf (_T("\n"));
557 for (p = szIn; _istspace (*p); p++)
562 else if (*p == _T('N'))
567 else if (*p == _T('\03'))
574 /* unfinished sollution */
576 RemoveBreakHandler ();
582 cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar);
583 if (_tcschr (szKeys, cKey[0]) == NULL)
588 while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
589 (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) ||
590 (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL));
595 if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
596 ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') &&
597 (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))))