-X for XML DTD
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@500 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1print/asn1print.c b/libasn1print/asn1print.c
index 4132204..a6c3edb 100644
--- a/libasn1print/asn1print.c
+++ b/libasn1print/asn1print.c
@@ -10,7 +10,7 @@
#include "asn1print.h"
#define INDENT(fmt, args...) do { \
- int __i = level; while(__i--) putchar(' '); \
+ int __i = level; while(__i--) printf(" "); \
printf(fmt, ##args); \
} while(0)
@@ -22,8 +22,8 @@
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_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);
/*
* Print the contents of the parsed ASN tree.
@@ -38,6 +38,9 @@
return -1;
}
+ if(flags & APF_PRINT_XML_DTD)
+ printf("<!-- XML DTD generated by asn1c-" VERSION " -->\n\n");
+
TQ_FOR(mod, &(asn->modules), mod_next) {
if(modno++) printf("\n");
asn1print_module(asn, mod, flags);
@@ -50,12 +53,28 @@
asn1print_module(asn1p_t *asn, asn1p_module_t *mod, enum asn1print_flags flags) {
asn1p_expr_t *tc;
+ if(flags & APF_PRINT_XML_DTD)
+ printf("<!-- ASN.1 module\n");
+
printf("%s ", mod->Identifier);
if(mod->module_oid) {
asn1print_oid(mod->module_oid, flags);
printf("\n");
}
+ if(flags & APF_PRINT_XML_DTD) {
+ if(mod->source_file_name
+ && strcmp(mod->source_file_name, "-"))
+ printf("found in %s", mod->source_file_name);
+ printf(" -->\n\n");
+
+ TQ_FOR(tc, &(mod->members), next) {
+ asn1print_expr_dtd(asn, mod, tc, flags, 0);
+ }
+
+ return 0;
+ }
+
printf("DEFINITIONS");
if(mod->module_flags & MSF_TAG_INSTRUCTIONS)
@@ -442,7 +461,7 @@
int SEQ_OF = 0;
if(flags & APF_LINE_COMMENTS)
- INDENT("-- #line %d\n", tc->_lineno);
+ INDENT("-- #line %d\n", tc->_lineno);
if(tc->Identifier)
INDENT("%s", tc->Identifier);
@@ -539,7 +558,7 @@
/*
* Print the expression as it were a stand-alone type.
*/
- asn1print_expr(asn, mod, se, flags, level + 4);
+ asn1print_expr(asn, mod, se, flags, level + 1);
if((se->marker.flags & EM_DEFAULT) == EM_DEFAULT) {
printf(" DEFAULT ");
asn1print_value(se->marker.default_value, flags);
@@ -614,3 +633,115 @@
return 0;
}
+
+static int
+asn1print_expr_dtd(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, enum asn1print_flags flags, int level) {
+ asn1p_expr_t *se;
+ int expr_unordered = 0;
+
+ switch(expr->meta_type) {
+ case AMT_TYPE:
+ case AMT_TYPEREF:
+ break;
+ default:
+ if(expr->expr_type == A1TC_UNIVERVAL)
+ break;
+ return 0;
+ }
+
+ if(!expr->Identifier) return 0;
+
+ if(expr->expr_type == ASN_CONSTR_CHOICE
+ || expr->expr_type == ASN_CONSTR_SEQUENCE_OF
+ || expr->expr_type == ASN_CONSTR_SET_OF
+ || expr->expr_type == ASN_CONSTR_SET
+ || expr->expr_type == ASN_BASIC_INTEGER
+ || expr->expr_type == ASN_BASIC_ENUMERATED) {
+ expr_unordered = 1;
+ }
+
+ if(flags & APF_LINE_COMMENTS)
+ INDENT("<!-- #line %d -->\n", expr->_lineno);
+ INDENT("<!ELEMENT %s", expr->Identifier);
+
+ if(expr->expr_type == A1TC_REFERENCE) {
+ se = asn1f_find_terminal_type_ex(asn, expr);
+ if(!se) {
+ printf("(ANY)");
+ return 0;
+ }
+ expr = se;
+ }
+
+ if(TQ_FIRST(&expr->members)) {
+ int extensible = 0;
+ printf(" (");
+ TQ_FOR(se, &(expr->members), next) {
+ if(se->expr_type == A1TC_EXTENSIBLE) {
+ extensible = 1;
+ continue;
+ } else if(!se->Identifier
+ && se->expr_type == A1TC_REFERENCE) {
+ asn1print_ref(se->reference, flags);
+ } else if(se->Identifier) {
+ printf("%s", se->Identifier);
+ } else {
+ printf("ANY");
+ }
+ if(expr->expr_type != ASN_CONSTR_SET
+ && expr->expr_type != ASN_CONSTR_CHOICE
+ && expr->expr_type != ASN_BASIC_INTEGER
+ && expr->expr_type != ASN_BASIC_ENUMERATED) {
+ if(expr_unordered)
+ printf("*");
+ else if(se->marker.flags)
+ printf("?");
+ }
+ if(TQ_NEXT(se, next)
+ && TQ_NEXT(se, next)->expr_type != A1TC_EXTENSIBLE) {
+ printf(expr_unordered?"|":", ");
+ }
+ }
+ if(extensible) {
+ printf(expr_unordered?"|":", ");
+ printf("ANY");
+ if(expr->expr_type != ASN_CONSTR_SET
+ && expr->expr_type != ASN_CONSTR_CHOICE
+ && expr->expr_type != ASN_BASIC_INTEGER
+ && expr->expr_type != ASN_BASIC_ENUMERATED)
+ printf("*");
+ }
+
+ printf(")");
+ if(expr->expr_type == ASN_CONSTR_SET)
+ printf("*");
+
+ } else if((expr->expr_type & ASN_CONSTR_MASK)
+ || expr->expr_type == ASN_BASIC_NULL) {
+ printf(" EMPTY");
+ } else if(expr->expr_type == A1TC_UNIVERVAL) {
+ printf(" EMPTY");
+ } else if(expr->expr_type == ASN_TYPE_ANY) {
+ printf(" ANY");
+ } else if(expr->expr_type == ASN_BASIC_BIT_STRING
+ || expr->expr_type == ASN_BASIC_OBJECT_IDENTIFIER
+ || expr->expr_type == ASN_BASIC_RELATIVE_OID
+ || expr->expr_type == ASN_BASIC_UTCTime
+ || expr->expr_type == ASN_BASIC_GeneralizedTime
+ ) {
+ printf(" (#CDATA)");
+ } else {
+ printf(" (#PCDATA)");
+ }
+ printf(">\n");
+
+ /*
+ * Display the descendants (children) of the current type.
+ */
+ TQ_FOR(se, &(expr->members), next) {
+ if(se->expr_type == A1TC_EXTENSIBLE) continue;
+ asn1print_expr_dtd(asn, mod, se, flags, level + 1);
+ }
+
+ return 0;
+}