Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
47 целиком в буфер. Увеличить буфер и попытаться снова. */48 if (p[-1] != 'n')49 goto more_buffer;5051 /* Мы получили новую строку, увеличить число строк. */52 ++nlines;Строки 43–52 увеличивают указатель на участок буфера за только что прочитанными данными. Затем код проверяет, является ли последний прочитанный символ символом конца строки. Конструкция
p[-1]p[0]p[1]*(p-1)Если последний символ не был символом конца строки, это означает, что нам не хватило места, и код выходит (с помощью
goto54 #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<stdio.h>64 backslash = 0;65 for (p2 = p - 2; p2 >= start; --p2)66 {67 if (*p2 != '\')68 break;69 backslash = !backslash;70 }7172 if (!backslash)73 {74 p[-1] = ' ';75 break;76 }7778 /* Это была комбинация обратный слеш/новая строка. Если есть79 место, прочесть еще одну строку. */80 if (end - p >= 80)81 continue;8283 /* В конце буфера нужно больше места, поэтому выделить еще.84 Позаботиться о сохранении текущего смещения в p. */85 more_buffer:86 {87 unsigned long off = p - start;88 ebuf->size *= 2;89 start = ebuf->buffer=ebuf->bufstart=(char*)xrealloc(start,90 ebuf->size);91 p = start + off;92 end = start + ebuf->size;93 *p = ' ';94 }95 }До сих пор мы имели дело с механизмом получения в буфер по крайней мере одной полной строки. Следующий участок обрабатывает случай строки с продолжением. Хотя он должен гарантировать, что конечный символ обратного слеша не является частью нескольких обратных слешей в конце строки. Код проверяет, является ли общее число таких символов четным или нечетным путем простого переключения переменной
backslashЕсли число четное, условие '
!backshlashС другой стороны, если число нечетно, строка содержит четное число пар обратных слешей (представляющих символы \, как в С), и конечную комбинацию символов обратного слеша и конца строки. [43] В этом случае, если в буфере остались по крайней мере 80 свободных байтов, программа продолжает чтение в цикле следующей строки (строки 78–81). (Использование магического числа 80 не очень здорово; было бы лучше определить и использовать макроподстановку.)
По достижении строки 83 программе нужно больше места в буфере. Именно здесь вступает в игру динамическое управление памятью. Обратите внимание на комментарий относительно сохранения значения
pОбратите внимание, что здесь вызывается функция
xrealloc()malloc()realloc()NULLextern const char *myname; /* установлено в main() */void *xrealloc(void *ptr, size_t amount) { void *p = realloc(ptr, amount); if (p == NULL) { fprintf(stderr, "%s: out of memory!n", myname); exit(1); } return p;}Таким образом, если функция
xrealloc()ptr = xrealloc(ptr, new_size)