Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
Правда в том, что обе версии труднее воспринимать, чем оригинал, и поэтому, возможно, содержат ошибки. Однако, поскольку текущий код работает, мы решили оставить как есть.
Наконец, мы обращаем внимание, что не все программисты-эксперты согласились бы здесь с нашим советом. Когда каждый компонент условия является вызовом функции, можно установить на каждую контрольную точку, использовать
step
finish
cont
step
15.4.1.4. Используйте вспомогательные функции отладки
Типичной методикой, применимой во многих случаях, является использование набора значений флагов; когда флаг установлен (т.е. равен true), имеет место определенный факт или применяется определенное условие. Обычно это осуществляется при помощи именованных констант
#define
statvfs()
fstatvfs()
Например, главная структура данных
gawk
NODE
awk.h
typedef struct exp_node {
/* ... Куча материала опущена */
unsigned short flags;
#define MALLOC 1 /* может быть освобожден */
#define TEMP 2 /* должен быть освобожден */
#define PERM 4 /* не может быть освобожден */
#define STRING 8 /* назначен в виде строки */
#define STRCUR 16 /* текущее значение строковое */
#define NUMCUR 32 /* текущее значение числовое */
#define NUMBER 64 /* назначен в виде числа */
#define MAYBE_NUM 128 /* ввод пользователя: если NUMERIC, тогда
* NUMBER */
#define ARRAYMAXED 256 /* размер массива максимальный */
#define FUNC 512 /* параметр представляет имя функции;
* см. awkgram.y */
#define FIELD 1024 /* это является полем */
#define INTLSTR 2048 /* использовать локализованную версию */
} NODE;
Причина для использования значений флагов заключается в том, что они значительно экономят пространство данных. Если бы структура
NODE
char
unsigned short
NODE
gawk
NODE
Что это должно делать с отладкой? Разве мы не рекомендовали только что использовать для именованных констант
enum
enum
Рекомендация: предусмотрите функцию для преобразования флагов в строки. Если у вас есть несколько независимых флагов, установите процедуру общего назначения.
ЗАМЕЧАНИЕ. Необычность этих функций отладки заключается в том, что код приложения никогда их не вызывает. Они существуют лишь для того, чтобы их можно было вызывать из отладчика. Такие функции всегда должны быть откомпилированы с кодом, даже без окружающих
#ifdef
Сначала мы покажем вам, как мы это делали первоначально. Вот (сокращенная версия)
flags2str()
gawk
1 /* flags2str --- делает значения флагов удобочитаемыми */
2
3 char *
4 flags2str(flagval)
5 int flagval;
6 {
7 static char buffer[BUFSIZ];
8 char *sp;
9
10 sp = buffer;
11
12 if (flagval & MALLOC) {
13 strcpy(sp, "MALLOC");
14 sp += strlen(sp);
15 }
16 if (flagval & TEMP) {
17 if (sp >= buffer)
18 *sp++ = '|';
19 strcpy(sp, "TEMP");
20 sp += strlen(sp);
21 }
22 if (flagval & PERM) {
23 if (sp != buffer)
24 *sp++ = '|';
25 strcpy(sp, "PERM");
26 sp += strlen(sp);
27 }
/* ...многое то же самое, опущено для краткости... */
82
83 return buffer;
84 }
(Номера строк даны относительно начала функции.) Результатом является строка, что- то наподобие "
MALLOC | PERM | NUMBER
|