【问题标题】:scsi err codes and translation to stringsscsi 错误代码和字符串转换
【发布时间】:2014-03-13 13:32:46
【问题描述】:

我想知道将错误代码映射到字符串的最佳方法是什么,例如在 SCSI 协议中,错误总是以数字形式返回。像这样:

00h GOOD
02h CHECK CONDITION
04h CONDITION MET
08h BUSY
18h RESERVATION CONFLICT
28h TASK SET FULL
30h ACA ACTIVE
40h TASK ABORTED

我想知道将这些代码即时翻译成字符串对应的最佳方法是什么?我想过做一个数组或其他东西,但 Ig 必须制作一个长度为 40h 的数组,即使我不会使用大多数索引。那么创建一个以数字作为输入并返回字符串的函数的最佳方法是什么?

【问题讨论】:

  • 很难说这是否是“最好”的方式,但在我看来这是一种不错的方式。
  • 我怀疑这些不是实际的错误代码,而是位字段定义(或在几种情况下的位组合) - 您有时可能会得到一个与这些数字中的任何一个都不完全匹配的状态代码,因为这是它们的组合......
  • 我不这么认为。似乎其他错误代码要么是保留的,要么是特定于供应商的。没有提及您在 scsi 协议中的想法。至少我没见过。

标签: c linux char int


【解决方案1】:

这有点棘手,但您可以尝试使用X-macro

#include <stdio.h>

#define SCSI_ERR_TABLE                          \
    X(GOOD,            "good",            0x00) \
    X(CHECK_CONDITION, "check condition", 0x02) \
    X(CONDITION_MET,   "condition met",   0x04) \
    X(BUSY,            "busy",            0x08) \

#define X(ERR, STR, ID) ERR = ID,
enum {
    SCSI_ERR_TABLE
};
#undef X


#define X(ERR, STR, ID) {.id = ID, .string = STR},
static const struct {
    int id;
    char string[32];
} scsi_err_strings[] = { SCSI_ERR_TABLE };
#undef X

const char *scsi_get_err_string(int error)
{
    for (int i = 0; i < sizeof(scsi_err_strings) / sizeof(scsi_err_strings[0]); i++) {
        if (scsi_err_strings[i].id == error)
            return scsi_err_strings[i].string;
    }

    return NULL;
}

int main(void)
{
    int err;

    err = CHECK_CONDITION;
    printf("%d -> %s\n", err, scsi_get_err_string(err));

    err = BUSY;
    printf("%d -> %s\n", err, scsi_get_err_string(err));

    return 0;
}

【讨论】:

    【解决方案2】:

    下面是一个示例,说明如何将一些代码定义为宏,然后使用另一个宏函数来获取宏的字符串值:

    #include <stdio.h>
    
    #define GOOD 0
    #define CHECK_CONDITON 2
    #define CONDITION_MET 4
    
    /* more codes here */
    
    #define STR_VALUE(CODE) #CODE
    
    void print_scsi(int code) {
      char *scsi_string;
    
      switch (code) {
        case GOOD: 
          scsi_string = STR_VALUE(GOOD); break;
        case CHECK_CONDITON: 
          scsi_string = STR_VALUE(CHECK_CONDITON); break;
        case CONDITION_MET: 
          scsi_string = STR_VALUE(CONDITION_MET); break;
    
        /* ... */
      }
      printf("code: %d string: %s\n", code, scsi_string);
    }
    
    int main(void) {
      print_scsi(0);
      print_scsi(2);
      print_scsi(4);
    }
    

    运行此命令:

    code: 0 string: GOOD
    code: 2 string: CHECK_CONDITON
    code: 4 string: CONDITION_MET
    

    如果代码列表很长,请在单独的头文件中定义宏,以及 STR_VALUE 并将其包含在您的主程序中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多