Linux программирование в примерах | страница 62



Функция возвращает число строк в буфере. (Номера строк здесь даны относительно начала функции, а не исходного файла.)

>1  static long

>2  readline(ebuf) /* static long readline(struct ebuffer *ebuf) */

>3  struct ebuffer *ebuf;

>4  {

>5   char *p;

>6   char *end;

>7   char *start;

>8   long nlines = 0;

>9

>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 при неудаче или значение указателя первого аргумента при успешном завершении.