Commit f4b711a2 authored by Lev Walkin's avatar Lev Walkin

show constraint

parent e3204e7d
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <asn1_buffer.h>
#include <asn1_namespace.h> #include <asn1_namespace.h>
#include <asn1parser.h> #include <asn1parser.h>
#include <asn1fix_export.h> #include <asn1fix_export.h>
...@@ -11,6 +12,14 @@ ...@@ -11,6 +12,14 @@
#include "asn1print.h" #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 { \ #define INDENT(fmt, args...) do { \
if(!(flags & APF_NOINDENT)) { \ if(!(flags & APF_NOINDENT)) { \
int tmp_i = level; \ int tmp_i = level; \
...@@ -21,29 +30,50 @@ ...@@ -21,29 +30,50 @@
static int asn1print_module(asn1p_t *asn, asn1p_module_t *mod, enum asn1print_flags flags); 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_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_ref(const asn1p_ref_t *ref, enum asn1print_flags flags);
static int asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags); static int asn1print_tag(const asn1p_expr_t *tc, enum asn1print_flags flags);
static int asn1print_params(asn1p_paramlist_t *pl,enum asn1print_flags flags); static int asn1print_params(const asn1p_paramlist_t *pl,enum asn1print_flags flags);
static int asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags); static int asn1print_with_syntax(const asn1p_wsyntx_t *wx, enum asn1print_flags flags);
static int asn1print_constraint(asn1p_constraint_t *, enum asn1print_flags); static int asn1print_constraint(const asn1p_constraint_t *, enum asn1print_flags);
static int asn1print_value(asn1p_value_t *val, enum asn1print_flags 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(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); 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. */ /* Check printf's error code, to be pedantic. */
static int safe_printf(const char *fmt, ...) { static int safe_printf(const char *fmt, ...) {
int ret;
va_list ap; va_list ap;
va_start(ap, fmt); 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); assert(ret >= 0);
va_end(ap); va_end(ap);
return ret; return ret;
} }
/* Pedantically check fwrite's return value. */ /* Pedantically check fwrite's return value. */
static size_t safe_fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream) { static size_t safe_fwrite(const void *ptr, size_t size) {
size_t ret = fwrite(ptr, 1, size * nitems, stream); size_t ret;
assert(ret == size * nitems);
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; return ret;
} }
...@@ -170,7 +200,7 @@ asn1print_oid(int prior_len, asn1p_oid_t *oid, enum asn1print_flags flags) { ...@@ -170,7 +200,7 @@ asn1print_oid(int prior_len, asn1p_oid_t *oid, enum asn1print_flags flags) {
} }
static int 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 */ (void)flags; /* Unused argument */
...@@ -183,8 +213,8 @@ asn1print_ref(asn1p_ref_t *ref, enum asn1print_flags flags) { ...@@ -183,8 +213,8 @@ asn1print_ref(asn1p_ref_t *ref, enum asn1print_flags flags) {
} }
static int static int
asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags) { asn1print_tag(const asn1p_expr_t *tc, enum asn1print_flags flags) {
struct asn1p_type_tag_s *tag = &tc->tag; const struct asn1p_type_tag_s *tag = &tc->tag;
(void)flags; /* Unused argument */ (void)flags; /* Unused argument */
...@@ -194,7 +224,7 @@ asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags) { ...@@ -194,7 +224,7 @@ asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags) {
} }
static int 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) if(val == NULL)
return 0; return 0;
...@@ -236,22 +266,22 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) { ...@@ -236,22 +266,22 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) {
case ATV_STRING: case ATV_STRING:
{ {
char *p = (char *)val->value.string.buf; char *p = (char *)val->value.string.buf;
putchar('"'); safe_printf("\"");
if(strchr(p, '"')) { if(strchr(p, '"')) {
/* Mask quotes */ /* Mask quotes */
for(; *p; p++) { for(; *p; p++) {
if(*p == '"') if(*p == '"')
putchar(*p); safe_printf("%c", *p);
putchar(*p); safe_printf("%c", *p);
} }
} else { } else {
fputs(p, stdout); safe_printf("%s", p);
} }
putchar('"'); safe_printf("\"");
} }
return 0; return 0;
case ATV_UNPARSED: case ATV_UNPARSED:
fputs((char *)val->value.string.buf, stdout); safe_printf("%s", (char *)val->value.string.buf);
return 0; return 0;
case ATV_BITVECTOR: case ATV_BITVECTOR:
{ {
...@@ -267,14 +297,14 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) { ...@@ -267,14 +297,14 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) {
for(i = 0; i < bits; i++) { for(i = 0; i < bits; i++) {
uint8_t uc; uint8_t uc;
uc = bitvector[i>>3]; 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"); safe_printf("'B");
} else { } else {
char hextable[16] = "0123456789ABCDEF"; char hextable[16] = "0123456789ABCDEF";
for(i = 0; i < (bits>>3); i++) { for(i = 0; i < (bits>>3); i++) {
putchar(hextable[bitvector[i] >> 4]); safe_printf("%c", hextable[bitvector[i] >> 4]);
putchar(hextable[bitvector[i] & 0x0f]); safe_printf("%c", hextable[bitvector[i] & 0x0f]);
} }
safe_printf("'H"); safe_printf("'H");
} }
...@@ -294,8 +324,18 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) { ...@@ -294,8 +324,18 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) {
return 0; 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 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; int symno = 0;
if(ct == 0) return 0; if(ct == 0) return 0;
...@@ -353,8 +393,7 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) { ...@@ -353,8 +393,7 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
asn1p_constraint_t *cel = ct->elements[i]; asn1p_constraint_t *cel = ct->elements[i];
if(i) safe_printf(", "); if(i) safe_printf(", ");
safe_fwrite(cel->value->value.string.buf, safe_fwrite(cel->value->value.string.buf,
1, cel->value->value.string.size, cel->value->value.string.size);
stdout);
if(cel->el_count) { if(cel->el_count) {
assert(cel->el_count == 1); assert(cel->el_count == 1);
safe_printf(" "); safe_printf(" ");
...@@ -374,8 +413,7 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) { ...@@ -374,8 +413,7 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
case ACT_CT_CTDBY: case ACT_CT_CTDBY:
safe_printf("CONSTRAINED BY "); safe_printf("CONSTRAINED BY ");
assert(ct->value->type == ATV_UNPARSED); assert(ct->value->type == ATV_UNPARSED);
safe_fwrite(ct->value->value.string.buf, safe_fwrite(ct->value->value.string.buf, ct->value->value.string.size);
1, ct->value->value.string.size, stdout);
break; break;
case ACT_CT_CTNG: case ACT_CT_CTNG:
safe_printf("CONTAINING "); safe_printf("CONTAINING ");
...@@ -399,13 +437,13 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) { ...@@ -399,13 +437,13 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
"", "(" }; "", "(" };
unsigned int i; unsigned int i;
for(i = 0; i < ct->el_count; i++) { for(i = 0; i < ct->el_count; i++) {
if(i) fputs(symtable[symno], stdout); if(i) safe_printf("%s", symtable[symno]);
if(ct->type == ACT_CA_CRC) fputs("{", stdout); if(ct->type == ACT_CA_CRC) safe_printf("{");
asn1print_constraint(ct->elements[i], flags); 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 if(i+1 < ct->el_count
&& ct->type == ACT_CA_SET) && ct->type == ACT_CA_SET)
fputs(")", stdout); safe_printf(")");
} }
} }
break; break;
...@@ -426,7 +464,7 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) { ...@@ -426,7 +464,7 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
} }
static int 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) { if(pl) {
int i; int i;
safe_printf("{"); safe_printf("{");
...@@ -445,9 +483,9 @@ asn1print_params(asn1p_paramlist_t *pl, enum asn1print_flags flags) { ...@@ -445,9 +483,9 @@ asn1print_params(asn1p_paramlist_t *pl, enum asn1print_flags flags) {
} }
static int 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) { if(wx) {
asn1p_wsyntx_chunk_t *wc; const asn1p_wsyntx_chunk_t *wc;
TQ_FOR(wc, &(wx->chunks), next) { TQ_FOR(wc, &(wx->chunks), next) {
switch(wc->type) { switch(wc->type) {
case WC_LITERAL: case WC_LITERAL:
...@@ -468,7 +506,7 @@ asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags) { ...@@ -468,7 +506,7 @@ asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags) {
} }
static int 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) { switch(edge->type) {
case ARE_MIN: safe_printf("MIN"); break; case ARE_MIN: safe_printf("MIN"); break;
case ARE_MAX: safe_printf("MAX"); break; case ARE_MAX: safe_printf("MAX"); break;
......
...@@ -15,5 +15,6 @@ enum asn1print_flags { ...@@ -15,5 +15,6 @@ enum asn1print_flags {
*/ */
int asn1print(asn1p_t *asn, enum asn1print_flags flags); int asn1print(asn1p_t *asn, enum asn1print_flags flags);
const char *asn1p_constraint_string(const asn1p_constraint_t *ct);
#endif /* ASN1PRINT_H */ #endif /* ASN1PRINT_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment