From f15320bf6b50a0c02636405561ac8323ae901abd Mon Sep 17 00:00:00 2001 From: Lev Walkin Date: Thu, 3 Jun 2004 03:38:44 +0000 Subject: Initial revision --- libasn1print/Makefile.am | 14 ++ libasn1print/Makefile.in | 382 +++++++++++++++++++++++++++++++++++++++ libasn1print/README | 4 + libasn1print/asn1print.c | 456 +++++++++++++++++++++++++++++++++++++++++++++++ libasn1print/asn1print.h | 16 ++ 5 files changed, 872 insertions(+) create mode 100644 libasn1print/Makefile.am create mode 100644 libasn1print/Makefile.in create mode 100644 libasn1print/README create mode 100644 libasn1print/asn1print.c create mode 100644 libasn1print/asn1print.h (limited to 'libasn1print') diff --git a/libasn1print/Makefile.am b/libasn1print/Makefile.am new file mode 100644 index 00000000..fb4861a4 --- /dev/null +++ b/libasn1print/Makefile.am @@ -0,0 +1,14 @@ + +AM_CFLAGS = @ADD_CFLAGS@ +AM_CPPFLAGS = -I${top_srcdir}/libasn1parser + +noinst_LTLIBRARIES = libasn1print.la + +libasn1print_la_LDFLAGS = -all-static +libasn1print_la_SOURCES = \ + asn1print.c asn1print.h + +LDADD = ${noinst_LTLIBRARIES} ${libasn1fix_la_LIBADD} +DEPENDENCIES = ${LDADD} + +TESTS = ${check_PROGRAMS} diff --git a/libasn1print/Makefile.in b/libasn1print/Makefile.in new file mode 100644 index 00000000..e1e876e5 --- /dev/null +++ b/libasn1print/Makefile.in @@ -0,0 +1,382 @@ +# Makefile.in generated automatically by automake 1.5 from Makefile.am. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +ADD_CFLAGS = @ADD_CFLAGS@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AWK = @AWK@ +CC = @CC@ +CONFIGURE_DEPENDS = @CONFIGURE_DEPENDS@ +CPP = @CPP@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +EXEEXT = @EXEEXT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LEX = @LEX@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PATH = @PATH@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +YACC = @YACC@ +am__include = @am__include@ +am__quote = @am__quote@ +install_sh = @install_sh@ + +AM_CFLAGS = @ADD_CFLAGS@ +AM_CPPFLAGS = -I${top_srcdir}/libasn1parser + +noinst_LTLIBRARIES = libasn1print.la + +libasn1print_la_LDFLAGS = -all-static +libasn1print_la_SOURCES = \ + asn1print.c asn1print.h + + +LDADD = ${noinst_LTLIBRARIES} ${libasn1fix_la_LIBADD} +DEPENDENCIES = ${LDADD} + +TESTS = ${check_PROGRAMS} +subdir = libasn1print +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) + +libasn1print_la_LIBADD = +am_libasn1print_la_OBJECTS = asn1print.lo +libasn1print_la_OBJECTS = $(am_libasn1print_la_OBJECTS) + +DEFS = @DEFS@ +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/asn1print.Plo +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ + $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CFLAGS = @CFLAGS@ +DIST_SOURCES = $(libasn1print_la_SOURCES) +DIST_COMMON = README Makefile.am Makefile.in +SOURCES = $(libasn1print_la_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libasn1print/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && \ + CONFIG_HEADERS= CONFIG_LINKS= \ + CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) +libasn1print.la: $(libasn1print_la_OBJECTS) $(libasn1print_la_DEPENDENCIES) + $(LINK) $(libasn1print_la_LDFLAGS) $(libasn1print_la_OBJECTS) $(libasn1print_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1print.Plo@am__quote@ + +distclean-depend: + -rm -rf $(DEPDIR) + +.c.o: +@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(COMPILE) -c `test -f $< || echo '$(srcdir)/'`$< + +.c.obj: +@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(COMPILE) -c `cygpath -w $<` + +.c.lo: +@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(LTCOMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$< +CCDEPMODE = @CCDEPMODE@ +uninstall-info-am: + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || etags $(ETAGS_ARGS) $$tags $$unique $(LISP) + +GTAGS: + here=`CDPATH=: && cd $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + fi + +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + $(mkinstalldirs) "$(distdir)/$$dir"; \ + fi; \ + if test -d $$d/$$file; then \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(LTLIBRARIES) + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +uninstall-am: uninstall-info-am + +.PHONY: GTAGS all all-am check check-TESTS check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES distclean \ + distclean-compile distclean-depend distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am info \ + info-am install install-am install-data install-data-am \ + install-exec install-exec-am install-info install-info-am \ + install-man install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool tags uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libasn1print/README b/libasn1print/README new file mode 100644 index 00000000..5c1071cf --- /dev/null +++ b/libasn1print/README @@ -0,0 +1,4 @@ + +Ad hoc ASN tree printing procedures. Use for debugging purposes, this library +isn't thought through enough to be universally useful or even accurate. + diff --git a/libasn1print/asn1print.c b/libasn1print/asn1print.c new file mode 100644 index 00000000..992dcfa0 --- /dev/null +++ b/libasn1print/asn1print.c @@ -0,0 +1,456 @@ +#include +#include +#include +#include + +#include + +#include "asn1print.h" + +#define INDENT(fmt, args...) do { \ + int __i = level; while(__i--) putchar(' '); \ + printf(fmt, ##args); \ + } while(0) + +static int asn1print_module(asn1p_module_t *mod, enum asn1print_flags_e flags); +static int asn1print_oid(asn1p_oid_t *oid, enum asn1print_flags_e flags); +static int asn1print_ref(asn1p_ref_t *ref, enum asn1print_flags_e flags); +static int asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags_e flags); +static int asn1print_params(asn1p_paramlist_t *pl,enum asn1print_flags_e flags); +static int asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags_e flags); +static int asn1print_constraint(asn1p_constraint_t *, enum asn1print_flags_e); +static int asn1print_value(asn1p_value_t *val, enum asn1print_flags_e flags); +static int asn1print_expr(asn1p_expr_t *tc, enum asn1print_flags_e flags, + int level); + +/* + * Print the contents of the parsed ASN tree. + */ +int +asn1print(asn1p_t *asn, enum asn1print_flags_e flags) { + asn1p_module_t *mod; + + if(asn == NULL) { + errno = EINVAL; + return -1; + } + + TQ_FOR(mod, &(asn->modules), mod_next) { + asn1print_module(mod, flags); + } + + return 0; +} + +static int +asn1print_module(asn1p_module_t *mod, enum asn1print_flags_e flags) { + asn1p_expr_t *tc; + + if(!(flags & APF_NO_SOURCE_COMMENTS)) + printf("\n-- Contents of \"%s\"\n", mod->source_file_name); + + printf("\n%s ", mod->Identifier); + if(mod->module_oid) { + asn1print_oid(mod->module_oid, flags); + printf("\n"); + } + + printf("DEFINITIONS"); + + if(mod->module_flags & MSF_EXPLICIT_TAGS) + printf(" EXPLICIT TAGS"); + if(mod->module_flags & MSF_IMPLICIT_TAGS) + printf(" IMPLICIT TAGS"); + if(mod->module_flags & MSF_AUTOMATIC_TAGS) + printf(" AUTOMATIC TAGS"); + if(mod->module_flags & MSF_EXTENSIBILITY_IMPLIED) + printf(" EXTENSIBILITY IMPLIED"); + + printf(" ::=\n"); + printf("BEGIN\n\n"); + + TQ_FOR(tc, &(mod->members), next) { + asn1print_expr(tc, flags, 0); + printf("\n\n"); + } + + printf("END\n"); + + return 0; +} + +static int +asn1print_oid(asn1p_oid_t *oid, enum asn1print_flags_e flags) { + int ac; + int accum = 0; + + printf("{"); + for(ac = 0; ac < oid->arcs_count; ac++) { + if(accum + strlen(oid->arcs[ac].name?:"") > 50) { + printf("\n\t"); + accum = 0; + } else if(ac) printf(" "); + + if(oid->arcs[ac].name) { + printf("%s(%d)", + oid->arcs[ac].name, + (int)oid->arcs[ac].number); + accum += strlen(oid->arcs[ac].name); + } else { + printf("%d", + (int)oid->arcs[ac].number); + } + accum += 4; + } + printf(" }"); + + return 0; +} + +static int +asn1print_ref(asn1p_ref_t *ref, enum asn1print_flags_e flags) { + int cc; + + for(cc = 0; cc < ref->comp_count; cc++) { + if(cc) printf("."); + printf("%s", ref->components[cc].name); + } + + return 0; +} + +static int +asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags_e flags) { + struct asn1p_type_tag_s *tag = &tc->tag; + + if(tag->tag_class == TC_NOCLASS) + return 0; + + printf("["); + switch(tag->tag_class) { + case TC_NOCLASS: + assert(tag->tag_class != TC_NOCLASS); + break; + case TC_UNIVERSAL: printf("UNIVERSAL "); break; + case TC_PRIVATE: printf("PRIVATE "); break; + case TC_APPLICATION: printf("APPLICATION "); break; + case TC_CONTEXT_SPECIFIC: + break; + } + printf("%lld]", (long long)tag->tag_value); + + switch(tag->tag_mode) { + case TM_DEFAULT: break; + case TM_IMPLICIT: printf(" IMPLICIT"); break; + case TM_EXPLICIT: printf(" EXPLICIT"); break; + } + + return 0; +} + +static int +asn1print_value(asn1p_value_t *val, enum asn1print_flags_e flags) { + + if(val == NULL) + return 0; + + switch(val->type) { + case ATV_NOVALUE: + break; + case ATV_REFERENCED: + return asn1print_ref(val->value.reference, flags); + case ATV_INTEGER: + printf("%lld", (long long)val->value.v_integer); + return 0; + case ATV_MIN: printf("MIN"); return 0; + case ATV_MAX: printf("MAX"); return 0; + case ATV_FALSE: printf("FALSE"); return 0; + case ATV_TRUE: printf("TRUE"); return 0; + case ATV_REAL: + printf("%f", val->value.v_double); + return 0; + case ATV_STRING: + { + char *p = val->value.string.buf; + putchar('"'); + if(strchr(p, '"')) { + /* Mask quotes */ + for(; *p; p++) { + if(*p == '"') + putchar(*p); + putchar(*p); + } + } else { + fputs(p, stdout); + } + putchar('"'); + } + return 0; + case ATV_UNPARSED: + fputs(val->value.string.buf, stdout); + return 0; + case ATV_BITVECTOR: + { + uint8_t *bitvector; + int bits; + int i; + + bitvector = val->value.binary_vector.bits; + bits = val->value.binary_vector.size_in_bits; + + printf("'"); + if(bits%8) { + for(i = 0; i < bits; i++) { + uint8_t uc; + uc = bitvector[i>>3]; + putchar(((uc >> (7-(i%8)))&1)?'1':'0'); + } + printf("'B"); + } else { + char hextable[16] = "0123456789ABCDEF"; + for(i = 0; i < (bits>>3); i++) { + putchar(hextable[bitvector[i] >> 4]); + putchar(hextable[bitvector[i] & 0x0f]); + } + printf("'H"); + } + } + } + + assert(val->type || !"Unknown"); + + return 0; +} + +static int +asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags_e flags) { + int symno = 0; + + if(ct == 0) return 0; + + if(ct->type == ACT_CA_SET) + printf("("); + + switch(ct->type) { + case ACT_EL_VALUE: + asn1print_value(ct->value, flags); + break; + case ACT_EL_RANGE: + case ACT_EL_LLRANGE: + case ACT_EL_RLRANGE: + case ACT_EL_ULRANGE: + asn1print_value(ct->range_start, flags); + switch(ct->type) { + case ACT_EL_RANGE: printf(".."); break; + case ACT_EL_LLRANGE: printf("<.."); break; + case ACT_EL_RLRANGE: printf("..<"); break; + case ACT_EL_ULRANGE: printf("<..<"); break; + default: printf("?..?"); break; + } + asn1print_value(ct->range_stop, flags); + break; + case ACT_EL_EXT: + printf("..."); + break; + case ACT_CT_SIZE: + case ACT_CT_FROM: + switch(ct->type) { + case ACT_CT_SIZE: printf("SIZE ("); break; + case ACT_CT_FROM: printf("FROM ("); break; + default: printf("??? ("); break; + } + assert(ct->el_count != 0); + assert(ct->el_count == 1); + asn1print_constraint(ct->elements[0], flags); + printf(")"); + break; + case ACT_CT_WCOMP: + case ACT_CT_WCOMPS: + printf("???"); + break; + case ACT_CA_SET: symno++; + case ACT_CA_CRC: symno++; + case ACT_CA_CSV: symno++; + case ACT_CA_UNI: symno++; + case ACT_CA_INT: symno++; + case ACT_CA_EXC: + { + char *symtable[] = { " EXCEPT ", "^", "|", ",", + "", "(" }; + int i; + for(i = 0; i < ct->el_count; i++) { + enum asn1print_flags_e nflags = flags; + if(i) fputs(symtable[symno], stdout); + if(ct->type == ACT_CA_CRC) fputs("{", stdout); + asn1print_constraint(ct->elements[i], nflags); + if(ct->type == ACT_CA_CRC) fputs("}", stdout); + if(i+1 < ct->el_count + && ct->type == ACT_CA_SET) + fputs(")", stdout); + } + } + break; + case ACT_INVALID: + assert(ct->type != ACT_INVALID); + break; + } + + if(ct->type == ACT_CA_SET) + printf(")"); + + return 0; +} + +static int +asn1print_params(asn1p_paramlist_t *pl, enum asn1print_flags_e flags) { + if(pl) { + int i; + printf("{"); + for(i = 0; i < pl->params_count; i++) { + if(i) printf(", "); + if(pl->params[i].governor) { + asn1print_ref(pl->params[i].governor, flags); + printf(":"); + } + printf("%s", pl->params[i].argument); + } + printf("}"); + } + + return 0; +} + +static int +asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags_e flags) { + if(wx) { + asn1p_wsyntx_chunk_t *wc; + printf(" WITH SYNTAX {"); + TQ_FOR(wc, &(wx->chunks), next) { + if(wc->ref) { + asn1print_ref(wc->ref, flags); + } else { + fwrite(wc->buf, 1, wc->len, stdout); + } + } + printf("}\n"); + } + + return 0; +} + +static int +asn1print_expr(asn1p_expr_t *tc, enum asn1print_flags_e flags, int level) { + + if(flags & APF_LINE_COMMENTS) + INDENT("-- #line %d\n", tc->_lineno); + if(tc->Identifier) + INDENT("%s", tc->Identifier); + + if(tc->params) { + asn1print_params(tc->params, flags); + } + + if(tc->meta_type != AMT_VALUE + && tc->expr_type != A1TC_EXTENSIBLE) { + if(level) { + if(tc->Identifier) + printf("\t"); + } else { + printf(" ::="); + } + } + + if(tc->tag.tag_class) { + printf(" "); + asn1print_tag(tc, flags); + } + + switch(tc->expr_type) { + case A1TC_EXTENSIBLE: + if(tc->value) { + printf("!"); + asn1print_value(tc->value, flags); + } + break; + case A1TC_REFERENCE: + case A1TC_UNIVERVAL: + case A1TC_PARAMETRIZED: + break; + case A1TC_CLASSDEF: + printf(" CLASS"); + break; + case A1TC_CLASSFIELD: + /* Nothing to print here */ + break; + default: + { + char *p = ASN_EXPR_TYPE2STR(tc->expr_type); + printf(" %s", p?p:""); + } + break; + } + + if(tc->reference) { + printf(" "); + asn1print_ref(tc->reference, flags); + } + + /* + * Display the descendants (children) of the current type. + */ + if(TQ_FIRST(&(tc->members))) { + asn1p_expr_t *se; /* SubExpression */ + + if((tc->expr_type != ASN_CONSTR_SEQUENCE_OF + && tc->expr_type != ASN_CONSTR_SET_OF) + || TQ_FIRST(&(tc->members))->expr_type & ASN_CONSTR_MASK) + printf(" {\n"); + + TQ_FOR(se, &(tc->members), next) { + /* + * Print the expression as it were stand-alone type. + */ + asn1print_expr(se, flags, level + 4); + switch(se->marker) { + case EM_NOMARK: break; + case EM_OPTIONAL: printf(" OPTIONAL"); break; + case EM_DEFAULT: printf(" DEFAULT "); break; + } + if(TQ_NEXT(se, next)) { + printf(","); + INDENT("\n"); + } + } + + if((tc->expr_type != ASN_CONSTR_SEQUENCE_OF + && tc->expr_type != ASN_CONSTR_SET_OF) + || TQ_FIRST(&(tc->members))->expr_type & ASN_CONSTR_MASK) { + printf("\n"); + INDENT("}"); + } + } + + if(tc->with_syntax) + asn1print_with_syntax(tc->with_syntax, flags); + + if(tc->constraints) { + printf(" "); + asn1print_constraint(tc->constraints, flags); + } + if(tc->unique) { + printf(" UNIQUE"); + } + + if(tc->meta_type == AMT_VALUE + && tc->expr_type != A1TC_EXTENSIBLE) { + if(tc->expr_type == A1TC_UNIVERVAL) + printf("("); + else + printf(" ::= "); + asn1print_value(tc->value, flags); + if(tc->expr_type == A1TC_UNIVERVAL) + printf(")"); + } + + return 0; +} diff --git a/libasn1print/asn1print.h b/libasn1print/asn1print.h new file mode 100644 index 00000000..73875fb1 --- /dev/null +++ b/libasn1print/asn1print.h @@ -0,0 +1,16 @@ +#ifndef _ASN1PRINT_H_ +#define _ASN1PRINT_H_ + +enum asn1print_flags_e { + APF_NOFLAGS = 0x00, + APF_LINE_COMMENTS = 0x01, + APF_NO_SOURCE_COMMENTS = 0x02, +}; + +/* + * Print the contents of the parsed ASN.1 syntax tree. + */ +int asn1print(asn1p_t *asn, enum asn1print_flags_e flags); + + +#endif /* _ASN1PRINT_H_ */ -- cgit v1.2.3