show constraint
diff --git a/libasn1print/asn1print.c b/libasn1print/asn1print.c
index 486f025..d4e24bc 100644
--- a/libasn1print/asn1print.c
+++ b/libasn1print/asn1print.c
@@ -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 @@
}
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 @@
}
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
"", "(" };
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 @@
}
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 @@
}
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 @@
}
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;
diff --git a/libasn1print/asn1print.h b/libasn1print/asn1print.h
index 02ac4be..1666b99 100644
--- a/libasn1print/asn1print.h
+++ b/libasn1print/asn1print.h
@@ -15,5 +15,6 @@
*/
int asn1print(asn1p_t *asn, enum asn1print_flags flags);
+const char *asn1p_constraint_string(const asn1p_constraint_t *ct);
#endif /* ASN1PRINT_H */