Чтение онлайн

ЖАНРЫ

Linux программирование в примерах
Шрифт:

53 if (optind == argc) /* файлов нет, по умолчанию stdin */

54 process("standard input", stdin);

55 else {

56 /* цикл с файлами */

57 for (i = optind; i < argc; i++) {

58 if (strcmp(argv[i], "-") == 0)

59 process("standard input", stdin);

60 else if ((fp = fopen(argv[i], "r")) != NULL) {

61 process(argv[i], fp);

62 fclose(fp);

63 } else {

64 fprintf(stderr, "%s: %s: could not open: %s\n",

65 argv[0], argv[i], strerror(errno));

66 errors++;

67 }

68 }

69 }

70

71 regfree(&pattern);

72 return errors != 0;

73 }

Строки 53–69

обрабатывают файлы, отыскивая соответствующие шаблону строки. Строки 53–54 обрабатывают случай, когда файлы не указаны: программа читает со стандартного ввода. В противном случае, строки 57–68 обрабатывают в цикле файлы. Строка 58 обрабатывает особый случай '
', обозначающий стандартный ввод, строки 60–62 обрабатывают обычные файлы, а строки 63–67 обрабатывают ошибки.

75 /* compile_pattern --- компиляция шаблона */

76

77 void compile_pattern(const char *pat)

78 {

79 int flags = REG_NOSUB; /* информация о месте совпадения не требуется */

80 int ret;

81 #define MSGBUFSIZE 512 /* произвольно */

82 char error[MSGBUFSIZE];

83

84 if (ignore_case)

85 flags |= REG_ICASE;

86 if (extended)

87 flags |= REG_EXTENDED;

88

89 ret = regcomp(&pattern, pat, flags);

90 if (ret != 0) {

91 (void)regerror(ret, &pattern, error, sizeof error);

92 fprintf(stderr, "%s: pattern '%s': %s\n", myname, pat, error);

93 errors++;

94 }

95 }

Строки 75–95 определяют функцию

compile_pattern
. Она сначала устанавливает
REG_NOSUB
в
flags
, поскольку нам нужно знать лишь «подходит ли строка?», а не «где в строке располагается подходящий текст?»

Строки 84-85 добавляют дополнительные флаги в соответствии с опциями командной строки. Строка 89 компилирует шаблон, а строки 90–94 сообщают о возникших ошибках

97 /* process --- читает строки текста и сопоставляет их с шаблоном */

98

99 void process(const char *name, FILE *fp)

100 {

101 char *buf = NULL;

102 size_t size = 0;

103 char error[MSGBUFSIZE];

104 int ret;

105

106 while (getline(&buf, &size, fp) != -1) {

107 ret = regexec(&pattern, buf, 0, NULL, 0);

108 if (ret != 0) {

109 if (ret != REG_NOMATCH) {

110 (void)regerror(ret, &pattern, error, sizeof error);

111 fprintf(stderr, "%s: file %s: %s\n", myname, name, error);

112 free(buf);

113 errors++;

114 return;

115 }

116 } else

117 printf("%s: %s", name, buf); /*
вывести подходящие строки */

118 }

119 free(buf);

120 }

Строки 97–120 определяют функцию

process
, которая читает файл и выполняет сопоставление с регулярным выражением. Внешний цикл (строки 106–119) читает строки ввода. Для избежания проблем с длиной строки мы используем
getline
(см. раздел 3.2.1.9 «Только GLIBC: чтение целых строк:
getline
и
getdelim
»). Строка 107 вызывает
regexec
. Ненулевое возвращаемое значение означает либо неудачное сопоставление, либо какую-нибудь другую ошибку. Строки 109–115 соответственно проверяют
REG_NOMATCН
и выводят ошибку лишь тогда, когда возникла какая-нибудь другая проблема — неудачное сопоставление не является ошибкой

Если возвращаемое значение равно 0, строка совпала с шаблоном и соответственно строка 117 выводит имя файла и совпавшую строку.

122 /* usage --- вывод сообщения об использовании и выход */

123

124 void usage(void)

125 {

126 fprintf(stderr, "usage: %s [-i] [-E] pattern [ files ... ]\n", myname);

127 exit(1);

128 }

Функция

usage
выводит сообщение об использовании и завершает программу. Она вызывается, когда предоставлены недействительные аргументы или не предоставлен шаблон (строки 38–40 и 44–45).

Вот и все! Скромная, но тем не менее полезная версия

grep
в 130 строк кода.

12.9. Рекомендуемая литература

1. Programming Pearls, 2nd edition, by Jon Louis Bentley Addison-Wesley, Reading, Massachusetts, USA, 2000. ISBN- 0-201-65788-0. См. также веб-сайт этой книги. [131]

Проектирование программы с операторами проверки является одной из главных тем в этой книге.

131

http://www.cs.bell-labs.com/cm/cs/pearls/
Примеч. автора.

2. Building Secure Software How to Avoid Security Problems the Right Way, by John Viega and Gary McGraw Addison-Wesley, Reading, Massachusetts, USA, 2001. ISBN: 0-201-72152-X.

Состояния гонки являются одной из многих проблем, о которых нужно побеспокоиться при написании безопасного программного обеспечения. Другой проблемой являются случайные числа. Данная книга рассматривает наряду с другими обе эти проблемы (Мы упоминали о ней в предыдущей главе.)

3. The Art of Computer Programming. Volume 2. Seminumerical Algorithms, 3rd edition, by Donald E. Knuth Addison-Wesley, Reading, Massachusetts, USA, 1998. ISBN- 0-201-89684-2. [132] См также веб-сайт этой книги. [133]

132

Русский перевод: Дональд E. Кнут. Искусство программирования. Том 2. Получисленные алгоритмы (3-е издание). Москва - Санкт-Петербург - Киев. Вильямс. 2000 — Примеч. науч. ред.

133

http://www-cs-faculty.stanford.edu/~knuth/taocp.html
Примеч. автора.

Поделиться с друзьями: