Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Linux ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 29

Автор Роббинс ΠΡ€Π½ΠΎΠ»ΡŒΠ΄

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

78Β  /* Π­Ρ‚ΠΎ Π±Ρ‹Π»Π° комбинация ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹ΠΉ слСш/новая строка. Если Π΅ΡΡ‚ΡŒ

79Β Β  Β  мСсто, ΠΏΡ€ΠΎΡ‡Π΅ΡΡ‚ΡŒ Π΅Ρ‰Π΅ ΠΎΠ΄Π½Ρƒ строку. */

80Β  if (end - p >= 80)

81Β Β  continue;

82

83Β  /* Π’ ΠΊΠΎΠ½Ρ†Π΅ Π±ΡƒΡ„Π΅Ρ€Π° Π½ΡƒΠΆΠ½ΠΎ большС мСста, поэтому Π²Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ Π΅Ρ‰Π΅.

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 = '\0';

94Β  }

95 }

Π”ΠΎ сих ΠΏΠΎΡ€ ΠΌΡ‹ ΠΈΠΌΠ΅Π»ΠΈ Π΄Π΅Π»ΠΎ с ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ получСния Π² Π±ΡƒΡ„Π΅Ρ€ ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΠ»Π½ΠΎΠΉ строки. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ участок ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ случай строки с ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ΠΌ. Π₯отя ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ символ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ слСша Π½Π΅ являСтся Ρ‡Π°ΡΡ‚ΡŒΡŽ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹Ρ… слСшСй Π² ΠΊΠΎΠ½Ρ†Π΅ строки. Код провСряСт, являСтся Π»ΠΈ ΠΎΠ±Ρ‰Π΅Π΅ число Ρ‚Π°ΠΊΠΈΡ… символов Ρ‡Π΅Ρ‚Π½Ρ‹ΠΌ ΠΈΠ»ΠΈ Π½Π΅Ρ‡Π΅Ρ‚Π½Ρ‹ΠΌ ΠΏΡƒΡ‚Π΅ΠΌ простого ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ

backslash
ΠΈΠ· 0 Π² 1 ΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ. (Π‘Ρ‚Ρ€ΠΎΠΊΠΈ 64–70.)

Если число Ρ‡Π΅Ρ‚Π½ΠΎΠ΅, условиС '

!backshlash
' (строка 72) Π±ΡƒΠ΄Π΅Ρ‚ истинным. Π’ этом случаС ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ символ ΠΊΠΎΠ½Ρ†Π° строки замСщаСтся Π±Π°ΠΉΡ‚ΠΎΠΌ NUL, ΠΈ ΠΊΠΎΠ΄ Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΈΠ· Ρ†ΠΈΠΊΠ»Π°.

Π‘ Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, Ссли число Π½Π΅Ρ‡Π΅Ρ‚Π½ΠΎ, строка содСрТит Ρ‡Π΅Ρ‚Π½ΠΎΠ΅ число ΠΏΠ°Ρ€ ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹Ρ… слСшСй (ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΡ… символы \\, ΠΊΠ°ΠΊ Π² Π‘), ΠΈ ΠΊΠΎΠ½Π΅Ρ‡Π½ΡƒΡŽ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΡŽ символов ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ слСша ΠΈ ΠΊΠΎΠ½Ρ†Π° строки. [43] Π’ этом случаС, Ссли Π² Π±ΡƒΡ„Π΅Ρ€Π΅ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ 80 свободных Π±Π°ΠΉΡ‚ΠΎΠ², ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ Π² Ρ†ΠΈΠΊΠ»Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ строки (строки 78–81). (ИспользованиС магичСского числа 80 Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ Π·Π΄ΠΎΡ€ΠΎΠ²ΠΎ; Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π»ΡƒΡ‡ΡˆΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ макроподстановку.)

По достиТСнии строки 83 ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π½ΡƒΠΆΠ½ΠΎ большС мСста Π² Π±ΡƒΡ„Π΅Ρ€Π΅. ИмСнно здСсь вступаСт Π² ΠΈΠ³Ρ€Ρƒ динамичСскоС ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ сохранСния значСния

p
(строки 83-84); ΠΌΡ‹ обсуТдали это Ρ€Π°Π½Π΅Π΅ Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Ρ… ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ для динамичСской памяти. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ end Ρ‚Π°ΠΊΠΆΠ΅ устанавливаСтся ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ. Π‘Ρ‚Ρ€ΠΎΠΊΠ° 89 измСняСт Ρ€Π°Π·ΠΌΠ΅Ρ€ памяти.

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ здСсь вызываСтся функция

xrealloc()
. МногиС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ GNU ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ вмСсто
malloc()
ΠΈ
realloc()
Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ автоматичСски выводят сообщСниС ΠΎΠ± ошибкС ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, ΠΊΠΎΠ³Π΄Π° стандартныС ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚
NULL
. Вакая функция-ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

extern 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)
', ΠΏΡ€ΠΎΡ‚ΠΈΠ² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΡ‹ прСдостСрСгали Ρ€Π°Π½Π΅Π΅.