mirror of https://gerrit.osmocom.org/asn1c
show constraint
This commit is contained in:
parent
e3204e7d23
commit
f4b711a2a9
|
@ -4,6 +4,7 @@
|
|||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <asn1_buffer.h>
|
||||
#include <asn1_namespace.h>
|
||||
#include <asn1parser.h>
|
||||
#include <asn1fix_export.h>
|
||||
|
@ -11,6 +12,14 @@
|
|||
|
||||
#include "asn1print.h"
|
||||
|
||||
static abuf all_output_;
|
||||
|
||||
typedef enum {
|
||||
PRINT_STDOUT,
|
||||
GLOBAL_BUFFER,
|
||||
} print_method_e;
|
||||
static print_method_e print_method_;
|
||||
|
||||
#define INDENT(fmt, args...) do { \
|
||||
if(!(flags & APF_NOINDENT)) { \
|
||||
int tmp_i = level; \
|
||||
|
@ -21,29 +30,50 @@
|
|||
|
||||
static int asn1print_module(asn1p_t *asn, asn1p_module_t *mod, enum asn1print_flags flags);
|
||||
static int asn1print_oid(int prior_len, asn1p_oid_t *oid, enum asn1print_flags flags);
|
||||
static int asn1print_ref(asn1p_ref_t *ref, enum asn1print_flags flags);
|
||||
static int asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags);
|
||||
static int asn1print_params(asn1p_paramlist_t *pl,enum asn1print_flags flags);
|
||||
static int asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags);
|
||||
static int asn1print_constraint(asn1p_constraint_t *, enum asn1print_flags);
|
||||
static int asn1print_value(asn1p_value_t *val, enum asn1print_flags flags);
|
||||
static int asn1print_ref(const asn1p_ref_t *ref, enum asn1print_flags flags);
|
||||
static int asn1print_tag(const asn1p_expr_t *tc, enum asn1print_flags flags);
|
||||
static int asn1print_params(const asn1p_paramlist_t *pl,enum asn1print_flags flags);
|
||||
static int asn1print_with_syntax(const asn1p_wsyntx_t *wx, enum asn1print_flags flags);
|
||||
static int asn1print_constraint(const asn1p_constraint_t *, enum asn1print_flags);
|
||||
static int asn1print_value(const asn1p_value_t *val, enum asn1print_flags flags);
|
||||
static int asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1print_flags flags, int level);
|
||||
static int asn1print_expr_dtd(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1print_flags flags, int level);
|
||||
|
||||
/* Check printf's error code, to be pedantic. */
|
||||
static int safe_printf(const char *fmt, ...) {
|
||||
int ret;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int ret = vprintf(fmt, ap);
|
||||
|
||||
switch(print_method_) {
|
||||
case PRINT_STDOUT:
|
||||
ret = vprintf(fmt, ap);
|
||||
break;
|
||||
case GLOBAL_BUFFER:
|
||||
ret = abuf_vprintf(&all_output_, fmt, ap);
|
||||
break;
|
||||
}
|
||||
assert(ret >= 0);
|
||||
va_end(ap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Pedantically check fwrite's return value. */
|
||||
static size_t safe_fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream) {
|
||||
size_t ret = fwrite(ptr, 1, size * nitems, stream);
|
||||
assert(ret == size * nitems);
|
||||
static size_t safe_fwrite(const void *ptr, size_t size) {
|
||||
size_t ret;
|
||||
|
||||
switch(print_method_) {
|
||||
case PRINT_STDOUT:
|
||||
ret = fwrite(ptr, 1, size, stdout);
|
||||
assert(ret == size);
|
||||
break;
|
||||
case GLOBAL_BUFFER:
|
||||
abuf_add_bytes(&all_output_, ptr, size);
|
||||
ret = size;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -170,7 +200,7 @@ asn1print_oid(int prior_len, asn1p_oid_t *oid, enum asn1print_flags flags) {
|
|||
}
|
||||
|
||||
static int
|
||||
asn1print_ref(asn1p_ref_t *ref, enum asn1print_flags flags) {
|
||||
asn1print_ref(const asn1p_ref_t *ref, enum asn1print_flags flags) {
|
||||
|
||||
(void)flags; /* Unused argument */
|
||||
|
||||
|
@ -183,8 +213,8 @@ asn1print_ref(asn1p_ref_t *ref, enum asn1print_flags flags) {
|
|||
}
|
||||
|
||||
static int
|
||||
asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags) {
|
||||
struct asn1p_type_tag_s *tag = &tc->tag;
|
||||
asn1print_tag(const asn1p_expr_t *tc, enum asn1print_flags flags) {
|
||||
const struct asn1p_type_tag_s *tag = &tc->tag;
|
||||
|
||||
(void)flags; /* Unused argument */
|
||||
|
||||
|
@ -194,7 +224,7 @@ asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags) {
|
|||
}
|
||||
|
||||
static int
|
||||
asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) {
|
||||
asn1print_value(const asn1p_value_t *val, enum asn1print_flags flags) {
|
||||
|
||||
if(val == NULL)
|
||||
return 0;
|
||||
|
@ -236,22 +266,22 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) {
|
|||
case ATV_STRING:
|
||||
{
|
||||
char *p = (char *)val->value.string.buf;
|
||||
putchar('"');
|
||||
safe_printf("\"");
|
||||
if(strchr(p, '"')) {
|
||||
/* Mask quotes */
|
||||
for(; *p; p++) {
|
||||
if(*p == '"')
|
||||
putchar(*p);
|
||||
putchar(*p);
|
||||
safe_printf("%c", *p);
|
||||
safe_printf("%c", *p);
|
||||
}
|
||||
} else {
|
||||
fputs(p, stdout);
|
||||
safe_printf("%s", p);
|
||||
}
|
||||
putchar('"');
|
||||
safe_printf("\"");
|
||||
}
|
||||
return 0;
|
||||
case ATV_UNPARSED:
|
||||
fputs((char *)val->value.string.buf, stdout);
|
||||
safe_printf("%s", (char *)val->value.string.buf);
|
||||
return 0;
|
||||
case ATV_BITVECTOR:
|
||||
{
|
||||
|
@ -267,14 +297,14 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) {
|
|||
for(i = 0; i < bits; i++) {
|
||||
uint8_t uc;
|
||||
uc = bitvector[i>>3];
|
||||
putchar(((uc >> (7-(i%8)))&1)?'1':'0');
|
||||
safe_printf("%c", ((uc >> (7-(i%8)))&1)?'1':'0');
|
||||
}
|
||||
safe_printf("'B");
|
||||
} else {
|
||||
char hextable[16] = "0123456789ABCDEF";
|
||||
for(i = 0; i < (bits>>3); i++) {
|
||||
putchar(hextable[bitvector[i] >> 4]);
|
||||
putchar(hextable[bitvector[i] & 0x0f]);
|
||||
safe_printf("%c", hextable[bitvector[i] >> 4]);
|
||||
safe_printf("%c", hextable[bitvector[i] & 0x0f]);
|
||||
}
|
||||
safe_printf("'H");
|
||||
}
|
||||
|
@ -294,8 +324,18 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
asn1p_constraint_string(const asn1p_constraint_t *ct) {
|
||||
size_t old_len = all_output_.length;
|
||||
print_method_e old_method = print_method_;
|
||||
print_method_ = GLOBAL_BUFFER;
|
||||
asn1print_constraint(ct, APF_NOINDENT);
|
||||
print_method_ = old_method;
|
||||
return &all_output_.buffer[old_len];
|
||||
}
|
||||
|
||||
static int
|
||||
asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
|
||||
asn1print_constraint(const asn1p_constraint_t *ct, enum asn1print_flags flags) {
|
||||
int symno = 0;
|
||||
|
||||
if(ct == 0) return 0;
|
||||
|
@ -353,8 +393,7 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
|
|||
asn1p_constraint_t *cel = ct->elements[i];
|
||||
if(i) safe_printf(", ");
|
||||
safe_fwrite(cel->value->value.string.buf,
|
||||
1, cel->value->value.string.size,
|
||||
stdout);
|
||||
cel->value->value.string.size);
|
||||
if(cel->el_count) {
|
||||
assert(cel->el_count == 1);
|
||||
safe_printf(" ");
|
||||
|
@ -374,8 +413,7 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
|
|||
case ACT_CT_CTDBY:
|
||||
safe_printf("CONSTRAINED BY ");
|
||||
assert(ct->value->type == ATV_UNPARSED);
|
||||
safe_fwrite(ct->value->value.string.buf,
|
||||
1, ct->value->value.string.size, stdout);
|
||||
safe_fwrite(ct->value->value.string.buf, ct->value->value.string.size);
|
||||
break;
|
||||
case ACT_CT_CTNG:
|
||||
safe_printf("CONTAINING ");
|
||||
|
@ -399,13 +437,13 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
|
|||
"", "(" };
|
||||
unsigned int i;
|
||||
for(i = 0; i < ct->el_count; i++) {
|
||||
if(i) fputs(symtable[symno], stdout);
|
||||
if(ct->type == ACT_CA_CRC) fputs("{", stdout);
|
||||
if(i) safe_printf("%s", symtable[symno]);
|
||||
if(ct->type == ACT_CA_CRC) safe_printf("{");
|
||||
asn1print_constraint(ct->elements[i], flags);
|
||||
if(ct->type == ACT_CA_CRC) fputs("}", stdout);
|
||||
if(ct->type == ACT_CA_CRC) safe_printf("}");
|
||||
if(i+1 < ct->el_count
|
||||
&& ct->type == ACT_CA_SET)
|
||||
fputs(")", stdout);
|
||||
safe_printf(")");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -426,7 +464,7 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
|
|||
}
|
||||
|
||||
static int
|
||||
asn1print_params(asn1p_paramlist_t *pl, enum asn1print_flags flags) {
|
||||
asn1print_params(const asn1p_paramlist_t *pl, enum asn1print_flags flags) {
|
||||
if(pl) {
|
||||
int i;
|
||||
safe_printf("{");
|
||||
|
@ -445,9 +483,9 @@ asn1print_params(asn1p_paramlist_t *pl, enum asn1print_flags flags) {
|
|||
}
|
||||
|
||||
static int
|
||||
asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags) {
|
||||
asn1print_with_syntax(const asn1p_wsyntx_t *wx, enum asn1print_flags flags) {
|
||||
if(wx) {
|
||||
asn1p_wsyntx_chunk_t *wc;
|
||||
const asn1p_wsyntx_chunk_t *wc;
|
||||
TQ_FOR(wc, &(wx->chunks), next) {
|
||||
switch(wc->type) {
|
||||
case WC_LITERAL:
|
||||
|
@ -468,7 +506,7 @@ asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags) {
|
|||
}
|
||||
|
||||
static int
|
||||
asn1print_crange_value(asn1cnst_edge_t *edge, int as_char) {
|
||||
asn1print_crange_value(const asn1cnst_edge_t *edge, int as_char) {
|
||||
switch(edge->type) {
|
||||
case ARE_MIN: safe_printf("MIN"); break;
|
||||
case ARE_MAX: safe_printf("MAX"); break;
|
||||
|
|
|
@ -15,5 +15,6 @@ enum asn1print_flags {
|
|||
*/
|
||||
int asn1print(asn1p_t *asn, enum asn1print_flags flags);
|
||||
|
||||
const char *asn1p_constraint_string(const asn1p_constraint_t *ct);
|
||||
|
||||
#endif /* ASN1PRINT_H */
|
||||
|
|
Loading…
Reference in New Issue