Linux программирование в примерах
Шрифт:
70 j = myrandom % 6; /* обеспечить диапазон 0 <= j <= 5 */
71 printf("+-------+\n");
72 for (k = 0; k < 3; k++)
73 printf("|%s|\n", die_faces[(j * 3) + k]);
74 printf("+-------+\n");
75 putchar('\n');
76 }
77
78 return 0;
79 }
Строки 35–47 предоставляют интерфейс вызова функции для
/dev/urandom
, читая каждый раз данные unsigned long
.
12.7. Расширения метасимволов
Три набора функции возрастающей сложности предусматривают возможность сопоставления с шаблонами групповых символов оболочки. Многим программам нужны такие библиотечные функции. Одним примером является
find
: 'find .
– name '*.с' -print
'. Другим примером является опция – name '*.с' -print
– -exclude
во многих программах, которая принимает шаблон файлов с групповыми символами для исключения из того или иного действия. В данном разделе по очереди рассматривается каждый набор функций. 12.7.1. Простое сопоставление с шаблоном:
fnmatch
Мы начинаем с функции
fnmatch
(«filename match» — сопоставление имени файла»).
#include <fnmatch.h> /* POSIX */
int fnmatch(const char *pattern, const char *string, int flags);
Эта функция сопоставляет
string
с pattern
, который является обычным шаблоном групповых символов оболочки. Значение флагов (которое вскоре будет описано) изменяет поведение функции. Возвращаемое значение равно 0, если string
соответствует pattern
, FNM_NOMATCH
, если не соответствует, и ненулевое значение, если возникла ошибка. К сожалению, POSIX не определяет каких-либо специфических ошибок; соответственно, вы можете лишь сказать, что что-то пошло не так, но не можете сказать, что. Переменная
flags
является побитовым ИЛИ одного или более флагов, перечисленных в табл. 12.1. Таблица 12.1. Значения флагов для
fnmatch
| Флаг | Только GLIBC | Значение |
|---|---|---|
| FNM_CASEFOLD | Сопоставление с учетом регистра | |
| FNM_FILE_NAME | Синоним GNU для FNM_PATHNAME | |
| FNM_LEADING_DIR | Флаг для внутреннего использования GLIBC; не используйте его в своих программах. Подробности см. в fnmatch(3) | |
| FNM_NOESCAPE | Обратный слеш является обычным символом, а не знаком перехода | |
| FNM_PATHNAME | Слеш в string должен соответствовать слешу в pattern , он не может быть подставлен через * , ? или '[...] ' | |
| FNM_PERIOD | Начальная
string подходит, лишь если в pattern также есть начальная точка. Точка должна быть первым символом в string . Однако, если также установлен FNM_PATHNAME , точка, которая идет за слешем, также рассматривается как начальная |
fnmatch
работает со строками из любого источника; сопоставляемые строки не обязательно должны быть действительными именами файлов. Хотя на практике fnmatch
используется в коде, читающем каталог с помощью readdir
(см раздел 5.3.1 «Базовое чтение каталогов»):
struct dirent dp;
DIR *dir;
char pattern[100];
/* ...заполнить шаблон, открыть каталог, проверить ошибки... */
while ((dp = readdir(dir)) != NULL) {
if (fnmatch(pattern, dir->d_name, FNM_PERIOD) == 0)
/* имя файла соответствует шаблону */
else
continue; /* не соответствует */
}
GNU
ls
использует fnmatch
для реализации своей опции – -ignore
. Вы можете предоставить несколько игнорируемых шаблонов (с помощью нескольких опций). ls
сопоставляет каждое имя файла со всеми шаблонами. Она делает это с помощью функции file_interesting
в ls.с
:
2269 /* Возвращает не ноль, если файл в 'next' должен быть перечислен. */
2270
2271 static int
2272 file_interesting(const struct dirent *next)
2273 {
2274 register struct ignore_pattern* ignore;
2275
2276 for (ignore = ignore_patterns; ignore; ignore = ignore->next)
2277 if (fnmatch(ignore->pattern, next->d_name, FNM_PERIOD) == 0)
2278 return 0;
2279
2280 if (really_all_files
2281 || next->d_name[0] !=
2282 || (all_files
2283 && next->d_name[1] != '\0 '
2284 && (next->d_name[1] || next->d_name[2] != '\0')))
2285 return 1;
2286
2287 return 0;
2288 }
Цикл в строках 2276–2278 сопоставляет имя файла со списком шаблонов для игнорируемых файлов. Если один из шаблонов подходит, файл не интересен и
file_interesting
возвращает false (то есть 0). Переменная
all_files
соответствует опции – А
, которая показывает файлы, имена которых начинаются с точки, но не являются '.
' и '..
'. Переменная really_all_files
соответствует опции – а
, которая предполагает – А
, а также показывает '.
' и '..
'. При наличии таких сведений, условие в строках 228–2284 может быть представлено следующим псевдокодом:
Поделиться:
Популярные книги
Гезат
22. Вечный капитан
Фантастика:
альтернативная история
5.25
рейтинг книги
Метатель. Книга 2
2. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Старый, но крепкий 2
2. Культивация без насилия
Фантастика:
рпг
уся
эпическая фантастика
5.00
рейтинг книги
Кодекс Охотника. Книга XXXIII
33. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Газлайтер. Том 26
26. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Жрец Хаоса. Книга III
3. Зов пустоты
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Геном хищника. Книга шестая
6. Я - Легенда!
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Кодекс Охотника. Книга XXXV
35. Кодекс Охотника
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XVIII
18. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Разведчик. Заброшенный в 43-й
Героическая фантастика
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.93
рейтинг книги
Кодекс Охотника. Книга XXXVIII
38. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
юмористическое фэнтези
5.00
рейтинг книги
Вперед в прошлое 7
7. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Имперец. Том 1 и Том 2
1. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
На границе империй. Том 7. Часть 4
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
5.00