Категории
Самые читаемые
PochitayKnigi » Компьютеры и Интернет » Интернет » Linux программирование в примерах - Роббинс Арнольд

Linux программирование в примерах - Роббинс Арнольд

Читать онлайн Linux программирование в примерах - Роббинс Арнольд

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 104 105 106 107 108 109 110 111 112 ... 253
Перейти на страницу:

92  {

93   n_alloc = info->level * 2; /* Удвоить сумму */

94   sum_ent = XREALLOC(sum_ent, uintmax_t, realloc); /* И выделить повторно */

95   sum_subdir = XREALLOC(sum_subdir, uintmax_t, n_alloc);

96  }

97 }

98

99 size_to_print = size;

Строки 78–97 управляют динамической памятью, используемой для хранения статистики о размере файла, first_call является статической переменной (строка 12), которая равна true при первом вызове process_file(). В этом случае вызывается calloc() (через упаковывающий макрос в строках 81–82; это обсуждалось в разделе 3.2.1.8 «Пример чтение строк произвольной длины»). Остальную часть времени first_call равно false, и используется realloc() (снова через упаковывающий макрос, строки 91–96).

Строка 99 заносит значение size в size_to_print; эта переменная может обновляться в зависимости от того, должна ли она включать размеры дочерних элементов. Хотя size могла бы использоваться повторно, отдельная переменная упрощает чтение кода.

101 if (!first_call)

102 {

103  if ((size_t)info->level == prev_level)

104  {

105   /* Обычно самый частый случай. Ничего не делать. */

106  }

107  else if ((size_t)info->level > prev_level)

108  {

109   /* Нисхождение по иерархии.

110      Очистить аккумуляторы для *всех* уровней между prev_level

111      и текущим. Глубина может значительно меняться,

112      например, от 1 до 10. */

113   int i;

114   for (i = prev_level +1; i <= info->level; i++)

115    sum_ent[i] = sum_subdir[i] = 0;

116  }

117  else /* info->level < prev_level */

118  {

119   /* Восхождение по иерархии.

120      nftw обрабатывает каталог лишь после всех элементов,

121      в которых был обработан каталог. Когда глубина уменьшается,

122      передать суммы от детей (prev_level) родителям.

123      Здесь текущий уровень всегда меньше, чем

124      предыдущий. */

125   assert (<size_t) info->level == prev_level - 1);

126   size_to_print += sum_ent[prev_level];

127   if (!opt_separate_dirs)

128    size_to_print += sum_subdir[prev_level];

129   sum_subdir[info->level] += (sum_ent[prev_level]

130    + sum_subdir[prev_level]);

131  }

132 }

Строки 101–132 сравнивают текущий уровень с предыдущим. Возможны три случая.

Уровни те же самые

В этом случае нет необходимости беспокоиться о статистике дочерних элементов. (Строки 103–106.)

Текущий уровень выше предыдущего

В этом случае мы спустились по иерархии, и статистику нужно восстановить (строки 107–116). Термин «аккумулятор» в комментарии подходящий: каждый элемент аккумулирует общее дисковое пространство, использованное на этом уровне. (На заре вычислительной техники регистры центрального процессора часто назывались «аккумуляторами».)

Текущий уровень ниже предыдущего

В этом случае мы завершили обработку всех дочерних элементов каталога и только что вернулись обратно в родительский каталог (строки 117–131). Код обновляет суммы, включая size_to_print.

134 prev_level = info->level; /* Установить статические переменные */

135 first_call = 0;

136

137 /* Включить элемент каталога в общую сумму для содержащего

138    каталога, если не указана --separate-dirs (-S). */

139 if (!(opt_separate_dirs && IS_FTW_DIR_TYPE(file_type)))

140  sum_ent[info->level] += size;

141

142 /* Даже если каталог нельзя прочесть или перейти в него,

143    включить его размер в общую сумму, ... */

144 tot_size += size;

145

146 /* ...но не выводить для него итог, поскольку без размера(-ов)

147    потенциальных элементов, это может сильно запутывать. */

148 if (file_type == FTW_DNR || file_type == FTW_DCH)

149  return 0;

150

151 /* Если мы не считаем элемент, например, потому что это прямая

152    ссылка на файл, который уже посчитан (и --count-links), не

153    выводить для него строку. */

154 if (!print)

155  return 0;

Строки 134–135 устанавливают статические переменные prev_level и first_call таким образом, что они содержат правильные значения для последующего вызова process_file(), гарантируя, что весь предыдущий код работает правильно.

Строки 137–144 выверяют статистику на основе опций и типа файла. Комментарии и код достаточно просты. Строки 146–155 сразу завершают функцию, если сведения не должны выводиться.

157  /* FIXME: Это выглядит подозрительно годным для упрощения. */

158  if ((IS_FTW_DIR_TYPE(file_type) &&

159   (info->level <= max_depth || info->level == 0))

1 ... 104 105 106 107 108 109 110 111 112 ... 253
Перейти на страницу:
Тут вы можете бесплатно читать книгу Linux программирование в примерах - Роббинс Арнольд.
Комментарии