Generated from the b-test.def file:
/* -*- buffer-read-only: t -*- vi: set ro:
*
* DO NOT EDIT THIS FILE (b-test.c)
*
* It has been AutoGen-ed Saturday May 24, 2008 at 11:49:29 AM PDT
* From the definitions /home/bkorb/ag/addon/bits/b-test.def
* and the template file bits.tpl
*/
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "b-test.h"
static char const nm[136] =
"* INVALID *\0" "alpha\0" "beta\0" "gamma\0"
"delta\0" "epsilon\0" "zeta\0" "eta\0"
"theta\0" "iota\0" "kappa\0" "lambda\0"
"mu\0" "nu\0" "xi\0" "omicron\0"
"pi\0" "rho\0" "sigma\0" "tau\0"
"upsilon\0" "phi\0" "chi\0" "psi\0"
"omega\0";
char *
status_names( status_bits_t bits )
{
static int const nm_ixa[ 39 ] = {
12, 18, 23, 29, 35, 43, 48, 52, 58, 63, 69, 76, 79, 82,
85, 93, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 100, 106, 110, 118, 122, 126, 130 };
static char buf[ 160 ];
char * buf_p = buf;
int ix = 0;
while (bits != 0) {
if ((bits & 1) != 0) {
char const * p = nm + nm_ixa[ix];
if (buf_p > buf) {
*(buf_p++) = ',';
*(buf_p++) = ' ';
}
if (p == nm) {
Oops:
strncpy(buf_p, nm, sizeof (buf) - (buf_p - buf));
break;
}
while ((*(buf_p++) = *(p++)) != '\0') ;
buf_p--;
}
bits >>= 1;
if (++ix > 38) {
if (bits != 0)
goto Oops;
break;
}
}
return buf;
}
static int
str_to_id( char const * str, char const ** p_str )
{
static char nm_buf[ 8 ];
int res = -1;
int part = 1;
size_t len = 0;
/*
* Extract the lower cased name with '-' replaced with '_'
*/
{
char * p = nm_buf;
for (;;) {
char ch = *(str++);
switch (ch) {
case '-':
ch = '_';
/* FALLTHROUGH */
case '_':
break;
default:
if (isupper(ch))
ch = tolower(ch);
else if (! isalnum(ch)) {
str--;
goto have_name;
}
}
if (++len > 7)
return -1;
*(p++) = ch;
} have_name :;
*p = '\0';
len = p - nm_buf;
if (len == 0)
return INV_STATUS;
}
/*
* Search the alphabetized table
*/
do {
static struct {
unsigned short const nm_off, val;
} nm_ixa[ 24 ] = {
{ 12, 0 }, { 18, 1 }, { 122, 36 }, { 29, 3 }, { 35, 4 },
{ 48, 6 }, { 23, 2 }, { 58, 8 }, { 63, 9 }, { 69, 10 },
{ 76, 11 }, { 79, 12 }, { 130, 38 }, { 85, 14 }, { 118, 35 },
{ 93, 15 }, { 126, 37 }, { 96, 16 }, { 100, 32 }, { 106, 33 },
{ 52, 7 }, { 110, 34 }, { 82, 13 }, { 43, 5 } };
int av;
int lo = 0;
int hi = 23;
/*
* Binary search for first match
*/
do {
char const * p;
int df;
av = (lo + hi) / 2;
p = nm + nm_ixa[av].nm_off;
df = strncmp(p, nm_buf, len);
if (df == 0) {
res = nm_ixa[av].val;
if (p[len] == '\0')
part = 0;
break;
}
if (df > 0)
hi = av - 1;
else lo = av + 1;
} while (lo <= hi);
if (res < 0)
return INV_STATUS;
if (part == 0)
break;
/*
* Partial match. Look for preceeding matches. One may be full match.
*/
lo = av;
while (lo > 0) {
char const * p = nm + nm_ixa[--lo].nm_off;
int df = strncmp(p, nm_buf, len);
if (df != 0)
break;
if (p[len] == '\0') {
part = 0;
res = nm_ixa[lo].val;
break;
}
part++;
}
if (part > 1) {
*p_str = nm_buf;
return DUP_STATUS;
}
if ((part == 0) || (av == 23))
break;
/*
* Look for a successor match. No full match possible.
*/
{
char const * p = nm + nm_ixa[av+1].nm_off;
int df = strncmp(p, nm_buf, len);
if (df == 0) {
*p_str = nm_buf;
return DUP_STATUS;
}
}
} while (0);
while (isspace(*str)) str++;
*p_str = str;
return res;
}
int
status_bits(
status_bits_t * const bits,
char const * str)
{
int ct = 0;
int res = 0;
memset(bits, '\0', sizeof(status_bits_t));
another_bit:
while (isspace(*str) || (*str == ',')) str++;
for (;;) {
if (isdigit(*str)) {
uint64_t num =
(uint64_t)strtoull(str, &str, 0);
*bits |= num;
ct += (num != 0);
} else if (isalpha(*str)) {
res = str_to_id(str, &str);
if (res < 0) {
if (res == DUP_STATUS)
fprintf(stderr, "duplicate matches for '%s'\n", str);
goto fail_exit;
}
ct++;
*bits |= 1ULL << res;
} else switch (*str) {
case ',':
goto another_bit;
case '\0':
return ct;
default:
res = INV_STATUS;
goto fail_exit;
}
}
fail_exit:
memset(bits, '\0', sizeof(*bits));
return res;
}
#ifdef TEST_BITS
static char const bit_names[] =
"The known status bit names are:\n\
alpha beta chi delta epsilon eta gamma iota kappa\n\
lambda mu nu omega omicron phi pi psi rho\n\
sigma tau theta upsilon xi zeta\n";
int
main( int argc, char** argv )
{
static char const fmt_z[] = "'%s' yields: %s\n";
status_bits_t bts;
if (argc != 2) {
fputs(bit_names, stderr);
return 1;
}
{
int ct = status_bits(&bts, argv[1]);
if (ct <= 0) {
char const * pz;
switch (ct) {
case 0: pz = "no results"; break;
case INV_STATUS: pz = "invalid name"; break;
case DUP_STATUS: pz = "multiple match"; break;
}
fprintf(stderr, fmt_z, argv[1], pz);
fputs(bit_names, stderr);
return 1;
}
}
{
char * pz = status_names( bts );
printf(fmt_z, argv[1], pz);
}
return 0;
}
#endif
/* end of b-test.c */