Выбрать главу

145:      если мы игнорируем регистр в регулярном выражении, однако позволяет

146:      функции strstr() правильно обработать -i */

147:   chptr = alloca(strlen(pattern) + 1);

148:   strcpy(chptr, pattern);

149:   pattern = chptr;

150:

151:   while (*chptr) {

152:    if (isalpha(*chptr)) *chptr = tolower(*chptr);

153:    chptr++;

154:   }

155:  }

156:

157:

158:  switch (mode) {

159:  case MODE_EXTENDED:

160:   regFlags |= REG_EXTENDED;

161:  case MODE_REGEXP:

162:   if ((rc = regcomp(&regPattern, pattern, regFlags))) {

163:    do_regerror(rc, &regPattern);

164:    return 1;

165:   }

166:   finalPattern = &regPattern;

167:   break;

168:

169:  case MODE_FIXED:

170:   finalPattern = pattern;

171:   break;

172:  }

173:

174:  if (!*files) {

175:   rc = scanFile(stdin, mode, finalPattern, ignoreCase, NULL,

176:    &maxCount);

177:  } else if (!files[1]) {

178:   /* эта часть обрабатывается отдельно, поскольку имя файла

179:      выводить не нужно */

180:   if (!(f = fopen(*files, "r"))) {

181:    perror(*files);

182:    rc = 1;

183:   } else {

184:    rc = scanFile(f, mode, finalPattern, ignoreCase, NULL,

185:     &maxCount);

186:    fclose(f);

187:   }

188:  } else {

189:   rc = 0;

190:

191:   while (*files) {

192:    if (!(f = fopen(*files, "r"))) {

193:     perror(*files);

194:     rc = 1;

195:    } else {

196:     rc |= scanFile(f, mode, finalPattern, ignoreCase,

197:      *files, &maxCount);

198:     fclose(f);

199:    }

200:    files++;

201:    if (!maxCount) break;

202:   }

203:  }

204:

205:  return rc;

206: }

Глава 24

Управление терминалами с помощью библиотеки S-Lang

С помощью библиотеки S-Lang, написанной Джоном Дэвисом (John Е. Davis), можно осуществлять доступ к терминалам на среднем уровне. Все действия, связанные с управлением терминалами на низком уровне, осуществляются посредством набора подпрограмм, предлагающих прямой доступ к видеотерминалам и автоматически управляющих прокруткой и цветами. Несмотря на незначительную прямую поддержку окон и отсутствие в S-Lang каких-либо элементов управления, для таких задач эта библиотека предлагает удобную основу[167].

Библиотеку S-Lang можно использовать и для работы в DOS, что делает ее привлекательной для создания приложений, которые будут выполняться на платформах Unix и DOS.

Возможности управления терминалами с помощью библиотеки S-Lang можно разделить на две категории. Во-первых, библиотека предлагает набор функций для управляемого считывания нажатий клавиш из терминала. Во-вторых, она содержит набор подпрограмм для полноэкранного вывода на терминал. Многие возможности терминалов будут недоступными для программистов, однако функциональными возможностями каждого терминала можно будет воспользоваться[168]. В этой главе вы узнаете о том, каким образом можно использовать библиотеку S-Lang применительно ко всем этим функциональным возможностям, а в конце главы вам будет предложен пример программы для закрепления материала.

24.1. Обработка ввода

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

Широко распространенными подсистемами являются BSD sgtty, System termio, a также POSIX termios. За работу по управлению входными данными в библиотеке S-Lang отвечают несколько функций, предназначенных специально для того, чтобы сделать обработку данных, поступающих с клавиатуры, более простой и доступной.

Чтобы написать программу для посимвольного чтения из терминала и вывода каждого символа в отдельной строке потребуется несложный код.

 1: /* slecho.c */

 2:

 3: #include <ctype.h>

 4: #include <slang/slang.h>

 5: #include <stdio.h>

 6:

 7: int main(void) {

 8:  char ch = '\0';

 9:

10:  /*

11:   Начать обработку SLANG tty со следующими параметрами:

12:   -1 символ прерывания по умолчанию (обычно Ctrl-C)

13:   0 управление потоком не производится; все символы (кроме

14:   символа прерывания) будут переданы в программу 1 разрешение

15:   обработки выходных данных OPOST управляющих последовательностей

16:  */

17:  SLang_init_tty(-1, 0, 1);

18:

19:  while (ch != 'q') {

20:   ch = SLang_getkey();

21:   printf("чтение: %c 0x%x\n", isprint(ch) ? ch : ' ', ch);

22:  }

23:

24:  SLang_reset_tty();

25:

26:  return 0;

27: }

Эта программа предполагает, что все заголовочные файлы S-Lang содержатся в каталоге /usr/include/slang. Если в вашей системе они находятся в другом каталоге, то тогда следует изменить соответствующим образом код (это касается всех примеров в этой главе). Для компилирования и компоновки этой программы в команду компоновки потребуется добавить -lslang, чтобы компоновщик мог найти функции S-Lang.

24.1.1. Инициализация обработки ввода в S-Lang

Прежде чем какая-либо функция обработки входных данных сможет работать, с помощью функции Slang_init_tty() нужно перевести терминал в состояние, которое ожидается S-Lang:

int SLang_init_tty(int abort_char, int flow_ctrl, int opost);

Первый параметр функции Slang_init_tty() определяет символ, который будет использован для прекращения работы. При передаче значения -1 будет сохранен текущий символ прерывания tty (обычно, <Ctrl+C>); в противном случае символу прерывания будет назначено переданное значение. Каждый раз при вводе на терминале символа прекращения работы ядро посылает сигнал SIGINT тому процессу, который обычно завершает работу приложения. В главе 12 мы рассказывали о том, как производится обработка сигналов, подобных SIGINT.

вернуться

167

Один из авторов этой книги разработал набор инструментальных средств newt для управления окнами на высоком уровне на основе S-Lang; этот набор входит в состав большинства распространяемых дистрибутивов Linux.

вернуться

168

Как это описано в базе данных terminfo.