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