Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
Правда в том, что обе версии труднее воспринимать, чем оригинал, и поэтому, возможно, содержат ошибки. Однако, поскольку текущий код работает, мы решили оставить как есть.
Наконец, мы обращаем внимание, что не все программисты-эксперты согласились бы здесь с нашим советом. Когда каждый компонент условия является вызовом функции, можно установить на каждую контрольную точку, использовать
stepfinishcontstep15.4.1.4. Используйте вспомогательные функции отладки
Типичной методикой, применимой во многих случаях, является использование набора значений флагов; когда флаг установлен (т.е. равен true), имеет место определенный факт или применяется определенное условие. Обычно это осуществляется при помощи именованных констант
#definestatvfs()fstatvfs()Например, главная структура данных
gawkNODEawk.htypedef 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;Причина для использования значений флагов заключается в том, что они значительно экономят пространство данных. Если бы структура
NODEcharunsigned shortNODEgawkNODEЧто это должно делать с отладкой? Разве мы не рекомендовали только что использовать для именованных констант
enumenumРекомендация: предусмотрите функцию для преобразования флагов в строки. Если у вас есть несколько независимых флагов, установите процедуру общего назначения.
ЗАМЕЧАНИЕ. Необычность этих функций отладки заключается в том, что код приложения никогда их не вызывает. Они существуют лишь для того, чтобы их можно было вызывать из отладчика. Такие функции всегда должны быть откомпилированы с кодом, даже без окружающих
#ifdefСначала мы покажем вам, как мы это делали первоначально. Вот (сокращенная версия)
flags2str()gawk1 /* flags2str --- делает значения флагов удобочитаемыми */23 char *4 flags2str(flagval)5 int flagval;6 {7 static char buffer[BUFSIZ];8 char *sp;910 sp = buffer;1112 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 } /* ...многое то же самое, опущено для краткости... */8283 return buffer;84 }(Номера строк даны относительно начала функции.) Результатом является строка, что- то наподобие "
MALLOC | PERM | NUMBER|