OptStr — текстовая строка, содержащая все возможные параметры, находящиеся во взаимно-однозначном соответствии с адресами булевских переменных в списке аргументов (...). Эти флаги устанавливаются тогда и только тогда, когда символ соответствующей опции встречается в argv[1], argv[2], …Возвращаемым значением является индекс (в argv) первого аргумента, указанного вслед за опциями. */
{
va_list pFlagList;
LPBOOL pFlag;
int iFlag = 0, iArg;
va_start(pFlagList, OptStr);
while ((pFlag = va_arg(pFlagList, LPBOOL)) != NULL && iFlag < (int)_tcslen(OptStr)) {
*pFlag = FALSE;
for (iArg = 1; !(*pFlag) && iArg < argc && argv[iArg][0] == '-'; iArg++) *pFlag = _memtchr(argv[iArg], OptStr[iFlag], _tcslen(argv[iArg])) != NULL;
iFlag++;
}
va_end(pFlagList);
for (iArg = 1; iArg < argc && argv[iArg][0] == '-'; iArg++);
return iArg;
}
SkipArg.сЭта функция обрабатывает командную строку, пропуская одно поле, отделенное пробельным символом. Впервые используется в программе timep (программа 6.2).
Программа А.8. Функция SkipArg/* SkipArg.с
Пропуск одного аргумента командной строки – символы табуляции и пробела пропускаются. */
#include "EvryThng.h"
LPTSTR SkipArg(LPCTSTR targv) {
LPTSTR p;
p = (LPTSTR)targv;
/* Перейти к следующему символу табуляции или пробела. */
while (*р != '\0' && *р != TSPACE && *р != TAB) p++;
/* Пропустить символы табуляции и пробела и перейти к следующему аргументу. */
while (*р != '\0' && (*р == TSPACE || *р == TAB)) p++;
return р;
}
GetArgs.сЭта функция просматривает строку, отыскивая слова, разделенные символами пробелов или табуляции, и помещает результат в массив строк, передаваемый функции. Эта функция может пригодиться для преобразования командной строки в массив argv[] и впервые используется в программе JobShell в главе 6. Функция Win32 CommandLineToArgW решает ту же задачу, но сфера ее применимости ограничивается символами Unicode.
Программа А.9. Функция GetArgs/* GetArgs. Преобразует командную строку к виду argc/argv. */
#include "EvryThng.h"
VOID GetArgs(LPCTSTR Command, int *pArgc, LPTSTR argstr[]) {
int i, icm = 0;
DWORD ic = 0;
for (i = 0; ic < _tcslen(Command); i++) {
while (ic < _tcslen(Command) && Command[ic] != TSPACE && Command [ic] != TAB) {
argstr[i][icm] = Command[ic];
ic++;
icm++;
}
argstr[i][icm] = '\0';
while (ic < _tcslen(Command) && (Command[ic] == TSPACE || Command[ic] == TAB)) ic++;
icm = 0;
}
if (pArgc != NULL) *pArgc = i;
return;
}
ПРИЛОЖЕНИЕ Б Сопоставление функций Windows, UNIX и библиотеки С
В этом приложении приводятся таблицы, в которых представлены функции Windows (Win32 и Win64), описанные в основном тексте, а также сопоставимые с ними функции UNIX/Linux[36] и стандартной библиотеки ANSI С, если таковые имеются.
Таблицы расположены в порядке следования глав (некоторые таблицы объединяют данные, относящиеся к нескольким главам). В пределах каждой главы данные в таблицах отсортированы сначала в соответствии с их функциональным назначением (файловая система, управление каталогами и так далее), а затем по именам функций Windows.
В каждой из строк таблицы представлена следующая информация:
• Функциональная область (категория).
• Имя функции Windows.
• Имя соответствующей функции UNIX. В некоторых случаях существует несколько таких функций.
• Имя соответствующей функции библиотеки С, если таковая имеется.
Используемые в таблицах обозначения нуждаются в некоторых пояснениях.
• В библиотеке функций Microsoft Visual C++ содержатся некоторые функции, совместимые с UNIX. Так, функция _open является функцией библиотеки совместимости, эквивалентной UNIX-функции open. Выделение имени функции UNIX курсивом означает, что эта функция является совместимой. Символ звездочки в конце имени функции указывает на существование версии функции, ориентированной на работу с расширенными символами UNICODE. Так, существует функция _wopen.
• Программа, в которой используются только функции стандартной библиотеки С и отсутствуют вызовы функций Windows или UNIX, должны компилироваться, компоноваться и выполняться в обеих системах. В то же время, возможности такой программы в отношении работы с файлами и выполнения операций ввода/вывода будут ограниченными.
• Функция, следующая за разделительной запятой, является альтернативной версией, часто использующей другие характеристики или эмулирующей какой-то один из аспектов функции Windows.
• Разделение функций символом точки с запятой указывает на то, что эмуляция функции Windows достигается за счет последовательного использования этих функций. Так, функции CreateProcess соответствуют функции fork; exec.
• Подчеркивание имени элемента указывает на глобальную переменную, например errno.
• В некоторых случаях UNIX-эквивалент указывается в обобщенной форме с использованием такой, например, терминологии, как "функции терминального ввода/вывода" в случае Windows-функции AllocConsole. Часто приводится только соответствующий простой комментарий наподобие "Используйте библиотеку С", как это сделано в случае функции GetTempFileName. В других случаях ситуация обращается. Так, для функций управления сигналами в UNIX (функция sigaddset и подобные ей) в столбце "Windows" содержатся записи "Используйте SEH, VEH", означающие, что для обеспечения желаемого поведения программы программист должен установить структурные или векторные обработчики исключений и функции фильтров. В отличии от UNIX, группы процессов в Windows не поддерживаются, и в подобных случаях в столбце "Windows" ставится прочерк, что, впрочем, не помешало нам эмулировать отношения между процессами при управлении заданиями в главе 6.