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

на главную - закладки

Жанры

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

10 /* Использование строковых буферов и буферов потоков достаточно

11 различается, чтобы использовать разные функции. */

12

13 if (!ebuf->fp)

14 return readstring(ebuf);

15

16 /* При чтении из файла для каждой новой строки мы всегда

17 начинаем с начала буфера. */

18

19 p = start = ebuf->bufstart;

20 end = p + ebuf->size;

21 *p = '\0';

Для

начала заметим, что GNU Make написан на С K&R для максимальной переносимости. В исходной части объявляются переменные, и если ввод осуществляется из строки (как в случае расширения макроса), код вызывает другую функцию,
readstring
(строки 13 и 14). Строка '
!ebuf->fp
' (строка 13) является более короткой (и менее понятной, по нашему мнению) проверкой на пустой указатель; это то же самое, что и '
ebuf->fp==NULL
'.

Строки 19-21 инициализируют указатели и вводят байт NUL, который является символом завершения строки С в конце буфера. Затем функция входит в цикл (строки 23–95), который продолжается до завершения всего ввода.

23 while (fgets(p, end - р, ebuf->fp) != 0)

24 {

25 char *p2;

26 unsigned long len;

27 int backslash;

28

29 len = strlen(p);

30 if (len == 0)

31 {

32 /* Это случается лишь тогда, когда первый символ строки '\0'.

33 Это довольно безнадежный случай, но (верите или нет) ляп Афины

34 бьет снова! (xmkmf помещает NUL в свои makefile.)

35 Здесь на самом деле нечего делать; мы создаем новую строку, чтобы

36 следующая строка не была частью данной строки. */

37 error (&ebuf->floc,

38 _("warning: NUL character seen; rest of line ignored"));

39 p[0] = '\n';

40 len = l;

41 }

Функция

fgets
(строка 23) принимает указатель на буфер, количество байтов для прочтения и переменную
FILE*
для файла, из которого осуществляется чтение. Она читает на один байт меньше указанного, чтобы можно было завершить буфер символом '
\0
'. Эта функция подходит, поскольку она позволяет избежать переполнения буфера. Она прекращает чтение, когда встречается с символами конца строки или конца файла; если это символ новой строки, он помещается в буфер. Функция возвращает
NULL
при неудаче или значение указателя первого аргумента при успешном завершении.

В этом случае аргументами являются указатель на свободную область буфера, размер оставшейся части буфера и указатель

FILE
для чтения.

Комментарии в строках 32–36 очевидны; если встречается нулевой байт, программа выводит сообщение об ошибке и представляет вывод как пустую

строку. После компенсирования нулевого байта (строки 30–41) код продолжает работу.

43 /* Обойти только что прочитанный текст. */

44 p += len;

45

46 /* Если последний символ - не конец строки, она не поместилась

47 целиком в буфер. Увеличить буфер и попытаться снова. */

48 if (p[-1] != '\n')

49 goto more_buffer;

50

51 /* Мы получили новую строку, увеличить число строк. */

52 ++nlines;

Строки 43–52 увеличивают указатель на участок буфера за только что прочитанными данными. Затем код проверяет, является ли последний прочитанный символ символом конца строки. Конструкция

p[-1]
(строка 48) проверяет символ перед p, также как
p[0]
является текущим символом, а
p[1]
— следующим. Сначала это кажется странным, но если вы переведете это на язык математики указателей,
*(p-1)
, это приобретет больший смысл, а индексированная форма, возможно, проще для чтения.

Если последний символ не был символом конца строки, это означает, что нам не хватило места, и код выходит (с помощью

goto
) для увеличения размера буфера (строка 49). В противном случае увеличивается число строк.

54 #if !defined(WINDOWS32) && !defined(__MSDOS__)

55 /* Проверить, что строка завершилась CRLF; если так,

56 игнорировать CR. */

57 if ((p - start) > 1 && p[-2] == '\r')

58 {

59 --p;

60 p[-1] = '\n';

61 }

62 #endif

Строки 54–62 обрабатывают вводимые строки, следующие соглашению Microsoft по завершению строк комбинацией символов возврата каретки и перевода строки (CR-LF), а не просто символом перевода строки (новой строки), который является соглашением Linux/Unix. Обратите внимание, что

#ifdef
исключает этот код на платформе Microsoft, очевидно, библиотека
<stdio.h>
на этих системах автоматически осуществляет это преобразование. Это верно также для других не-Unix систем, поддерживающих стандартный С.

64 backslash = 0;

65 for (p2 = p - 2; p2 >= start; --p2)

66 {

67 if (*p2 != '\\')

68 break;

69 backslash = !backslash;

70 }

71

72 if (!backslash)

73 {

74 p[-1] = '\0';

75 break;

76 }

77

Поделиться:
Популярные книги

Золото Советского Союза: назад в 1975

Майоров Сергей
Фантастика:
попаданцы
альтернативная история
5.25
рейтинг книги
Золото Советского Союза: назад в 1975

Мачеха Золушки - попаданка

Максонова Мария
Фантастика:
попаданцы
сказочная фантастика
фэнтези
5.00
рейтинг книги
Мачеха Золушки - попаданка

Кодекс Охотника. Книга XXVI

Винокуров Юрий
26. Кодекс Охотника
Фантастика:
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXVI

Хорунжий

Вязовский Алексей
1. Индийский поход
Фантастика:
попаданцы
альтернативная история
5.40
рейтинг книги
Хорунжий

Чехов книга 3

Гоблин (MeXXanik)
3. Адвокат Чехов
Фантастика:
попаданцы
альтернативная история
аниме
6.00
рейтинг книги
Чехов книга 3

Один на миллион. Трилогия

Земляной Андрей Борисович
Один на миллион
Фантастика:
боевая фантастика
8.95
рейтинг книги
Один на миллион. Трилогия

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Матабар

Клеванский Кирилл Сергеевич
1. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар

Диверсант

Вайс Александр
2. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Диверсант

Око василиска

Кас Маркус
2. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Око василиска

Сержант. Назад в СССР. Книга 4

Гаусс Максим
4. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сержант. Назад в СССР. Книга 4

Тринадцатый XIII

NikL
13. Видящий смерть
Фантастика:
городское фэнтези
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Тринадцатый XIII

Последний натиск на восток ч. 2

Чайка Дмитрий
7. Третий Рим
Фантастика:
попаданцы
альтернативная история
7.50
рейтинг книги
Последний натиск на восток ч. 2

Император Пограничья 3

Астахов Евгений Евгеньевич
3. Император Пограничья
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 3