开发者

How to format flags in c?

Assume that there are flag definitions such as:

SHF_WRITE     0x1
SHF_ALLOC     0x2
SHF_EXECINSTR 0x4
SHF_MASKPROC 开发者_开发百科 0xf0000000

Given a flag, I need to output SHF_WRITE|SHF_ALLOC if the bits 0x1 and 0x2 is on.

How to do the trick in C?


#define V(n) { n, #n }

struct Code {
  int  value;
  char *name;
} decode[] = {
  V(SHF_WRITE),
  V(SHF_ALLOC),
  { 0, NULL },
};

void f(const int x) {
  struct Code *c = decode;
  int beenthere = 0;

  for(; c->name; ++c)
    if(x & c->value)
      printf("%s%s", beenthere++ ? "|" : "", c->name);
  if(beenthere)
    printf("\n");
}


Just create a character buffer with enough space to hold all possible combinations of strings and add to it the appropriate strings for each applicable bit set. (or you could ditch the buffer and write straight to stdout, your choice) Here's a naive implementation of how you could do such a thing:

void print_flags(int flag)
{
#define BUFLEN (9+9+13+12+3+1)
                  /* for the text, pipes and null terminator*/
#define PAIRLEN 4
static struct { int value; const char *string; } pair[] =
{
    { SHF_WRITE,     "SHF_WRITE" },
    { SHF_ALLOC,     "SHF_ALLOC" },
    { SHF_EXECINSTR, "SHF_EXECINSTR" },
    { SHF_MASKPROC,  "SHF_MASKPROC" },
};

    char buf[BUFLEN];  /* declare the buffer */
    char *write = buf;    /* and a "write" pointer */
    int i;
    for (i = 0; i < PAIRLEN; i++)
    {
        if ((flag & pair[i].value) == pair[i].value) /* if flag is set... */
        {
            size_t written = write - buf;
            write += _snprintf(write, BUFLEN-written, "%s%s",
                written > 0 ? "|" : "",
                pair[i].string); /* write to the buffer */
        }
    }
    if (write != buf) /* if any of the flags were set... */
    {
        *write = '\0'; /* null terminate (just in case) */
        printf("(%s)", buf); /* print out the buffer */
    }
#undef PAIRLEN
#undef BUFLEN
}


PROBLEM:

"SHF_WRITE|SHF_ALLOC" says "bit 0x1 OR bit 0x2", not "bits 0x1 AND 02x".

Nevertheless, if you wanted to print "SOME MSG" if the bits 0x1 and 0x2 were both "on" in some value "flag", here's how:

  if (flag & SHF_WRITE & SHF_ALLOC)
    printf ("SOME MSG, flag= 0x%x\n", flag);

If you wanted to print the text represtation of ANY bits that were "on" in the value, you might do something like this:

  char buf[80] = '\0';
  if (flag & SHF_WRITE)
    strcpy (buf, " SHF_WRITE");
  if (flag & SHF_ALLOC)
    strcpy (buf, " SHF_ALLOC");
  ...
  printf ("SOME MSG, flag= %s\n", buf);

And finally, if you DON'T want to print if NO bit is set, just do this:

  if (flag)
  {
    ... do printing ...
  }
  else
  {
    ... do nothing? ...
  }

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜