From fa67ddcad9ce4ce04668d8ce46f4ac0057c914c2 Mon Sep 17 00:00:00 2001 From: vlm Date: Thu, 3 Jun 2004 03:38:44 +0000 Subject: Initial revision git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@2 59561ff5-6e30-0410-9f3c-9617f08c8826 --- libasn1parser/Makefile.am | 35 + libasn1parser/Makefile.in | 459 +++++ libasn1parser/asn1p_class.c | 135 ++ libasn1parser/asn1p_class.h | 53 + libasn1parser/asn1p_constr.c | 91 + libasn1parser/asn1p_constr.h | 79 + libasn1parser/asn1p_expr.c | 112 ++ libasn1parser/asn1p_expr.h | 214 ++ libasn1parser/asn1p_expr2uclass.h | 41 + libasn1parser/asn1p_expr_str.h | 57 + libasn1parser/asn1p_l.c | 3861 +++++++++++++++++++++++++++++++++++++ libasn1parser/asn1p_l.l | 560 ++++++ libasn1parser/asn1p_list.h | 57 + libasn1parser/asn1p_module.c | 62 + libasn1parser/asn1p_module.h | 88 + libasn1parser/asn1p_oid.c | 95 + libasn1parser/asn1p_oid.h | 66 + libasn1parser/asn1p_param.c | 111 ++ libasn1parser/asn1p_param.h | 30 + libasn1parser/asn1p_ref.c | 137 ++ libasn1parser/asn1p_ref.h | 62 + libasn1parser/asn1p_value.c | 178 ++ libasn1parser/asn1p_value.h | 60 + libasn1parser/asn1p_xports.c | 34 + libasn1parser/asn1p_xports.h | 40 + libasn1parser/asn1p_y.c | 3484 +++++++++++++++++++++++++++++++++ libasn1parser/asn1p_y.h | 132 ++ libasn1parser/asn1p_y.y | 1982 +++++++++++++++++++ libasn1parser/asn1parser.c | 171 ++ libasn1parser/asn1parser.h | 73 + libasn1parser/expr-h.pl | 49 + 31 files changed, 12608 insertions(+) create mode 100644 libasn1parser/Makefile.am create mode 100644 libasn1parser/Makefile.in create mode 100644 libasn1parser/asn1p_class.c create mode 100644 libasn1parser/asn1p_class.h create mode 100644 libasn1parser/asn1p_constr.c create mode 100644 libasn1parser/asn1p_constr.h create mode 100644 libasn1parser/asn1p_expr.c create mode 100644 libasn1parser/asn1p_expr.h create mode 100644 libasn1parser/asn1p_expr2uclass.h create mode 100644 libasn1parser/asn1p_expr_str.h create mode 100644 libasn1parser/asn1p_l.c create mode 100644 libasn1parser/asn1p_l.l create mode 100644 libasn1parser/asn1p_list.h create mode 100644 libasn1parser/asn1p_module.c create mode 100644 libasn1parser/asn1p_module.h create mode 100644 libasn1parser/asn1p_oid.c create mode 100644 libasn1parser/asn1p_oid.h create mode 100644 libasn1parser/asn1p_param.c create mode 100644 libasn1parser/asn1p_param.h create mode 100644 libasn1parser/asn1p_ref.c create mode 100644 libasn1parser/asn1p_ref.h create mode 100644 libasn1parser/asn1p_value.c create mode 100644 libasn1parser/asn1p_value.h create mode 100644 libasn1parser/asn1p_xports.c create mode 100644 libasn1parser/asn1p_xports.h create mode 100644 libasn1parser/asn1p_y.c create mode 100644 libasn1parser/asn1p_y.h create mode 100644 libasn1parser/asn1p_y.y create mode 100644 libasn1parser/asn1parser.c create mode 100644 libasn1parser/asn1parser.h create mode 100755 libasn1parser/expr-h.pl (limited to 'libasn1parser') diff --git a/libasn1parser/Makefile.am b/libasn1parser/Makefile.am new file mode 100644 index 00000000..0f9ff161 --- /dev/null +++ b/libasn1parser/Makefile.am @@ -0,0 +1,35 @@ + +AM_CFLAGS = @ADD_CFLAGS@ +AM_YFLAGS = -p asn1p_ -d +AM_LFLAGS = -sp -Cem -Pasn1p_ -olex.yy.c + +noinst_LTLIBRARIES = libasn1parser.la + +libasn1parser_la_LDFLAGS = -all-static +libasn1parser_la_SOURCES = \ + asn1parser.c asn1parser.h \ + asn1p_y.y asn1p_l.l \ + asn1p_module.c asn1p_module.h \ + asn1p_oid.c asn1p_oid.h \ + asn1p_value.c asn1p_value.h \ + asn1p_expr.c asn1p_expr.h \ + asn1p_expr_str.h \ + asn1p_expr2uclass.h \ + asn1p_xports.c asn1p_xports.h \ + asn1p_constr.c asn1p_constr.h \ + asn1p_param.c asn1p_param.h \ + asn1p_class.c asn1p_class.h \ + asn1p_ref.c asn1p_ref.h \ + asn1p_list.h + +asn1p_expr_str.h: expr-h.pl asn1p_expr.h + ./expr-h.pl asn1p_expr.h > $@ + +EXTRA_DIST = expr-h.pl + +check_PROGRAMS = check_parser + +LDADD = ${noinst_LTLIBRARIES} +DEPENDENCIES = ${noinst_LTLIBRARIES} + +TESTS = ${check_PROGRAMS} diff --git a/libasn1parser/Makefile.in b/libasn1parser/Makefile.in new file mode 100644 index 00000000..7c4bd5f8 --- /dev/null +++ b/libasn1parser/Makefile.in @@ -0,0 +1,459 @@ +# 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_YFLAGS = -p asn1p_ -d +AM_LFLAGS = -sp -Cem -Pasn1p_ -olex.yy.c + +noinst_LTLIBRARIES = libasn1parser.la + +libasn1parser_la_LDFLAGS = -all-static +libasn1parser_la_SOURCES = \ + asn1parser.c asn1parser.h \ + asn1p_y.y asn1p_l.l \ + asn1p_module.c asn1p_module.h \ + asn1p_oid.c asn1p_oid.h \ + asn1p_value.c asn1p_value.h \ + asn1p_expr.c asn1p_expr.h \ + asn1p_expr_str.h \ + asn1p_expr2uclass.h \ + asn1p_xports.c asn1p_xports.h \ + asn1p_constr.c asn1p_constr.h \ + asn1p_param.c asn1p_param.h \ + asn1p_class.c asn1p_class.h \ + asn1p_ref.c asn1p_ref.h \ + asn1p_list.h + + +EXTRA_DIST = expr-h.pl + +check_PROGRAMS = check_parser + +LDADD = ${noinst_LTLIBRARIES} +DEPENDENCIES = ${noinst_LTLIBRARIES} + +TESTS = ${check_PROGRAMS} +subdir = libasn1parser +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) + +libasn1parser_la_LIBADD = +am_libasn1parser_la_OBJECTS = asn1parser.lo asn1p_y.lo asn1p_l.lo \ + asn1p_module.lo asn1p_oid.lo asn1p_value.lo asn1p_expr.lo \ + asn1p_xports.lo asn1p_constr.lo asn1p_param.lo asn1p_class.lo \ + asn1p_ref.lo +libasn1parser_la_OBJECTS = $(am_libasn1parser_la_OBJECTS) +check_PROGRAMS = check_parser$(EXEEXT) +check_parser_SOURCES = check_parser.c +check_parser_OBJECTS = check_parser.$(OBJEXT) +check_parser_LDADD = $(LDADD) +check_parser_DEPENDENCIES = libasn1parser.la +check_parser_LDFLAGS = + +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)/asn1p_class.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/asn1p_constr.Plo $(DEPDIR)/asn1p_expr.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/asn1p_l.Plo $(DEPDIR)/asn1p_module.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/asn1p_oid.Plo $(DEPDIR)/asn1p_param.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/asn1p_ref.Plo $(DEPDIR)/asn1p_value.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/asn1p_xports.Plo $(DEPDIR)/asn1p_y.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/asn1parser.Plo $(DEPDIR)/check_parser.Po +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@ +LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) +LTLEXCOMPILE = $(LIBTOOL) --mode=compile $(LEX) $(LFLAGS) $(AM_LFLAGS) +YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS) +LTYACCCOMPILE = $(LIBTOOL) --mode=compile $(YACC) $(YFLAGS) $(AM_YFLAGS) +DIST_SOURCES = $(libasn1parser_la_SOURCES) check_parser.c +DIST_COMMON = Makefile.am Makefile.in asn1p_l.c asn1p_y.c asn1p_y.h +SOURCES = $(libasn1parser_la_SOURCES) check_parser.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .l .lo .o .obj .y + +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 libasn1parser/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) +asn1p_y.h: asn1p_y.c +libasn1parser.la: $(libasn1parser_la_OBJECTS) $(libasn1parser_la_DEPENDENCIES) + $(LINK) $(libasn1parser_la_LDFLAGS) $(libasn1parser_la_OBJECTS) $(libasn1parser_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) +check_parser$(EXEEXT): $(check_parser_OBJECTS) $(check_parser_DEPENDENCIES) + @rm -f check_parser$(EXEEXT) + $(LINK) $(check_parser_LDFLAGS) $(check_parser_OBJECTS) $(check_parser_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_class.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_constr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_expr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_l.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_module.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_oid.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_param.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_ref.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_value.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_xports.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1p_y.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/check_parser.Po@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@ + +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LEXLIB = @LEXLIB@ + +.l.c: + $(LEXCOMPILE) $< && mv $(LEX_OUTPUT_ROOT).c $@ + +.y.c: + $(YACCCOMPILE) $< && mv y.tab.c $@ + if test -f y.tab.h; then \ + if cmp -s y.tab.h $*.h; then \ + rm -f y.tab.h; \ + else \ + mv y.tab.h $*.h; \ + fi; \ + fi +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_PROGRAMS) + $(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." + -test -z "asn1p_y.h" || rm -f asn1p_y.h +clean: clean-am + +clean-am: clean-checkPROGRAMS 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-checkPROGRAMS 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 + + +asn1p_expr_str.h: expr-h.pl asn1p_expr.h + ./expr-h.pl asn1p_expr.h > $@ +# 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/libasn1parser/asn1p_class.c b/libasn1parser/asn1p_class.c new file mode 100644 index 00000000..cd0e385a --- /dev/null +++ b/libasn1parser/asn1p_class.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include + +#include "asn1parser.h" + +asn1p_wsyntx_chunk_t * +asn1p_wsyntx_chunk_new() { + asn1p_wsyntx_chunk_t *wc; + + wc = calloc(1, sizeof(*wc)); + + return wc; +} + +void +asn1p_wsyntx_chunk_free(asn1p_wsyntx_chunk_t *wc) { + if(wc) { + if(wc->ref) + asn1p_ref_free(wc->ref); + if(wc->buf) + free(wc->buf); + free(wc); + } +} + +asn1p_wsyntx_chunk_t * +asn1p_wsyntx_chunk_clone(asn1p_wsyntx_chunk_t *wc) { + asn1p_wsyntx_chunk_t *nc; + + nc = asn1p_wsyntx_chunk_new(); + if(nc) { + if(wc->buf) { + nc->buf = malloc(wc->len + 1); + if(nc->buf) { + nc->len = wc->len; + memcpy(nc->buf, wc->buf, wc->len); + nc->buf[nc->len] = '\0'; + } + } + if(wc->ref) { + nc->ref = asn1p_ref_clone(wc->ref); + } + + if(!nc->ref && !nc->buf) { + asn1p_wsyntx_chunk_free(nc); + return NULL; + } + } + + return nc; +} + +asn1p_wsyntx_t * +asn1p_wsyntx_new() { + asn1p_wsyntx_t *wx; + + wx = calloc(1, sizeof(*wx)); + if(wx) { + TQ_INIT(&(wx->chunks)); + } + + return wx; +} + +void +asn1p_wsyntx_free(asn1p_wsyntx_t *wx) { + if(wx) { + asn1p_wsyntx_chunk_t *wc; + while((wc = TQ_REMOVE(&(wx->chunks), next))) + asn1p_wsyntx_chunk_free(wc); + free(wx); + } +} + +asn1p_wsyntx_t * +asn1p_wsyntx_clone(asn1p_wsyntx_t *wx) { + asn1p_wsyntx_t *nw; + + nw = asn1p_wsyntx_new(); + if(nw) { + asn1p_wsyntx_chunk_t *wc; + asn1p_wsyntx_chunk_t *nc; + TQ_FOR(wc, &(wx->chunks), next) { + nc = asn1p_wsyntx_chunk_clone(wc); + if(nc) { + TQ_ADD(&(nw->chunks), nc, next); + } else { + asn1p_wsyntx_free(nw); + return NULL; + } + } + } + + return nw; +} + +asn1p_wsyntx_chunk_t * +asn1p_wsyntx_chunk_fromref(asn1p_ref_t *ref, int do_copy) { + asn1p_wsyntx_chunk_t *wc; + + if(do_copy) { + static asn1p_wsyntx_chunk_t tmp; + tmp.ref = ref; + wc = asn1p_wsyntx_chunk_clone(&tmp); + } else { + wc = asn1p_wsyntx_chunk_new(); + if(wc) wc->ref = ref; + } + + return wc; +} + +asn1p_wsyntx_chunk_t * +asn1p_wsyntx_chunk_frombuf(char *buf, int len, int do_copy) { + asn1p_wsyntx_chunk_t *wc; + + if(do_copy) { + static asn1p_wsyntx_chunk_t tmp; + tmp.buf = buf; + tmp.len = len; + wc = asn1p_wsyntx_chunk_clone(&tmp); + } else { + wc = asn1p_wsyntx_chunk_new(); + if(wc) { + wc->buf = buf; + wc->len = len; + } + } + + return wc; +} + diff --git a/libasn1parser/asn1p_class.h b/libasn1parser/asn1p_class.h new file mode 100644 index 00000000..4a0f19e1 --- /dev/null +++ b/libasn1parser/asn1p_class.h @@ -0,0 +1,53 @@ +/* + * CLASS-related stuff. + */ +#ifndef ASN1_PARSER_CLASS_H +#define ASN1_PARSER_CLASS_H + +#include + +/* + * WITH SYNTAX free-form chunks. + */ +typedef struct asn1p_wsyntx_chunk_s { + /* + * It could be the union, but the story is: + * if ref is here, the ref is used. + * Otherwise, buf/len is used. + */ + asn1p_ref_t *ref; + + char *buf; + int len; + + TQ_ENTRY(struct asn1p_wsyntx_chunk_s) next; +} asn1p_wsyntx_chunk_t; + +typedef struct asn1p_wsyntx_s { + + TQ_HEAD(struct asn1p_wsyntx_chunk_s) chunks; + +} asn1p_wsyntx_t; + + +/* + * Constructor, destructor and cloning function. + */ +asn1p_wsyntx_chunk_t *asn1p_wsyntx_chunk_new(void); +void asn1p_wsyntx_chunk_free(asn1p_wsyntx_chunk_t *); +asn1p_wsyntx_chunk_t *asn1p_wsyntx_chunk_clone(asn1p_wsyntx_chunk_t *); + +asn1p_wsyntx_t *asn1p_wsyntx_new(void); +void asn1p_wsyntx_free(asn1p_wsyntx_t *); +asn1p_wsyntx_t *asn1p_wsyntx_clone(asn1p_wsyntx_t *); + +/* + * RETURN VALUES: + * 0: Component has been added + * -1: Failure to add component (refer to errno) + */ +asn1p_wsyntx_chunk_t *asn1p_wsyntx_chunk_fromref(asn1p_ref_t *ref, int do_copy); +asn1p_wsyntx_chunk_t *asn1p_wsyntx_chunk_frombuf(char *buf, int len, int do_copy); + + +#endif /* ASN1_PARSER_CLASS_H */ diff --git a/libasn1parser/asn1p_constr.c b/libasn1parser/asn1p_constr.c new file mode 100644 index 00000000..6e198892 --- /dev/null +++ b/libasn1parser/asn1p_constr.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include + +#include "asn1parser.h" + +asn1p_constraint_t * +asn1p_constraint_new(int _lineno) { + asn1p_constraint_t *ct; + + ct = calloc(1, sizeof(*ct)); + if(ct) { + ct->_lineno = _lineno; + } + + return ct; +} + + +void +asn1p_constraint_free(asn1p_constraint_t *ct) { + if(ct) { + + if(ct->value) + asn1p_value_free(ct->value); + if(ct->range_start) + asn1p_value_free(ct->range_start); + if(ct->range_stop) + asn1p_value_free(ct->range_stop); + + if(ct->elements) { + while(ct->el_count--) { + asn1p_constraint_free( + ct->elements[ct->el_count]); + } + free(ct->elements); + } + + free(ct); + } +} + +asn1p_constraint_t * +asn1p_constraint_clone(asn1p_constraint_t *src) { + asn1p_constraint_t *clone; + +#define CLONE(field, func) do { if(src->field) { \ + clone->field = func(src->field); \ + if(clone->field == NULL) { \ + asn1p_constraint_free(clone); \ + return NULL; \ + } \ + } } while(0) + + clone = asn1p_constraint_new(src->_lineno); + if(clone) { + clone->type = src->type; + CLONE(value, asn1p_value_clone); + CLONE(range_start, asn1p_value_clone); + CLONE(range_stop, asn1p_value_clone); + } + + return clone; +} + +int +asn1p_constraint_insert(asn1p_constraint_t *into, asn1p_constraint_t *what) { + assert(into); + assert(what); + + /* + * Make sure there's enough space to add an element. + */ + if(into->el_count == into->el_size) { + int newsize = into->el_size?into->el_size<<2:4; + void *p; + p = realloc(into->elements, + newsize * sizeof(into->elements[0])); + if(p) { + into->elements = p; + into->el_size = newsize; + } else { + return -1; + } + } + + into->elements[into->el_count++] = what; + + return 0; +} diff --git a/libasn1parser/asn1p_constr.h b/libasn1parser/asn1p_constr.h new file mode 100644 index 00000000..19099b2f --- /dev/null +++ b/libasn1parser/asn1p_constr.h @@ -0,0 +1,79 @@ +/* + * Type constraints. + */ +#ifndef ASN1_PARSER_CONSTRAINT_H +#define ASN1_PARSER_CONSTRAINT_H + +typedef struct asn1p_constraint_s { + + enum asn1p_constraint_type_e { + ACT_INVALID, /* for assertions */ + /* + * Constraint elements. + */ + ACT_EL_VALUE, /* 123, "A", T (elementary value) */ + ACT_EL_RANGE, /* 1..2 (elementary range) */ + ACT_EL_LLRANGE, /* 1<..2 (elementary range) */ + ACT_EL_RLRANGE, /* 1..<2 (elementary range) */ + ACT_EL_ULRANGE, /* 1<..<2 (elementary range) */ + ACT_EL_EXT, /* ... (extensibility mark) */ + /* + * Constraint types. + */ + ACT_CT_SIZE, /* SIZE constraint type */ + ACT_CT_FROM, /* FROM constraint type */ + ACT_CT_WCOMP, /* WITH COMPONENT */ + ACT_CT_WCOMPS, /* WITH COMPONENTS */ + /* + * Arrays of constraints. + */ + ACT_CA_SET, /* A set of constraints: (c1)(c2) */ + ACT_CA_CRC, /* Comp. relation c-t: ({a})({@b}) */ + ACT_CA_CSV, /* Comma-separated constraints array */ + ACT_CA_UNI, /* UNION (|) */ + ACT_CA_INT, /* INTERSECTION (^) */ + ACT_CA_EXC, /* EXCEPT */ + } type; + + enum asn1p_constr_pres_e { + ACPRES_DEFAULT, + ACPRES_PRESENT, + ACPRES_ABSENT, + ACPRES_OPTIONAL, + } presence; + + /* + * A single values. + */ + asn1p_value_t *value; + asn1p_value_t *range_start; + asn1p_value_t *range_stop; + + /* + * A collection of constraint elements. + */ + struct asn1p_constraint_s **elements; + int el_count; /* Number of meaningful elements */ + int el_size; /* Size of the allocated (elements) */ + + int _lineno; /* Position in a source file */ +} asn1p_constraint_t; + + +/* + * Constructors and a recursive destructor. + */ +asn1p_constraint_t *asn1p_constraint_new(int _lineno); +void asn1p_constraint_free(asn1p_constraint_t *); + +/* + * Clone the constraint and all its children. + */ +asn1p_constraint_t *asn1p_constraint_clone(asn1p_constraint_t *source_to_clone); + +/* + * Insert additional element into the element array of a (to) constraint. + */ +int asn1p_constraint_insert(asn1p_constraint_t *into, asn1p_constraint_t *what); + +#endif /* ASN1_PARSER_CONSTRAINT_H */ diff --git a/libasn1parser/asn1p_expr.c b/libasn1parser/asn1p_expr.c new file mode 100644 index 00000000..23ab4cb3 --- /dev/null +++ b/libasn1parser/asn1p_expr.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include + +#include "asn1parser.h" + +/* + * Construct a new empty types collection. + */ +asn1p_expr_t * +asn1p_expr_new(int _lineno) { + asn1p_expr_t *expr; + + expr = calloc(1, sizeof *expr); + if(expr) { + TQ_INIT(&(expr->members)); + expr->_lineno = _lineno; + } + + return expr; +} + +asn1p_expr_t * +asn1p_expr_clone(asn1p_expr_t *expr) { + asn1p_expr_t *clone; + asn1p_expr_t *tcmemb; /* Child of tc */ + + clone = asn1p_expr_new(expr->_lineno); + if(clone == NULL) return NULL; + +#define CLCOPY(field) do { clone->field = expr->field; } while(0) +#define CLCLONE(field, func) do { if(expr->field) { \ + clone->field = func(expr->field); \ + if(clone->field == NULL) { \ + asn1p_expr_free(clone); \ + return NULL; \ + } \ + } } while(0) + + /* + * Copy simple fields. + */ + CLCOPY(meta_type); + CLCOPY(expr_type); + CLCOPY(tag); + CLCOPY(marker); + CLCOPY(_mark); + + clone->data = 0; /* Do not clone this */ + clone->data_free = 0; /* Do not clone this */ + + /* + * Clone complex fields. + */ + CLCLONE(Identifier, strdup); + CLCLONE(reference, asn1p_ref_clone); + CLCLONE(constraints, asn1p_constraint_clone); + CLCLONE(params, asn1p_paramlist_clone); + CLCLONE(value, asn1p_value_clone); + CLCLONE(with_syntax, asn1p_wsyntx_clone); + + /* + * Copy all the children of this expr. + */ + TQ_FOR(tcmemb, &(expr->members), next) { + asn1p_expr_t *cmemb = asn1p_expr_clone(tcmemb); + if(cmemb == NULL) { + asn1p_expr_free(clone); + return NULL; + } + TQ_ADD(&(clone->members), cmemb, next); + } + + return clone; +} + +/* + * Destruct the types collection structure. + */ +void +asn1p_expr_free(asn1p_expr_t *expr) { + if(expr) { + asn1p_expr_t *tm; + + if(expr->Identifier) + free(expr->Identifier); + if(expr->reference) + asn1p_ref_free(expr->reference); + if(expr->constraints) + asn1p_constraint_free(expr->constraints); + if(expr->params) + asn1p_paramlist_free(expr->params); + if(expr->value) + asn1p_value_free(expr->value); + if(expr->with_syntax) + asn1p_wsyntx_free(expr->with_syntax); + + /* Remove all children */ + while((tm = TQ_REMOVE(&(expr->members), next))) { + asn1p_expr_free(tm); + } + + if(expr->data && expr->data_free) + expr->data_free(expr->data); + + memset(expr, 0, sizeof(*expr)); + free(expr); + } +} + diff --git a/libasn1parser/asn1p_expr.h b/libasn1parser/asn1p_expr.h new file mode 100644 index 00000000..331285c7 --- /dev/null +++ b/libasn1parser/asn1p_expr.h @@ -0,0 +1,214 @@ +/* + * A collection of data members of unspecified types. + */ +#ifndef ASN1_PARSER_EXPR_H +#define ASN1_PARSER_EXPR_H + +/* + * Meta type of the ASN expression. + */ +typedef enum asn1p_expr_meta { + AMT_INVALID, + AMT_TYPE, /* Type1 ::= INTEGER */ + AMT_TYPEREF, /* Type2 ::= Type1 */ + AMT_PARAMTYPE, /* Type3{Parameter} ::= SET { ... } */ + AMT_VALUE, /* value1 Type1 ::= 1 */ + AMT_VALUESET, /* ValueSet Type1 ::= { value1 } */ + AMT_OBJECT, /* FUNCTION ::= CLASS {...} */ + AMT_OBJECTSET, /* Functions FUNCTION ::= {...} */ + AMT_OBJECTFIELD, /* ... */ + AMT_EXPR_META_MAX +} asn1p_expr_meta_e; + +/* + * ASN type of the expression. + */ +typedef enum asn1p_expr_type { + /* + * Internal types. + */ + A1TC_INVALID, /* Invalid type */ + A1TC_REFERENCE, /* Reference to the type defined elsewhere */ + A1TC_EXPORTVAR, /* We're exporting this definition */ + A1TC_UNIVERVAL, /* A value of an ENUMERATED, INTEGER or BS */ + A1TC_BOOLBITPOS, /* A bit position in a BIT STRING */ + A1TC_BITVECTOR, /* A plain collection of bits */ + A1TC_OPAQUE, /* Opaque data encoded as a bitvector */ + A1TC_EXTENSIBLE, /* An extension marker "..." */ + A1TC_PARAMETRIZED, /* A parametrized type declaration */ + A1TC_VALUESET, /* Value set definition */ + A1TC_CLASSDEF, /* Information Object Class */ + A1TC_CLASSFIELD, /* Information Object Class field */ + A1TC_INSTANCE, /* Instance of Object Class */ + A1TC_TYPEID, /* Type identifier */ + /* + * ASN.1 Constructed types + */ +#define ASN_CONSTR_MASK 0x10 /* Every constructed type */ + ASN_CONSTR_SEQUENCE = ASN_CONSTR_MASK, /* SEQUENCE */ + ASN_CONSTR_CHOICE, /* CHOICE */ + ASN_CONSTR_SET, /* SET */ + ASN_CONSTR_SEQUENCE_OF, /* SEQUENCE OF */ + ASN_CONSTR_SET_OF, /* SET OF */ + ASN_CONSTR_ANY, /* ANY (deprecated) */ + /* + * ASN.1 Basic types + */ +#define ASN_BASIC_MASK 0x20 /* Every basic type */ + ASN_BASIC_BOOLEAN = ASN_BASIC_MASK, + ASN_BASIC_NULL, + ASN_BASIC_INTEGER, + ASN_BASIC_REAL, + ASN_BASIC_ENUMERATED, + ASN_BASIC_BIT_STRING, + ASN_BASIC_OCTET_STRING, + ASN_BASIC_OBJECT_IDENTIFIER, + ASN_BASIC_RELATIVE_OID, + ASN_BASIC_EXTERNAL, + ASN_BASIC_EMBEDDED_PDV, + ASN_BASIC_CHARACTER_STRING, + ASN_BASIC_UTCTime, + ASN_BASIC_GeneralizedTime, + /* + * ASN.1 String types + */ +#define ASN_STRING_MASK 0x40 /* Every string type */ + ASN_STRING_BMPString = ASN_STRING_MASK, + ASN_STRING_GeneralString, + ASN_STRING_GraphicString, + ASN_STRING_IA5String, + ASN_STRING_ISO646String, + ASN_STRING_NumericString, + ASN_STRING_PrintableString, + ASN_STRING_TeletexString, + ASN_STRING_T61String, + ASN_STRING_UniversalString, + ASN_STRING_UTF8String, + ASN_STRING_VideotexString, + ASN_STRING_VisibleString, + ASN_STRING_ObjectDescriptor, + ASN_EXPR_TYPE_MAX +} asn1p_expr_type_e; + +#include "asn1p_expr_str.h" +#include "asn1p_expr2uclass.h" + +/* + * A named collection of types. + */ +typedef struct asn1p_expr_s { + + /* + * Human readable name. + */ + char *Identifier; + + /* + * Meta type of the expression (type, value, value set, etc). + */ + asn1p_expr_meta_e meta_type; + + /* + * ASN type of the expression. + */ + asn1p_expr_type_e expr_type; + + /* + * Referenced type, if defined elsewhere. + * (If expr_type == A1TC_REFERENCE) + */ + asn1p_ref_t *reference; + + /* + * Constraints for the type. + */ + asn1p_constraint_t *constraints; + + /* + * A list of parameters for parametrized type declaration + * (AMT_PARAMTYPE). + */ + asn1p_paramlist_t *params; + + /* + * The actual value (DefinedValue or inlined value). + */ + asn1p_value_t *value; + + /* + * The WITH SYHTAX clause. + */ + asn1p_wsyntx_t *with_syntax; + + /* + * A tag. + */ + struct asn1p_type_tag_s { + enum { + TC_NOCLASS, + TC_UNIVERSAL, + TC_APPLICATION, + TC_CONTEXT_SPECIFIC, + TC_PRIVATE, + } tag_class; + enum { + TM_DEFAULT, + TM_IMPLICIT, + TM_EXPLICIT, + } tag_mode; + asn1_integer_t tag_value; + } tag; + + /* + * Whether automatic tagging is applicable for subtypes. + */ + int auto_tags_OK; + + enum asn1p_expr_marker_e { + EM_NOMARK, + EM_OPTIONAL, + EM_DEFAULT, /* FIXME: store the value somewhere. */ + } marker; + int unique; /* UNIQUE */ + + /* + * Members of the constructed type. + */ + TQ_HEAD(struct asn1p_expr_s) members; + + /* + * Next expression in the list. + */ + TQ_ENTRY(struct asn1p_expr_s) next; + + /* + * Line number where this structure is defined in the original + * grammar source. + */ + int _lineno; + /* + * Marks are used for various purposes. + * Here are some predefined ones. + */ + enum { + TM_NOMARK, + TM_RECURSION, /* Used to break recursion */ + } _mark; + + /* + * Opaque data may be attached to this structure, + * probably by compiler. + */ + void *data; + void (*data_free)(void *data); +} asn1p_expr_t; + + +/* + * Constructor and destructor. + */ +asn1p_expr_t *asn1p_expr_new(int _lineno); +asn1p_expr_t *asn1p_expr_clone(asn1p_expr_t *); +void asn1p_expr_free(asn1p_expr_t *expr); + +#endif /* ASN1_PARSER_EXPR_H */ diff --git a/libasn1parser/asn1p_expr2uclass.h b/libasn1parser/asn1p_expr2uclass.h new file mode 100644 index 00000000..416c9f72 --- /dev/null +++ b/libasn1parser/asn1p_expr2uclass.h @@ -0,0 +1,41 @@ +#ifndef ASN1_PARSER_EXPR2UCLASS_H +#define ASN1_PARSER_EXPR2UCLASS_H + +static int +expr_type2uclass_value[ASN_EXPR_TYPE_MAX] + __attribute__ ((unused)) = { + [ ASN_BASIC_BOOLEAN ] = 1, + [ ASN_BASIC_INTEGER ] = 2, + [ ASN_BASIC_BIT_STRING ] = 3, + [ ASN_BASIC_OCTET_STRING ] = 4, + [ ASN_BASIC_NULL ] = 5, + [ ASN_BASIC_OBJECT_IDENTIFIER ] = 6, + [ ASN_BASIC_EXTERNAL ] = 7, + [ ASN_STRING_ObjectDescriptor ] = 7, + [ ASN_BASIC_REAL ] = 9, + [ ASN_BASIC_ENUMERATED ] = 10, + [ ASN_BASIC_EMBEDDED_PDV ] = 11, + [ ASN_STRING_UTF8String ] = 12, + [ ASN_BASIC_RELATIVE_OID ] = 13, + [ ASN_CONSTR_SEQUENCE ] = 16, + [ ASN_CONSTR_SEQUENCE_OF ] = 16, + [ ASN_CONSTR_SET ] = 17, + [ ASN_CONSTR_SET_OF ] = 17, + [ ASN_STRING_NumericString ] = 18, + [ ASN_STRING_PrintableString ] = 19, + [ ASN_STRING_TeletexString ] = 20, + [ ASN_STRING_T61String ] = 20, + [ ASN_STRING_VideotexString ] = 21, + [ ASN_STRING_IA5String ] = 22, + [ ASN_BASIC_UTCTime ] = 23, + [ ASN_BASIC_GeneralizedTime ] = 24, + [ ASN_STRING_GraphicString ] = 25, + [ ASN_STRING_VisibleString ] = 26, + [ ASN_STRING_ISO646String ] = 26, + [ ASN_STRING_GeneralString ] = 27, + [ ASN_STRING_UniversalString ] = 28, + [ ASN_BASIC_CHARACTER_STRING ] = 29, + [ ASN_STRING_BMPString ] = 30, +}; + +#endif /* ASN1_PARSER_EXPR2UCLASS_H */ diff --git a/libasn1parser/asn1p_expr_str.h b/libasn1parser/asn1p_expr_str.h new file mode 100644 index 00000000..02de131b --- /dev/null +++ b/libasn1parser/asn1p_expr_str.h @@ -0,0 +1,57 @@ +/* + * This file is automatically generated by ./expr-h.pl + * DO NOT EDIT MANUALLY, fix the ./expr-h.pl instead if necessary. + */ +#ifndef ASN1_PARSER_EXPR_STR_H +#define ASN1_PARSER_EXPR_STR_H + +static char *asn1p_expr_type2str[] __attribute__ ((unused)) = { + [ ASN_CONSTR_SEQUENCE ] = "SEQUENCE", + [ ASN_CONSTR_CHOICE ] = "CHOICE", + [ ASN_CONSTR_SET ] = "SET", + [ ASN_CONSTR_SEQUENCE_OF ] = "SEQUENCE OF", + [ ASN_CONSTR_SET_OF ] = "SET OF", + [ ASN_CONSTR_ANY ] = "ANY", + [ ASN_BASIC_BOOLEAN ] = "BOOLEAN", + [ ASN_BASIC_NULL ] = "NULL", + [ ASN_BASIC_INTEGER ] = "INTEGER", + [ ASN_BASIC_REAL ] = "REAL", + [ ASN_BASIC_ENUMERATED ] = "ENUMERATED", + [ ASN_BASIC_BIT_STRING ] = "BIT STRING", + [ ASN_BASIC_OCTET_STRING ] = "OCTET STRING", + [ ASN_BASIC_OBJECT_IDENTIFIER ] = "OBJECT IDENTIFIER", + [ ASN_BASIC_RELATIVE_OID ] = "RELATIVE-OID", + [ ASN_BASIC_EXTERNAL ] = "EXTERNAL", + [ ASN_BASIC_EMBEDDED_PDV ] = "EMBEDDED PDV", + [ ASN_BASIC_CHARACTER_STRING ] = "CHARACTER STRING", + [ ASN_BASIC_UTCTime ] = "UTCTime", + [ ASN_BASIC_GeneralizedTime ] = "GeneralizedTime", + [ ASN_STRING_BMPString ] = "BMPString", + [ ASN_STRING_GeneralString ] = "GeneralString", + [ ASN_STRING_GraphicString ] = "GraphicString", + [ ASN_STRING_IA5String ] = "IA5String", + [ ASN_STRING_ISO646String ] = "ISO646String", + [ ASN_STRING_NumericString ] = "NumericString", + [ ASN_STRING_PrintableString ] = "PrintableString", + [ ASN_STRING_TeletexString ] = "TeletexString", + [ ASN_STRING_T61String ] = "T61String", + [ ASN_STRING_UniversalString ] = "UniversalString", + [ ASN_STRING_UTF8String ] = "UTF8String", + [ ASN_STRING_VideotexString ] = "VideotexString", + [ ASN_STRING_VisibleString ] = "VisibleString", + [ ASN_STRING_ObjectDescriptor ] = "ObjectDescriptor", +}; + +/* + * Convert the ASN.1 expression type back into the string representation. + */ +#define ASN_EXPR_TYPE2STR(type) \ + ( \ + ((type) < 0 \ + || (type) >= sizeof(asn1p_expr_type2str) \ + / sizeof(asn1p_expr_type2str[0])) \ + ? (char *)0 \ + : asn1p_expr_type2str[(type)] \ + ) + +#endif /* ASN1_PARSER_EXPR_STR_H */ diff --git a/libasn1parser/asn1p_l.c b/libasn1parser/asn1p_l.c new file mode 100644 index 00000000..6a6eb446 --- /dev/null +++ b/libasn1parser/asn1p_l.c @@ -0,0 +1,3861 @@ +#define yy_create_buffer asn1p__create_buffer +#define yy_delete_buffer asn1p__delete_buffer +#define yy_scan_buffer asn1p__scan_buffer +#define yy_scan_string asn1p__scan_string +#define yy_scan_bytes asn1p__scan_bytes +#define yy_flex_debug asn1p__flex_debug +#define yy_init_buffer asn1p__init_buffer +#define yy_flush_buffer asn1p__flush_buffer +#define yy_load_buffer_state asn1p__load_buffer_state +#define yy_switch_to_buffer asn1p__switch_to_buffer +#define yyin asn1p_in +#define yyleng asn1p_leng +#define yylex asn1p_lex +#define yyout asn1p_out +#define yyrestart asn1p_restart +#define yytext asn1p_text +#define yylineno asn1p_lineno + +#line 20 "lex.yy.c" +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header$ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + + +#define YY_USES_REJECT + +#define yywrap() 1 +#define YY_SKIP_YYWRAP + +#define FLEX_DEBUG +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; + +#define FLEX_DEBUG +extern int yylineno; +int yylineno = 1; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 123 +#define YY_END_OF_BUFFER 124 +static yyconst short int yy_acclist[1196] = + { 0, + 124, 122, 123, 117, 122, 123, 117, 123, 116, 122, + 123, 15, 122, 123, 116, 122, 123, 122, 123, 116, + 122, 123, 122, 123, 116, 122, 123, 122, 123, 23, + 122, 123, 22, 122, 123, 116, 122, 123, 122, 123, + 111, 112, 122, 123, 111, 112, 122, 123, 111, 112, + 122, 123, 111, 112, 122, 123, 111, 112, 122, 123, + 111, 112, 122, 123, 111, 112, 122, 123, 111, 112, + 122, 123, 111, 112, 122, 123, 111, 112, 122, 123, + 111, 112, 122, 123, 111, 112, 122, 123, 111, 112, + 122, 123, 111, 112, 122, 123, 111, 112, 122, 123, + + 111, 112, 122, 123, 111, 112, 122, 123, 111, 112, + 122, 123, 111, 112, 122, 123, 116, 122, 123, 110, + 122, 123, 5, 122, 123, 2, 123, 2, 122, 123, + 4, 122, 123, 7, 9, 122, 123, 7, 123, 9, + 122, 123, 9, 122, 123, 17, 122, 123, 17, 123, + 18, 122, 123, 12, 122, 123, 12, 123, 14, 122, + 123, 14, 122, 123, 10, 122, 123, 11, 122, 123, + 119, 122, 123, 120, 122, 123, 120, 123, 122, 123, + 121, 122, 123, 117, 15, 15, 108, 109, 1, 21, + 115, 6, 22, 111, 112, 111, 112, 111, 112, 111, + + 112, 111, 112, 111, 112, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 36, 111, 112, 111, 112, 111, + 112, 111, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 111, 112, 111, 112, 112, 112, 111, 112, 111, + 112, 111, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 111, 112, 112, 111, 112, 111, 112, 79, 111, + 112, 111, 112, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 111, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 112, 111, 112, 111, 112, 112, 112, 111, 112, + + 110, 5, 3, 8, 17, 16, 12, 119, 120, 118, + 108, 109, 21, 114, 113, 111, 112, 28, 111, 112, + 29, 111, 112, 111, 112, 111, 112, 111, 112, 33, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 49, 111, 112, 111, 112, 111, 112, 111, + 112, 111, 112, 111, 112, 111, 112, 112, 112, 111, + 112, 111, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 111, 112, 71, 111, 112, 72, 111, 112, 111, + 112, 112, 111, 112, 111, 112, 111, 112, 112, 111, + + 112, 82, 111, 112, 111, 112, 111, 112, 111, 112, + 112, 111, 112, 111, 112, 111, 112, 90, 111, 112, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 112, 111, 112, 111, 112, 111, + 112, 112, 112, 112, 111, 112, 24, 13, 20, 19, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 111, 112, 57, 111, 112, 112, + + 112, 111, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 111, 112, 111, 112, 111, 112, 111, 112, 74, + 111, 112, 112, 111, 112, 111, 112, 111, 112, 112, + 111, 112, 111, 112, 111, 112, 111, 112, 112, 87, + 111, 112, 111, 112, 111, 112, 91, 111, 112, 111, + 112, 111, 112, 111, 112, 95, 111, 112, 97, 111, + 112, 111, 112, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 112, 112, 112, 107, 111, 112, + 111, 112, 111, 112, 111, 112, 111, 112, 32, 111, + 112, 112, 111, 112, 111, 112, 111, 112, 39, 111, + + 112, 111, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 111, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 111, 112, 111, 112, 111, 112, 56, 111, 112, + 112, 112, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 111, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 112, 111, 112, 78, 111, 112, 111, 112, 112, + 111, 112, 111, 112, 111, 112, 111, 112, 112, 111, + 112, 111, 112, 111, 112, 111, 112, 112, 111, 112, + 112, 99, 111, 112, 111, 112, 111, 112, 112, 111, + 112, 112, 112, 112, 25, 26, 111, 112, 111, 112, + + 111, 112, 111, 112, 112, 111, 112, 111, 112, 38, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + 51, 111, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 112, 112, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 111, 112, 112, 76, 111, 112, 111, 112, + 112, 111, 112, 111, 112, 111, 112, 111, 112, 112, + 111, 112, 111, 112, 92, 111, 112, 93, 111, 112, + 112, 111, 112, 112, 100, 111, 112, 111, 112, 112, + + 112, 112, 112, 112, 111, 112, 111, 112, 111, 112, + 112, 35, 111, 112, 111, 112, 111, 112, 111, 112, + 111, 112, 44, 111, 112, 45, 111, 112, 111, 112, + 111, 112, 48, 111, 112, 111, 112, 111, 112, 53, + 111, 112, 111, 112, 111, 112, 112, 112, 112, 111, + 112, 111, 112, 64, 111, 112, 65, 111, 112, 111, + 112, 111, 112, 68, 111, 112, 111, 112, 111, 112, + 111, 112, 112, 111, 112, 112, 81, 111, 112, 111, + 112, 84, 111, 112, 86, 111, 112, 112, 111, 112, + 111, 112, 112, 111, 112, 112, 111, 112, 103, 112, + + 112, 112, 112, 112, 111, 112, 111, 112, 111, 112, + 112, 111, 112, 111, 112, 111, 112, 111, 112, 111, + 112, 47, 111, 112, 111, 112, 52, 111, 112, 111, + 112, 55, 111, 112, 112, 112, 112, 112, 111, 112, + 63, 111, 112, 66, 111, 112, 67, 111, 112, 111, + 112, 112, 111, 112, 112, 80, 111, 112, 112, 111, + 112, 112, 111, 112, 89, 111, 112, 112, 111, 112, + 112, 111, 112, 112, 112, 112, 112, 111, 112, 111, + 112, 31, 111, 112, 34, 112, 37, 111, 112, 40, + 111, 112, 111, 112, 111, 112, 111, 112, 111, 112, + + 111, 112, 112, 112, 112, 61, 112, 111, 112, 111, + 112, 112, 111, 112, 112, 112, 111, 112, 112, 111, + 112, 94, 112, 111, 112, 112, 101, 111, 112, 112, + 112, 112, 112, 111, 112, 111, 112, 41, 111, 112, + 42, 111, 112, 43, 111, 112, 111, 112, 50, 111, + 112, 111, 112, 112, 112, 112, 62, 111, 112, 111, + 112, 112, 111, 112, 112, 112, 111, 112, 112, 111, + 112, 111, 112, 112, 104, 112, 112, 112, 112, 111, + 112, 30, 111, 112, 46, 111, 112, 111, 112, 112, + 112, 112, 111, 112, 112, 111, 112, 112, 112, 111, + + 112, 112, 111, 112, 111, 112, 112, 112, 112, 112, + 24, 25, 111, 112, 111, 112, 112, 112, 112, 69, + 111, 112, 70, 112, 111, 112, 112, 112, 111, 112, + 112, 88, 111, 112, 111, 112, 112, 112, 112, 112, + 111, 112, 54, 111, 112, 59, 112, 112, 60, 112, + 111, 112, 75, 112, 112, 83, 111, 112, 112, 111, + 112, 96, 112, 112, 112, 106, 112, 111, 112, 112, + 73, 111, 112, 112, 112, 111, 112, 112, 105, 112, + 27, 111, 112, 58, 112, 112, 85, 112, 98, 111, + 112, 102, 112, 77, 112 + + } ; + +static yyconst short int yy_accept[676] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 4, 7, 9, 12, 15, 18, + 20, 23, 25, 28, 30, 33, 36, 39, 41, 45, + 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, + 89, 93, 97, 101, 105, 109, 113, 117, 120, 123, + 126, 128, 131, 134, 138, 140, 143, 146, 149, 151, + 154, 157, 159, 162, 165, 168, 171, 174, 177, 179, + 181, 184, 184, 185, 186, 187, 187, 188, 188, 189, + 189, 189, 190, 191, 192, 193, 194, 194, 196, 198, + 200, 202, 204, 206, 207, 209, 211, 213, 215, 218, + + 220, 222, 224, 226, 228, 230, 232, 234, 236, 237, + 238, 240, 242, 244, 246, 248, 250, 252, 254, 255, + 257, 259, 262, 264, 265, 267, 269, 271, 273, 274, + 276, 278, 280, 282, 284, 286, 288, 290, 292, 293, + 295, 297, 298, 299, 301, 301, 301, 301, 301, 301, + 302, 303, 304, 305, 306, 307, 308, 308, 309, 310, + 311, 311, 312, 313, 313, 313, 314, 315, 316, 318, + 321, 324, 326, 328, 330, 333, 335, 337, 339, 341, + 343, 345, 347, 349, 351, 353, 356, 358, 360, 362, + 364, 366, 368, 369, 370, 372, 374, 376, 378, 380, + + 382, 384, 387, 390, 392, 393, 395, 397, 399, 400, + 402, 405, 407, 409, 411, 412, 414, 416, 418, 421, + 423, 425, 427, 429, 431, 433, 435, 436, 438, 440, + 442, 443, 444, 445, 447, 448, 448, 448, 448, 448, + 449, 449, 450, 451, 453, 455, 457, 459, 461, 463, + 465, 467, 469, 471, 473, 475, 477, 479, 481, 483, + 485, 487, 489, 491, 493, 495, 497, 500, 501, 502, + 504, 506, 508, 510, 512, 514, 516, 518, 520, 523, + 524, 526, 528, 530, 531, 533, 535, 537, 539, 540, + 543, 545, 547, 550, 552, 554, 556, 559, 562, 564, + + 565, 567, 569, 571, 573, 575, 576, 577, 578, 581, + 581, 581, 581, 581, 583, 585, 587, 589, 592, 593, + 595, 597, 599, 602, 604, 606, 608, 610, 612, 614, + 616, 618, 620, 622, 624, 626, 628, 631, 632, 633, + 634, 636, 638, 640, 642, 644, 646, 648, 650, 652, + 653, 655, 658, 660, 661, 663, 665, 667, 669, 670, + 672, 674, 676, 678, 679, 681, 682, 685, 687, 689, + 690, 692, 693, 694, 695, 696, 696, 696, 696, 699, + 701, 703, 705, 706, 708, 710, 713, 715, 717, 719, + 721, 723, 725, 727, 729, 731, 734, 736, 738, 740, + + 742, 743, 744, 745, 747, 749, 751, 753, 755, 757, + 759, 761, 763, 765, 766, 769, 771, 772, 774, 776, + 778, 780, 781, 783, 785, 788, 791, 792, 794, 795, + 798, 800, 801, 802, 803, 804, 805, 805, 805, 805, + 807, 809, 811, 812, 815, 817, 819, 821, 823, 826, + 829, 831, 833, 836, 838, 840, 843, 845, 847, 848, + 849, 850, 852, 854, 857, 860, 862, 864, 867, 869, + 871, 873, 874, 876, 877, 880, 882, 885, 888, 889, + 891, 893, 894, 896, 897, 899, 901, 902, 903, 904, + 905, 905, 905, 905, 907, 909, 911, 912, 914, 916, + + 918, 920, 922, 925, 927, 930, 932, 935, 936, 937, + 938, 939, 941, 944, 947, 950, 952, 953, 955, 956, + 959, 960, 962, 963, 965, 968, 969, 971, 972, 974, + 975, 976, 977, 978, 978, 978, 978, 980, 982, 985, + 987, 990, 993, 995, 997, 999, 1001, 1003, 1004, 1005, + 1006, 1008, 1010, 1012, 1013, 1015, 1016, 1017, 1019, 1020, + 1022, 1024, 1026, 1027, 1030, 1031, 1032, 1033, 1034, 1034, + 1034, 1034, 1036, 1038, 1041, 1044, 1047, 1049, 1052, 1054, + 1055, 1056, 1057, 1060, 1062, 1063, 1065, 1066, 1067, 1069, + 1070, 1072, 1074, 1075, 1077, 1078, 1079, 1080, 1080, 1080, + + 1080, 1082, 1085, 1088, 1090, 1091, 1092, 1093, 1095, 1096, + 1098, 1099, 1100, 1102, 1103, 1105, 1107, 1108, 1109, 1110, + 1111, 1111, 1113, 1113, 1115, 1117, 1118, 1119, 1120, 1123, + 1125, 1127, 1128, 1129, 1131, 1132, 1135, 1137, 1138, 1139, + 1140, 1141, 1141, 1143, 1146, 1148, 1149, 1151, 1153, 1155, + 1156, 1159, 1160, 1162, 1164, 1165, 1166, 1168, 1168, 1170, + 1171, 1174, 1175, 1176, 1178, 1179, 1181, 1184, 1186, 1187, + 1189, 1192, 1194, 1196, 1196 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 5, 6, 1, 1, 1, 7, 8, 9, + 9, 10, 1, 9, 11, 12, 13, 14, 15, 16, + 16, 17, 18, 19, 16, 20, 16, 21, 22, 23, + 24, 1, 1, 9, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 1, 52, 53, 1, 1, 54, 55, 56, 57, + + 58, 59, 60, 61, 62, 63, 59, 64, 65, 66, + 67, 68, 59, 69, 70, 71, 72, 73, 59, 74, + 59, 75, 76, 77, 78, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[79] = + { 0, + 1, 2, 3, 3, 1, 4, 5, 6, 1, 1, + 7, 1, 1, 8, 8, 8, 8, 8, 8, 8, + 9, 1, 1, 9, 8, 8, 8, 8, 8, 8, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 1, 1, 1, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 12, 1, 12 + } ; + +static yyconst short int yy_base[691] = + { 0, + 0, 0, 76, 78, 80, 81, 82, 89, 83, 93, + 96, 106, 844, 833, 116, 119, 822, 821, 177, 126, + 4166, 127, 816, 123, 4166, 134, 805, 4166, 242, 292, + 141, 298, 152, 314, 322, 130, 338, 359, 360, 376, + 382, 397, 410, 437, 440, 462, 463, 495, 0, 0, + 4166, 4166, 811, 4166, 4166, 807, 807, 0, 0, 809, + 0, 0, 787, 4166, 4166, 4166, 0, 160, 191, 104, + 4166, 800, 261, 0, 798, 797, 0, 79, 0, 426, + 793, 4166, 511, 787, 4166, 527, 771, 512, 513, 528, + 529, 544, 550, 0, 561, 567, 578, 589, 595, 611, + + 617, 628, 641, 644, 664, 661, 672, 685, 727, 737, + 696, 702, 713, 719, 730, 741, 747, 758, 725, 771, + 774, 787, 795, 725, 798, 811, 822, 835, 720, 851, + 857, 868, 874, 885, 900, 901, 916, 917, 716, 932, + 933, 716, 45, 948, 980, 987, 736, 97, 120, 0, + 0, 4166, 4166, 0, 4166, 0, 750, 0, 291, 4166, + 761, 0, 0, 79, 739, 994, 4166, 4166, 990, 1003, + 1011, 1014, 1027, 1035, 1038, 1051, 1059, 1067, 1075, 1088, + 1096, 1099, 1120, 1121, 1136, 1142, 1153, 1159, 1170, 1176, + 1187, 1198, 707, 693, 1211, 1219, 1222, 1237, 1240, 1243, + + 1267, 1261, 1264, 1282, 702, 1285, 1300, 1306, 696, 1317, + 1328, 1334, 1345, 1356, 686, 1367, 1373, 1384, 1390, 1405, + 1406, 1421, 1432, 1438, 1453, 1459, 692, 1470, 1481, 1492, + 675, 686, 681, 1503, 4166, 1542, 697, 143, 158, 4166, + 683, 4166, 4166, 1527, 1528, 1543, 1549, 1564, 1565, 1582, + 1581, 1597, 1603, 1614, 1625, 1643, 1640, 1646, 1661, 1664, + 1667, 1682, 1688, 1699, 1710, 1725, 1731, 664, 668, 1742, + 1748, 1763, 1764, 1779, 1785, 1796, 1809, 1817, 1825, 658, + 1840, 1843, 1856, 670, 1864, 1880, 1879, 1896, 649, 1897, + 1912, 1925, 1933, 1936, 1954, 1951, 1957, 1972, 1975, 648, + + 1978, 1993, 1999, 2010, 2016, 660, 649, 660, 2031, 2063, + 283, 280, 305, 2048, 2064, 2072, 2080, 2088, 644, 2096, + 2104, 2117, 2125, 2128, 2146, 2143, 2149, 2164, 2170, 2185, + 2186, 2201, 2216, 2222, 2233, 2239, 2254, 653, 641, 627, + 2255, 2275, 2272, 2293, 2292, 2310, 2309, 2325, 2331, 633, + 2342, 2353, 2359, 623, 2370, 2381, 2387, 2398, 639, 2411, + 2414, 2422, 2435, 616, 2446, 625, 2452, 2467, 2468, 613, + 2483, 607, 604, 610, 4166, 302, 321, 96, 2489, 2504, + 2507, 2515, 610, 2530, 2536, 2547, 2553, 2564, 2570, 2581, + 2592, 2598, 2615, 2621, 2637, 2638, 2653, 2654, 2669, 2675, + + 605, 607, 599, 2686, 2692, 2707, 2708, 2728, 2729, 2744, + 2752, 2765, 2773, 604, 2776, 2794, 631, 2791, 2797, 2812, + 2815, 603, 2823, 2838, 2841, 2844, 590, 2859, 574, 2862, + 2865, 588, 576, 574, 583, 581, 317, 309, 328, 2880, + 2883, 2896, 572, 2904, 2917, 2925, 2928, 2941, 2949, 2952, + 2965, 2976, 2973, 2989, 3000, 3011, 3017, 3028, 54, 589, + 564, 3034, 3045, 3056, 3062, 3073, 3079, 3094, 3095, 3110, + 3111, 583, 3126, 566, 3127, 3144, 3147, 3150, 558, 3165, + 3171, 554, 3186, 576, 3192, 0, 555, 559, 536, 566, + 347, 226, 339, 3203, 3209, 3224, 548, 3230, 3241, 3254, + + 3262, 3265, 3280, 3283, 3291, 3304, 3307, 531, 525, 525, + 531, 3322, 3328, 3339, 3345, 3356, 516, 3367, 512, 3373, + 511, 3384, 521, 3395, 3401, 517, 3412, 504, 3418, 506, + 507, 520, 466, 325, 465, 348, 3429, 3440, 3451, 0, + 3457, 3468, 3479, 3490, 3496, 3511, 3512, 467, 476, 464, + 0, 3527, 3528, 470, 3544, 450, 462, 3545, 474, 3560, + 0, 3566, 447, 3577, 444, 454, 423, 424, 361, 3616, + 353, 3601, 3602, 3617, 3618, 3633, 3634, 3649, 3650, 430, + 434, 428, 3665, 3673, 421, 3681, 421, 412, 3689, 403, + 3697, 3705, 410, 0, 400, 401, 403, 189, 3737, 519, + + 3722, 3723, 3738, 3746, 398, 417, 394, 3759, 398, 3767, + 391, 391, 3770, 383, 3783, 3794, 383, 378, 383, 378, + 371, 4166, 3833, 3818, 3819, 378, 363, 359, 3834, 0, + 3840, 357, 347, 3851, 351, 3857, 3868, 330, 315, 305, + 295, 558, 3884, 3881, 0, 282, 0, 3892, 0, 262, + 3907, 256, 3910, 0, 188, 141, 0, 3954, 3939, 138, + 3940, 120, 105, 3955, 95, 0, 3956, 0, 37, 0, + 3972, 0, 0, 4166, 4017, 4029, 4041, 4053, 4065, 4077, + 4088, 4089, 4093, 4104, 4116, 4128, 4139, 4144, 4149, 4154 + } ; + +static yyconst short int yy_def[691] = + { 0, + 674, 1, 675, 675, 676, 676, 677, 677, 678, 678, + 679, 679, 674, 674, 674, 674, 674, 680, 674, 681, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 682, 683, 684, + 674, 674, 674, 674, 674, 674, 674, 685, 685, 674, + 686, 686, 674, 674, 674, 674, 687, 674, 674, 19, + 674, 674, 674, 680, 680, 674, 688, 674, 689, 681, + 681, 674, 674, 674, 674, 674, 674, 29, 29, 29, + 29, 29, 29, 690, 29, 29, 29, 29, 29, 29, + + 29, 29, 29, 29, 29, 29, 29, 29, 690, 690, + 29, 29, 29, 29, 29, 29, 29, 29, 690, 29, + 29, 29, 29, 690, 29, 29, 29, 29, 690, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 690, 29, + 29, 690, 690, 29, 674, 682, 146, 146, 146, 683, + 684, 674, 674, 685, 674, 686, 674, 687, 674, 674, + 674, 688, 689, 674, 674, 674, 674, 674, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 690, 690, 29, 29, 29, 29, 29, 29, + + 29, 29, 29, 29, 690, 29, 29, 29, 690, 29, + 29, 29, 29, 29, 690, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 690, 29, 29, 29, + 690, 690, 690, 29, 674, 674, 146, 146, 146, 674, + 674, 674, 674, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 690, 690, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 690, + 29, 29, 29, 690, 29, 29, 29, 29, 690, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 690, + + 29, 29, 29, 29, 29, 690, 690, 690, 29, 674, + 146, 146, 146, 29, 29, 29, 29, 29, 690, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 690, 690, 690, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 690, + 29, 29, 29, 690, 29, 29, 29, 29, 690, 29, + 29, 29, 29, 690, 29, 690, 29, 29, 29, 690, + 29, 690, 690, 690, 674, 146, 146, 146, 29, 29, + 29, 29, 690, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + + 690, 690, 690, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 690, 29, 29, 690, 29, 29, 29, + 29, 690, 29, 29, 29, 29, 690, 29, 690, 29, + 29, 690, 690, 690, 690, 690, 146, 146, 146, 29, + 29, 29, 690, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 690, 690, + 690, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 690, 29, 690, 29, 29, 29, 29, 690, 29, + 29, 690, 29, 690, 29, 690, 690, 690, 690, 690, + 146, 146, 146, 29, 29, 29, 690, 29, 29, 29, + + 29, 29, 29, 29, 29, 29, 29, 690, 690, 690, + 690, 29, 29, 29, 29, 29, 690, 29, 690, 29, + 690, 29, 690, 29, 29, 690, 29, 690, 29, 690, + 690, 690, 690, 146, 146, 146, 29, 29, 29, 690, + 29, 29, 29, 29, 29, 29, 29, 690, 690, 690, + 690, 29, 29, 690, 29, 690, 690, 29, 690, 29, + 690, 29, 690, 29, 690, 690, 690, 690, 146, 674, + 146, 29, 29, 29, 29, 29, 29, 29, 29, 690, + 690, 690, 29, 29, 690, 29, 690, 690, 29, 690, + 29, 29, 690, 690, 690, 690, 690, 146, 674, 146, + + 29, 29, 29, 29, 690, 690, 690, 29, 690, 29, + 690, 690, 29, 690, 29, 29, 690, 690, 690, 690, + 146, 674, 674, 29, 29, 690, 690, 690, 29, 690, + 29, 690, 690, 29, 690, 29, 29, 690, 690, 690, + 690, 146, 29, 29, 690, 690, 690, 29, 690, 690, + 29, 690, 29, 690, 690, 690, 690, 674, 29, 690, + 29, 690, 690, 29, 690, 690, 29, 690, 690, 690, + 29, 690, 690, 0, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674 + } ; + +static yyconst short int yy_nxt[4245] = + { 0, + 14, 15, 16, 15, 17, 18, 19, 20, 21, 14, + 22, 23, 24, 25, 26, 26, 26, 26, 26, 26, + 27, 17, 28, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 36, 36, 36, 38, 39, 40, 41, + 36, 42, 43, 44, 45, 46, 47, 36, 36, 36, + 48, 17, 14, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 21, 17, 21, 51, 52, + 51, 52, 55, 55, 59, 62, 53, 60, 53, 56, + 56, 59, 57, 57, 60, 62, 508, 68, 69, 68, + + 76, 232, 70, 63, 242, 673, 64, 68, 69, 68, + 243, 674, 70, 63, 233, 509, 64, 73, 73, 73, + 73, 73, 73, 72, 439, 674, 72, 80, 80, 80, + 72, 78, 85, 72, 72, 147, 147, 82, 238, 80, + 80, 83, 83, 83, 83, 83, 83, 86, 86, 86, + 86, 86, 86, 86, 672, 88, 674, 239, 65, 147, + 66, 159, 159, 159, 670, 88, 88, 88, 65, 88, + 66, 28, 100, 71, 88, 312, 101, 88, 88, 102, + 88, 28, 147, 71, 72, 88, 669, 88, 104, 105, + 313, 88, 159, 159, 159, 668, 88, 147, 76, 106, + + 666, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 621, 147, 78, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 88, 665, 535, 88, 88, 88, 88, 88, + 88, 88, 73, 73, 73, 147, 88, 89, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 90, 88, 91, + 88, 92, 88, 88, 88, 88, 93, 88, 88, 88, + 88, 88, 159, 159, 159, 94, 94, 94, 94, 94, + + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 88, 376, 147, + 95, 663, 147, 88, 96, 377, 103, 88, 97, 88, + 98, 88, 662, 88, 437, 88, 88, 88, 107, 88, + 99, 147, 88, 491, 147, 438, 660, 88, 147, 88, + 378, 88, 492, 88, 657, 108, 147, 88, 88, 88, + 147, 88, 111, 88, 147, 112, 88, 147, 569, 493, + 656, 534, 571, 88, 113, 114, 655, 88, 147, 109, + 115, 536, 88, 116, 88, 88, 147, 147, 600, 654, + 110, 117, 147, 598, 88, 88, 88, 88, 88, 88, + + 147, 120, 121, 88, 118, 122, 125, 88, 642, 126, + 147, 88, 652, 88, 650, 123, 649, 127, 647, 88, + 88, 88, 88, 128, 646, 130, 88, 80, 80, 80, + 124, 119, 88, 164, 88, 88, 88, 645, 131, 80, + 80, 88, 132, 641, 640, 88, 639, 88, 638, 88, + 129, 635, 633, 133, 88, 135, 632, 630, 134, 628, + 627, 136, 88, 626, 620, 88, 570, 570, 570, 619, + 618, 617, 88, 614, 88, 88, 88, 140, 137, 88, + 612, 88, 611, 141, 88, 138, 609, 88, 88, 607, + 606, 605, 597, 596, 139, 144, 595, 88, 88, 88, + + 88, 88, 88, 594, 147, 142, 88, 88, 145, 145, + 145, 145, 145, 145, 145, 593, 590, 588, 587, 146, + 623, 623, 623, 143, 166, 166, 166, 166, 166, 166, + 166, 585, 582, 581, 148, 580, 568, 88, 88, 149, + 86, 86, 86, 86, 86, 86, 86, 88, 88, 88, + 88, 88, 88, 88, 88, 169, 88, 88, 147, 658, + 658, 658, 567, 170, 88, 88, 88, 88, 88, 88, + 566, 565, 88, 88, 563, 88, 561, 171, 559, 88, + 557, 88, 556, 172, 554, 88, 88, 88, 88, 88, + 551, 174, 88, 173, 88, 550, 88, 147, 88, 549, + + 88, 548, 88, 88, 88, 88, 88, 540, 533, 532, + 175, 88, 531, 88, 88, 88, 530, 176, 528, 526, + 88, 523, 88, 521, 88, 519, 88, 177, 88, 511, + 88, 510, 88, 88, 88, 178, 88, 497, 490, 88, + 489, 180, 88, 488, 487, 486, 88, 484, 88, 179, + 88, 482, 88, 88, 88, 88, 88, 479, 474, 472, + 461, 88, 460, 88, 181, 182, 88, 88, 459, 184, + 183, 443, 88, 436, 435, 434, 88, 432, 88, 88, + 88, 88, 429, 88, 427, 88, 88, 188, 88, 88, + 185, 186, 422, 417, 414, 403, 88, 88, 88, 88, + + 189, 88, 402, 88, 190, 88, 401, 191, 187, 88, + 88, 88, 383, 195, 374, 373, 88, 372, 366, 359, + 88, 88, 88, 192, 88, 354, 350, 88, 339, 88, + 196, 88, 338, 88, 160, 88, 311, 88, 88, 88, + 88, 88, 308, 307, 88, 198, 88, 306, 88, 300, + 88, 289, 197, 284, 88, 88, 88, 88, 88, 280, + 269, 199, 200, 88, 268, 88, 88, 88, 201, 88, + 243, 241, 88, 240, 88, 147, 88, 231, 88, 227, + 88, 215, 88, 88, 203, 88, 88, 209, 202, 205, + 194, 88, 193, 204, 168, 88, 88, 88, 167, 88, + + 165, 161, 88, 160, 206, 160, 88, 157, 88, 88, + 88, 88, 88, 88, 155, 88, 85, 207, 88, 153, + 88, 152, 88, 88, 88, 87, 88, 84, 75, 72, + 88, 88, 88, 88, 88, 88, 88, 88, 208, 88, + 72, 210, 88, 674, 674, 674, 88, 88, 88, 674, + 88, 674, 674, 674, 674, 88, 211, 88, 674, 88, + 88, 88, 674, 213, 674, 674, 212, 214, 674, 674, + 88, 674, 88, 674, 88, 216, 88, 674, 674, 88, + 674, 674, 88, 674, 674, 674, 217, 674, 88, 674, + 88, 674, 88, 88, 88, 88, 88, 218, 674, 88, + + 219, 88, 674, 88, 674, 88, 674, 88, 674, 88, + 88, 88, 88, 88, 223, 221, 674, 220, 88, 674, + 88, 674, 222, 674, 88, 88, 88, 674, 674, 88, + 674, 224, 674, 674, 674, 88, 88, 88, 88, 88, + 88, 88, 88, 674, 88, 88, 674, 674, 674, 674, + 674, 88, 88, 88, 88, 88, 226, 88, 88, 229, + 225, 88, 230, 674, 228, 674, 674, 88, 88, 88, + 88, 88, 88, 88, 674, 674, 88, 88, 674, 674, + 674, 674, 674, 88, 674, 88, 674, 88, 236, 236, + 236, 234, 88, 145, 145, 145, 145, 145, 145, 145, + + 674, 674, 674, 674, 674, 674, 674, 166, 166, 166, + 166, 166, 166, 166, 674, 88, 674, 674, 244, 674, + 674, 674, 674, 674, 674, 88, 237, 88, 88, 88, + 674, 235, 674, 245, 88, 674, 88, 674, 88, 88, + 88, 674, 88, 674, 674, 674, 88, 88, 88, 246, + 88, 88, 88, 88, 674, 88, 674, 674, 88, 674, + 88, 674, 88, 88, 88, 247, 88, 248, 674, 674, + 88, 88, 88, 88, 88, 88, 88, 88, 674, 88, + 674, 674, 88, 674, 88, 674, 88, 674, 88, 674, + 88, 674, 88, 249, 250, 88, 88, 674, 88, 674, + + 88, 674, 88, 88, 88, 674, 88, 252, 251, 674, + 88, 88, 88, 88, 88, 674, 674, 674, 674, 88, + 674, 88, 674, 88, 88, 88, 674, 88, 674, 674, + 253, 88, 88, 88, 88, 254, 88, 674, 88, 674, + 88, 255, 256, 88, 257, 88, 88, 674, 674, 259, + 674, 674, 258, 674, 674, 88, 88, 88, 88, 88, + 88, 88, 674, 674, 88, 88, 674, 88, 674, 674, + 674, 88, 674, 88, 260, 88, 674, 88, 88, 88, + 88, 88, 674, 674, 88, 674, 88, 262, 88, 261, + 88, 674, 88, 674, 88, 88, 88, 88, 88, 674, + + 674, 88, 674, 88, 265, 263, 674, 88, 264, 88, + 674, 88, 88, 88, 88, 88, 674, 674, 674, 674, + 88, 674, 88, 88, 88, 674, 88, 674, 674, 266, + 674, 88, 674, 88, 267, 88, 88, 88, 674, 674, + 674, 674, 88, 674, 88, 674, 88, 88, 88, 674, + 88, 674, 674, 270, 88, 88, 271, 272, 88, 88, + 273, 88, 88, 88, 674, 88, 88, 674, 88, 674, + 674, 276, 274, 674, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 275, 88, 277, 88, 88, 674, 88, + 674, 674, 88, 674, 674, 674, 88, 674, 88, 88, + + 88, 88, 88, 88, 88, 88, 88, 88, 278, 674, + 88, 88, 674, 281, 674, 674, 674, 279, 674, 88, + 88, 88, 88, 674, 88, 88, 88, 674, 282, 88, + 674, 88, 674, 674, 674, 88, 674, 88, 283, 88, + 674, 88, 88, 88, 88, 88, 674, 674, 674, 674, + 88, 674, 88, 88, 88, 674, 88, 674, 674, 88, + 285, 88, 674, 88, 674, 88, 674, 88, 674, 88, + 88, 88, 88, 88, 674, 674, 286, 674, 88, 674, + 88, 88, 88, 674, 88, 674, 674, 287, 674, 88, + 674, 88, 88, 88, 674, 88, 674, 291, 88, 674, + + 88, 288, 290, 674, 88, 674, 88, 674, 88, 88, + 88, 88, 88, 674, 674, 88, 674, 88, 674, 88, + 674, 88, 674, 88, 674, 88, 674, 88, 292, 88, + 88, 88, 674, 293, 88, 674, 674, 674, 294, 674, + 88, 88, 88, 88, 88, 88, 88, 674, 674, 88, + 88, 674, 674, 674, 674, 674, 88, 88, 88, 674, + 88, 674, 674, 88, 295, 88, 674, 88, 674, 88, + 674, 88, 674, 88, 296, 88, 88, 88, 88, 674, + 297, 298, 88, 674, 88, 674, 674, 299, 88, 674, + 88, 674, 88, 674, 88, 88, 88, 88, 88, 674, + + 674, 674, 674, 88, 674, 88, 88, 88, 301, 88, + 302, 305, 674, 674, 88, 303, 88, 88, 88, 674, + 88, 674, 674, 674, 304, 88, 674, 88, 88, 88, + 674, 88, 674, 674, 309, 674, 88, 674, 88, 674, + 88, 674, 88, 236, 236, 236, 674, 88, 674, 674, + 674, 674, 88, 88, 674, 310, 310, 310, 310, 310, + 310, 310, 88, 88, 314, 88, 88, 88, 88, 315, + 674, 88, 88, 674, 88, 316, 674, 674, 88, 674, + 88, 674, 88, 674, 88, 317, 88, 88, 88, 88, + 88, 674, 674, 88, 674, 674, 674, 674, 674, 88, + + 88, 318, 88, 88, 88, 321, 88, 88, 88, 88, + 320, 674, 674, 674, 674, 674, 88, 88, 88, 88, + 88, 88, 88, 322, 674, 88, 88, 674, 88, 674, + 674, 674, 88, 674, 88, 319, 88, 674, 88, 88, + 88, 88, 88, 674, 674, 323, 674, 88, 674, 88, + 88, 88, 324, 88, 674, 674, 674, 674, 88, 674, + 88, 674, 88, 674, 88, 88, 325, 326, 88, 88, + 674, 88, 674, 674, 674, 88, 674, 88, 88, 88, + 88, 88, 88, 328, 327, 88, 88, 88, 329, 88, + 88, 330, 88, 674, 674, 331, 88, 674, 88, 88, + + 88, 88, 88, 88, 88, 88, 88, 88, 88, 674, + 674, 88, 674, 88, 674, 674, 674, 88, 674, 88, + 333, 332, 674, 88, 88, 88, 88, 88, 674, 674, + 674, 674, 88, 674, 88, 88, 88, 674, 88, 674, + 334, 674, 674, 88, 674, 88, 674, 335, 674, 88, + 88, 336, 674, 337, 88, 674, 88, 674, 674, 674, + 88, 674, 88, 674, 88, 674, 88, 88, 88, 88, + 88, 674, 674, 88, 674, 88, 674, 88, 674, 88, + 674, 88, 674, 88, 674, 88, 88, 88, 88, 88, + 674, 341, 88, 674, 674, 342, 674, 674, 88, 88, + + 88, 88, 88, 88, 88, 343, 674, 88, 88, 345, + 88, 674, 340, 674, 88, 674, 88, 674, 88, 674, + 88, 88, 88, 344, 88, 348, 346, 674, 674, 88, + 674, 88, 674, 88, 88, 88, 674, 347, 674, 674, + 88, 674, 88, 674, 88, 674, 88, 674, 88, 674, + 88, 674, 88, 88, 88, 674, 88, 674, 674, 349, + 88, 88, 88, 674, 88, 88, 351, 674, 88, 88, + 674, 674, 674, 674, 674, 88, 674, 88, 88, 88, + 88, 88, 88, 674, 88, 674, 352, 88, 674, 88, + 356, 88, 355, 88, 353, 88, 674, 674, 674, 88, + + 88, 88, 674, 88, 88, 88, 674, 357, 88, 674, + 674, 674, 674, 674, 88, 88, 88, 88, 88, 88, + 358, 88, 88, 88, 88, 674, 674, 674, 674, 674, + 674, 88, 88, 88, 88, 88, 88, 88, 674, 674, + 88, 88, 674, 674, 674, 674, 674, 88, 674, 88, + 88, 88, 674, 361, 674, 360, 88, 674, 88, 674, + 88, 88, 88, 674, 88, 674, 674, 674, 88, 88, + 88, 88, 88, 362, 674, 88, 88, 88, 363, 88, + 88, 674, 88, 674, 674, 365, 88, 674, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 674, + + 88, 88, 674, 88, 674, 674, 674, 88, 674, 88, + 88, 88, 88, 88, 88, 367, 88, 88, 88, 88, + 674, 364, 88, 674, 88, 674, 674, 369, 88, 674, + 88, 674, 88, 674, 88, 88, 88, 368, 88, 674, + 674, 88, 674, 88, 674, 88, 674, 88, 674, 88, + 674, 88, 674, 88, 88, 88, 88, 674, 371, 674, + 88, 674, 674, 674, 674, 674, 88, 674, 88, 674, + 88, 370, 674, 88, 674, 88, 310, 310, 310, 310, + 310, 310, 310, 88, 674, 88, 674, 88, 380, 88, + 674, 379, 88, 674, 674, 674, 674, 88, 381, 88, + + 674, 88, 674, 88, 382, 88, 674, 88, 88, 88, + 674, 88, 674, 88, 375, 88, 88, 88, 674, 88, + 384, 88, 674, 88, 88, 88, 674, 88, 674, 88, + 385, 88, 88, 88, 674, 88, 674, 674, 674, 88, + 88, 88, 88, 88, 674, 386, 674, 674, 88, 674, + 88, 674, 88, 88, 88, 674, 88, 674, 674, 674, + 88, 88, 88, 88, 88, 387, 674, 88, 88, 88, + 388, 88, 88, 674, 88, 389, 674, 674, 88, 674, + 88, 88, 88, 88, 390, 88, 88, 88, 88, 88, + 88, 674, 391, 88, 674, 88, 392, 393, 674, 88, + + 674, 88, 674, 88, 674, 88, 674, 88, 88, 88, + 88, 88, 674, 394, 88, 674, 674, 674, 674, 674, + 88, 88, 88, 88, 88, 88, 88, 395, 674, 88, + 88, 674, 674, 674, 674, 674, 88, 674, 88, 674, + 88, 88, 397, 674, 396, 88, 674, 88, 674, 674, + 674, 88, 674, 88, 674, 88, 674, 88, 88, 88, + 88, 88, 674, 674, 88, 398, 88, 674, 88, 674, + 88, 674, 88, 674, 88, 399, 400, 88, 88, 88, + 88, 674, 674, 88, 674, 674, 674, 404, 674, 88, + 88, 88, 88, 88, 88, 674, 674, 88, 88, 88, + + 88, 405, 674, 406, 674, 674, 674, 88, 674, 88, + 88, 88, 88, 674, 88, 407, 88, 88, 88, 88, + 408, 674, 674, 674, 674, 674, 674, 88, 88, 409, + 88, 88, 88, 674, 88, 88, 88, 88, 410, 674, + 674, 413, 674, 412, 88, 88, 88, 88, 88, 88, + 88, 411, 674, 88, 88, 674, 88, 674, 674, 674, + 88, 674, 88, 674, 88, 674, 88, 88, 88, 88, + 88, 674, 674, 674, 674, 88, 674, 88, 88, 88, + 674, 88, 674, 674, 88, 415, 88, 674, 88, 674, + 88, 674, 88, 674, 88, 88, 416, 88, 88, 674, + + 674, 674, 674, 88, 674, 88, 88, 88, 674, 88, + 674, 418, 88, 419, 88, 674, 88, 674, 88, 674, + 88, 674, 88, 88, 420, 88, 88, 674, 674, 674, + 674, 88, 674, 88, 674, 88, 88, 88, 674, 88, + 674, 421, 88, 423, 674, 674, 88, 88, 88, 88, + 88, 424, 425, 88, 674, 88, 674, 88, 88, 88, + 88, 88, 674, 674, 674, 674, 88, 674, 674, 674, + 88, 88, 88, 674, 88, 674, 674, 88, 428, 88, + 674, 88, 426, 88, 674, 88, 674, 88, 674, 88, + 88, 88, 88, 88, 674, 430, 88, 674, 674, 674, + + 674, 674, 88, 88, 88, 88, 88, 88, 88, 431, + 674, 88, 88, 674, 88, 674, 674, 674, 88, 674, + 88, 674, 88, 674, 88, 674, 88, 88, 88, 88, + 440, 441, 88, 88, 674, 674, 674, 674, 674, 88, + 88, 88, 88, 88, 88, 674, 88, 674, 88, 674, + 88, 88, 88, 433, 88, 88, 674, 674, 442, 88, + 674, 88, 674, 674, 674, 88, 674, 444, 674, 88, + 674, 88, 88, 88, 88, 88, 674, 674, 88, 445, + 88, 446, 88, 674, 88, 674, 88, 674, 88, 88, + 88, 88, 88, 674, 674, 88, 447, 88, 674, 88, + + 674, 88, 674, 88, 674, 88, 88, 448, 88, 88, + 674, 674, 674, 674, 88, 674, 88, 88, 88, 450, + 88, 674, 674, 88, 449, 88, 674, 88, 674, 88, + 674, 88, 674, 88, 674, 88, 88, 88, 674, 674, + 88, 451, 88, 452, 674, 674, 88, 674, 453, 674, + 88, 674, 88, 674, 88, 674, 88, 674, 88, 88, + 88, 454, 88, 88, 674, 88, 674, 674, 674, 674, + 674, 674, 88, 88, 88, 88, 88, 88, 88, 88, + 674, 88, 88, 674, 674, 455, 674, 674, 88, 88, + 88, 88, 88, 88, 88, 674, 456, 88, 88, 458, + + 88, 457, 674, 674, 88, 674, 88, 674, 88, 674, + 88, 88, 88, 88, 88, 462, 674, 88, 674, 88, + 674, 88, 674, 88, 463, 88, 674, 88, 674, 88, + 88, 88, 88, 88, 464, 674, 88, 674, 674, 674, + 674, 674, 88, 88, 88, 88, 88, 88, 674, 674, + 465, 88, 88, 88, 88, 467, 466, 674, 674, 674, + 674, 674, 674, 88, 88, 88, 88, 88, 88, 88, + 674, 674, 88, 88, 674, 674, 674, 88, 674, 88, + 469, 88, 674, 88, 674, 468, 674, 88, 88, 88, + 88, 88, 674, 674, 674, 674, 88, 674, 88, 674, + + 88, 88, 88, 674, 88, 471, 674, 470, 88, 88, + 88, 88, 88, 88, 674, 88, 88, 88, 473, 88, + 88, 674, 88, 674, 674, 674, 88, 674, 475, 88, + 88, 88, 88, 88, 476, 88, 88, 88, 88, 674, + 88, 88, 674, 478, 674, 674, 674, 88, 88, 88, + 88, 88, 88, 674, 88, 477, 88, 674, 88, 88, + 88, 674, 88, 88, 481, 674, 88, 88, 480, 88, + 674, 674, 674, 88, 674, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 483, 88, 88, 674, + 88, 674, 674, 674, 88, 674, 88, 88, 88, 88, + + 88, 88, 88, 88, 88, 88, 88, 485, 88, 88, + 674, 674, 674, 674, 674, 88, 674, 88, 88, 88, + 88, 88, 88, 494, 88, 674, 495, 88, 496, 88, + 674, 88, 674, 88, 674, 88, 674, 674, 674, 88, + 88, 88, 88, 88, 674, 498, 674, 674, 88, 674, + 88, 674, 88, 88, 88, 674, 88, 674, 674, 674, + 88, 88, 499, 88, 88, 500, 88, 88, 674, 88, + 674, 674, 88, 501, 88, 674, 88, 88, 88, 674, + 88, 674, 674, 674, 88, 88, 88, 88, 88, 88, + 88, 88, 674, 88, 674, 674, 88, 502, 88, 674, + + 88, 88, 88, 503, 88, 674, 674, 674, 88, 88, + 88, 88, 88, 88, 88, 88, 674, 88, 674, 674, + 88, 674, 674, 674, 88, 88, 88, 674, 88, 674, + 674, 674, 504, 88, 674, 88, 88, 88, 674, 88, + 674, 674, 506, 505, 88, 674, 88, 674, 88, 674, + 88, 674, 88, 88, 88, 88, 88, 674, 674, 88, + 674, 88, 674, 507, 674, 88, 512, 88, 674, 88, + 88, 88, 88, 88, 674, 674, 674, 674, 88, 674, + 88, 88, 88, 674, 88, 674, 674, 88, 513, 88, + 674, 88, 674, 88, 674, 88, 674, 88, 88, 88, + + 88, 88, 674, 674, 88, 674, 88, 515, 88, 674, + 88, 674, 88, 674, 88, 514, 88, 88, 88, 88, + 88, 516, 674, 88, 674, 674, 674, 674, 674, 88, + 88, 88, 88, 88, 88, 88, 88, 674, 88, 88, + 674, 674, 674, 674, 674, 88, 88, 88, 518, 88, + 88, 88, 88, 674, 88, 88, 674, 674, 674, 674, + 674, 520, 88, 88, 88, 88, 88, 674, 674, 88, + 88, 88, 88, 522, 674, 88, 674, 674, 674, 88, + 517, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 674, 524, 88, 674, 88, 674, 674, 525, + + 88, 674, 88, 674, 88, 674, 88, 674, 88, 88, + 88, 88, 674, 537, 527, 88, 529, 88, 674, 674, + 674, 88, 674, 88, 674, 88, 674, 88, 88, 88, + 88, 88, 674, 674, 88, 674, 88, 674, 88, 674, + 88, 538, 88, 674, 88, 674, 88, 88, 88, 88, + 539, 674, 674, 88, 674, 88, 674, 674, 674, 88, + 674, 88, 674, 88, 674, 88, 88, 88, 88, 88, + 674, 541, 674, 674, 88, 674, 88, 674, 88, 88, + 88, 674, 543, 674, 542, 88, 674, 88, 674, 88, + 88, 88, 674, 88, 674, 674, 674, 88, 88, 544, + + 88, 88, 88, 545, 88, 88, 88, 674, 88, 88, + 674, 546, 674, 674, 674, 88, 88, 88, 88, 88, + 88, 674, 88, 674, 88, 674, 88, 88, 88, 88, + 88, 674, 88, 674, 674, 88, 547, 674, 674, 88, + 674, 88, 88, 88, 88, 674, 88, 88, 88, 674, + 552, 88, 674, 88, 674, 674, 674, 88, 674, 88, + 674, 88, 674, 88, 88, 88, 88, 88, 674, 674, + 88, 674, 88, 674, 88, 674, 88, 674, 88, 674, + 88, 88, 88, 88, 88, 674, 674, 674, 674, 88, + 674, 88, 88, 88, 674, 88, 555, 674, 88, 553, + + 88, 674, 88, 674, 88, 560, 88, 674, 88, 88, + 88, 88, 88, 674, 674, 674, 558, 88, 674, 88, + 88, 88, 674, 88, 674, 674, 88, 674, 88, 674, + 88, 674, 88, 674, 88, 674, 88, 88, 88, 88, + 88, 674, 674, 88, 674, 88, 674, 88, 674, 562, + 674, 88, 674, 564, 88, 88, 88, 88, 674, 674, + 674, 674, 88, 674, 88, 88, 88, 674, 88, 674, + 674, 572, 674, 88, 674, 88, 88, 88, 573, 88, + 674, 674, 88, 674, 88, 674, 88, 674, 88, 674, + 88, 674, 88, 88, 88, 88, 88, 674, 674, 674, + + 674, 88, 674, 88, 88, 88, 575, 88, 674, 674, + 574, 674, 88, 674, 88, 88, 88, 674, 88, 674, + 576, 88, 674, 88, 674, 88, 674, 88, 674, 88, + 674, 88, 674, 577, 88, 88, 88, 88, 578, 674, + 88, 674, 674, 674, 674, 674, 88, 579, 88, 88, + 88, 88, 88, 88, 674, 88, 88, 674, 674, 674, + 584, 674, 88, 88, 88, 88, 88, 88, 583, 88, + 88, 88, 88, 674, 674, 674, 586, 674, 674, 88, + 88, 88, 589, 88, 88, 88, 674, 674, 88, 88, + 674, 88, 674, 674, 674, 88, 674, 88, 591, 88, + + 674, 88, 88, 88, 88, 88, 674, 674, 674, 592, + 88, 674, 88, 674, 88, 674, 88, 570, 570, 570, + 674, 88, 674, 674, 674, 674, 88, 88, 674, 599, + 599, 599, 599, 599, 599, 599, 88, 88, 88, 602, + 88, 88, 88, 88, 674, 88, 88, 674, 674, 601, + 674, 674, 88, 88, 88, 88, 88, 88, 88, 88, + 674, 88, 88, 674, 674, 674, 674, 674, 88, 88, + 88, 88, 88, 88, 88, 88, 603, 88, 88, 674, + 674, 674, 604, 674, 88, 88, 88, 88, 88, 88, + 88, 674, 674, 88, 88, 674, 674, 674, 88, 674, + + 88, 674, 88, 674, 88, 674, 88, 674, 88, 88, + 88, 608, 88, 674, 88, 674, 88, 88, 610, 674, + 88, 613, 88, 674, 88, 88, 88, 674, 88, 615, + 88, 674, 88, 88, 88, 674, 88, 616, 674, 674, + 88, 88, 88, 674, 88, 674, 674, 88, 88, 88, + 599, 599, 599, 599, 599, 599, 599, 88, 88, 624, + 88, 88, 88, 88, 674, 674, 88, 88, 674, 674, + 674, 88, 674, 88, 674, 88, 674, 88, 674, 674, + 674, 88, 88, 88, 88, 88, 674, 674, 622, 625, + 88, 674, 88, 674, 88, 88, 629, 674, 88, 631, + + 674, 674, 88, 88, 88, 88, 88, 88, 88, 88, + 636, 88, 674, 634, 88, 674, 674, 674, 88, 88, + 88, 674, 88, 637, 674, 674, 674, 88, 674, 88, + 674, 88, 674, 88, 623, 623, 623, 674, 88, 674, + 674, 674, 674, 88, 88, 674, 599, 599, 599, 599, + 599, 599, 599, 88, 88, 88, 88, 88, 88, 88, + 674, 643, 88, 88, 674, 88, 674, 644, 674, 88, + 674, 88, 674, 88, 674, 88, 88, 88, 88, 88, + 674, 674, 88, 648, 88, 674, 88, 674, 88, 674, + 88, 674, 88, 88, 88, 88, 88, 674, 674, 651, + + 653, 88, 674, 88, 674, 88, 88, 88, 659, 88, + 674, 674, 88, 674, 674, 674, 88, 88, 88, 88, + 88, 88, 674, 88, 674, 88, 674, 88, 88, 88, + 674, 88, 88, 674, 674, 88, 88, 674, 664, 674, + 661, 674, 88, 674, 88, 88, 88, 88, 674, 88, + 674, 88, 674, 674, 88, 658, 658, 658, 674, 674, + 674, 674, 674, 674, 88, 88, 674, 599, 599, 599, + 599, 599, 599, 599, 88, 88, 88, 88, 88, 88, + 88, 88, 674, 88, 88, 674, 667, 674, 674, 674, + 88, 88, 88, 88, 88, 88, 671, 88, 674, 88, + + 88, 674, 674, 674, 674, 674, 674, 88, 674, 88, + 674, 88, 674, 674, 674, 674, 88, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 74, 74, 74, + 674, 74, 74, 74, 74, 74, 74, 74, 74, 81, + 81, 674, 674, 81, 674, 81, 147, 674, 147, 150, + + 150, 674, 150, 150, 151, 151, 674, 151, 151, 151, + 674, 151, 151, 151, 151, 151, 154, 154, 154, 674, + 154, 154, 154, 154, 154, 154, 154, 154, 156, 156, + 156, 156, 156, 156, 156, 156, 674, 156, 156, 158, + 674, 674, 158, 674, 158, 158, 158, 158, 158, 158, + 162, 162, 674, 162, 162, 163, 163, 674, 163, 163, + 94, 94, 674, 94, 94, 13, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674 + } ; + +static yyconst short int yy_chk[4245] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, + 4, 4, 5, 6, 7, 9, 3, 7, 4, 5, + 6, 8, 5, 6, 8, 10, 459, 11, 11, 11, + + 78, 143, 11, 9, 164, 669, 9, 12, 12, 12, + 164, 70, 12, 10, 143, 459, 10, 15, 15, 15, + 16, 16, 16, 15, 378, 70, 16, 20, 20, 20, + 24, 78, 24, 20, 22, 378, 148, 22, 148, 20, + 20, 22, 22, 22, 22, 22, 22, 26, 26, 26, + 26, 26, 26, 26, 665, 36, 70, 149, 9, 149, + 9, 68, 68, 68, 663, 36, 31, 36, 10, 36, + 10, 11, 31, 11, 36, 238, 31, 33, 31, 31, + 31, 12, 238, 12, 19, 31, 662, 33, 33, 33, + 239, 33, 69, 69, 69, 660, 33, 239, 19, 33, + + 656, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 598, 598, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 29, 655, 492, 29, 29, 29, 29, 29, + 29, 29, 73, 73, 73, 492, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 159, 159, 159, 29, 29, 29, 29, 29, + + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 30, 311, 312, + 30, 652, 311, 32, 30, 312, 32, 30, 30, 30, + 30, 30, 650, 32, 376, 32, 30, 32, 34, 34, + 30, 376, 32, 437, 313, 377, 646, 35, 438, 34, + 313, 34, 438, 34, 641, 34, 437, 35, 34, 35, + 377, 35, 37, 37, 534, 37, 35, 439, 534, 439, + 640, 491, 536, 37, 37, 37, 639, 37, 493, 35, + 37, 493, 37, 38, 38, 39, 491, 536, 571, 638, + 35, 38, 571, 569, 38, 39, 38, 39, 38, 39, + + 569, 40, 40, 38, 39, 40, 41, 41, 621, 41, + 621, 40, 635, 40, 633, 40, 632, 41, 628, 41, + 40, 41, 42, 41, 627, 42, 41, 80, 80, 80, + 40, 39, 42, 80, 42, 43, 42, 626, 43, 80, + 80, 42, 43, 620, 619, 43, 618, 43, 617, 43, + 41, 614, 612, 43, 43, 44, 611, 609, 43, 607, + 606, 44, 44, 605, 597, 45, 535, 535, 535, 596, + 595, 593, 44, 590, 44, 45, 44, 45, 44, 45, + 588, 44, 587, 45, 45, 44, 585, 46, 47, 582, + 581, 580, 568, 567, 44, 47, 566, 46, 47, 46, + + 47, 46, 47, 565, 535, 45, 46, 47, 48, 48, + 48, 48, 48, 48, 48, 563, 559, 557, 556, 48, + 600, 600, 600, 46, 83, 83, 83, 83, 83, 83, + 83, 554, 550, 549, 48, 548, 533, 88, 89, 48, + 86, 86, 86, 86, 86, 86, 86, 88, 89, 88, + 89, 88, 89, 90, 91, 89, 88, 89, 600, 642, + 642, 642, 532, 90, 91, 90, 91, 90, 91, 92, + 531, 530, 90, 91, 528, 93, 526, 91, 523, 92, + 521, 92, 519, 92, 517, 93, 95, 93, 92, 93, + 511, 95, 96, 93, 93, 510, 95, 642, 95, 509, + + 95, 508, 96, 97, 96, 95, 96, 497, 490, 489, + 96, 96, 488, 97, 98, 97, 487, 97, 484, 482, + 99, 479, 97, 474, 98, 472, 98, 98, 98, 461, + 99, 460, 99, 98, 99, 100, 100, 443, 436, 99, + 435, 101, 101, 434, 433, 432, 100, 429, 100, 100, + 100, 427, 101, 102, 101, 100, 101, 422, 417, 414, + 403, 101, 402, 102, 102, 102, 103, 102, 401, 104, + 103, 383, 102, 374, 373, 372, 103, 370, 103, 104, + 103, 104, 366, 104, 364, 103, 106, 106, 104, 105, + 105, 105, 359, 354, 350, 340, 106, 107, 106, 105, + + 106, 105, 339, 105, 106, 106, 338, 107, 105, 107, + 108, 107, 319, 111, 308, 307, 107, 306, 300, 289, + 108, 111, 108, 108, 108, 284, 280, 112, 269, 108, + 112, 111, 268, 111, 241, 111, 237, 112, 113, 112, + 111, 112, 233, 232, 114, 114, 112, 231, 113, 227, + 113, 215, 113, 209, 114, 115, 114, 113, 114, 205, + 194, 114, 114, 114, 193, 115, 116, 115, 115, 115, + 165, 161, 117, 157, 115, 147, 116, 142, 116, 139, + 116, 129, 117, 118, 117, 116, 117, 124, 116, 119, + 110, 117, 109, 118, 87, 118, 120, 118, 84, 121, + + 81, 76, 118, 75, 120, 72, 120, 63, 120, 121, + 120, 121, 122, 121, 60, 120, 57, 121, 121, 56, + 123, 53, 122, 125, 122, 27, 122, 23, 18, 17, + 123, 122, 123, 125, 123, 125, 126, 125, 123, 123, + 14, 125, 125, 13, 0, 0, 126, 127, 126, 0, + 126, 0, 0, 0, 0, 126, 126, 127, 0, 127, + 128, 127, 0, 128, 0, 0, 127, 128, 0, 0, + 128, 0, 128, 0, 128, 130, 130, 0, 0, 128, + 0, 0, 131, 0, 0, 0, 130, 0, 130, 0, + 130, 0, 131, 132, 131, 130, 131, 131, 0, 133, + + 131, 131, 0, 132, 0, 132, 0, 132, 0, 133, + 134, 133, 132, 133, 135, 133, 0, 132, 133, 0, + 134, 0, 134, 0, 134, 135, 136, 0, 0, 134, + 0, 136, 0, 0, 0, 135, 136, 135, 136, 135, + 136, 137, 138, 0, 135, 136, 0, 0, 0, 0, + 0, 137, 138, 137, 138, 137, 138, 140, 141, 141, + 137, 138, 141, 0, 140, 0, 0, 140, 141, 140, + 141, 140, 141, 144, 0, 0, 140, 141, 0, 0, + 0, 0, 0, 144, 0, 144, 0, 144, 146, 146, + 146, 144, 144, 145, 145, 145, 145, 145, 145, 145, + + 146, 146, 146, 146, 146, 146, 146, 166, 166, 166, + 166, 166, 166, 166, 0, 169, 0, 0, 169, 0, + 0, 0, 0, 0, 0, 169, 146, 169, 170, 169, + 0, 145, 0, 169, 169, 0, 171, 0, 170, 172, + 170, 0, 170, 0, 0, 0, 171, 170, 171, 172, + 171, 172, 173, 172, 0, 171, 0, 0, 172, 0, + 174, 0, 173, 175, 173, 173, 173, 174, 0, 0, + 174, 173, 174, 175, 174, 175, 176, 175, 0, 174, + 0, 0, 175, 0, 177, 0, 176, 0, 176, 0, + 176, 0, 178, 176, 177, 176, 177, 0, 177, 0, + + 179, 0, 178, 177, 178, 0, 178, 179, 178, 0, + 179, 178, 179, 180, 179, 0, 0, 0, 0, 179, + 0, 181, 0, 180, 182, 180, 0, 180, 0, 0, + 180, 181, 180, 181, 182, 181, 182, 0, 182, 0, + 181, 182, 182, 182, 183, 183, 184, 0, 0, 184, + 0, 0, 183, 0, 0, 183, 184, 183, 184, 183, + 184, 185, 0, 0, 183, 184, 0, 186, 0, 0, + 0, 185, 0, 185, 185, 185, 0, 186, 187, 186, + 185, 186, 0, 0, 188, 0, 186, 188, 187, 187, + 187, 0, 187, 0, 188, 189, 188, 187, 188, 0, + + 0, 190, 0, 188, 190, 189, 0, 189, 189, 189, + 0, 190, 191, 190, 189, 190, 0, 0, 0, 0, + 190, 0, 191, 192, 191, 0, 191, 0, 0, 191, + 0, 191, 0, 192, 192, 192, 195, 192, 0, 0, + 0, 0, 192, 0, 196, 0, 195, 197, 195, 0, + 195, 0, 0, 195, 196, 195, 196, 197, 196, 197, + 197, 197, 198, 196, 0, 199, 197, 0, 200, 0, + 0, 200, 198, 0, 198, 199, 198, 199, 200, 199, + 200, 198, 200, 199, 199, 201, 202, 200, 0, 203, + 0, 0, 201, 0, 0, 0, 202, 0, 202, 203, + + 202, 203, 201, 203, 201, 202, 201, 204, 203, 0, + 206, 201, 0, 206, 0, 0, 0, 204, 0, 204, + 206, 204, 206, 0, 206, 207, 204, 0, 207, 206, + 0, 208, 0, 0, 0, 207, 0, 207, 208, 207, + 0, 208, 210, 208, 207, 208, 0, 0, 0, 0, + 208, 0, 210, 211, 210, 0, 210, 0, 0, 212, + 210, 210, 0, 211, 0, 211, 0, 211, 0, 212, + 213, 212, 211, 212, 0, 0, 212, 0, 212, 0, + 213, 214, 213, 0, 213, 0, 0, 213, 0, 213, + 0, 214, 216, 214, 0, 214, 0, 217, 217, 0, + + 214, 214, 216, 0, 216, 0, 216, 0, 217, 218, + 217, 216, 217, 0, 0, 219, 0, 217, 0, 218, + 0, 218, 0, 218, 0, 219, 0, 219, 218, 219, + 220, 221, 0, 220, 219, 0, 0, 0, 221, 0, + 220, 221, 220, 221, 220, 221, 222, 0, 0, 220, + 221, 0, 0, 0, 0, 0, 222, 223, 222, 0, + 222, 0, 0, 224, 222, 222, 0, 223, 0, 223, + 0, 223, 0, 224, 223, 224, 223, 224, 225, 0, + 224, 225, 224, 0, 226, 0, 0, 226, 225, 0, + 225, 0, 225, 0, 226, 228, 226, 225, 226, 0, + + 0, 0, 0, 226, 0, 228, 229, 228, 228, 228, + 228, 230, 0, 0, 228, 228, 229, 230, 229, 0, + 229, 0, 0, 0, 229, 229, 0, 230, 234, 230, + 0, 230, 0, 0, 234, 0, 230, 0, 234, 0, + 234, 0, 234, 236, 236, 236, 0, 234, 0, 0, + 0, 0, 244, 245, 0, 236, 236, 236, 236, 236, + 236, 236, 244, 245, 244, 245, 244, 245, 246, 245, + 0, 244, 245, 0, 247, 246, 0, 0, 246, 0, + 246, 0, 246, 0, 247, 247, 247, 246, 247, 248, + 249, 0, 0, 247, 0, 0, 0, 0, 0, 248, + + 249, 248, 249, 248, 249, 251, 251, 250, 248, 249, + 250, 0, 0, 0, 0, 0, 251, 250, 251, 250, + 251, 250, 252, 252, 0, 251, 250, 0, 253, 0, + 0, 0, 252, 0, 252, 249, 252, 0, 253, 254, + 253, 252, 253, 0, 0, 253, 0, 253, 0, 254, + 255, 254, 254, 254, 0, 0, 0, 0, 254, 0, + 255, 0, 255, 0, 255, 257, 255, 256, 256, 255, + 0, 258, 0, 0, 0, 257, 0, 257, 256, 257, + 256, 258, 256, 258, 257, 258, 259, 256, 259, 260, + 258, 260, 261, 0, 0, 261, 259, 0, 259, 260, + + 259, 260, 261, 260, 261, 259, 261, 262, 260, 0, + 0, 261, 0, 263, 0, 0, 0, 262, 0, 262, + 263, 262, 0, 263, 264, 263, 262, 263, 0, 0, + 0, 0, 263, 0, 264, 265, 264, 0, 264, 0, + 264, 0, 0, 264, 0, 265, 0, 265, 0, 265, + 266, 265, 0, 266, 265, 0, 267, 0, 0, 0, + 266, 0, 266, 0, 266, 0, 267, 270, 267, 266, + 267, 0, 0, 271, 0, 267, 0, 270, 0, 270, + 0, 270, 0, 271, 0, 271, 270, 271, 272, 273, + 0, 271, 271, 0, 0, 272, 0, 0, 272, 273, + + 272, 273, 272, 273, 274, 273, 0, 272, 273, 275, + 275, 0, 270, 0, 274, 0, 274, 0, 274, 0, + 275, 276, 275, 274, 275, 277, 276, 0, 0, 275, + 0, 276, 0, 276, 277, 276, 0, 276, 0, 0, + 276, 0, 278, 0, 277, 0, 277, 0, 277, 0, + 279, 0, 278, 277, 278, 0, 278, 0, 0, 278, + 279, 278, 279, 0, 279, 281, 281, 0, 282, 279, + 0, 0, 0, 0, 0, 281, 0, 281, 282, 281, + 282, 283, 282, 0, 281, 0, 282, 282, 0, 285, + 286, 283, 285, 283, 283, 283, 0, 0, 0, 285, + + 283, 285, 0, 285, 287, 286, 0, 287, 285, 0, + 0, 0, 0, 0, 287, 286, 287, 286, 287, 286, + 288, 288, 290, 287, 286, 0, 0, 0, 0, 0, + 0, 288, 290, 288, 290, 288, 290, 291, 0, 0, + 288, 290, 0, 0, 0, 0, 0, 291, 0, 291, + 292, 291, 0, 292, 0, 291, 291, 0, 293, 0, + 292, 294, 292, 0, 292, 0, 0, 0, 293, 292, + 293, 294, 293, 294, 0, 294, 296, 293, 295, 295, + 294, 0, 297, 0, 0, 299, 296, 0, 296, 295, + 296, 295, 297, 295, 297, 296, 297, 298, 295, 0, + + 299, 297, 0, 301, 0, 0, 0, 298, 0, 298, + 299, 298, 299, 301, 299, 301, 298, 301, 302, 299, + 0, 296, 301, 0, 303, 0, 0, 303, 302, 0, + 302, 0, 302, 0, 303, 304, 303, 302, 303, 0, + 0, 305, 0, 303, 0, 304, 0, 304, 0, 304, + 0, 305, 0, 305, 304, 305, 309, 0, 305, 0, + 305, 0, 0, 0, 0, 0, 309, 0, 309, 0, + 309, 304, 0, 314, 0, 309, 310, 310, 310, 310, + 310, 310, 310, 314, 0, 314, 0, 314, 315, 315, + 0, 314, 314, 0, 0, 0, 0, 316, 316, 315, + + 0, 315, 0, 315, 317, 317, 0, 316, 315, 316, + 0, 316, 0, 318, 310, 317, 316, 317, 0, 317, + 320, 320, 0, 318, 317, 318, 0, 318, 0, 321, + 321, 320, 318, 320, 0, 320, 0, 0, 0, 321, + 320, 321, 322, 321, 0, 322, 0, 0, 321, 0, + 323, 0, 322, 324, 322, 0, 322, 0, 0, 0, + 323, 322, 323, 324, 323, 324, 0, 324, 326, 323, + 325, 325, 324, 0, 327, 326, 0, 0, 326, 0, + 326, 325, 326, 325, 327, 325, 327, 326, 327, 328, + 325, 0, 328, 327, 0, 329, 328, 329, 0, 328, + + 0, 328, 0, 328, 0, 329, 0, 329, 328, 329, + 330, 331, 0, 330, 329, 0, 0, 0, 0, 0, + 330, 331, 330, 331, 330, 331, 332, 331, 0, 330, + 331, 0, 0, 0, 0, 0, 332, 0, 332, 0, + 332, 333, 333, 0, 332, 332, 0, 334, 0, 0, + 0, 333, 0, 333, 0, 333, 0, 334, 335, 334, + 333, 334, 0, 0, 336, 334, 334, 0, 335, 0, + 335, 0, 335, 0, 336, 335, 336, 335, 336, 337, + 341, 0, 0, 336, 0, 0, 0, 341, 0, 337, + 341, 337, 341, 337, 341, 0, 0, 343, 337, 341, + + 342, 342, 0, 342, 0, 0, 0, 343, 0, 343, + 342, 343, 342, 0, 342, 343, 343, 345, 344, 342, + 344, 0, 0, 0, 0, 0, 0, 345, 344, 345, + 344, 345, 344, 0, 347, 346, 345, 344, 346, 0, + 0, 349, 0, 348, 347, 346, 347, 346, 347, 346, + 348, 347, 0, 347, 346, 0, 349, 0, 0, 0, + 348, 0, 348, 0, 348, 0, 349, 351, 349, 348, + 349, 0, 0, 0, 0, 349, 0, 351, 352, 351, + 0, 351, 0, 0, 353, 351, 351, 0, 352, 0, + 352, 0, 352, 0, 353, 355, 353, 352, 353, 0, + + 0, 0, 0, 353, 0, 355, 356, 355, 0, 355, + 0, 355, 357, 356, 355, 0, 356, 0, 356, 0, + 356, 0, 357, 358, 357, 356, 357, 0, 0, 0, + 0, 357, 0, 358, 0, 358, 360, 358, 0, 361, + 0, 358, 358, 360, 0, 0, 360, 362, 360, 361, + 360, 361, 362, 361, 0, 360, 0, 362, 361, 362, + 363, 362, 0, 0, 0, 0, 362, 0, 0, 0, + 363, 365, 363, 0, 363, 0, 0, 367, 365, 363, + 0, 365, 363, 365, 0, 365, 0, 367, 0, 367, + 365, 367, 368, 369, 0, 368, 367, 0, 0, 0, + + 0, 0, 368, 369, 368, 369, 368, 369, 371, 369, + 0, 368, 369, 0, 379, 0, 0, 0, 371, 0, + 371, 0, 371, 0, 379, 0, 379, 371, 379, 380, + 380, 381, 381, 379, 0, 0, 0, 0, 0, 380, + 382, 380, 381, 380, 381, 0, 381, 0, 380, 0, + 382, 381, 382, 371, 382, 384, 0, 0, 382, 382, + 0, 385, 0, 0, 0, 384, 0, 384, 0, 384, + 0, 385, 386, 385, 384, 385, 0, 0, 387, 385, + 385, 387, 386, 0, 386, 0, 386, 0, 387, 388, + 387, 386, 387, 0, 0, 389, 388, 387, 0, 388, + + 0, 388, 0, 388, 0, 389, 390, 389, 388, 389, + 0, 0, 0, 0, 389, 0, 390, 391, 390, 391, + 390, 0, 0, 392, 390, 390, 0, 391, 0, 391, + 0, 391, 0, 392, 0, 392, 391, 392, 0, 0, + 393, 392, 392, 393, 0, 0, 394, 0, 394, 0, + 393, 0, 393, 0, 393, 0, 394, 0, 394, 393, + 394, 395, 395, 396, 0, 394, 0, 0, 0, 0, + 0, 0, 395, 396, 395, 396, 395, 396, 397, 398, + 0, 395, 396, 0, 0, 397, 0, 0, 397, 398, + 397, 398, 397, 398, 399, 0, 398, 397, 398, 400, + + 400, 399, 0, 0, 399, 0, 399, 0, 399, 0, + 400, 404, 400, 399, 400, 404, 0, 405, 0, 400, + 0, 404, 0, 404, 405, 404, 0, 405, 0, 405, + 404, 405, 406, 407, 406, 0, 405, 0, 0, 0, + 0, 0, 406, 407, 406, 407, 406, 407, 0, 0, + 407, 406, 407, 408, 409, 409, 408, 0, 0, 0, + 0, 0, 0, 408, 409, 408, 409, 408, 409, 410, + 0, 0, 408, 409, 0, 0, 0, 411, 0, 410, + 411, 410, 0, 410, 0, 410, 0, 411, 410, 411, + 412, 411, 0, 0, 0, 0, 411, 0, 413, 0, + + 412, 415, 412, 0, 412, 413, 0, 412, 413, 412, + 413, 415, 413, 415, 0, 415, 418, 413, 416, 416, + 415, 0, 419, 0, 0, 0, 418, 0, 418, 416, + 418, 416, 419, 416, 419, 418, 419, 420, 416, 0, + 421, 419, 0, 421, 0, 0, 0, 420, 423, 420, + 421, 420, 421, 0, 421, 420, 420, 0, 423, 421, + 423, 0, 423, 424, 424, 0, 425, 423, 423, 426, + 0, 0, 0, 424, 0, 424, 425, 424, 425, 426, + 425, 426, 424, 426, 428, 425, 428, 430, 426, 0, + 431, 0, 0, 0, 428, 0, 428, 430, 428, 430, + + 431, 430, 431, 428, 431, 440, 430, 431, 441, 431, + 0, 0, 0, 0, 0, 440, 0, 440, 441, 440, + 441, 442, 441, 440, 440, 0, 441, 441, 442, 444, + 0, 442, 0, 442, 0, 442, 0, 0, 0, 444, + 442, 444, 445, 444, 0, 445, 0, 0, 444, 0, + 446, 0, 445, 447, 445, 0, 445, 0, 0, 0, + 446, 445, 446, 447, 446, 447, 448, 447, 0, 446, + 0, 0, 447, 448, 449, 0, 448, 450, 448, 0, + 448, 0, 0, 0, 449, 448, 449, 450, 449, 450, + 451, 450, 0, 449, 0, 0, 450, 451, 453, 0, + + 451, 452, 451, 452, 451, 0, 0, 0, 453, 451, + 453, 452, 453, 452, 454, 452, 0, 453, 0, 0, + 452, 0, 0, 0, 454, 455, 454, 0, 454, 0, + 0, 0, 454, 454, 0, 455, 456, 455, 0, 455, + 0, 0, 457, 455, 455, 0, 456, 0, 456, 0, + 456, 0, 457, 458, 457, 456, 457, 0, 0, 462, + 0, 457, 0, 458, 0, 458, 462, 458, 0, 462, + 463, 462, 458, 462, 0, 0, 0, 0, 462, 0, + 463, 464, 463, 0, 463, 0, 0, 465, 463, 463, + 0, 464, 0, 464, 0, 464, 0, 465, 466, 465, + + 464, 465, 0, 0, 467, 0, 465, 467, 466, 0, + 466, 0, 466, 0, 467, 466, 467, 466, 467, 468, + 469, 469, 0, 467, 0, 0, 0, 0, 0, 468, + 469, 468, 469, 468, 469, 470, 471, 0, 468, 469, + 0, 0, 0, 0, 0, 470, 471, 470, 471, 470, + 471, 473, 475, 0, 470, 471, 0, 0, 0, 0, + 0, 473, 475, 473, 475, 473, 475, 0, 0, 476, + 473, 475, 477, 476, 0, 478, 0, 0, 0, 476, + 470, 476, 477, 476, 477, 478, 477, 478, 476, 478, + 480, 477, 0, 480, 478, 0, 481, 0, 0, 481, + + 480, 0, 480, 0, 480, 0, 481, 0, 481, 480, + 481, 483, 0, 494, 483, 481, 485, 485, 0, 0, + 0, 483, 0, 483, 0, 483, 0, 485, 494, 485, + 483, 485, 0, 0, 495, 0, 485, 0, 494, 0, + 494, 495, 494, 0, 495, 0, 495, 494, 495, 496, + 496, 0, 0, 495, 0, 498, 0, 0, 0, 496, + 0, 496, 0, 496, 0, 498, 499, 498, 496, 498, + 0, 498, 0, 0, 498, 0, 499, 0, 499, 500, + 499, 0, 500, 0, 499, 499, 0, 501, 0, 500, + 502, 500, 0, 500, 0, 0, 0, 501, 500, 501, + + 502, 501, 502, 502, 502, 503, 501, 0, 504, 502, + 0, 504, 0, 0, 0, 503, 505, 503, 504, 503, + 504, 0, 504, 0, 503, 0, 505, 504, 505, 506, + 505, 0, 507, 0, 0, 505, 506, 0, 0, 506, + 0, 506, 507, 506, 507, 0, 507, 512, 506, 0, + 512, 507, 0, 513, 0, 0, 0, 512, 0, 512, + 0, 512, 0, 513, 514, 513, 512, 513, 0, 0, + 515, 0, 513, 0, 514, 0, 514, 0, 514, 0, + 515, 516, 515, 514, 515, 0, 0, 0, 0, 515, + 0, 516, 518, 516, 0, 516, 518, 0, 520, 516, + + 516, 0, 518, 0, 518, 524, 518, 0, 520, 522, + 520, 518, 520, 0, 0, 0, 522, 520, 0, 522, + 524, 522, 0, 522, 0, 0, 525, 0, 522, 0, + 524, 0, 524, 0, 524, 0, 525, 527, 525, 524, + 525, 0, 0, 529, 0, 525, 0, 527, 0, 527, + 0, 527, 0, 529, 537, 529, 527, 529, 0, 0, + 0, 0, 529, 0, 537, 538, 537, 0, 537, 0, + 0, 537, 0, 537, 0, 538, 539, 538, 538, 538, + 0, 0, 541, 0, 538, 0, 539, 0, 539, 0, + 539, 0, 541, 542, 541, 539, 541, 0, 0, 0, + + 0, 541, 0, 542, 543, 542, 543, 542, 0, 0, + 542, 0, 542, 0, 543, 544, 543, 0, 543, 0, + 544, 545, 0, 543, 0, 544, 0, 544, 0, 544, + 0, 545, 0, 545, 544, 545, 546, 547, 546, 0, + 545, 0, 0, 0, 0, 0, 546, 547, 546, 547, + 546, 547, 552, 553, 0, 546, 547, 0, 0, 0, + 553, 0, 552, 553, 552, 553, 552, 553, 552, 555, + 558, 552, 553, 0, 0, 0, 555, 0, 0, 555, + 558, 555, 558, 555, 558, 560, 0, 0, 555, 558, + 0, 562, 0, 0, 0, 560, 0, 560, 560, 560, + + 0, 562, 564, 562, 560, 562, 0, 0, 0, 562, + 562, 0, 564, 0, 564, 0, 564, 570, 570, 570, + 0, 564, 0, 0, 0, 0, 572, 573, 0, 570, + 570, 570, 570, 570, 570, 570, 572, 573, 572, 573, + 572, 573, 574, 575, 0, 572, 573, 0, 0, 572, + 0, 0, 574, 575, 574, 575, 574, 575, 576, 577, + 0, 574, 575, 0, 0, 0, 0, 0, 576, 577, + 576, 577, 576, 577, 578, 579, 577, 576, 577, 0, + 0, 0, 579, 0, 578, 579, 578, 579, 578, 579, + 583, 0, 0, 578, 579, 0, 0, 0, 584, 0, + + 583, 0, 583, 0, 583, 0, 586, 0, 584, 583, + 584, 584, 584, 0, 589, 0, 586, 584, 586, 0, + 586, 589, 591, 0, 589, 586, 589, 0, 589, 591, + 592, 0, 591, 589, 591, 0, 591, 592, 0, 0, + 592, 591, 592, 0, 592, 0, 0, 601, 602, 592, + 599, 599, 599, 599, 599, 599, 599, 601, 602, 601, + 602, 601, 602, 603, 0, 0, 601, 602, 0, 0, + 0, 604, 0, 603, 0, 603, 0, 603, 0, 0, + 0, 604, 603, 604, 608, 604, 0, 0, 599, 604, + 604, 0, 610, 0, 608, 613, 608, 0, 608, 610, + + 0, 0, 610, 608, 610, 613, 610, 613, 615, 613, + 615, 610, 0, 613, 613, 0, 0, 0, 615, 616, + 615, 0, 615, 616, 0, 0, 0, 615, 0, 616, + 0, 616, 0, 616, 623, 623, 623, 0, 616, 0, + 0, 0, 0, 624, 625, 0, 623, 623, 623, 623, + 623, 623, 623, 624, 625, 624, 625, 624, 625, 629, + 0, 624, 624, 625, 0, 631, 0, 625, 0, 629, + 0, 629, 0, 629, 0, 631, 634, 631, 629, 631, + 0, 0, 636, 631, 631, 0, 634, 0, 634, 0, + 634, 0, 636, 637, 636, 634, 636, 0, 0, 634, + + 637, 636, 0, 637, 0, 637, 644, 637, 643, 643, + 0, 0, 637, 0, 0, 0, 644, 648, 644, 643, + 644, 643, 0, 643, 0, 644, 0, 648, 643, 648, + 0, 648, 651, 0, 0, 653, 648, 0, 653, 0, + 648, 0, 651, 0, 651, 653, 651, 653, 0, 653, + 0, 651, 0, 0, 653, 658, 658, 658, 0, 0, + 0, 0, 0, 0, 659, 661, 0, 658, 658, 658, + 658, 658, 658, 658, 659, 661, 659, 661, 659, 661, + 664, 667, 0, 659, 661, 0, 659, 0, 0, 0, + 664, 667, 664, 667, 664, 667, 664, 671, 0, 664, + + 667, 0, 0, 0, 0, 0, 0, 671, 0, 671, + 0, 671, 0, 0, 0, 0, 671, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, 675, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 677, 677, 677, 677, 677, 677, 677, 677, 677, + 677, 677, 677, 678, 678, 678, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 679, 679, 679, 679, 679, + 679, 679, 679, 679, 679, 679, 679, 680, 680, 680, + 0, 680, 680, 680, 680, 680, 680, 680, 680, 681, + 681, 0, 0, 681, 0, 681, 682, 0, 682, 683, + + 683, 0, 683, 683, 684, 684, 0, 684, 684, 684, + 0, 684, 684, 684, 684, 684, 685, 685, 685, 0, + 685, 685, 685, 685, 685, 685, 685, 685, 686, 686, + 686, 686, 686, 686, 686, 686, 0, 686, 686, 687, + 0, 0, 687, 0, 687, 687, 687, 687, 687, 687, + 688, 688, 0, 688, 688, 689, 689, 0, 689, 689, + 690, 690, 0, 690, 690, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674 + } ; + +extern int yy_flex_debug; +int yy_flex_debug = 1; + +static yyconst short int yy_rule_linenum[123] = + { 0, + 101, 104, 106, 107, 108, 111, 113, 114, 115, 127, + 134, 141, 147, 156, 164, 172, 173, 175, 194, 200, + 207, 214, 221, 231, 265, 272, 273, 274, 275, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, + + 366, 367, 372, 373, 378, 379, 380, 383, 389, 396, + 405, 416, 422, 424, 425, 427, 429, 431, 444, 450, + 456, 464 + } ; + +static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; +static char *yy_full_match; +static int yy_lp; +#define REJECT \ +{ \ +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \ +yy_cp = yy_full_match; /* restore poss. backed-over text */ \ +++yy_lp; \ +goto find_rule; \ +} +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "asn1p_l.l" +#define INITIAL 0 +#line 2 "asn1p_l.l" + +#include +#include +#include + +#include "asn1parser.h" +#include "asn1p_y.h" + +int asn1p_lex(void); +void asn1p_lexer_hack_push_opaque_state(void); /* Used in .y */ +void asn1p_lexer_hack_enable_with_syntax(void); /* Used in .y */ + +#define YY_FATAL_ERROR(msg) do { \ + fprintf(stderr, \ + "lexer error at line %d, " \ + "text \"%s\"\n", \ + yylineno, yytext); \ + exit(1); \ + } while(0) + +int asn1p_lexer_pedantic_1990 = 0; +int asn1p_lexer_types_year = 0; +int asn1p_lexer_constructs_year = 0; +static int _check_dashes(char *ptr); +static asn1_integer_t asn1p_atoi(char *ptr); /* errno is either 0 or ERANGE */ + +/* + * Check that the type is defined in the year of the standard choosen. + */ +#define TYPE_LIFETIME(fyr, lyr) \ + (!asn1p_lexer_types_year \ + || (fyr && fyr <= asn1p_lexer_types_year) \ + || (lyr && lyr > asn1p_lexer_types_year)) + +/* + * Check the the construction (or concept, i.e. CLASS) is defined in + * a given year. + */ +#define CONSTRUCT_LIFETIME(fyr, lyr) \ + (!asn1p_lexer_constructs_year \ + || (fyr && fyr <= asn1p_lexer_constructs_year) \ + || (lyr && lyr > asn1p_lexer_constructs_year)) + +/* + * Make sure that the label is compliant with the naming rules. + */ +#define CHECK_DASHES do { \ + if(_check_dashes(yytext)) { \ + fprintf(stderr, \ + "%s: Identifier format invalid: " \ + "Improper dash location\n", yytext); \ + return -1; \ + } } while(0) + +/* + * Append quoted string. + */ +#define QAPPEND(text, tlen) do { \ + char *prev_text = asn1p_lval.tv_opaque.buf; \ + int prev_len = asn1p_lval.tv_opaque.len; \ + char *p; \ + \ + p = malloc((tlen) + prev_len + 1); \ + if(p == NULL) return -1; \ + \ + if(prev_text) memcpy(p, prev_text, prev_len); \ + memcpy(p + prev_len, text, tlen); \ + p[prev_len + (tlen)] = '\0'; \ + \ + free(asn1p_lval.tv_opaque.buf); \ + asn1p_lval.tv_opaque.buf = p; \ + asn1p_lval.tv_opaque.len = (tlen) + prev_len; \ + } while(0) + +#define YY_NEVER_INTERACTIVE 1 +#define YY_NO_INPUT 1 +#define YY_NO_UNPUT 1 +#define YY_STACK_USED 1 +/* Performance penalty is OK */ +/* Controlled from within application */ +#define dash_comment 1 + +#define cpp_comment 2 + +#define quoted 3 + +#define opaque 4 + +#define with_syntax 5 + +/* Newline */ +/* White-space */ +#line 1806 "lex.yy.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 99 "asn1p_l.l" + + +#line 1960 "lex.yy.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 675 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 4166 ); + +yy_find_action: + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; +find_rule: /* we branch to this label when backing up */ + for ( ; ; ) /* until we find what rule we matched */ + { + if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[yy_lp]; + { + yy_full_match = yy_cp; + break; + } + } + --yy_cp; + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + if ( yy_act != YY_END_OF_BUFFER ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + ++yylineno; + } + +do_action: /* This label is used only to access EOF actions. */ + + if ( yy_flex_debug ) + { + if ( yy_act == 0 ) + fprintf( stderr, "--scanner backing up\n" ); + else if ( yy_act < 123 ) + fprintf( stderr, "--accepting rule at line %d (\"%s\")\n", + yy_rule_linenum[yy_act], yytext ); + else if ( yy_act == 123 ) + fprintf( stderr, "--accepting default rule (\"%s\")\n", + yytext ); + else if ( yy_act == 124 ) + fprintf( stderr, "--(end of buffer or a NUL)\n" ); + else + fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); + } + + switch ( yy_act ) + { /* beginning of action switch */ +case 1: +YY_RULE_SETUP +#line 101 "asn1p_l.l" +yy_push_state(dash_comment); + YY_BREAK + +case 2: +YY_RULE_SETUP +#line 104 "asn1p_l.l" +yy_pop_state(); + YY_BREAK +case 3: +YY_RULE_SETUP +#line 106 "asn1p_l.l" +yy_pop_state(); /* End of comment */ + YY_BREAK +case 4: +YY_RULE_SETUP +#line 107 "asn1p_l.l" +/* Eat single dash */ + YY_BREAK +case 5: +YY_RULE_SETUP +#line 108 "asn1p_l.l" +/* Eat */ + YY_BREAK + +case 6: +YY_RULE_SETUP +#line 111 "asn1p_l.l" +yy_push_state(cpp_comment); + YY_BREAK + +case 7: +YY_RULE_SETUP +#line 113 "asn1p_l.l" +/* Eat */ + YY_BREAK +case 8: +YY_RULE_SETUP +#line 114 "asn1p_l.l" +yy_pop_state(); + YY_BREAK +case 9: +YY_RULE_SETUP +#line 115 "asn1p_l.l" +/* Eat */ + YY_BREAK + +/* + * This is state is being set from corresponding .y module when + * higher-level data is necessary to make proper parsing of the + * underlying data. Thus, we enter the state and save + * everything for later processing. + */ + +case 10: +YY_RULE_SETUP +#line 127 "asn1p_l.l" +{ + yy_push_state(opaque); + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 134 "asn1p_l.l" +{ + yy_pop_state(); + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 141 "asn1p_l.l" +{ + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 147 "asn1p_l.l" +{ + fprintf(stderr, + "ASN.1 Parser syncronization failure: " + "\"%s\" at line %d must not appear " + "inside value definition\n", + yytext, yylineno); + return -1; + } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 156 "asn1p_l.l" +{ + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + YY_BREAK + +case 15: +YY_RULE_SETUP +#line 164 "asn1p_l.l" +{ + asn1p_lval.tv_opaque.buf = 0; + asn1p_lval.tv_opaque.len = 0; + QAPPEND(yytext+1, yyleng-1); + yy_push_state(quoted); + } + YY_BREAK + +case 16: +YY_RULE_SETUP +#line 172 "asn1p_l.l" +{ QAPPEND(yytext, yyleng-1); } /* Add a single quote */ + YY_BREAK +case 17: +YY_RULE_SETUP +#line 173 "asn1p_l.l" +{ QAPPEND(yytext, yyleng); } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 175 "asn1p_l.l" +{ + yy_pop_state(); + /* Do not append last quote: + // QAPPEND(yytext, yyleng); */ + + if(asn1p_lexer_pedantic_1990 + && strchr(yytext, '\n')) { + fprintf(stderr, "%s: " + "Newlines are prohibited by ASN.1:1990\n", + asn1p_lval.tv_opaque.buf); + return -1; + } + + return TOK_cstring; + } + YY_BREAK + +case 19: +YY_RULE_SETUP +#line 194 "asn1p_l.l" +{ + /* " \t\r\n" weren't allowed in ASN.1:1990. */ + asn1p_lval.tv_str = yytext; + return TOK_hstring; + } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 200 "asn1p_l.l" +{ + /* " \t\r\n" weren't allowed in ASN.1:1990. */ + asn1p_lval.tv_str = strdup(yytext); + return TOK_bstring; + } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 207 "asn1p_l.l" +{ + asn1p_lval.a_int = asn1p_atoi(yytext); + if(errno == ERANGE) + return -1; + return TOK_number_negative; + } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 214 "asn1p_l.l" +{ + asn1p_lval.a_int = asn1p_atoi(yytext); + if(errno == ERANGE) + return -1; + return TOK_number; + } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 221 "asn1p_l.l" +{ + asn1p_lval.a_int = asn1p_atoi(yytext); + if(errno == ERANGE) + return -1; + return TOK_number; + } + YY_BREAK +/* + * Tags + */ +case 24: +YY_RULE_SETUP +#line 231 "asn1p_l.l" +{ + char *p; + memset(&asn1p_lval.a_tag, 0, sizeof(asn1p_lval.a_tag)); + switch(yytext[1]) { + case 'U': + asn1p_lval.a_tag.tag_class = TC_UNIVERSAL; + p = yytext + sizeof("UNIVERSAL") + 1; + break; + case 'A': + asn1p_lval.a_tag.tag_class = TC_APPLICATION; + p = yytext + sizeof("APPLICATION") + 1; + break; + case 'P': + asn1p_lval.a_tag.tag_class = TC_PRIVATE; + p = yytext + sizeof("PRIVATE") + 1; + break; + default: + assert(yytext[1] >= '0' && yytext[1] <= '9'); + asn1p_lval.a_tag.tag_class = TC_CONTEXT_SPECIFIC; + p = yytext + 1; + break; + } + asn1p_lval.a_tag.tag_value = asn1p_atoi(p); + if(*p == '0' && asn1p_lval.a_tag.tag_value) { + fprintf(stderr, + "Tag value at line %d " + "cannot start with zero " + "and have multiple digits: \"%s\"\n", + yylineno, yytext); + return -1; + } + return TOK_tag; + } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 265 "asn1p_l.l" +{ + fprintf(stderr, + "Unsupported tag syntax at line %d: \"%s\"\n", + yylineno, yytext); + return -1; + } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 272 "asn1p_l.l" +return TOK_ABSENT; + YY_BREAK +case 27: +YY_RULE_SETUP +#line 273 "asn1p_l.l" +return TOK_ABSTRACT_SYNTAX; + YY_BREAK +case 28: +YY_RULE_SETUP +#line 274 "asn1p_l.l" +return TOK_ALL; + YY_BREAK +case 29: +YY_RULE_SETUP +#line 275 "asn1p_l.l" +{ + /* Appeared in 1990, removed in 1997 */ + if(TYPE_LIFETIME(1990, 1997)) + return TOK_ANY; + fprintf(stderr, "Keyword \"%s\" at line %d " + "is obsolete\n", yytext, yylineno); + REJECT; + } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 283 "asn1p_l.l" +return TOK_APPLICATION; + YY_BREAK +case 31: +YY_RULE_SETUP +#line 284 "asn1p_l.l" +return TOK_AUTOMATIC; + YY_BREAK +case 32: +YY_RULE_SETUP +#line 285 "asn1p_l.l" +return TOK_BEGIN; + YY_BREAK +case 33: +YY_RULE_SETUP +#line 286 "asn1p_l.l" +return TOK_BIT; + YY_BREAK +case 34: +YY_RULE_SETUP +#line 287 "asn1p_l.l" +{ + if(TYPE_LIFETIME(1994, 0)) + return TOK_BMPString; + REJECT; + } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 292 "asn1p_l.l" +return TOK_BOOLEAN; + YY_BREAK +case 36: +YY_RULE_SETUP +#line 293 "asn1p_l.l" +return TOK_BY; + YY_BREAK +case 37: +YY_RULE_SETUP +#line 294 "asn1p_l.l" +return TOK_CHARACTER; + YY_BREAK +case 38: +YY_RULE_SETUP +#line 295 "asn1p_l.l" +return TOK_CHOICE; + YY_BREAK +case 39: +YY_RULE_SETUP +#line 296 "asn1p_l.l" +return TOK_CLASS; + YY_BREAK +case 40: +YY_RULE_SETUP +#line 297 "asn1p_l.l" +return TOK_COMPONENT; + YY_BREAK +case 41: +YY_RULE_SETUP +#line 298 "asn1p_l.l" +return TOK_COMPONENTS; + YY_BREAK +case 42: +YY_RULE_SETUP +#line 299 "asn1p_l.l" +return TOK_CONSTRAINED; + YY_BREAK +case 43: +YY_RULE_SETUP +#line 300 "asn1p_l.l" +return TOK_CONTAINING; + YY_BREAK +case 44: +YY_RULE_SETUP +#line 301 "asn1p_l.l" +return TOK_DEFAULT; + YY_BREAK +case 45: +YY_RULE_SETUP +#line 302 "asn1p_l.l" +{ + /* Appeared in 1990, removed in 1997 */ + if(TYPE_LIFETIME(1990, 1997)) + return TOK_DEFINED; + fprintf(stderr, "Keyword \"%s\" at line %d " + "is obsolete\n", yytext, yylineno); + /* Deprecated since */ + REJECT; + } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 311 "asn1p_l.l" +return TOK_DEFINITIONS; + YY_BREAK +case 47: +YY_RULE_SETUP +#line 312 "asn1p_l.l" +return TOK_EMBEDDED; + YY_BREAK +case 48: +YY_RULE_SETUP +#line 313 "asn1p_l.l" +return TOK_ENCODED; + YY_BREAK +case 49: +YY_RULE_SETUP +#line 314 "asn1p_l.l" +return TOK_END; + YY_BREAK +case 50: +YY_RULE_SETUP +#line 315 "asn1p_l.l" +return TOK_ENUMERATED; + YY_BREAK +case 51: +YY_RULE_SETUP +#line 316 "asn1p_l.l" +return TOK_EXCEPT; + YY_BREAK +case 52: +YY_RULE_SETUP +#line 317 "asn1p_l.l" +return TOK_EXPLICIT; + YY_BREAK +case 53: +YY_RULE_SETUP +#line 318 "asn1p_l.l" +return TOK_EXPORTS; + YY_BREAK +case 54: +YY_RULE_SETUP +#line 319 "asn1p_l.l" +return TOK_EXTENSIBILITY; + YY_BREAK +case 55: +YY_RULE_SETUP +#line 320 "asn1p_l.l" +return TOK_EXTERNAL; + YY_BREAK +case 56: +YY_RULE_SETUP +#line 321 "asn1p_l.l" +return TOK_FALSE; + YY_BREAK +case 57: +YY_RULE_SETUP +#line 322 "asn1p_l.l" +return TOK_FROM; + YY_BREAK +case 58: +YY_RULE_SETUP +#line 323 "asn1p_l.l" +return TOK_GeneralizedTime; + YY_BREAK +case 59: +YY_RULE_SETUP +#line 324 "asn1p_l.l" +return TOK_GeneralString; + YY_BREAK +case 60: +YY_RULE_SETUP +#line 325 "asn1p_l.l" +return TOK_GraphicString; + YY_BREAK +case 61: +YY_RULE_SETUP +#line 326 "asn1p_l.l" +return TOK_IA5String; + YY_BREAK +case 62: +YY_RULE_SETUP +#line 327 "asn1p_l.l" +return TOK_IDENTIFIER; + YY_BREAK +case 63: +YY_RULE_SETUP +#line 328 "asn1p_l.l" +return TOK_IMPLICIT; + YY_BREAK +case 64: +YY_RULE_SETUP +#line 329 "asn1p_l.l" +return TOK_IMPLIED; + YY_BREAK +case 65: +YY_RULE_SETUP +#line 330 "asn1p_l.l" +return TOK_IMPORTS; + YY_BREAK +case 66: +YY_RULE_SETUP +#line 331 "asn1p_l.l" +return TOK_INCLUDES; + YY_BREAK +case 67: +YY_RULE_SETUP +#line 332 "asn1p_l.l" +return TOK_INSTANCE; + YY_BREAK +case 68: +YY_RULE_SETUP +#line 333 "asn1p_l.l" +return TOK_INTEGER; + YY_BREAK +case 69: +YY_RULE_SETUP +#line 334 "asn1p_l.l" +return TOK_INTERSECTION; + YY_BREAK +case 70: +YY_RULE_SETUP +#line 335 "asn1p_l.l" +return TOK_ISO646String; + YY_BREAK +case 71: +YY_RULE_SETUP +#line 336 "asn1p_l.l" +return TOK_MAX; + YY_BREAK +case 72: +YY_RULE_SETUP +#line 337 "asn1p_l.l" +return TOK_MIN; + YY_BREAK +case 73: +YY_RULE_SETUP +#line 338 "asn1p_l.l" +return TOK_MINUS_INFINITY; + YY_BREAK +case 74: +YY_RULE_SETUP +#line 339 "asn1p_l.l" +return TOK_NULL; + YY_BREAK +case 75: +YY_RULE_SETUP +#line 340 "asn1p_l.l" +return TOK_NumericString; + YY_BREAK +case 76: +YY_RULE_SETUP +#line 341 "asn1p_l.l" +return TOK_OBJECT; + YY_BREAK +case 77: +YY_RULE_SETUP +#line 342 "asn1p_l.l" +return TOK_ObjectDescriptor; + YY_BREAK +case 78: +YY_RULE_SETUP +#line 343 "asn1p_l.l" +return TOK_OCTET; + YY_BREAK +case 79: +YY_RULE_SETUP +#line 344 "asn1p_l.l" +return TOK_OF; + YY_BREAK +case 80: +YY_RULE_SETUP +#line 345 "asn1p_l.l" +return TOK_OPTIONAL; + YY_BREAK +case 81: +YY_RULE_SETUP +#line 346 "asn1p_l.l" +return TOK_PATTERN; + YY_BREAK +case 82: +YY_RULE_SETUP +#line 347 "asn1p_l.l" +return TOK_PDV; + YY_BREAK +case 83: +YY_RULE_SETUP +#line 348 "asn1p_l.l" +return TOK_PLUS_INFINITY; + YY_BREAK +case 84: +YY_RULE_SETUP +#line 349 "asn1p_l.l" +return TOK_PRESENT; + YY_BREAK +case 85: +YY_RULE_SETUP +#line 350 "asn1p_l.l" +return TOK_PrintableString; + YY_BREAK +case 86: +YY_RULE_SETUP +#line 351 "asn1p_l.l" +return TOK_PRIVATE; + YY_BREAK +case 87: +YY_RULE_SETUP +#line 352 "asn1p_l.l" +return TOK_REAL; + YY_BREAK +case 88: +YY_RULE_SETUP +#line 353 "asn1p_l.l" +return TOK_RELATIVE_OID; + YY_BREAK +case 89: +YY_RULE_SETUP +#line 354 "asn1p_l.l" +return TOK_SEQUENCE; + YY_BREAK +case 90: +YY_RULE_SETUP +#line 355 "asn1p_l.l" +return TOK_SET; + YY_BREAK +case 91: +YY_RULE_SETUP +#line 356 "asn1p_l.l" +return TOK_SIZE; + YY_BREAK +case 92: +YY_RULE_SETUP +#line 357 "asn1p_l.l" +return TOK_STRING; + YY_BREAK +case 93: +YY_RULE_SETUP +#line 358 "asn1p_l.l" +return TOK_SYNTAX; + YY_BREAK +case 94: +YY_RULE_SETUP +#line 359 "asn1p_l.l" +return TOK_T61String; + YY_BREAK +case 95: +YY_RULE_SETUP +#line 360 "asn1p_l.l" +return TOK_TAGS; + YY_BREAK +case 96: +YY_RULE_SETUP +#line 361 "asn1p_l.l" +return TOK_TeletexString; + YY_BREAK +case 97: +YY_RULE_SETUP +#line 362 "asn1p_l.l" +return TOK_TRUE; + YY_BREAK +case 98: +YY_RULE_SETUP +#line 363 "asn1p_l.l" +return TOK_TYPE_IDENTIFIER; + YY_BREAK +case 99: +YY_RULE_SETUP +#line 364 "asn1p_l.l" +return TOK_UNION; + YY_BREAK +case 100: +YY_RULE_SETUP +#line 365 "asn1p_l.l" +return TOK_UNIQUE; + YY_BREAK +case 101: +YY_RULE_SETUP +#line 366 "asn1p_l.l" +return TOK_UNIVERSAL; + YY_BREAK +case 102: +YY_RULE_SETUP +#line 367 "asn1p_l.l" +{ + if(TYPE_LIFETIME(1994, 0)) + return TOK_UniversalString; + REJECT; + } + YY_BREAK +case 103: +YY_RULE_SETUP +#line 372 "asn1p_l.l" +return TOK_UTCTime; + YY_BREAK +case 104: +YY_RULE_SETUP +#line 373 "asn1p_l.l" +{ + if(TYPE_LIFETIME(1994, 0)) + return TOK_UTF8String; + REJECT; + } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 378 "asn1p_l.l" +return TOK_VideotexString; + YY_BREAK +case 106: +YY_RULE_SETUP +#line 379 "asn1p_l.l" +return TOK_VisibleString; + YY_BREAK +case 107: +YY_RULE_SETUP +#line 380 "asn1p_l.l" +return TOK_WITH; + YY_BREAK +case 108: +YY_RULE_SETUP +#line 383 "asn1p_l.l" +{ + CHECK_DASHES; + asn1p_lval.tv_str = strdup(yytext); + return TOK_typefieldreference; + } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 389 "asn1p_l.l" +{ + CHECK_DASHES; + asn1p_lval.tv_str = strdup(yytext); + return TOK_valuefieldreference; + } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 396 "asn1p_l.l" +{ + CHECK_DASHES; + asn1p_lval.tv_str = strdup(yytext); + return TOK_identifier; + } + YY_BREAK +/* + * objectclassreference + */ +case 111: +YY_RULE_SETUP +#line 405 "asn1p_l.l" +{ + CHECK_DASHES; + asn1p_lval.tv_str = strdup(yytext); + return TOK_objectclassreference; + } + YY_BREAK +/* + * typereference, modulereference + * NOTE: TOK_objectclassreference must be combined + * with this token to produce true typereference. + */ +case 112: +YY_RULE_SETUP +#line 416 "asn1p_l.l" +{ + CHECK_DASHES; + asn1p_lval.tv_str = strdup(yytext); + return TOK_typereference; + } + YY_BREAK +case 113: +YY_RULE_SETUP +#line 422 "asn1p_l.l" +return TOK_PPEQ; + YY_BREAK +case 114: +YY_RULE_SETUP +#line 424 "asn1p_l.l" +return TOK_ThreeDots; + YY_BREAK +case 115: +YY_RULE_SETUP +#line 425 "asn1p_l.l" +return TOK_TwoDots; + YY_BREAK +case 116: +YY_RULE_SETUP +#line 427 "asn1p_l.l" +return yytext[0]; + YY_BREAK +case 117: +YY_RULE_SETUP +#line 429 "asn1p_l.l" +/* Ignore whitespace */ + YY_BREAK +case 118: +YY_RULE_SETUP +#line 431 "asn1p_l.l" +{ + if(TYPE_LIFETIME(1994, 0)) + fprintf(stderr, "ERROR: "); + fprintf(stderr, + "Symbol '%c' at line %d is prohibited " + "by ASN.1:1994 and ASN.1:1997\n", + yytext[0], yylineno); + if(TYPE_LIFETIME(1994, 0)) + return -1; + } + YY_BREAK + +case 119: +YY_RULE_SETUP +#line 444 "asn1p_l.l" +{ + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + YY_BREAK +case 120: +YY_RULE_SETUP +#line 450 "asn1p_l.l" +{ + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + YY_BREAK +case 121: +YY_RULE_SETUP +#line 456 "asn1p_l.l" +{ + yy_pop_state(); + return '}'; + } + YY_BREAK + +case 122: +YY_RULE_SETUP +#line 464 "asn1p_l.l" +{ + fprintf(stderr, + "Unexpected token at line %d: \"%s\"\n", + yylineno, yytext); + while(YYSTATE != INITIAL) + yy_pop_state(); + yy_top_state(); /* Just to use this function. */ + yyterminate(); + yy_fatal_error("Unexpected token"); + return -1; +} + YY_BREAK +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(dash_comment): +case YY_STATE_EOF(cpp_comment): +case YY_STATE_EOF(quoted): +case YY_STATE_EOF(opaque): +case YY_STATE_EOF(with_syntax): +#line 476 "asn1p_l.l" +{ + while(YYSTATE != INITIAL) + yy_pop_state(); + yyterminate(); + } + YY_BREAK +case 123: +YY_RULE_SETUP +#line 483 "asn1p_l.l" +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK +#line 2902 "lex.yy.c" + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 675 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + + register YY_CHAR yy_c = 1; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 675 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 674); + if ( ! yy_is_jam ) + *yy_state_ptr++ = yy_current_state; + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + if ( c == '\n' ) + --yylineno; + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + if ( c == '\n' ) + ++yylineno; + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 483 "asn1p_l.l" + + +/* + * Very dirty but wonderful hack allowing to rule states from within .y file. + */ +void +asn1p_lexer_hack_push_opaque_state() { + yy_push_state(opaque); +} + +/* + * Another hack which disables recognizing some tokens when inside WITH SYNTAX. + */ +void +asn1p_lexer_hack_enable_with_syntax() { + yy_push_state(with_syntax); +} + +/* + * Check that a token does not end with dash and does not contain + * several dashes in succession. + * "Name", "Type-Id", "T-y-p-e-i-d" are OK + * "end-", "vustom--value" are INVALID + */ +static int +_check_dashes(char *ptr) { + int prev_dash = 0; + + assert(*ptr != '-'); + + for(;; ptr++) { + switch(*ptr) { + case '-': + if(prev_dash++) /* No double dashes */ + return -1; + continue; + case '\0': + if(prev_dash) /* No dashes at the end */ + return -1; + break; + default: + prev_dash = 0; + continue; + } + break; + } + + return 0; +} + +static asn1_integer_t +asn1p_atoi(char *ptr) { + asn1_integer_t value; + errno = 0; /* Clear the error code */ + + if(sizeof(value) <= sizeof(int)) { + value = strtol(ptr, 0, 10); + } else { +#ifdef HAVE_STRTOIMAX + value = strtoimax(ptr, 0, 10); +#elif HAVE_STRTOLL + value = strtoll(ptr, 0, 10); +#else + value = strtol(ptr, 0, 10); +#endif + } + + if(errno == ERANGE) { + fprintf(stderr, + "Value \"%s\" at line %d is too large " + "for this compiler! Please contact the vendor.", + ptr, yylineno); + errno = ERANGE; /* Restore potentially clobbered errno */ + } + + return value; +} + diff --git a/libasn1parser/asn1p_l.l b/libasn1parser/asn1p_l.l new file mode 100644 index 00000000..0d86cb74 --- /dev/null +++ b/libasn1parser/asn1p_l.l @@ -0,0 +1,560 @@ +%{ + +#include +#include +#include + +#include "asn1parser.h" +#include "asn1p_y.h" + +int asn1p_lex(void); +void asn1p_lexer_hack_push_opaque_state(void); /* Used in .y */ +void asn1p_lexer_hack_enable_with_syntax(void); /* Used in .y */ + +#define YY_FATAL_ERROR(msg) do { \ + fprintf(stderr, \ + "lexer error at line %d, " \ + "text \"%s\"\n", \ + yylineno, yytext); \ + exit(1); \ + } while(0) + +int asn1p_lexer_pedantic_1990 = 0; +int asn1p_lexer_types_year = 0; +int asn1p_lexer_constructs_year = 0; +static int _check_dashes(char *ptr); +static asn1_integer_t asn1p_atoi(char *ptr); /* errno is either 0 or ERANGE */ + +/* + * Check that the type is defined in the year of the standard choosen. + */ +#define TYPE_LIFETIME(fyr, lyr) \ + (!asn1p_lexer_types_year \ + || (fyr && fyr <= asn1p_lexer_types_year) \ + || (lyr && lyr > asn1p_lexer_types_year)) + +/* + * Check the the construction (or concept, i.e. CLASS) is defined in + * a given year. + */ +#define CONSTRUCT_LIFETIME(fyr, lyr) \ + (!asn1p_lexer_constructs_year \ + || (fyr && fyr <= asn1p_lexer_constructs_year) \ + || (lyr && lyr > asn1p_lexer_constructs_year)) + +/* + * Make sure that the label is compliant with the naming rules. + */ +#define CHECK_DASHES do { \ + if(_check_dashes(yytext)) { \ + fprintf(stderr, \ + "%s: Identifier format invalid: " \ + "Improper dash location\n", yytext); \ + return -1; \ + } } while(0) + +/* + * Append quoted string. + */ +#define QAPPEND(text, tlen) do { \ + char *prev_text = asn1p_lval.tv_opaque.buf; \ + int prev_len = asn1p_lval.tv_opaque.len; \ + char *p; \ + \ + p = malloc((tlen) + prev_len + 1); \ + if(p == NULL) return -1; \ + \ + if(prev_text) memcpy(p, prev_text, prev_len); \ + memcpy(p + prev_len, text, tlen); \ + p[prev_len + (tlen)] = '\0'; \ + \ + free(asn1p_lval.tv_opaque.buf); \ + asn1p_lval.tv_opaque.buf = p; \ + asn1p_lval.tv_opaque.len = (tlen) + prev_len; \ + } while(0) + +%} + +%option never-interactive +%option noinput nounput +%option noyywrap stack +/* Performance penalty is OK */ +%option yylineno +/* Controlled from within application */ +%option debug + +%pointer + +%x dash_comment +%x cpp_comment +%x quoted +%x opaque +%x with_syntax + +/* Newline */ +NL [\r\v\f\n] +/* White-space */ +WSP [\t\r\v\f\n ] + +%% + +"--" yy_push_state(dash_comment); +{ + + {NL} yy_pop_state(); + + -- yy_pop_state(); /* End of comment */ + - /* Eat single dash */ + [^\r\v\f\n-]+ /* Eat */ + +} +"/*" yy_push_state(cpp_comment); +{ + [^*/] /* Eat */ + "*/" yy_pop_state(); + . /* Eat */ +} + + + /* + * This is state is being set from corresponding .y module when + * higher-level data is necessary to make proper parsing of the + * underlying data. Thus, we enter the state and save + * everything for later processing. + */ +{ + + "{" { + yy_push_state(opaque); + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + + "}" { + yy_pop_state(); + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + + [^{}:=]+ { + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + + "::=" { + fprintf(stderr, + "ASN.1 Parser syncronization failure: " + "\"%s\" at line %d must not appear " + "inside value definition\n", + yytext, yylineno); + return -1; + } + + [:=] { + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + + } + +\"[^\"]* { + asn1p_lval.tv_opaque.buf = 0; + asn1p_lval.tv_opaque.len = 0; + QAPPEND(yytext+1, yyleng-1); + yy_push_state(quoted); + } +{ + + \"\" { QAPPEND(yytext, yyleng-1); } /* Add a single quote */ + [^\"]+ { QAPPEND(yytext, yyleng); } + + \" { + yy_pop_state(); + /* Do not append last quote: + // QAPPEND(yytext, yyleng); */ + + if(asn1p_lexer_pedantic_1990 + && strchr(yytext, '\n')) { + fprintf(stderr, "%s: " + "Newlines are prohibited by ASN.1:1990\n", + asn1p_lval.tv_opaque.buf); + return -1; + } + + return TOK_cstring; + } + + } + + +'[0-9A-F \t\r\v\f\n]+'H { + /* " \t\r\n" weren't allowed in ASN.1:1990. */ + asn1p_lval.tv_str = yytext; + return TOK_hstring; + } + +'[01 \t\r\v\f\n]+'B { + /* " \t\r\n" weren't allowed in ASN.1:1990. */ + asn1p_lval.tv_str = strdup(yytext); + return TOK_bstring; + } + + +-[1-9][0-9]* { + asn1p_lval.a_int = asn1p_atoi(yytext); + if(errno == ERANGE) + return -1; + return TOK_number_negative; + } + +[1-9][0-9]* { + asn1p_lval.a_int = asn1p_atoi(yytext); + if(errno == ERANGE) + return -1; + return TOK_number; + } + +"0" { + asn1p_lval.a_int = asn1p_atoi(yytext); + if(errno == ERANGE) + return -1; + return TOK_number; + } + + /* + * Tags + */ +\[(UNIVERSAL[ \t\r\v\f\n]+|APPLICATION[ \t\r\v\f\n]+|PRIVATE[ \t\r\v\f\n]+)?[0-9]+\] { + char *p; + memset(&asn1p_lval.a_tag, 0, sizeof(asn1p_lval.a_tag)); + switch(yytext[1]) { + case 'U': + asn1p_lval.a_tag.tag_class = TC_UNIVERSAL; + p = yytext + sizeof("UNIVERSAL") + 1; + break; + case 'A': + asn1p_lval.a_tag.tag_class = TC_APPLICATION; + p = yytext + sizeof("APPLICATION") + 1; + break; + case 'P': + asn1p_lval.a_tag.tag_class = TC_PRIVATE; + p = yytext + sizeof("PRIVATE") + 1; + break; + default: + assert(yytext[1] >= '0' && yytext[1] <= '9'); + asn1p_lval.a_tag.tag_class = TC_CONTEXT_SPECIFIC; + p = yytext + 1; + break; + } + asn1p_lval.a_tag.tag_value = asn1p_atoi(p); + if(*p == '0' && asn1p_lval.a_tag.tag_value) { + fprintf(stderr, + "Tag value at line %d " + "cannot start with zero " + "and have multiple digits: \"%s\"\n", + yylineno, yytext); + return -1; + } + return TOK_tag; + } + +\[[A-Z]+[ \t\r\v\f\n]+[0-9]+\] { + fprintf(stderr, + "Unsupported tag syntax at line %d: \"%s\"\n", + yylineno, yytext); + return -1; + } + +ABSENT return TOK_ABSENT; +ABSTRACT-SYNTAX return TOK_ABSTRACT_SYNTAX; +ALL return TOK_ALL; +ANY { + /* Appeared in 1990, removed in 1997 */ + if(TYPE_LIFETIME(1990, 1997)) + return TOK_ANY; + fprintf(stderr, "Keyword \"%s\" at line %d " + "is obsolete\n", yytext, yylineno); + REJECT; + } +APPLICATION return TOK_APPLICATION; +AUTOMATIC return TOK_AUTOMATIC; +BEGIN return TOK_BEGIN; +BIT return TOK_BIT; +BMPString { + if(TYPE_LIFETIME(1994, 0)) + return TOK_BMPString; + REJECT; + } +BOOLEAN return TOK_BOOLEAN; +BY return TOK_BY; +CHARACTER return TOK_CHARACTER; +CHOICE return TOK_CHOICE; +CLASS return TOK_CLASS; +COMPONENT return TOK_COMPONENT; +COMPONENTS return TOK_COMPONENTS; +CONSRAINED return TOK_CONSTRAINED; +CONTAINING return TOK_CONTAINING; +DEFAULT return TOK_DEFAULT; +DEFINED { + /* Appeared in 1990, removed in 1997 */ + if(TYPE_LIFETIME(1990, 1997)) + return TOK_DEFINED; + fprintf(stderr, "Keyword \"%s\" at line %d " + "is obsolete\n", yytext, yylineno); + /* Deprecated since */ + REJECT; + } +DEFINITIONS return TOK_DEFINITIONS; +EMBEDDED return TOK_EMBEDDED; +ENCODED return TOK_ENCODED; +END return TOK_END; +ENUMERATED return TOK_ENUMERATED; +EXCEPT return TOK_EXCEPT; +EXPLICIT return TOK_EXPLICIT; +EXPORTS return TOK_EXPORTS; +EXTENSIBILITY return TOK_EXTENSIBILITY; +EXTERNAL return TOK_EXTERNAL; +FALSE return TOK_FALSE; +FROM return TOK_FROM; +GeneralizedTime return TOK_GeneralizedTime; +GeneralString return TOK_GeneralString; +GraphicString return TOK_GraphicString; +IA5String return TOK_IA5String; +IDENTIFIER return TOK_IDENTIFIER; +IMPLICIT return TOK_IMPLICIT; +IMPLIED return TOK_IMPLIED; +IMPORTS return TOK_IMPORTS; +INCLUDES return TOK_INCLUDES; +INSTANCE return TOK_INSTANCE; +INTEGER return TOK_INTEGER; +INTERSECTION return TOK_INTERSECTION; +ISO646String return TOK_ISO646String; +MAX return TOK_MAX; +MIN return TOK_MIN; +MINUS-INFINITY return TOK_MINUS_INFINITY; +NULL return TOK_NULL; +NumericString return TOK_NumericString; +OBJECT return TOK_OBJECT; +ObjectDescriptor return TOK_ObjectDescriptor; +OCTET return TOK_OCTET; +OF return TOK_OF; +OPTIONAL return TOK_OPTIONAL; +PATTERN return TOK_PATTERN; +PDV return TOK_PDV; +PLUS-INFINITY return TOK_PLUS_INFINITY; +PRESENT return TOK_PRESENT; +PrintableString return TOK_PrintableString; +PRIVATE return TOK_PRIVATE; +REAL return TOK_REAL; +RELATIVE-OID return TOK_RELATIVE_OID; +SEQUENCE return TOK_SEQUENCE; +SET return TOK_SET; +SIZE return TOK_SIZE; +STRING return TOK_STRING; +SYNTAX return TOK_SYNTAX; +T61String return TOK_T61String; +TAGS return TOK_TAGS; +TeletexString return TOK_TeletexString; +TRUE return TOK_TRUE; +TYPE-IDENTIFIER return TOK_TYPE_IDENTIFIER; +UNION return TOK_UNION; +UNIQUE return TOK_UNIQUE; +UNIVERSAL return TOK_UNIVERSAL; +UniversalString { + if(TYPE_LIFETIME(1994, 0)) + return TOK_UniversalString; + REJECT; + } +UTCTime return TOK_UTCTime; +UTF8String { + if(TYPE_LIFETIME(1994, 0)) + return TOK_UTF8String; + REJECT; + } +VideotexString return TOK_VideotexString; +VisibleString return TOK_VisibleString; +WITH return TOK_WITH; + + +&[A-Z][A-Za-z0-9-]* { + CHECK_DASHES; + asn1p_lval.tv_str = strdup(yytext); + return TOK_typefieldreference; + } + +&[a-z][a-zA-Z0-9-]* { + CHECK_DASHES; + asn1p_lval.tv_str = strdup(yytext); + return TOK_valuefieldreference; + } + + +[a-z][a-zA-Z0-9-]* { + CHECK_DASHES; + asn1p_lval.tv_str = strdup(yytext); + return TOK_identifier; + } + + /* + * objectclassreference + */ +[A-Z][A-Z0-9-]* { + CHECK_DASHES; + asn1p_lval.tv_str = strdup(yytext); + return TOK_objectclassreference; + } + + /* + * typereference, modulereference + * NOTE: TOK_objectclassreference must be combined + * with this token to produce true typereference. + */ +[A-Z][A-Za-z0-9-]* { + CHECK_DASHES; + asn1p_lval.tv_str = strdup(yytext); + return TOK_typereference; + } + +"::=" return TOK_PPEQ; + +"..." return TOK_ThreeDots; +".." return TOK_TwoDots; + +[(){},;:|!.&@\[\]] return yytext[0]; + +{WSP}+ /* Ignore whitespace */ + +[^A-Za-z0-9:=,{}<.@()[]'\"|&^*;!-] { + if(TYPE_LIFETIME(1994, 0)) + fprintf(stderr, "ERROR: "); + fprintf(stderr, + "Symbol '%c' at line %d is prohibited " + "by ASN.1:1994 and ASN.1:1997\n", + yytext[0], yylineno); + if(TYPE_LIFETIME(1994, 0)) + return -1; + } + +{ + + [^&{} \t\r\v\f\n]+ { + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + + {WSP}+ { + asn1p_lval.tv_opaque.buf = strdup(yytext); + asn1p_lval.tv_opaque.len = yyleng; + return TOK_opaque; + } + + "}" { + yy_pop_state(); + return '}'; + } + +} + + +<*>. { + fprintf(stderr, + "Unexpected token at line %d: \"%s\"\n", + yylineno, yytext); + while(YYSTATE != INITIAL) + yy_pop_state(); + yy_top_state(); /* Just to use this function. */ + yyterminate(); + yy_fatal_error("Unexpected token"); + return -1; +} + +<*><> { + while(YYSTATE != INITIAL) + yy_pop_state(); + yyterminate(); + } + + +%% + +/* + * Very dirty but wonderful hack allowing to rule states from within .y file. + */ +void +asn1p_lexer_hack_push_opaque_state() { + yy_push_state(opaque); +} + +/* + * Another hack which disables recognizing some tokens when inside WITH SYNTAX. + */ +void +asn1p_lexer_hack_enable_with_syntax() { + yy_push_state(with_syntax); +} + +/* + * Check that a token does not end with dash and does not contain + * several dashes in succession. + * "Name", "Type-Id", "T-y-p-e-i-d" are OK + * "end-", "vustom--value" are INVALID + */ +static int +_check_dashes(char *ptr) { + int prev_dash = 0; + + assert(*ptr != '-'); + + for(;; ptr++) { + switch(*ptr) { + case '-': + if(prev_dash++) /* No double dashes */ + return -1; + continue; + case '\0': + if(prev_dash) /* No dashes at the end */ + return -1; + break; + default: + prev_dash = 0; + continue; + } + break; + } + + return 0; +} + +static asn1_integer_t +asn1p_atoi(char *ptr) { + asn1_integer_t value; + errno = 0; /* Clear the error code */ + + if(sizeof(value) <= sizeof(int)) { + value = strtol(ptr, 0, 10); + } else { +#ifdef HAVE_STRTOIMAX + value = strtoimax(ptr, 0, 10); +#elif HAVE_STRTOLL + value = strtoll(ptr, 0, 10); +#else + value = strtol(ptr, 0, 10); +#endif + } + + if(errno == ERANGE) { + fprintf(stderr, + "Value \"%s\" at line %d is too large " + "for this compiler! Please contact the vendor.", + ptr, yylineno); + errno = ERANGE; /* Restore potentially clobbered errno */ + } + + return value; +} + diff --git a/libasn1parser/asn1p_list.h b/libasn1parser/asn1p_list.h new file mode 100644 index 00000000..1f808780 --- /dev/null +++ b/libasn1parser/asn1p_list.h @@ -0,0 +1,57 @@ +/* + * Singly linked tail queue support. + */ +#ifndef ASN1_PARSER_LIST_H +#define ASN1_PARSER_LIST_H + +#define TQ_HEAD(type) \ + struct { \ + type *tq_head; \ + type**tq_tail; \ + } + +#define TQ_HEAD_COPY(to, from) \ + do { (to)->tq_head = (from)->tq_head; \ + (to)->tq_tail = (from)->tq_tail; } while(0) + +#define TQ_ENTRY(type) \ + struct { \ + type *tq_next; \ + } + +#define TQ_FIRST(headp) ((headp)->tq_head) +#define TQ_NEXT(el, field) ((el)->field.tq_next) + +#define TQ_INIT(head) do { \ + TQ_FIRST((head)) = 0; \ + (head)->tq_tail = &TQ_FIRST((head)); \ + } while(0) + +#define TQ_FOR(var, head, field) \ + for((var) = TQ_FIRST((head)); \ + (var); (var) = TQ_NEXT((var), field)) + +#define TQ_ADD(head, xel, field) do { \ + typeof(xel) __el = xel; \ + assert(TQ_NEXT((__el), field) == 0); \ + *(head)->tq_tail = (__el); \ + (head)->tq_tail = &TQ_NEXT((__el), field); \ + } while(0) + +/* + * Remove the first element and return it. + */ +#define TQ_REMOVE(head, field) ({ \ + typeof(TQ_FIRST((head))) __fel; \ + __fel = TQ_FIRST((head)); \ + if(__fel == 0 \ + || (TQ_FIRST((head)) = TQ_NEXT(__fel, field)) \ + == 0) { \ + (head)->tq_tail = &TQ_FIRST((head)); \ + } else { \ + TQ_NEXT(__fel, field) = 0; \ + } \ + __fel; }) + + +#endif /* ASN1_PARSER_LIST_H */ diff --git a/libasn1parser/asn1p_module.c b/libasn1parser/asn1p_module.c new file mode 100644 index 00000000..d430844e --- /dev/null +++ b/libasn1parser/asn1p_module.c @@ -0,0 +1,62 @@ +#include +#include + +#include "asn1parser.h" + +/* + * Construct a new empty module. + */ +asn1p_module_t * +asn1p_module_new() { + asn1p_module_t *mod; + + mod = calloc(1, sizeof *mod); + if(mod) { + TQ_INIT(&(mod->imports)); + TQ_INIT(&(mod->exports)); + TQ_INIT(&(mod->members)); + } + return mod; +} + +/* + * Destroy the module. + */ +void +asn1p_module_free(asn1p_module_t *mod) { + if(mod) { + asn1p_expr_t *expr; + + if(mod->Identifier) + free(mod->Identifier); + + if(mod->module_oid) + asn1p_oid_free(mod->module_oid); + + while((expr = TQ_REMOVE(&(mod->members), next))) + asn1p_expr_free(expr); + + free(mod); + } +} + +asn1p_t * +asn1p_new() { + asn1p_t *asn; + asn = calloc(1, sizeof(*asn)); + if(asn) { + TQ_INIT(&(asn->modules)); + } + return asn; +} + + +void +asn1p_free(asn1p_t *asn) { + if(asn) { + asn1p_module_t *mod; + while((mod = TQ_REMOVE(&(asn->modules), mod_next))) + asn1p_module_free(mod); + free(asn); + } +} diff --git a/libasn1parser/asn1p_module.h b/libasn1parser/asn1p_module.h new file mode 100644 index 00000000..906c784a --- /dev/null +++ b/libasn1parser/asn1p_module.h @@ -0,0 +1,88 @@ +/* + * A Module definition structure used by the ASN.1 parser. + */ +#ifndef ASN1_PARSER_MODULE_H +#define ASN1_PARSER_MODULE_H + +/* + * Flags specific to a module. + */ +typedef enum asn1p_module_flags { + MSF_NOFLAGS, + MSF_EXPLICIT_TAGS = 0x1, + MSF_IMPLICIT_TAGS = 0x2, + MSF_AUTOMATIC_TAGS = 0x4, + MSF_EXTENSIBILITY_IMPLIED = 0x8, +} asn1p_module_flags_e; + +/* + * === EXAMPLE === + * MySyntax DEFINITIONS AUTOMATIC TAGS ::= + * BEGIN + * ... + * END + * === EOF === + */ +typedef struct asn1p_module_s { + + /* + * Name of the source file. + */ + char *source_file_name; + + /* + * Human-readable module identifier. + */ + char *Identifier; /* Module name */ + + /* + * Unique module identifier, OID. + */ + asn1p_oid_t *module_oid; /* Optional OID of the module */ + + /* + * Module flags. + */ + asn1p_module_flags_e module_flags; /* AUTOMATIC TAGS? */ + + /* + * List of everything that this module IMPORTS. + */ + TQ_HEAD(struct asn1p_xports_s) imports; + + /* + * List of everything that this module EXPORTS. + */ + TQ_HEAD(struct asn1p_xports_s) exports; + + /* + * List of everything that this module defines itself. + */ + TQ_HEAD(struct asn1p_expr_s) members; + + /* + * Next module in the list. + */ + TQ_ENTRY(struct asn1p_module_s) + mod_next; + +} asn1p_module_t; + +/* + * Constructor and destructor. + */ +asn1p_module_t *asn1p_module_new(void); +void asn1p_module_free(asn1p_module_t *mod); + +/* + * No more than a container for several modules. + */ +typedef struct asn1p_s { + TQ_HEAD(struct asn1p_module_s) modules; +} asn1p_t; + +asn1p_t *asn1p_new(void); +void asn1p_free(asn1p_t *asn); + + +#endif /* ASN1_PARSER_MODULE_H */ diff --git a/libasn1parser/asn1p_oid.c b/libasn1parser/asn1p_oid.c new file mode 100644 index 00000000..2c22b0fd --- /dev/null +++ b/libasn1parser/asn1p_oid.c @@ -0,0 +1,95 @@ +#include +#include +#include + +#include "asn1parser.h" + +asn1p_oid_t * +asn1p_oid_new() { + return calloc(1, sizeof(asn1p_oid_t)); +} + +int +asn1p_oid_add_arc(asn1p_oid_t *oid, asn1p_oid_arc_t *template) { + void *p; + p = realloc(oid->arcs, (oid->arcs_count + 1) * sizeof(oid->arcs[0])); + if(p) { + oid->arcs = p; + oid->arcs[oid->arcs_count].name + = template->name?strdup(template->name):0; + oid->arcs[oid->arcs_count].number = template->number; + oid->arcs_count++; + return 0; + } else { + return -1; + } +} + +void +asn1p_oid_free(asn1p_oid_t *oid) { + if(oid) { + if(oid->arcs) { + while(oid->arcs_count--) { + if(oid->arcs[oid->arcs_count].name) + free(oid->arcs[oid->arcs_count].name); + } + } + free(oid); + } +} + +asn1p_oid_arc_t * +asn1p_oid_arc_new(const char *optName, asn1_integer_t optNumber /* = -1 */) { + asn1p_oid_arc_t *arc; + + arc = calloc(1, sizeof *arc); + if(arc) { + if(optName) + arc->name = strdup(optName); + arc->number = optNumber; + } + + return arc; +} + +void +asn1p_oid_arc_free(asn1p_oid_arc_t *arc) { + if(arc) { + if(arc->name) + free(arc->name); + free(arc); + } +} + +int +asn1p_oid_compare(asn1p_oid_t *a, asn1p_oid_t *b) { + int i; + + for(i = 0; ; i++) { + asn1_integer_t cmp; + + if(b->arcs_count > i) { + if(a->arcs_count <= i) + return -1; + } else if(a->arcs_count > i) { + if(b->arcs_count <= i) + return 1; + } else if(b->arcs_count <= i && a->arcs_count <= i) { + cmp = b->arcs_count - a->arcs_count; + if(cmp < 0) + return -1; + else if(cmp > 0) + return 1; + return 0; + } + + cmp = b->arcs[i].number - a->arcs[i].number; + if(cmp < 0) + return -1; + else if(cmp > 0) + return 1; + } + +} + + diff --git a/libasn1parser/asn1p_oid.h b/libasn1parser/asn1p_oid.h new file mode 100644 index 00000000..cbb6b079 --- /dev/null +++ b/libasn1parser/asn1p_oid.h @@ -0,0 +1,66 @@ +/* + * Object Identifier definition. + */ +#ifndef ASN1_PARSER_OID_H +#define ASN1_PARSER_OID_H + +/******************************** + * Single Object Identifier Arc * + ********************************/ + +/* + * Object identifier arc (one number in the hierarchy). + */ +typedef struct asn1p_oid_arc_s { + asn1_integer_t number; /* -1 if not yet defined */ + char *name; /* 0 if not defined */ +} asn1p_oid_arc_t; + + +/* + * Arc constructor. + */ +asn1p_oid_arc_t *asn1p_oid_arc_new( + const char *optName, asn1_integer_t optNumber /* = -1 */); +/* + * Arc destructor. + */ +void asn1p_oid_arc_free(asn1p_oid_arc_t *); + + +/************************************************** + * Object Identifier itself, a collection of arcs * + **************************************************/ + +/* + * Object Identifier as a collection of arcs. + */ +typedef struct asn1p_oid_s { + asn1p_oid_arc_t *arcs; + int arcs_count; +} asn1p_oid_t; + +/* + * OID constructor. + */ +asn1p_oid_t *asn1p_oid_new(void); + +/* + * Add another arc using given one as a template + */ +int asn1p_oid_add_arc(asn1p_oid_t *, asn1p_oid_arc_t *template); + +/* + * OID destructor. + */ +void asn1p_oid_free(asn1p_oid_t *); + +/* + * RETURN VALUES: + * 0: The specified OIDs are equal. + * -1 or 1 otherwise. + */ +int asn1p_oid_compare(asn1p_oid_t *a, asn1p_oid_t *b); + + +#endif /* ASN1_PARSER_OID_H */ diff --git a/libasn1parser/asn1p_param.c b/libasn1parser/asn1p_param.c new file mode 100644 index 00000000..f7082241 --- /dev/null +++ b/libasn1parser/asn1p_param.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include + +#include "asn1parser.h" + +/* + * Construct a new empty parameters list. + */ +asn1p_paramlist_t * +asn1p_paramlist_new(int _lineno) { + asn1p_paramlist_t *pl; + + pl = calloc(1, sizeof *pl); + if(pl) { + pl->_lineno = _lineno; + } + + return pl; +} + +void +asn1p_paramlist_free(asn1p_paramlist_t *pl) { + if(pl) { + if(pl->params) { + int i = pl->params_count; + while(i--) { + if(pl->params[i].governor) + asn1p_ref_free(pl->params[i].governor); + if(pl->params[i].argument) + free(pl->params[i].argument); + pl->params[i].governor = 0; + pl->params[i].argument = 0; + } + free(pl->params); + pl->params = 0; + } + + free(pl); + } +} + +int +asn1p_paramlist_add_param(asn1p_paramlist_t *pl, asn1p_ref_t *gov, char *arg) { + + if(!pl || !arg) { + errno = EINVAL; + return -1; + } + + /* + * Make sure there's enough space to insert a new element. + */ + if(pl->params_count == pl->params_size) { + int newsize = pl->params_size?pl->params_size<<2:4; + void *p; + p = realloc(pl->params, + newsize * sizeof(pl->params[0])); + if(p) { + pl->params = p; + pl->params_size = newsize; + } else { + return -1; + } + + } + + if(gov) { + pl->params[pl->params_count].governor = asn1p_ref_clone(gov); + if(pl->params[pl->params_count].governor == NULL) { + return -1; + } + } else { + pl->params[pl->params_count].governor = 0; + } + + pl->params[pl->params_count].argument = strdup(arg); + if(pl->params[pl->params_count].argument) { + pl->params_count++; + return 0; + } else { + if(pl->params[pl->params_count].governor) + asn1p_ref_free(pl->params[pl->params_count].governor); + return -1; + } +} + +asn1p_paramlist_t * +asn1p_paramlist_clone(asn1p_paramlist_t *pl) { + asn1p_paramlist_t *newpl; + + newpl = asn1p_paramlist_new(pl->_lineno); + if(newpl) { + int i; + for(i = 0; i < pl->params_count; i++) { + if(asn1p_paramlist_add_param(newpl, + pl->params[i].governor, + pl->params[i].argument + )) { + asn1p_paramlist_free(newpl); + newpl = NULL; + break; + } + } + } + + return newpl; +} + diff --git a/libasn1parser/asn1p_param.h b/libasn1parser/asn1p_param.h new file mode 100644 index 00000000..c9c20c23 --- /dev/null +++ b/libasn1parser/asn1p_param.h @@ -0,0 +1,30 @@ +/* + * Structures and prototypes related to parametrization + */ +#ifndef ASN1_PARSER_PARAMETRIZATION_H +#define ASN1_PARSER_PARAMETRIZATION_H + +typedef struct asn1p_paramlist_s { + struct asn1p_param_s { + asn1p_ref_t *governor; + char *argument; + } *params; + int params_count; + int params_size; + + int _lineno; +} asn1p_paramlist_t; + +/* + * Constructor and destructor. + */ +asn1p_paramlist_t *asn1p_paramlist_new(int _lineno); +void asn1p_paramlist_free(asn1p_paramlist_t *); + +asn1p_paramlist_t *asn1p_paramlist_clone(asn1p_paramlist_t *ref); + +int asn1p_paramlist_add_param(asn1p_paramlist_t *, + asn1p_ref_t *opt_gov, char *arg); + + +#endif /* ASN1_PARSER_PARAMETRIZATION_H */ diff --git a/libasn1parser/asn1p_ref.c b/libasn1parser/asn1p_ref.c new file mode 100644 index 00000000..4ac2b32d --- /dev/null +++ b/libasn1parser/asn1p_ref.c @@ -0,0 +1,137 @@ +#include +#include +#include +#include +#include + +#include "asn1parser.h" + +/* + * Construct a new empty reference. + */ +asn1p_ref_t * +asn1p_ref_new(int _lineno) { + asn1p_ref_t *ref; + + ref = calloc(1, sizeof *ref); + if(ref) { + ref->_lineno = _lineno; + } + + return ref; +} + +void +asn1p_ref_free(asn1p_ref_t *ref) { + if(ref) { + if(ref->components) { + int i = ref->comp_count; + while(i--) { + if(ref->components[i].name) + free(ref->components[i].name); + ref->components[i].name = 0; + } + free(ref->components); + ref->components = 0; + } + + free(ref); + } +} + +static enum asn1p_ref_lex_type_e +asn1p_ref_name2lextype(char *name) { + enum asn1p_ref_lex_type_e lex_type; + int has_lowercase = 0; + + if(*name == '&') { + if(name[1] >= 'A' && name[1] <= 'Z') { + lex_type = RLT_AmpUppercase; + } else { + lex_type = RLT_Amplowercase; + } + } else if(*name >= 'A' && *name <= 'Z') { + char *p; + + for(p = name; *p; p++) { + if(*p >= 'a' && *p <= 'z') { + has_lowercase = 1; + break; + } + } + + if(has_lowercase) { + lex_type = RLT_Uppercase; + } else { + lex_type = RLT_CAPITALS; + } + } else if(*name == '@') { + if(name[1] == '.') + lex_type = RLT_AtDotlowercase; + else + lex_type = RLT_Atlowercase; + } else { + lex_type = RLT_lowercase; + } + + return lex_type; +} + +int +asn1p_ref_add_component(asn1p_ref_t *ref, char *name, enum asn1p_ref_lex_type_e lex_type) { + + if(!ref || !name || lex_type < RLT_UNKNOWN || lex_type >= RLT_MAX) { + errno = EINVAL; + return -1; + } + + if(ref->comp_count == ref->comp_size) { + int newsize = ref->comp_size?(ref->comp_size<<2):4; + void *p = realloc(ref->components, + newsize * sizeof(ref->components[0])); + if(p) { + ref->components = p; + ref->comp_size = newsize; + } else { + return -1; + } + + } + + if(lex_type == RLT_UNKNOWN) { + lex_type = asn1p_ref_name2lextype(name); + } else { + assert(lex_type == asn1p_ref_name2lextype(name)); + } + + ref->components[ref->comp_count].name = strdup(name); + ref->components[ref->comp_count].lex_type = lex_type; + if(ref->components[ref->comp_count].name) { + ref->comp_count++; + return 0; + } else { + return -1; + } +} + +asn1p_ref_t * +asn1p_ref_clone(asn1p_ref_t *ref) { + asn1p_ref_t *newref; + + newref = asn1p_ref_new(ref->_lineno); + if(newref) { + int i; + for(i = 0; i < ref->comp_count; i++) { + if(asn1p_ref_add_component(newref, + ref->components[i].name, + ref->components[i].lex_type + )) { + asn1p_ref_free(newref); + newref = NULL; + break; + } + } + } + + return newref; +} diff --git a/libasn1parser/asn1p_ref.h b/libasn1parser/asn1p_ref.h new file mode 100644 index 00000000..dc7a7165 --- /dev/null +++ b/libasn1parser/asn1p_ref.h @@ -0,0 +1,62 @@ +/* + * Generic reference to the yet unknown type defined elsewhere. + */ +#ifndef ASN1_PARSER_REFERENCE_H +#define ASN1_PARSER_REFERENCE_H + +typedef struct asn1p_ref_s { + + /* + * A set of reference name components. + * A reference name consists of several components separated by dots: + * "OBJECT-CLASS.&Algorithm.&id" + */ + struct asn1p_ref_component_s { + enum asn1p_ref_lex_type_e { + RLT_UNKNOWN, /* Invalid? */ + /* + * Object class reference "OCLASS1", + * type reference "Type1", + * value reference "id", + * type field reference "&Type1", + * value field reference "&id", + * "OBJECT-CLASS" + */ + RLT_CAPITALS, + RLT_Uppercase, + RLT_lowercase, + RLT_AmpUppercase, + RLT_Amplowercase, + RLT_Atlowercase, + RLT_AtDotlowercase, + RLT_MAX + } lex_type; /* Inferred lexical type of the identifier */ + char *name; /* An identifier */ + } *components; + + int comp_count; /* Number of the components in the reference name. */ + int comp_size; /* Number of allocated structures */ + + int _lineno; /* Number of line in the file */ +} asn1p_ref_t; + +/* + * Constructor and destructor. + */ +asn1p_ref_t *asn1p_ref_new(int _lineno); +void asn1p_ref_free(asn1p_ref_t *); + +asn1p_ref_t *asn1p_ref_clone(asn1p_ref_t *ref); + +/* + * Add a new reference component to the existing reference structure. + * + * RETURN VALUES: + * 0: All clear. + * -1/EINVAL: Invalid arguments + * -1/ENOMEM: Memory allocation failed + */ +int asn1p_ref_add_component(asn1p_ref_t *, + char *name, enum asn1p_ref_lex_type_e); + +#endif /* ASN1_PARSER_REFERENCE_H */ diff --git a/libasn1parser/asn1p_value.c b/libasn1parser/asn1p_value.c new file mode 100644 index 00000000..fb3a9453 --- /dev/null +++ b/libasn1parser/asn1p_value.c @@ -0,0 +1,178 @@ +#include +#include +#include +#include + +#include "asn1parser.h" + + +asn1p_value_t * +asn1p_value_fromref(asn1p_ref_t *ref, int do_copy) { + if(ref) { + asn1p_value_t *v = calloc(1, sizeof *v); + if(v) { + if(do_copy) { + v->value.reference = asn1p_ref_clone(ref); + if(v->value.reference == NULL) { + free(v); + return NULL; + } + } else { + v->value.reference = ref; + } + v->type = ATV_REFERENCED; + } + return v; + } else { + errno = EINVAL; + return NULL; + } +} + +asn1p_value_t * +asn1p_value_frombits(uint8_t *bits, int size_in_bits, int do_copy) { + if(bits) { + asn1p_value_t *v = calloc(1, sizeof *v); + assert(size_in_bits >= 0); + if(v) { + if(do_copy) { + int size = ((size_in_bits + 7) >> 3); + void *p; + p = malloc(size + 1); + if(p) { + memcpy(p, bits, size); + ((char *)p)[size] = '\0'; /* JIC */ + } else { + free(v); + return NULL; + } + v->value.binary_vector.bits = p; + } else { + v->value.binary_vector.bits = (void *)bits; + } + v->value.binary_vector.size_in_bits = size_in_bits; + v->type = ATV_BITVECTOR; + } + return v; + } else { + errno = EINVAL; + return NULL; + } +} +asn1p_value_t * +asn1p_value_frombuf(char *buffer, int size, int do_copy) { + if(buffer) { + asn1p_value_t *v = calloc(1, sizeof *v); + assert(size >= 0); + if(v) { + if(do_copy) { + void *p = malloc(size + 1); + if(p) { + memcpy(p, buffer, size); + ((char *)p)[size] = '\0'; /* JIC */ + } else { + free(v); + return NULL; + } + v->value.string.buf = p; + } else { + v->value.string.buf = buffer; + } + v->value.string.size = size; + v->type = ATV_STRING; + } + return v; + } else { + errno = EINVAL; + return NULL; + } +} + +asn1p_value_t * +asn1p_value_fromdouble(double d) { + asn1p_value_t *v = calloc(1, sizeof *v); + if(v) { + v->value.v_double = d; + v->type = ATV_REAL; + } + return v; +} + +asn1p_value_t * +asn1p_value_fromint(asn1_integer_t i) { + asn1p_value_t *v = calloc(1, sizeof *v); + if(v) { + v->value.v_integer = i; + v->type = ATV_INTEGER; + } + return v; +} + +asn1p_value_t * +asn1p_value_clone(asn1p_value_t *v) { + asn1p_value_t *clone; + if(v) { + switch(v->type) { + case ATV_NOVALUE: + return calloc(1, sizeof(*v)); + case ATV_REFERENCED: + return asn1p_value_fromref(v->value.reference, 1); + case ATV_REAL: + return asn1p_value_fromdouble(v->value.v_double); + case ATV_INTEGER: + case ATV_MIN: + case ATV_MAX: + case ATV_FALSE: + case ATV_TRUE: + clone = asn1p_value_fromint(v->value.v_integer); + if(clone) clone->type = v->type; + return clone; + case ATV_STRING: + clone = asn1p_value_frombuf(v->value.string.buf, + v->value.string.size, 1); + if(clone) clone->type = v->type; + return clone; + case ATV_UNPARSED: + clone = asn1p_value_frombuf(v->value.string.buf, + v->value.string.size, 1); + if(clone) clone->type = ATV_UNPARSED; + return clone; + case ATV_BITVECTOR: + return asn1p_value_frombuf(v->value.binary_vector.bits, + v->value.binary_vector.size_in_bits, 1); + } + } + return v; +} + +void +asn1p_value_free(asn1p_value_t *v) { + if(v) { + switch(v->type) { + case ATV_NOVALUE: + break; + case ATV_REFERENCED: + asn1p_ref_free(v->value.reference); + break; + case ATV_INTEGER: + case ATV_MIN: + case ATV_MAX: + case ATV_FALSE: + case ATV_TRUE: + case ATV_REAL: + /* No freeing necessary */ + break; + case ATV_STRING: + case ATV_UNPARSED: + assert(v->value.string.buf); + free(v->value.string.buf); + break; + case ATV_BITVECTOR: + assert(v->value.binary_vector.bits); + free(v->value.binary_vector.bits); + break; + } + free(v); + } +} + diff --git a/libasn1parser/asn1p_value.h b/libasn1parser/asn1p_value.h new file mode 100644 index 00000000..c9dabfcd --- /dev/null +++ b/libasn1parser/asn1p_value.h @@ -0,0 +1,60 @@ +/* + * A generic value of different syntaxes. + */ +#ifndef ASN1_PARSER_VALUE_H +#define ASN1_PARSER_VALUE_H + +/* + * A wrapper around various kinds of values. + */ +typedef struct asn1p_value_s { + /* + * The value of the element. + */ + enum { + ATV_NOVALUE, + ATV_REFERENCED, + ATV_REAL, + ATV_INTEGER, + ATV_MIN, + ATV_MAX, + ATV_FALSE, + ATV_TRUE, + ATV_STRING, + ATV_UNPARSED, + ATV_BITVECTOR, + } type; /* Value type and location */ + + union { + asn1p_ref_t *reference; + asn1_integer_t v_integer; + double v_double; + /* + * Binary bits vector. + */ + struct { + uint8_t *buf; + int size; + } string; + struct { + uint8_t *bits; + int size_in_bits; + } binary_vector; + } value; +} asn1p_value_t; + +/* + * Constructors and destructor for value. + * If ref, bits or buffer are omitted, the corresponding function returns + * (asn1p_value_t *)0 with errno = EINVAL. + * Allocated value (where applicable) is guaranteed to be NUL-terminated. + */ +asn1p_value_t *asn1p_value_fromref(asn1p_ref_t *ref, int do_copy); +asn1p_value_t *asn1p_value_frombits(uint8_t *bits, int size_in_bits, int dc); +asn1p_value_t *asn1p_value_frombuf(char *buffer, int size, int do_copy); +asn1p_value_t *asn1p_value_fromdouble(double); +asn1p_value_t *asn1p_value_fromint(asn1_integer_t); +asn1p_value_t *asn1p_value_clone(asn1p_value_t *); +void asn1p_value_free(asn1p_value_t *); + +#endif /* ASN1_PARSER_VALUE_H */ diff --git a/libasn1parser/asn1p_xports.c b/libasn1parser/asn1p_xports.c new file mode 100644 index 00000000..cfc9fa4f --- /dev/null +++ b/libasn1parser/asn1p_xports.c @@ -0,0 +1,34 @@ +#include +#include + +#include "asn1parser.h" + +/* + * Construct a new structure that would hold the EXPORTS or IMPORTS + * clause data. + */ +asn1p_xports_t * +asn1p_xports_new() { + asn1p_xports_t *xp; + + xp = calloc(1, sizeof *xp); + if(xp) { + TQ_INIT(&(xp->members)); + } + + return xp; +} + +/* + * Destroy the xports structure. + */ +void +asn1p_xports_free(asn1p_xports_t *xp) { + if(xp) { + if(xp->from) + free(xp->from); + if(xp->from_oid) + asn1p_oid_free(xp->from_oid); + free(xp); + } +} diff --git a/libasn1parser/asn1p_xports.h b/libasn1parser/asn1p_xports.h new file mode 100644 index 00000000..8f4fade3 --- /dev/null +++ b/libasn1parser/asn1p_xports.h @@ -0,0 +1,40 @@ +/* + * Imports and exports structure. + */ +#ifndef ASN1_PARSE_XPORTS_H +#define ASN1_PARSE_XPORTS_H + + +typedef struct asn1p_xports_s { + /* + * Type of the xports structure. + */ + enum asn1p_xports { + XPT_IMPORTS, + XPT_EXPORTS, + } xports_type; + + /* + * Module name and optional OID, occur after FROM. + */ + char *from; /* Name of the module */ + asn1p_oid_t *from_oid; /* Optional OID of the module */ + + /* + * Number of entities to import. + */ + TQ_HEAD(struct asn1p_expr_s) members; + + /* + * Pointer to the next xports structure in whatever list. + */ + TQ_ENTRY(struct asn1p_xports_s) xp_next; +} asn1p_xports_t; + +/* + * Constructor and destructor. + */ +asn1p_xports_t *asn1p_xports_new(void); +void asn1p_xports_free(asn1p_xports_t *); + +#endif /* ASN1_PARSE_XPORTS_H */ diff --git a/libasn1parser/asn1p_y.c b/libasn1parser/asn1p_y.c new file mode 100644 index 00000000..095c9041 --- /dev/null +++ b/libasn1parser/asn1p_y.c @@ -0,0 +1,3484 @@ + +/* A Bison parser, made from asn1p_y.y + by GNU Bison version 1.28 */ + +#define YYBISON 1 /* Identify Bison output. */ + +#define yyparse asn1p_parse +#define yylex asn1p_lex +#define yyerror asn1p_error +#define yylval asn1p_lval +#define yychar asn1p_char +#define yydebug asn1p_debug +#define yynerrs asn1p_nerrs +#define TOK_PPEQ 257 +#define TOK_opaque 258 +#define TOK_bstring 259 +#define TOK_cstring 260 +#define TOK_hstring 261 +#define TOK_identifier 262 +#define TOK_number 263 +#define TOK_number_negative 264 +#define TOK_typereference 265 +#define TOK_objectclassreference 266 +#define TOK_typefieldreference 267 +#define TOK_valuefieldreference 268 +#define TOK_ABSENT 269 +#define TOK_ABSTRACT_SYNTAX 270 +#define TOK_ALL 271 +#define TOK_ANY 272 +#define TOK_APPLICATION 273 +#define TOK_AUTOMATIC 274 +#define TOK_BEGIN 275 +#define TOK_BIT 276 +#define TOK_BMPString 277 +#define TOK_BOOLEAN 278 +#define TOK_BY 279 +#define TOK_CHARACTER 280 +#define TOK_CHOICE 281 +#define TOK_CLASS 282 +#define TOK_COMPONENT 283 +#define TOK_COMPONENTS 284 +#define TOK_CONSTRAINED 285 +#define TOK_CONTAINING 286 +#define TOK_DEFAULT 287 +#define TOK_DEFINITIONS 288 +#define TOK_DEFINED 289 +#define TOK_EMBEDDED 290 +#define TOK_ENCODED 291 +#define TOK_END 292 +#define TOK_ENUMERATED 293 +#define TOK_EXPLICIT 294 +#define TOK_EXPORTS 295 +#define TOK_EXTENSIBILITY 296 +#define TOK_EXTERNAL 297 +#define TOK_FALSE 298 +#define TOK_FROM 299 +#define TOK_GeneralizedTime 300 +#define TOK_GeneralString 301 +#define TOK_GraphicString 302 +#define TOK_IA5String 303 +#define TOK_IDENTIFIER 304 +#define TOK_IMPLICIT 305 +#define TOK_IMPLIED 306 +#define TOK_IMPORTS 307 +#define TOK_INCLUDES 308 +#define TOK_INSTANCE 309 +#define TOK_INTEGER 310 +#define TOK_ISO646String 311 +#define TOK_MAX 312 +#define TOK_MIN 313 +#define TOK_MINUS_INFINITY 314 +#define TOK_NULL 315 +#define TOK_NumericString 316 +#define TOK_OBJECT 317 +#define TOK_ObjectDescriptor 318 +#define TOK_OCTET 319 +#define TOK_OF 320 +#define TOK_OPTIONAL 321 +#define TOK_PATTERN 322 +#define TOK_PDV 323 +#define TOK_PLUS_INFINITY 324 +#define TOK_PRESENT 325 +#define TOK_PrintableString 326 +#define TOK_PRIVATE 327 +#define TOK_REAL 328 +#define TOK_RELATIVE_OID 329 +#define TOK_SEQUENCE 330 +#define TOK_SET 331 +#define TOK_SIZE 332 +#define TOK_STRING 333 +#define TOK_SYNTAX 334 +#define TOK_T61String 335 +#define TOK_TAGS 336 +#define TOK_TeletexString 337 +#define TOK_TRUE 338 +#define TOK_TYPE_IDENTIFIER 339 +#define TOK_UNIQUE 340 +#define TOK_UNIVERSAL 341 +#define TOK_UniversalString 342 +#define TOK_UTCTime 343 +#define TOK_UTF8String 344 +#define TOK_VideotexString 345 +#define TOK_VisibleString 346 +#define TOK_WITH 347 +#define TOK_UNION 348 +#define TOK_INTERSECTION 349 +#define TOK_EXCEPT 350 +#define TOK_TwoDots 351 +#define TOK_ThreeDots 352 +#define TOK_tag 353 + +#line 1 "asn1p_y.y" + + +#include +#include +#include +#include +#include + +#include "asn1parser.h" + +#define YYPARSE_PARAM param +#define YYERROR_VERBOSE + +int yylex(void); +int yyerror(const char *msg); +void asn1p_lexer_hack_push_opaque_state(void); +void asn1p_lexer_hack_enable_with_syntax(void); +#define yylineno asn1p_lineno +extern int asn1p_lineno; + + +static asn1p_value_t * + _convert_bitstring2binary(char *str, int base); + +#define checkmem(ptr) do { \ + if(!(ptr)) \ + return yyerror("Memory failure"); \ + } while(0) + +#define CONSTRAINT_INSERT(root, constr_type, arg1, arg2) do { \ + if(arg1->type != constr_type) { \ + int __ret; \ + root = asn1p_constraint_new(yylineno); \ + checkmem(root); \ + root->type = constr_type; \ + __ret = asn1p_constraint_insert(root, \ + arg1); \ + checkmem(__ret == 0); \ + } else { \ + root = arg1; \ + } \ + if(arg2) { \ + int __ret \ + = asn1p_constraint_insert(root, arg2); \ + checkmem(__ret == 0); \ + } \ + } while(0) + + +#line 57 "asn1p_y.y" +typedef union { + asn1p_t *a_grammar; + asn1p_module_flags_e a_module_flags; + asn1p_module_t *a_module; + asn1p_expr_type_e a_type; /* ASN.1 Type */ + asn1p_expr_t *a_expr; /* Constructed collection */ + asn1p_constraint_t *a_constr; /* Constraint */ + enum asn1p_constraint_type_e a_ctype;/* Constraint type */ + asn1p_xports_t *a_xports; /* IMports/EXports */ + asn1p_oid_t *a_oid; /* Object Identifier */ + asn1p_oid_arc_t a_oid_arc; /* Single OID's arc */ + struct asn1p_type_tag_s a_tag; /* A tag */ + asn1p_ref_t *a_ref; /* Reference to custom type */ + asn1p_wsyntx_t *a_wsynt; /* WITH SYNTAX contents */ + asn1p_wsyntx_chunk_t *a_wchunk; /* WITH SYNTAX chunk */ + struct asn1p_ref_component_s a_refcomp; /* Component of a reference */ + asn1p_value_t *a_value; /* Number, DefinedValue, etc */ + struct asn1p_param_s a_parg; /* A parameter argument */ + asn1p_paramlist_t *a_plist; /* A pargs list */ + enum asn1p_expr_marker_e a_marker; /* OPTIONAL/DEFAULT */ + enum asn1p_constr_pres_e a_pres; /* PRESENT/ABSENT/OPTIONAL */ + asn1_integer_t a_int; + char *tv_str; + struct { + char *buf; + int len; + } tv_opaque; + struct { + char *name; + struct asn1p_type_tag_s tag; + } tv_nametag; +} YYSTYPE; +#include + +#ifndef __cplusplus +#ifndef __STDC__ +#define const +#endif +#endif + + + +#define YYFINAL 375 +#define YYFLAG -32768 +#define YYNTBASE 113 + +#define YYTRANSLATE(x) ((unsigned)(x) <= 353 ? yytranslate[x] : 211) + +static const char yytranslate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 109, 2, 2, 2, 2, 2, 2, 104, + 105, 2, 2, 107, 2, 110, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 108, 106, 111, + 2, 2, 2, 112, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 102, 94, 103, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 95, 97, 98, + 99, 100, 101 +}; + +#if YYDEBUG != 0 +static const short yyprhs[] = { 0, + 0, 2, 4, 7, 16, 17, 19, 23, 26, 28, + 31, 33, 38, 40, 41, 43, 45, 48, 51, 54, + 57, 60, 61, 63, 65, 68, 70, 72, 74, 76, + 78, 80, 84, 87, 89, 92, 97, 99, 103, 105, + 107, 111, 115, 118, 120, 124, 126, 128, 135, 137, + 139, 140, 142, 147, 152, 156, 163, 165, 169, 171, + 175, 179, 181, 185, 187, 189, 191, 195, 201, 202, + 204, 206, 210, 213, 217, 222, 223, 225, 226, 233, + 235, 238, 240, 242, 245, 247, 251, 253, 257, 261, + 263, 265, 267, 272, 274, 278, 280, 284, 288, 290, + 294, 296, 300, 302, 304, 306, 308, 313, 314, 318, + 320, 322, 324, 326, 328, 330, 334, 336, 339, 341, + 343, 345, 347, 350, 353, 355, 357, 360, 363, 365, + 367, 369, 371, 374, 376, 379, 381, 383, 385, 387, + 389, 391, 393, 395, 397, 399, 401, 403, 405, 407, + 412, 417, 422, 427, 432, 434, 439, 440, 442, 444, + 446, 448, 450, 452, 457, 459, 462, 466, 468, 472, + 478, 480, 484, 486, 488, 492, 494, 498, 500, 504, + 506, 510, 515, 517, 519, 521, 524, 527, 531, 533, + 535, 537, 539, 541, 543, 545, 547, 549, 555, 557, + 561, 563, 567, 568, 570, 572, 574, 576, 578, 580, + 584, 589, 591, 595, 598, 602, 604, 608, 609, 611, + 613, 616, 618, 620, 621, 625, 628, 632, 634, 638, + 640, 645, 650, 652, 654, 656, 658, 659, 661, 663, + 666, 669, 671, 673, 675, 677, 679 +}; + +static const short yyrhs[] = { 114, + 0, 115, 0, 114, 115, 0, 207, 116, 34, 120, + 3, 21, 123, 38, 0, 0, 117, 0, 102, 118, + 103, 0, 102, 103, 0, 119, 0, 118, 119, 0, + 209, 0, 209, 104, 9, 105, 0, 9, 0, 0, + 121, 0, 122, 0, 121, 122, 0, 40, 82, 0, + 51, 82, 0, 20, 82, 0, 42, 52, 0, 0, + 124, 0, 125, 0, 124, 125, 0, 126, 0, 131, + 0, 137, 0, 161, 0, 134, 0, 169, 0, 53, + 127, 106, 0, 53, 45, 0, 128, 0, 127, 128, + 0, 129, 45, 207, 116, 0, 130, 0, 129, 107, + 130, 0, 207, 0, 209, 0, 41, 132, 106, 0, + 41, 17, 106, 0, 41, 106, 0, 133, 0, 132, + 107, 133, 0, 207, 0, 209, 0, 207, 135, 3, + 102, 136, 103, 0, 156, 0, 166, 0, 0, 177, + 0, 207, 3, 205, 85, 0, 207, 3, 205, 153, + 0, 207, 3, 143, 0, 207, 102, 138, 103, 3, + 153, 0, 139, 0, 138, 107, 139, 0, 207, 0, + 207, 108, 209, 0, 166, 108, 209, 0, 141, 0, + 140, 107, 141, 0, 155, 0, 209, 0, 152, 0, + 142, 107, 152, 0, 28, 102, 145, 103, 147, 0, + 0, 86, 0, 146, 0, 145, 107, 146, 0, 159, + 197, 0, 159, 153, 144, 0, 159, 159, 197, 144, + 0, 0, 148, 0, 0, 93, 80, 102, 149, 150, + 103, 0, 151, 0, 150, 151, 0, 4, 0, 159, + 0, 210, 153, 0, 154, 0, 155, 171, 197, 0, + 100, 0, 100, 109, 164, 0, 100, 109, 204, 0, + 168, 0, 169, 0, 170, 0, 207, 102, 140, 103, + 0, 156, 0, 55, 66, 156, 0, 11, 0, 11, + 110, 207, 0, 11, 110, 209, 0, 208, 0, 208, + 110, 157, 0, 158, 0, 157, 110, 158, 0, 160, + 0, 160, 0, 13, 0, 14, 0, 209, 135, 3, + 162, 0, 0, 102, 163, 165, 0, 5, 0, 7, + 0, 6, 0, 204, 0, 164, 0, 209, 0, 207, + 110, 209, 0, 4, 0, 165, 4, 0, 24, 0, + 61, 0, 74, 0, 167, 0, 65, 79, 0, 63, + 50, 0, 75, 0, 43, 0, 36, 69, 0, 26, + 79, 0, 89, 0, 46, 0, 56, 0, 39, 0, + 22, 79, 0, 166, 0, 167, 201, 0, 23, 0, + 47, 0, 48, 0, 49, 0, 57, 0, 62, 0, + 72, 0, 81, 0, 83, 0, 88, 0, 90, 0, + 91, 0, 92, 0, 64, 0, 27, 102, 142, 103, + 0, 76, 102, 142, 103, 0, 77, 102, 142, 103, + 0, 76, 171, 66, 155, 0, 77, 171, 66, 155, + 0, 18, 0, 18, 35, 25, 209, 0, 0, 175, + 0, 94, 0, 95, 0, 96, 0, 97, 0, 98, + 0, 78, 104, 177, 105, 0, 176, 0, 175, 176, + 0, 104, 177, 105, 0, 178, 0, 178, 107, 100, + 0, 178, 107, 100, 107, 178, 0, 100, 0, 100, + 107, 178, 0, 179, 0, 180, 0, 179, 172, 180, + 0, 181, 0, 180, 173, 181, 0, 182, 0, 181, + 174, 182, 0, 185, 0, 185, 183, 185, 0, 184, + 104, 177, 105, 0, 191, 0, 186, 0, 99, 0, + 99, 111, 0, 111, 99, 0, 111, 99, 111, 0, + 78, 0, 45, 0, 204, 0, 209, 0, 6, 0, + 59, 0, 58, 0, 44, 0, 84, 0, 93, 30, + 102, 187, 103, 0, 188, 0, 187, 107, 188, 0, + 100, 0, 209, 171, 189, 0, 0, 190, 0, 71, + 0, 15, 0, 67, 0, 192, 0, 193, 0, 102, + 207, 103, 0, 192, 102, 194, 103, 0, 195, 0, + 194, 107, 195, 0, 112, 196, 0, 112, 110, 196, + 0, 209, 0, 196, 110, 209, 0, 0, 198, 0, + 67, 0, 33, 199, 0, 185, 0, 166, 0, 0, + 102, 200, 165, 0, 102, 103, 0, 102, 202, 103, + 0, 203, 0, 202, 107, 203, 0, 209, 0, 209, + 104, 204, 105, 0, 209, 104, 164, 105, 0, 204, + 0, 100, 0, 9, 0, 10, 0, 0, 206, 0, + 101, 0, 101, 51, 0, 101, 40, 0, 11, 0, + 12, 0, 12, 0, 8, 0, 209, 0, 209, 206, + 0 +}; + +#endif + +#if YYDEBUG != 0 +static const short yyrline[] = { 0, + 297, 303, 309, 325, 350, 352, 355, 359, 364, 371, + 379, 384, 388, 397, 399, 407, 411, 419, 423, 426, + 429, 437, 439, 448, 452, 477, 481, 490, 497, 510, + 521, 534, 541, 546, 552, 558, 567, 573, 579, 586, + 594, 598, 601, 608, 614, 620, 627, 636, 646, 654, + 662, 664, 676, 688, 695, 711, 721, 731, 741, 746, + 753, 763, 769, 775, 779, 791, 797, 803, 813, 815, + 818, 826, 832, 841, 846, 863, 865, 870, 874, 879, + 884, 890, 894, 919, 926, 931, 939, 948, 957, 968, + 972, 978, 986, 1010, 1017, 1031, 1040, 1050, 1060, 1068, + 1089, 1098, 1107, 1108, 1110, 1117, 1129, 1139, 1141, 1146, + 1150, 1154, 1158, 1161, 1166, 1178, 1194, 1205, 1219, 1221, + 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, + 1237, 1239, 1240, 1243, 1250, 1262, 1264, 1268, 1272, 1273, + 1274, 1275, 1276, 1280, 1281, 1282, 1283, 1287, 1288, 1291, + 1298, 1304, 1310, 1318, 1326, 1332, 1348, 1350, 1353, 1353, + 1354, 1354, 1355, 1357, 1370, 1373, 1378, 1384, 1388, 1395, + 1403, 1408, 1417, 1419, 1421, 1426, 1428, 1434, 1436, 1441, + 1448, 1455, 1463, 1466, 1471, 1473, 1474, 1475, 1478, 1482, + 1487, 1491, 1502, 1506, 1511, 1516, 1521, 1528, 1534, 1538, + 1543, 1549, 1561, 1563, 1566, 1570, 1573, 1578, 1582, 1590, + 1605, 1611, 1618, 1631, 1643, 1658, 1662, 1679, 1681, 1684, + 1688, 1694, 1697, 1699, 1699, 1719, 1724, 1729, 1735, 1741, + 1749, 1757, 1765, 1772, 1782, 1787, 1817, 1819, 1822, 1827, + 1831, 1837, 1842, 1848, 1855, 1862, 1867 +}; +#endif + + +#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) + +static const char * const yytname[] = { "$","error","$undefined.","TOK_PPEQ", +"TOK_opaque","TOK_bstring","TOK_cstring","TOK_hstring","TOK_identifier","TOK_number", +"TOK_number_negative","TOK_typereference","TOK_objectclassreference","TOK_typefieldreference", +"TOK_valuefieldreference","TOK_ABSENT","TOK_ABSTRACT_SYNTAX","TOK_ALL","TOK_ANY", +"TOK_APPLICATION","TOK_AUTOMATIC","TOK_BEGIN","TOK_BIT","TOK_BMPString","TOK_BOOLEAN", +"TOK_BY","TOK_CHARACTER","TOK_CHOICE","TOK_CLASS","TOK_COMPONENT","TOK_COMPONENTS", +"TOK_CONSTRAINED","TOK_CONTAINING","TOK_DEFAULT","TOK_DEFINITIONS","TOK_DEFINED", +"TOK_EMBEDDED","TOK_ENCODED","TOK_END","TOK_ENUMERATED","TOK_EXPLICIT","TOK_EXPORTS", +"TOK_EXTENSIBILITY","TOK_EXTERNAL","TOK_FALSE","TOK_FROM","TOK_GeneralizedTime", +"TOK_GeneralString","TOK_GraphicString","TOK_IA5String","TOK_IDENTIFIER","TOK_IMPLICIT", +"TOK_IMPLIED","TOK_IMPORTS","TOK_INCLUDES","TOK_INSTANCE","TOK_INTEGER","TOK_ISO646String", +"TOK_MAX","TOK_MIN","TOK_MINUS_INFINITY","TOK_NULL","TOK_NumericString","TOK_OBJECT", +"TOK_ObjectDescriptor","TOK_OCTET","TOK_OF","TOK_OPTIONAL","TOK_PATTERN","TOK_PDV", +"TOK_PLUS_INFINITY","TOK_PRESENT","TOK_PrintableString","TOK_PRIVATE","TOK_REAL", +"TOK_RELATIVE_OID","TOK_SEQUENCE","TOK_SET","TOK_SIZE","TOK_STRING","TOK_SYNTAX", +"TOK_T61String","TOK_TAGS","TOK_TeletexString","TOK_TRUE","TOK_TYPE_IDENTIFIER", +"TOK_UNIQUE","TOK_UNIVERSAL","TOK_UniversalString","TOK_UTCTime","TOK_UTF8String", +"TOK_VideotexString","TOK_VisibleString","TOK_WITH","'|'","TOK_UNION","'^'", +"TOK_INTERSECTION","TOK_EXCEPT","TOK_TwoDots","TOK_ThreeDots","TOK_tag","'{'", +"'}'","'('","')'","';'","','","':'","'!'","'.'","'<'","'@'","ParsedGrammar", +"ModuleList","ModuleSpecification","optObjectIdentifier","ObjectIdentifier", +"ObjectIdentifierBody","ObjectIdentifierElement","optModuleSpecificationFlags", +"ModuleSpecificationFlags","ModuleSpecificationFlag","optModuleSpecificationBody", +"ModuleSpecificationBody","ModuleSpecificationElement","ImportsDefinition","ImportsBundleSet", +"ImportsBundle","ImportsList","ImportsElement","ExportsDefinition","ExportsBody", +"ExportsElement","ValueSetDefinition","DefinedTypeRef","optValueSetBody","DataTypeReference", +"ParameterArgumentList","ParameterArgumentName","ActualParameterList","ActualParameter", +"ConstructedDataTypeDefinition","ClassDeclaration","optUnique","ClassFieldList", +"ClassField","optWithSyntax","WithSyntax","@1","WithSyntaxFormat","WithSyntaxFormatToken", +"DataTypeMember","ConstrainedTypeDeclaration","ExtensionAndException","TypeDeclaration", +"ComplexTypeReference","ComplexTypeReferenceAmpList","ComplexTypeReferenceElement", +"ClassFieldIdentifier","ClassFieldName","ValueDefinition","InlineOrDefinedValue", +"@2","DefinedValue","Opaque","BasicTypeId","BasicTypeId_UniverationCompatible", +"BasicType","BasicString","ConstructedType","optConstraints","Union","Intersection", +"Except","Constraints","SingleConstraint","ConstraintElementSet","ConstraintElement", +"ConstraintElementUnion","ConstraintElementIntersection","ConstraintElementException", +"ConstraintSubtypeElement","ConstraintRangeSpec","ConstraintSpec","ConstraintValue", +"WithComponents","WithComponentsList","WithComponentsElement","optPresenceConstraint", +"PresenceConstraint","TableConstraint","SimpleTableConstraint","ComponentRelationConstraint", +"AtNotationList","AtNotationElement","ComponentIdList","optMarker","Marker", +"DefaultValue","@3","UniverationDefinition","UniverationList","UniverationElement", +"SignedNumber","optTag","Tag","TypeRefName","ObjectClassReference","Identifier", +"TaggedIdentifier", NULL +}; +#endif + +static const short yyr1[] = { 0, + 113, 114, 114, 115, 116, 116, 117, 117, 118, 118, + 119, 119, 119, 120, 120, 121, 121, 122, 122, 122, + 122, 123, 123, 124, 124, 125, 125, 125, 125, 125, + 125, 126, 126, 127, 127, 128, 129, 129, 130, 130, + 131, 131, 131, 132, 132, 133, 133, 134, 135, 135, + 136, 136, 137, 137, 137, 137, 138, 138, 139, 139, + 139, 140, 140, 141, 141, 142, 142, 143, 144, 144, + 145, 145, 146, 146, 146, 147, 147, 149, 148, 150, + 150, 151, 151, 152, 152, 153, 154, 154, 154, 155, + 155, 155, 155, 155, 155, 156, 156, 156, 156, 156, + 157, 157, 158, 159, 160, 160, 161, 163, 162, 162, + 162, 162, 162, 162, 164, 164, 165, 165, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 167, 167, 167, 168, 168, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 170, + 170, 170, 170, 170, 170, 170, 171, 171, 172, 172, + 173, 173, 174, 175, 175, 175, 176, 177, 177, 177, + 177, 177, 178, 179, 179, 180, 180, 181, 181, 182, + 182, 182, 182, 182, 183, 183, 183, 183, 184, 184, + 185, 185, 185, 185, 185, 185, 185, 186, 187, 187, + 188, 188, 189, 189, 190, 190, 190, 191, 191, 192, + 193, 194, 194, 195, 195, 196, 196, 197, 197, 198, + 198, 199, 199, 200, 199, 201, 201, 202, 202, 203, + 203, 203, 203, 203, 204, 204, 205, 205, 206, 206, + 206, 207, 207, 208, 209, 210, 210 +}; + +static const short yyr2[] = { 0, + 1, 1, 2, 8, 0, 1, 3, 2, 1, 2, + 1, 4, 1, 0, 1, 1, 2, 2, 2, 2, + 2, 0, 1, 1, 2, 1, 1, 1, 1, 1, + 1, 3, 2, 1, 2, 4, 1, 3, 1, 1, + 3, 3, 2, 1, 3, 1, 1, 6, 1, 1, + 0, 1, 4, 4, 3, 6, 1, 3, 1, 3, + 3, 1, 3, 1, 1, 1, 3, 5, 0, 1, + 1, 3, 2, 3, 4, 0, 1, 0, 6, 1, + 2, 1, 1, 2, 1, 3, 1, 3, 3, 1, + 1, 1, 4, 1, 3, 1, 3, 3, 1, 3, + 1, 3, 1, 1, 1, 1, 4, 0, 3, 1, + 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, + 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, + 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, + 4, 4, 4, 4, 1, 4, 0, 1, 1, 1, + 1, 1, 1, 4, 1, 2, 3, 1, 3, 5, + 1, 3, 1, 1, 3, 1, 3, 1, 3, 1, + 3, 4, 1, 1, 1, 2, 2, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 5, 1, 3, + 1, 3, 0, 1, 1, 1, 1, 1, 1, 3, + 4, 1, 3, 2, 3, 1, 3, 0, 1, 1, + 2, 1, 1, 0, 3, 2, 3, 1, 3, 1, + 4, 4, 1, 1, 1, 1, 0, 1, 1, 2, + 2, 1, 1, 1, 1, 1, 2 +}; + +static const short yydefact[] = { 0, + 242, 243, 1, 2, 5, 3, 0, 0, 6, 245, + 13, 8, 0, 9, 11, 14, 7, 10, 0, 0, + 0, 0, 0, 0, 15, 16, 0, 20, 18, 21, + 19, 0, 17, 12, 22, 136, 0, 137, 138, 139, + 0, 140, 141, 149, 142, 143, 144, 145, 146, 147, + 148, 0, 23, 24, 26, 27, 30, 28, 29, 31, + 0, 0, 0, 43, 0, 44, 46, 47, 33, 0, + 34, 0, 37, 39, 40, 4, 25, 237, 96, 244, + 0, 119, 0, 0, 132, 126, 130, 131, 120, 0, + 0, 121, 125, 129, 0, 0, 49, 50, 122, 99, + 0, 42, 41, 0, 32, 35, 0, 0, 0, 239, + 55, 0, 238, 0, 133, 128, 127, 124, 123, 0, + 57, 0, 59, 0, 0, 0, 45, 5, 38, 0, + 241, 240, 96, 244, 155, 0, 0, 157, 157, 53, + 54, 157, 94, 134, 122, 90, 91, 92, 0, 97, + 98, 0, 0, 0, 0, 51, 105, 106, 100, 101, + 103, 110, 112, 111, 235, 236, 108, 107, 114, 113, + 0, 115, 36, 0, 71, 218, 104, 0, 0, 0, + 0, 0, 0, 0, 158, 165, 0, 0, 218, 0, + 135, 0, 0, 58, 61, 60, 193, 196, 190, 195, + 194, 189, 197, 0, 171, 0, 0, 52, 168, 173, + 174, 176, 178, 0, 180, 184, 183, 208, 209, 191, + 192, 0, 0, 0, 76, 0, 0, 220, 69, 218, + 73, 219, 0, 87, 0, 66, 85, 246, 0, 95, + 0, 0, 0, 0, 166, 0, 0, 86, 234, 226, + 0, 228, 233, 230, 0, 62, 64, 65, 56, 0, + 0, 0, 48, 0, 159, 160, 0, 161, 162, 0, + 163, 0, 0, 185, 0, 0, 0, 102, 117, 109, + 116, 0, 68, 77, 72, 224, 223, 222, 221, 70, + 74, 69, 156, 0, 150, 0, 247, 84, 0, 151, + 167, 153, 152, 154, 227, 0, 0, 93, 0, 0, + 172, 210, 169, 175, 177, 179, 0, 186, 187, 181, + 0, 0, 212, 118, 0, 0, 75, 88, 89, 67, + 164, 229, 0, 0, 63, 201, 0, 199, 157, 0, + 182, 188, 0, 214, 216, 211, 0, 78, 225, 232, + 231, 198, 0, 203, 170, 215, 0, 213, 0, 200, + 206, 207, 205, 202, 204, 217, 82, 0, 80, 83, + 79, 81, 0, 0, 0 +}; + +static const short yydefgoto[] = { 373, + 3, 4, 8, 9, 13, 14, 24, 25, 26, 52, + 53, 54, 55, 70, 71, 72, 73, 56, 65, 66, + 57, 96, 207, 58, 120, 121, 255, 256, 235, 111, + 291, 174, 175, 283, 284, 359, 368, 369, 236, 141, + 237, 142, 143, 159, 160, 176, 177, 59, 168, 223, + 169, 280, 144, 145, 146, 147, 148, 184, 267, 270, + 272, 185, 186, 208, 209, 210, 211, 212, 213, 276, + 214, 215, 216, 337, 338, 364, 365, 217, 218, 219, + 322, 323, 344, 231, 232, 289, 326, 191, 251, 252, + 220, 112, 113, 149, 100, 221, 239 +}; + +static const short yypact[] = { 81, +-32768,-32768, 81,-32768, -45,-32768, 23, 70,-32768,-32768, +-32768,-32768, 47,-32768, 31, 190,-32768,-32768, 132, 61, + 69, 108, 86, 176, 190,-32768, 76,-32768,-32768,-32768, +-32768, 166,-32768,-32768, 442,-32768, 32,-32768,-32768,-32768, + 121,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768, 168, 442,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 179, 732, 103,-32768, 52,-32768,-32768,-32768,-32768, 39, +-32768, 16,-32768,-32768,-32768,-32768,-32768, -11, 111,-32768, + 150,-32768, 152, 142,-32768,-32768,-32768,-32768,-32768, 184, + 159,-32768,-32768,-32768, 748, 240,-32768,-32768,-32768, 135, + 243,-32768,-32768, 141,-32768,-32768, 81, 141, 145, 60, +-32768, 599,-32768, 141,-32768,-32768,-32768,-32768,-32768, -1, +-32768, 143, 144, 147, 206, 68,-32768, -45,-32768, 206, +-32768,-32768, -42, 148, 221, 161, 198, 40, 53,-32768, +-32768, -37,-32768,-32768, 163,-32768,-32768,-32768, 164,-32768, +-32768, 264, 748, 261, 261, 155,-32768,-32768, 160,-32768, +-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 162,-32768,-32768, 64,-32768, 524,-32768, 246, 21, 212, + 169, 21, 155, 208, 171,-32768, 21, 210, 2, 17, +-32768, 383, 674,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768, 247, 172, 81, 175,-32768, 173, 133, + 140, 185,-32768, 178, 35,-32768,-32768, 182,-32768,-32768, +-32768, 206, 281, 261, 193, 206, 301,-32768, 202, 2, +-32768,-32768, 261, 181, 66,-32768,-32768, 191, 674,-32768, + 155, 71, 186, 674,-32768, 89, 674,-32768,-32768,-32768, + 90,-32768,-32768, 189, 91,-32768,-32768,-32768,-32768, 192, + 309, 194,-32768, 196,-32768,-32768, 309,-32768,-32768, 309, +-32768, 309, 155, 187, 205, 78, 200,-32768,-32768, 297, +-32768, 225,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768, 202,-32768, 250,-32768, 21,-32768,-32768, 201,-32768, +-32768,-32768,-32768,-32768,-32768, 56, 250,-32768, 383, 25, +-32768,-32768, 209, 140, 185,-32768, 215,-32768, 211,-32768, + 6, 101,-32768,-32768, 219, 281,-32768,-32768,-32768,-32768, +-32768,-32768, 223, 224,-32768,-32768, 109,-32768, -37, 309, +-32768,-32768, 261, 203,-32768,-32768, 200,-32768, 297,-32768, +-32768,-32768, 25, 24,-32768, 203, 261,-32768, 126,-32768, +-32768,-32768,-32768,-32768,-32768,-32768,-32768, 9,-32768,-32768, +-32768,-32768, 324, 326,-32768 +}; + +static const short yypgoto[] = {-32768, +-32768, 327, 204,-32768,-32768, 318,-32768,-32768, 308,-32768, +-32768, 282,-32768,-32768, 268,-32768, 226,-32768,-32768, 235, +-32768, 279,-32768,-32768,-32768, 195,-32768, 33, -129,-32768, + 51,-32768, 123,-32768,-32768,-32768,-32768, -17, 59, -156, +-32768, -185, -52,-32768, 130, -173, -109,-32768,-32768,-32768, + -209, 30, -50, -43,-32768, 46,-32768, -137,-32768,-32768, +-32768,-32768, 180, -159, -246,-32768, 94, 88, 97,-32768, +-32768, -206,-32768,-32768, 10,-32768,-32768,-32768,-32768,-32768, +-32768, 26, 27, -141,-32768,-32768,-32768,-32768,-32768, 65, + -118,-32768, 134, 1,-32768, -7,-32768 +}; + + +#define YYLAST 837 + + +static const short yytable[] = { 15, + 5, 188, 230, 5, 189, 15, 257, 170, 97, 97, + 98, 98, 367, 10, 311, 161, 109, 99, 99, 229, + 288, 157, 158, 243, 10, 165, 166, 62, 10, 68, + 10, 11, 10, 75, 227, 61, 259, 67, 361, 10, + 181, 74, 1, 2, 122, 62, 10, 248, 63, 1, + 2, 99, 242, 61, 10, 11, 7, 246, 302, -242, + 107, 304, 75, 10, 165, 166, 183, 114, 228, 320, + 74, 253, 162, 163, 164, 10, 165, 166, 1, 2, + 60, 299, 298, 197, 328, 10, 165, 166, 292, 110, + 362, 1, 2, 355, 363, 123, 68, 333, 60, 131, + 75, 152, 122, 16, 67, 153, 151, 128, 74, 99, + 132, 371, 161, 317, 150, 343, 249, 181, 172, 250, + 234, 198, 108, 257, 336, 12, 171, 240, 10, 367, + 181, 1, 2, 274, 19, 200, 201, 64, 157, 158, + 27, 182, 28, 183, 105, 275, 195, 196, 10, 17, + 29, 1, 2, 123, 187, 249, 183, 103, 104, 30, + 197, 203, 10, 165, 166, 69, 225, 31, 295, 167, + 226, 238, 296, 300, 238, 329, 287, 296, 32, 238, + 34, 78, 254, 99, 258, 370, 35, 253, 334, 79, + 80, 303, 305, 308, 370, 296, 306, 309, 198, 199, + 81, 354, 82, 346, 83, 76, 262, 347, 102, 20, + 117, 352, 200, 201, 84, 353, 281, 85, 157, 158, + 114, 86, 79, 80, 87, 293, 265, 266, 115, 21, + 116, 22, 202, 118, 88, 268, 269, 119, 203, 89, + 23, 90, 124, 91, 125, 126, 130, 204, 156, -243, + 154, 155, 92, 93, 205, 178, 206, 10, 165, 166, + 1, 2, 179, 180, 190, 192, 193, 94, 10, 222, + 233, 224, 241, 244, 183, 247, 260, 263, 261, 264, + 95, 273, 271, 277, 279, 282, 172, 290, 238, 294, + 301, 110, 307, 310, 171, 313, 312, 318, 254, 172, + 324, 258, 339, 319, 325, 331, 197, 171, 10, 165, + 166, 321, 357, 345, 197, 340, 10, 165, 166, 341, + 348, 342, 81, 374, 82, 375, 83, 350, 351, 6, + 18, 173, 33, 129, 77, 345, 84, 106, 127, 85, + 101, 335, 327, 86, 198, 339, 87, 194, 285, 366, + 372, 278, 198, 199, 330, 349, 88, 315, 200, 201, + 314, 89, 360, 90, 245, 91, 200, 201, 316, 356, + 332, 297, 358, 0, 92, 93, 0, 0, 0, 0, + 0, 0, 0, 0, 203, 0, 202, 0, 0, 94, + 10, 0, 203, 133, 134, 0, 0, 0, 0, 0, + 135, 204, 286, 0, 81, 36, 82, 0, 83, 136, + 206, 0, 0, 0, 0, 0, 0, 0, 84, 0, + 0, 85, 0, 0, 0, 86, 0, 0, 87, 38, + 39, 40, 0, 0, 0, 0, 0, 137, 88, 42, + 0, 0, 0, 89, 43, 90, 44, 91, 0, 10, + 0, 0, 1, 2, 45, 0, 92, 93, 138, 139, + 0, 0, 0, 46, 36, 47, 0, 0, 0, 0, + 48, 94, 49, 50, 51, 0, 0, 0, 0, 0, + 0, 0, 37, 0, 0, 0, 0, 0, 38, 39, + 40, 0, 0, 0, 41, 0, 0, 0, 42, 0, + 0, 0, 0, 43, 0, 44, 0, 0, 0, 0, + 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, + 0, 0, 46, 0, 47, 0, 0, 0, 0, 48, + 0, 49, 50, 51, 133, 134, 157, 158, 0, 0, + 0, 135, 0, 0, 0, 81, 36, 82, 0, 83, + 136, 0, 0, 0, 0, 0, 227, 0, 0, 84, + 0, 0, 85, 0, 0, 0, 86, 0, 0, 87, + 38, 39, 40, 0, 0, 0, 0, 0, 137, 88, + 42, 0, 0, 0, 89, 43, 90, 44, 91, 0, + 228, 0, 0, 0, 0, 45, 0, 92, 93, 138, + 139, 0, 0, 0, 46, 0, 47, 0, 0, 133, + 134, 48, 94, 49, 50, 51, 135, 0, 0, 0, + 81, 36, 82, 0, 83, 136, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 0, 0, 85, 0, 0, + 0, 86, 0, 0, 87, 38, 39, 40, 0, 0, + 0, 0, 0, 137, 88, 42, 0, 0, 0, 89, + 43, 90, 44, 91, 0, 0, 0, 0, 0, 0, + 45, 0, 92, 93, 138, 139, 0, 0, 0, 46, + 0, 47, 0, 140, 133, 134, 48, 94, 49, 50, + 51, 135, 0, 0, 0, 81, 36, 82, 0, 83, + 136, 0, 0, 0, 0, 0, 0, 0, 0, 84, + 0, 0, 85, 0, 0, 0, 86, 0, 0, 87, + 38, 39, 40, 0, 0, 0, 0, 0, 137, 88, + 42, 0, 0, 0, 89, 43, 90, 44, 91, 0, + 0, 0, 79, 80, 0, 45, 0, 92, 93, 138, + 139, 0, 0, 81, 46, 82, 47, 83, 1, 2, + 0, 48, 94, 49, 50, 51, 0, 84, 0, 81, + 85, 82, 0, 83, 86, 0, 0, 87, 0, 0, + 0, 0, 0, 84, 0, 0, 85, 88, 0, 0, + 86, 0, 89, 87, 90, 0, 91, 0, 0, 0, + 0, 0, 0, 88, 0, 92, 93, 0, 89, 0, + 90, 0, 91, 0, 0, 0, 0, 0, 0, 0, + 94, 92, 93, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 94 +}; + +static const short yycheck[] = { 7, + 0, 139, 176, 3, 142, 13, 192, 126, 61, 62, + 61, 62, 4, 8, 261, 125, 28, 61, 62, 176, + 227, 13, 14, 183, 8, 9, 10, 35, 8, 37, + 8, 9, 8, 41, 33, 35, 193, 37, 15, 8, + 78, 41, 11, 12, 95, 53, 8, 189, 17, 11, + 12, 95, 182, 53, 8, 9, 102, 187, 244, 102, + 45, 247, 70, 8, 9, 10, 104, 110, 67, 276, + 70, 190, 5, 6, 7, 8, 9, 10, 11, 12, + 35, 241, 239, 6, 294, 8, 9, 10, 230, 101, + 67, 11, 12, 340, 71, 95, 104, 307, 53, 40, + 108, 103, 153, 34, 104, 107, 114, 107, 108, 153, + 51, 103, 222, 273, 114, 110, 100, 78, 126, 103, + 100, 44, 107, 309, 100, 103, 126, 180, 8, 4, + 78, 11, 12, 99, 104, 58, 59, 106, 13, 14, + 9, 102, 82, 104, 106, 111, 154, 155, 8, 103, + 82, 11, 12, 153, 102, 100, 104, 106, 107, 52, + 6, 84, 8, 9, 10, 45, 103, 82, 103, 102, + 107, 179, 107, 103, 182, 294, 227, 107, 3, 187, + 105, 3, 190, 227, 192, 359, 21, 306, 307, 11, + 12, 103, 103, 103, 368, 107, 107, 107, 44, 45, + 22, 339, 24, 103, 26, 38, 206, 107, 106, 20, + 69, 103, 58, 59, 36, 107, 224, 39, 13, 14, + 110, 43, 11, 12, 46, 233, 94, 95, 79, 40, + 79, 42, 78, 50, 56, 96, 97, 79, 84, 61, + 51, 63, 3, 65, 110, 3, 102, 93, 102, 102, + 108, 108, 74, 75, 100, 35, 102, 8, 9, 10, + 11, 12, 102, 66, 102, 102, 3, 89, 8, 110, + 25, 110, 104, 66, 104, 66, 30, 103, 107, 107, + 102, 104, 98, 102, 4, 93, 294, 86, 296, 109, + 105, 101, 104, 102, 294, 100, 103, 111, 306, 307, + 4, 309, 310, 99, 80, 105, 6, 307, 8, 9, + 10, 112, 110, 321, 6, 107, 8, 9, 10, 105, + 102, 111, 22, 0, 24, 0, 26, 105, 105, 3, + 13, 128, 25, 108, 53, 343, 36, 70, 104, 39, + 62, 309, 292, 43, 44, 353, 46, 153, 226, 357, + 368, 222, 44, 45, 296, 326, 56, 270, 58, 59, + 267, 61, 353, 63, 185, 65, 58, 59, 272, 343, + 306, 238, 347, -1, 74, 75, -1, -1, -1, -1, + -1, -1, -1, -1, 84, -1, 78, -1, -1, 89, + 8, -1, 84, 11, 12, -1, -1, -1, -1, -1, + 18, 93, 102, -1, 22, 23, 24, -1, 26, 27, + 102, -1, -1, -1, -1, -1, -1, -1, 36, -1, + -1, 39, -1, -1, -1, 43, -1, -1, 46, 47, + 48, 49, -1, -1, -1, -1, -1, 55, 56, 57, + -1, -1, -1, 61, 62, 63, 64, 65, -1, 8, + -1, -1, 11, 12, 72, -1, 74, 75, 76, 77, + -1, -1, -1, 81, 23, 83, -1, -1, -1, -1, + 88, 89, 90, 91, 92, -1, -1, -1, -1, -1, + -1, -1, 41, -1, -1, -1, -1, -1, 47, 48, + 49, -1, -1, -1, 53, -1, -1, -1, 57, -1, + -1, -1, -1, 62, -1, 64, -1, -1, -1, -1, + -1, -1, -1, 72, -1, -1, -1, -1, -1, -1, + -1, -1, 81, -1, 83, -1, -1, -1, -1, 88, + -1, 90, 91, 92, 11, 12, 13, 14, -1, -1, + -1, 18, -1, -1, -1, 22, 23, 24, -1, 26, + 27, -1, -1, -1, -1, -1, 33, -1, -1, 36, + -1, -1, 39, -1, -1, -1, 43, -1, -1, 46, + 47, 48, 49, -1, -1, -1, -1, -1, 55, 56, + 57, -1, -1, -1, 61, 62, 63, 64, 65, -1, + 67, -1, -1, -1, -1, 72, -1, 74, 75, 76, + 77, -1, -1, -1, 81, -1, 83, -1, -1, 11, + 12, 88, 89, 90, 91, 92, 18, -1, -1, -1, + 22, 23, 24, -1, 26, 27, -1, -1, -1, -1, + -1, -1, -1, -1, 36, -1, -1, 39, -1, -1, + -1, 43, -1, -1, 46, 47, 48, 49, -1, -1, + -1, -1, -1, 55, 56, 57, -1, -1, -1, 61, + 62, 63, 64, 65, -1, -1, -1, -1, -1, -1, + 72, -1, 74, 75, 76, 77, -1, -1, -1, 81, + -1, 83, -1, 85, 11, 12, 88, 89, 90, 91, + 92, 18, -1, -1, -1, 22, 23, 24, -1, 26, + 27, -1, -1, -1, -1, -1, -1, -1, -1, 36, + -1, -1, 39, -1, -1, -1, 43, -1, -1, 46, + 47, 48, 49, -1, -1, -1, -1, -1, 55, 56, + 57, -1, -1, -1, 61, 62, 63, 64, 65, -1, + -1, -1, 11, 12, -1, 72, -1, 74, 75, 76, + 77, -1, -1, 22, 81, 24, 83, 26, 11, 12, + -1, 88, 89, 90, 91, 92, -1, 36, -1, 22, + 39, 24, -1, 26, 43, -1, -1, 46, -1, -1, + -1, -1, -1, 36, -1, -1, 39, 56, -1, -1, + 43, -1, 61, 46, 63, -1, 65, -1, -1, -1, + -1, -1, -1, 56, -1, 74, 75, -1, 61, -1, + 63, -1, 65, -1, -1, -1, -1, -1, -1, -1, + 89, 74, 75, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 89 +}; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "/usr/share/bison.simple" +/* This file comes from bison-1.28. */ + +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +#ifndef YYSTACK_USE_ALLOCA +#ifdef alloca +#define YYSTACK_USE_ALLOCA +#else /* alloca not defined */ +#ifdef __GNUC__ +#define YYSTACK_USE_ALLOCA +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) +#define YYSTACK_USE_ALLOCA +#include +#else /* not sparc */ +/* We think this test detects Watcom and Microsoft C. */ +/* This used to test MSDOS, but that is a bad idea + since that symbol is in the user namespace. */ +#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) +#if 0 /* No need for malloc.h, which pollutes the namespace; + instead, just don't use alloca. */ +#include +#endif +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +/* I don't know what this was needed for, but it pollutes the namespace. + So I turned it off. rms, 2 May 1997. */ +/* #include */ + #pragma alloca +#define YYSTACK_USE_ALLOCA +#else /* not MSDOS, or __TURBOC__, or _AIX */ +#if 0 +#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, + and on HPUX 10. Eventually we can turn this on. */ +#define YYSTACK_USE_ALLOCA +#define alloca __builtin_alloca +#endif /* __hpux */ +#endif +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc */ +#endif /* not GNU C */ +#endif /* alloca not defined */ +#endif /* YYSTACK_USE_ALLOCA not defined */ + +#ifdef YYSTACK_USE_ALLOCA +#define YYSTACK_ALLOC alloca +#else +#define YYSTACK_ALLOC malloc +#endif + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 +/* Like YYERROR except do call yyerror. + This remains here temporarily to ease the + transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define YYFAIL goto yyerrlab +#define YYRECOVERING() (!!yyerrstatus) +#define YYBACKUP(token, value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { yychar = (token), yylval = (value); \ + yychar1 = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +#ifndef YYPURE +#define YYLEX yylex() +#endif + +#ifdef YYPURE +#ifdef YYLSP_NEEDED +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval, &yylloc) +#endif +#else /* not YYLSP_NEEDED */ +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval) +#endif +#endif /* not YYLSP_NEEDED */ +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef YYPURE + +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ + +#ifdef YYLSP_NEEDED +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ +#endif + +int yynerrs; /* number of parse errors so far */ +#endif /* not YYPURE */ + +#if YYDEBUG != 0 +int yydebug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif + +/* YYINITDEPTH indicates the initial size of the parser's stacks */ + +#ifndef YYINITDEPTH +#define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#if YYMAXDEPTH == 0 +#undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 10000 +#endif + +/* Define __yy_memcpy. Note that the size argument + should be passed with type unsigned int, because that is what the non-GCC + definitions require. With GCC, __builtin_memcpy takes an arg + of type size_t, but it can handle unsigned int. */ + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (to, from, count) + char *to; + char *from; + unsigned int count; +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#else /* __cplusplus */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (char *to, char *from, unsigned int count) +{ + register char *t = to; + register char *f = from; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#endif +#endif + +#line 217 "/usr/share/bison.simple" + +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef YYPARSE_PARAM +#ifdef __cplusplus +#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#else /* not __cplusplus */ +#define YYPARSE_PARAM_ARG YYPARSE_PARAM +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +#endif /* not __cplusplus */ +#else /* not YYPARSE_PARAM */ +#define YYPARSE_PARAM_ARG +#define YYPARSE_PARAM_DECL +#endif /* not YYPARSE_PARAM */ + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +#ifdef YYPARSE_PARAM +int yyparse (void *); +#else +int yyparse (void); +#endif +#endif + +int +yyparse(YYPARSE_PARAM_ARG) + YYPARSE_PARAM_DECL +{ + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + +#ifdef YYLSP_NEEDED + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + +#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#else +#define YYPOPSTACK (yyvsp--, yyssp--) +#endif + + int yystacksize = YYINITDEPTH; + int yyfree_stacks = 0; + +#ifdef YYPURE + int yychar; + YYSTYPE yylval; + int yynerrs; +#ifdef YYLSP_NEEDED + YYLTYPE yylloc; +#endif +#endif + + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int yylen; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Starting parse\n"); +#endif + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss - 1; + yyvsp = yyvs; +#ifdef YYLSP_NEEDED + yylsp = yyls; +#endif + +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: + + *++yyssp = yystate; + + if (yyssp >= yyss + yystacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; +#ifdef YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; +#endif + + /* Get the current used size of the three stacks, in elements. */ + int size = yyssp - yyss + 1; + +#ifdef yyoverflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef YYLSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yyls1, size * sizeof (*yylsp), + &yystacksize); +#else + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yystacksize); +#endif + + yyss = yyss1; yyvs = yyvs1; +#ifdef YYLSP_NEEDED + yyls = yyls1; +#endif +#else /* no yyoverflow */ + /* Extend the stack our own way. */ + if (yystacksize >= YYMAXDEPTH) + { + yyerror("parser stack overflow"); + if (yyfree_stacks) + { + free (yyss); + free (yyvs); +#ifdef YYLSP_NEEDED + free (yyls); +#endif + } + return 2; + } + yystacksize *= 2; + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; +#ifndef YYSTACK_USE_ALLOCA + yyfree_stacks = 1; +#endif + yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); + __yy_memcpy ((char *)yyss, (char *)yyss1, + size * (unsigned int) sizeof (*yyssp)); + yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); + __yy_memcpy ((char *)yyvs, (char *)yyvs1, + size * (unsigned int) sizeof (*yyvsp)); +#ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); + __yy_memcpy ((char *)yyls, (char *)yyls1, + size * (unsigned int) sizeof (*yylsp)); +#endif +#endif /* no yyoverflow */ + + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; +#ifdef YYLSP_NEEDED + yylsp = yyls + size - 1; +#endif + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yystacksize); +#endif + + if (yyssp >= yyss + yystacksize - 1) + YYABORT; + } + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); +#endif + + goto yybackup; + yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (yychar == YYEMPTY) + { +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Reading a token: "); +#endif + yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); +#endif + } + else + { + yychar1 = YYTRANSLATE(yychar); + +#if YYDEBUG != 0 + if (yydebug) + { + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); +#endif + fprintf (stderr, ")\n"); + } +#endif + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); +#endif + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; + + yystate = yyn; + goto yynewstate; + +/* Do the default action for the current state. */ +yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + +/* Do a reduction. yyn is the number of a rule to reduce with. */ +yyreduce: + yylen = yyr2[yyn]; + if (yylen > 0) + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + +#if YYDEBUG != 0 + if (yydebug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); + + /* Print the symbols being reduced, and their result. */ + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", yytname[yyrhs[i]]); + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } +#endif + + + switch (yyn) { + +case 1: +#line 298 "asn1p_y.y" +{ + *(void **)param = yyvsp[0].a_grammar; + ; + break;} +case 2: +#line 304 "asn1p_y.y" +{ + yyval.a_grammar = asn1p_new(); + checkmem(yyval.a_grammar); + TQ_ADD(&(yyval.a_grammar->modules), yyvsp[0].a_module, mod_next); + ; + break;} +case 3: +#line 309 "asn1p_y.y" +{ + yyval.a_grammar = yyvsp[-1].a_grammar; + TQ_ADD(&(yyval.a_grammar->modules), yyvsp[0].a_module, mod_next); + ; + break;} +case 4: +#line 330 "asn1p_y.y" +{ + + if(yyvsp[-1].a_module) { + yyval.a_module = yyvsp[-1].a_module; + } else { + /* There's a chance that a module is just plain empty */ + yyval.a_module = asn1p_module_new(); + } + checkmem(yyval.a_module); + + yyval.a_module->Identifier = yyvsp[-7].tv_str; + yyval.a_module->module_oid = yyvsp[-6].a_oid; + yyval.a_module->module_flags = yyvsp[-4].a_module_flags; + ; + break;} +case 5: +#line 351 "asn1p_y.y" +{ yyval.a_oid = 0; ; + break;} +case 6: +#line 352 "asn1p_y.y" +{ yyval.a_oid = yyvsp[0].a_oid; ; + break;} +case 7: +#line 356 "asn1p_y.y" +{ + yyval.a_oid = yyvsp[-1].a_oid; + ; + break;} +case 8: +#line 359 "asn1p_y.y" +{ + yyval.a_oid = 0; + ; + break;} +case 9: +#line 365 "asn1p_y.y" +{ + yyval.a_oid = asn1p_oid_new(); + asn1p_oid_add_arc(yyval.a_oid, &yyvsp[0].a_oid_arc); + if(yyvsp[0].a_oid_arc.name) + free(yyvsp[0].a_oid_arc.name); + ; + break;} +case 10: +#line 371 "asn1p_y.y" +{ + yyval.a_oid = yyvsp[-1].a_oid; + asn1p_oid_add_arc(yyval.a_oid, &yyvsp[0].a_oid_arc); + if(yyvsp[0].a_oid_arc.name) + free(yyvsp[0].a_oid_arc.name); + ; + break;} +case 11: +#line 380 "asn1p_y.y" +{ /* iso */ + yyval.a_oid_arc.name = yyvsp[0].tv_str; + yyval.a_oid_arc.number = -1; + ; + break;} +case 12: +#line 384 "asn1p_y.y" +{ /* iso(1) */ + yyval.a_oid_arc.name = yyvsp[-3].tv_str; + yyval.a_oid_arc.number = yyvsp[-1].a_int; + ; + break;} +case 13: +#line 388 "asn1p_y.y" +{ /* 1 */ + yyval.a_oid_arc.name = 0; + yyval.a_oid_arc.number = yyvsp[0].a_int; + ; + break;} +case 14: +#line 398 "asn1p_y.y" +{ yyval.a_module_flags = MSF_NOFLAGS; ; + break;} +case 15: +#line 399 "asn1p_y.y" +{ + yyval.a_module_flags = yyvsp[0].a_module_flags; + ; + break;} +case 16: +#line 408 "asn1p_y.y" +{ + yyval.a_module_flags = yyvsp[0].a_module_flags; + ; + break;} +case 17: +#line 411 "asn1p_y.y" +{ + yyval.a_module_flags = yyvsp[-1].a_module_flags | yyvsp[0].a_module_flags; + ; + break;} +case 18: +#line 420 "asn1p_y.y" +{ + yyval.a_module_flags = MSF_EXPLICIT_TAGS; + ; + break;} +case 19: +#line 423 "asn1p_y.y" +{ + yyval.a_module_flags = MSF_IMPLICIT_TAGS; + ; + break;} +case 20: +#line 426 "asn1p_y.y" +{ + yyval.a_module_flags = MSF_AUTOMATIC_TAGS; + ; + break;} +case 21: +#line 429 "asn1p_y.y" +{ + yyval.a_module_flags = MSF_EXTENSIBILITY_IMPLIED; + ; + break;} +case 22: +#line 438 "asn1p_y.y" +{ yyval.a_module = 0; ; + break;} +case 23: +#line 439 "asn1p_y.y" +{ + assert(yyvsp[0].a_module); + yyval.a_module = yyvsp[0].a_module; + ; + break;} +case 24: +#line 449 "asn1p_y.y" +{ + yyval.a_module = yyvsp[0].a_module; + ; + break;} +case 25: +#line 452 "asn1p_y.y" +{ + yyval.a_module = yyvsp[-1].a_module; + +#ifdef MY_IMPORT +#error MY_IMPORT DEFINED ELSEWHERE! +#endif +#define MY_IMPORT(foo,field) do { \ + if(TQ_FIRST(&(yyvsp[0].a_module->foo))) { \ + TQ_ADD(&(yyval.a_module->foo), \ + TQ_REMOVE(&(yyvsp[0].a_module->foo), field), \ + field); \ + assert(TQ_FIRST(&(yyvsp[0].a_module->foo)) == 0); \ + } } while(0) + + MY_IMPORT(imports, xp_next); + MY_IMPORT(exports, xp_next); + MY_IMPORT(members, next); +#undef MY_IMPORT + + ; + break;} +case 26: +#line 478 "asn1p_y.y" +{ + yyval.a_module = yyvsp[0].a_module; + ; + break;} +case 27: +#line 481 "asn1p_y.y" +{ + yyval.a_module = asn1p_module_new(); + checkmem(yyval.a_module); + if(yyvsp[0].a_xports) { + TQ_ADD(&(yyval.a_module->exports), yyvsp[0].a_xports, xp_next); + } else { + /* "EXPORTS ALL;" ? */ + } + ; + break;} +case 28: +#line 490 "asn1p_y.y" +{ + yyval.a_module = asn1p_module_new(); + checkmem(yyval.a_module); + assert(yyvsp[0].a_expr->expr_type != A1TC_INVALID); + assert(yyvsp[0].a_expr->meta_type != AMT_INVALID); + TQ_ADD(&(yyval.a_module->members), yyvsp[0].a_expr, next); + ; + break;} +case 29: +#line 497 "asn1p_y.y" +{ + yyval.a_module = asn1p_module_new(); + checkmem(yyval.a_module); + assert(yyvsp[0].a_expr->expr_type != A1TC_INVALID); + assert(yyvsp[0].a_expr->meta_type != AMT_INVALID); + TQ_ADD(&(yyval.a_module->members), yyvsp[0].a_expr, next); + ; + break;} +case 30: +#line 510 "asn1p_y.y" +{ + yyval.a_module = asn1p_module_new(); + checkmem(yyval.a_module); + assert(yyvsp[0].a_expr->expr_type != A1TC_INVALID); + assert(yyvsp[0].a_expr->meta_type != AMT_INVALID); + TQ_ADD(&(yyval.a_module->members), yyvsp[0].a_expr, next); + ; + break;} +case 31: +#line 521 "asn1p_y.y" +{ + return yyerror( + "Attempt to redefine a standard basic type, " + "use -ftypesXY to switch back " + "to older version of ASN.1 standard"); + ; + break;} +case 32: +#line 535 "asn1p_y.y" +{ + yyval.a_module = yyvsp[-1].a_module; + ; + break;} +case 33: +#line 541 "asn1p_y.y" +{ + return yyerror("Empty IMPORTS list"); + ; + break;} +case 34: +#line 547 "asn1p_y.y" +{ + yyval.a_module = asn1p_module_new(); + checkmem(yyval.a_module); + TQ_ADD(&(yyval.a_module->imports), yyvsp[0].a_xports, xp_next); + ; + break;} +case 35: +#line 552 "asn1p_y.y" +{ + yyval.a_module = yyvsp[-1].a_module; + TQ_ADD(&(yyval.a_module->imports), yyvsp[0].a_xports, xp_next); + ; + break;} +case 36: +#line 559 "asn1p_y.y" +{ + yyval.a_xports = yyvsp[-3].a_xports; + yyval.a_xports->from = yyvsp[-1].tv_str; + yyval.a_xports->from_oid = yyvsp[0].a_oid; + checkmem(yyval.a_xports); + ; + break;} +case 37: +#line 568 "asn1p_y.y" +{ + yyval.a_xports = asn1p_xports_new(); + checkmem(yyval.a_xports); + TQ_ADD(&(yyval.a_xports->members), yyvsp[0].a_expr, next); + ; + break;} +case 38: +#line 573 "asn1p_y.y" +{ + yyval.a_xports = yyvsp[-2].a_xports; + TQ_ADD(&(yyval.a_xports->members), yyvsp[0].a_expr, next); + ; + break;} +case 39: +#line 580 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = yyvsp[0].tv_str; + yyval.a_expr->expr_type = A1TC_REFERENCE; + ; + break;} +case 40: +#line 586 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = yyvsp[0].tv_str; + yyval.a_expr->expr_type = A1TC_REFERENCE; + ; + break;} +case 41: +#line 595 "asn1p_y.y" +{ + yyval.a_xports = yyvsp[-1].a_xports; + ; + break;} +case 42: +#line 598 "asn1p_y.y" +{ + yyval.a_xports = 0; + ; + break;} +case 43: +#line 601 "asn1p_y.y" +{ + /* Empty EXPORTS clause effectively prohibits export. */ + yyval.a_xports = asn1p_xports_new(); + checkmem(yyval.a_xports); + ; + break;} +case 44: +#line 609 "asn1p_y.y" +{ + yyval.a_xports = asn1p_xports_new(); + assert(yyval.a_xports); + TQ_ADD(&(yyval.a_xports->members), yyvsp[0].a_expr, next); + ; + break;} +case 45: +#line 614 "asn1p_y.y" +{ + yyval.a_xports = yyvsp[-2].a_xports; + TQ_ADD(&(yyval.a_xports->members), yyvsp[0].a_expr, next); + ; + break;} +case 46: +#line 621 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = yyvsp[0].tv_str; + yyval.a_expr->expr_type = A1TC_EXPORTVAR; + ; + break;} +case 47: +#line 627 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = yyvsp[0].tv_str; + yyval.a_expr->expr_type = A1TC_EXPORTVAR; + ; + break;} +case 48: +#line 637 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-4].a_expr; + assert(yyval.a_expr->Identifier == 0); + yyval.a_expr->Identifier = yyvsp[-5].tv_str; + yyval.a_expr->meta_type = AMT_VALUESET; + // take care of optValueSetBody + ; + break;} +case 49: +#line 647 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->reference = yyvsp[0].a_ref; + yyval.a_expr->expr_type = A1TC_REFERENCE; + yyval.a_expr->meta_type = AMT_TYPEREF; + ; + break;} +case 50: +#line 654 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->expr_type = yyvsp[0].a_type; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 51: +#line 663 "asn1p_y.y" +{ ; + break;} +case 52: +#line 664 "asn1p_y.y" +{ + ; + break;} +case 53: +#line 680 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = yyvsp[-3].tv_str; + yyval.a_expr->tag = yyvsp[-1].a_tag; + yyval.a_expr->expr_type = A1TC_TYPEID; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 54: +#line 688 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[0].a_expr; + yyval.a_expr->Identifier = yyvsp[-3].tv_str; + yyval.a_expr->tag = yyvsp[-1].a_tag; + assert(yyval.a_expr->expr_type); + assert(yyval.a_expr->meta_type); + ; + break;} +case 55: +#line 695 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[0].a_expr; + yyval.a_expr->Identifier = yyvsp[-2].tv_str; + assert(yyval.a_expr->expr_type == A1TC_CLASSDEF); + assert(yyval.a_expr->meta_type == AMT_OBJECT); + ; + break;} +case 56: +#line 712 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[0].a_expr; + assert(yyval.a_expr->Identifier == 0); + yyval.a_expr->Identifier = yyvsp[-5].tv_str; + yyval.a_expr->params = yyvsp[-3].a_plist; + yyval.a_expr->meta_type = AMT_PARAMTYPE; + ; + break;} +case 57: +#line 722 "asn1p_y.y" +{ + int ret; + yyval.a_plist = asn1p_paramlist_new(yylineno); + checkmem(yyval.a_plist); + ret = asn1p_paramlist_add_param(yyval.a_plist, yyvsp[0].a_parg.governor, yyvsp[0].a_parg.argument); + checkmem(ret == 0); + if(yyvsp[0].a_parg.governor) asn1p_ref_free(yyvsp[0].a_parg.governor); + if(yyvsp[0].a_parg.argument) free(yyvsp[0].a_parg.argument); + ; + break;} +case 58: +#line 731 "asn1p_y.y" +{ + int ret; + yyval.a_plist = yyvsp[-2].a_plist; + ret = asn1p_paramlist_add_param(yyval.a_plist, yyvsp[0].a_parg.governor, yyvsp[0].a_parg.argument); + checkmem(ret == 0); + if(yyvsp[0].a_parg.governor) asn1p_ref_free(yyvsp[0].a_parg.governor); + if(yyvsp[0].a_parg.argument) free(yyvsp[0].a_parg.argument); + ; + break;} +case 59: +#line 742 "asn1p_y.y" +{ + yyval.a_parg.governor = NULL; + yyval.a_parg.argument = yyvsp[0].tv_str; + ; + break;} +case 60: +#line 746 "asn1p_y.y" +{ + int ret; + yyval.a_parg.governor = asn1p_ref_new(yylineno); + ret = asn1p_ref_add_component(yyval.a_parg.governor, yyvsp[-2].tv_str, 0); + checkmem(ret == 0); + yyval.a_parg.argument = yyvsp[0].tv_str; + ; + break;} +case 61: +#line 753 "asn1p_y.y" +{ + int ret; + yyval.a_parg.governor = asn1p_ref_new(yylineno); + ret = asn1p_ref_add_component(yyval.a_parg.governor, + ASN_EXPR_TYPE2STR(yyvsp[-2].a_type), 1); + checkmem(ret == 0); + yyval.a_parg.argument = yyvsp[0].tv_str; + ; + break;} +case 62: +#line 764 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + TQ_ADD(&(yyval.a_expr->members), yyvsp[0].a_expr, next); + ; + break;} +case 63: +#line 769 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-2].a_expr; + TQ_ADD(&(yyval.a_expr->members), yyvsp[0].a_expr, next); + ; + break;} +case 64: +#line 776 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[0].a_expr; + ; + break;} +case 65: +#line 779 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = yyvsp[0].tv_str; + yyval.a_expr->expr_type = A1TC_REFERENCE; + yyval.a_expr->meta_type = AMT_VALUE; + ; + break;} +case 66: +#line 792 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + TQ_ADD(&(yyval.a_expr->members), yyvsp[0].a_expr, next); + ; + break;} +case 67: +#line 797 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-2].a_expr; + TQ_ADD(&(yyval.a_expr->members), yyvsp[0].a_expr, next); + ; + break;} +case 68: +#line 804 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-2].a_expr; + checkmem(yyval.a_expr); + yyval.a_expr->with_syntax = yyvsp[0].a_wsynt; + assert(yyval.a_expr->expr_type == A1TC_CLASSDEF); + assert(yyval.a_expr->meta_type == AMT_OBJECT); + ; + break;} +case 69: +#line 814 "asn1p_y.y" +{ yyval.a_int = 0; ; + break;} +case 70: +#line 815 "asn1p_y.y" +{ yyval.a_int = 1; ; + break;} +case 71: +#line 819 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->expr_type = A1TC_CLASSDEF; + yyval.a_expr->meta_type = AMT_OBJECT; + TQ_ADD(&(yyval.a_expr->members), yyvsp[0].a_expr, next); + ; + break;} +case 72: +#line 826 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-2].a_expr; + TQ_ADD(&(yyval.a_expr->members), yyvsp[0].a_expr, next); + ; + break;} +case 73: +#line 833 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = yyvsp[-1].a_refcomp.name; + yyval.a_expr->expr_type = A1TC_CLASSFIELD; + yyval.a_expr->meta_type = AMT_OBJECTFIELD; + yyval.a_expr->marker = yyvsp[0].a_marker; + ; + break;} +case 74: +#line 841 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-1].a_expr; + yyval.a_expr->Identifier = yyvsp[-2].a_refcomp.name; + yyval.a_expr->unique = yyvsp[0].a_int; + ; + break;} +case 75: +#line 846 "asn1p_y.y" +{ + int ret; + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = yyvsp[-3].a_refcomp.name; + yyval.a_expr->reference = asn1p_ref_new(yylineno); + checkmem(yyval.a_expr->reference); + ret = asn1p_ref_add_component(yyval.a_expr->reference, + yyvsp[-2].a_refcomp.name, yyvsp[-2].a_refcomp.lex_type); + checkmem(ret == 0); + yyval.a_expr->expr_type = A1TC_CLASSFIELD; + yyval.a_expr->meta_type = AMT_OBJECTFIELD; + yyval.a_expr->marker = yyvsp[-1].a_marker; + yyval.a_expr->unique = yyvsp[0].a_int; + ; + break;} +case 76: +#line 864 "asn1p_y.y" +{ yyval.a_wsynt = 0; ; + break;} +case 77: +#line 865 "asn1p_y.y" +{ + yyval.a_wsynt = yyvsp[0].a_wsynt; + ; + break;} +case 78: +#line 872 "asn1p_y.y" +{ asn1p_lexer_hack_enable_with_syntax(); ; + break;} +case 79: +#line 874 "asn1p_y.y" +{ + yyval.a_wsynt = yyvsp[-1].a_wsynt; + ; + break;} +case 80: +#line 880 "asn1p_y.y" +{ + yyval.a_wsynt = asn1p_wsyntx_new(); + TQ_ADD(&(yyval.a_wsynt->chunks), yyvsp[0].a_wchunk, next); + ; + break;} +case 81: +#line 884 "asn1p_y.y" +{ + yyval.a_wsynt = yyvsp[-1].a_wsynt; + TQ_ADD(&(yyval.a_wsynt->chunks), yyvsp[0].a_wchunk, next); + ; + break;} +case 82: +#line 891 "asn1p_y.y" +{ + yyval.a_wchunk = asn1p_wsyntx_chunk_frombuf(yyvsp[0].tv_opaque.buf, yyvsp[0].tv_opaque.len, 0); + ; + break;} +case 83: +#line 894 "asn1p_y.y" +{ + asn1p_ref_t *ref; + int ret; + ref = asn1p_ref_new(yylineno); + checkmem(ref); + ret = asn1p_ref_add_component(ref, yyvsp[0].a_refcomp.name, yyvsp[0].a_refcomp.lex_type); + checkmem(ret == 0); + yyval.a_wchunk = asn1p_wsyntx_chunk_fromref(ref, 0); + ; + break;} +case 84: +#line 920 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[0].a_expr; + assert(yyval.a_expr->Identifier == 0); + yyval.a_expr->Identifier = yyvsp[-1].tv_nametag.name; + yyval.a_expr->tag = yyvsp[-1].tv_nametag.tag; + ; + break;} +case 85: +#line 926 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[0].a_expr; + ; + break;} +case 86: +#line 932 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-2].a_expr; + yyval.a_expr->constraints = yyvsp[-1].a_constr; + yyval.a_expr->marker = yyvsp[0].a_marker; + ; + break;} +case 87: +#line 940 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = strdup("..."); + checkmem(yyval.a_expr->Identifier); + yyval.a_expr->expr_type = A1TC_EXTENSIBLE; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 88: +#line 948 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = strdup("..."); + checkmem(yyval.a_expr->Identifier); + yyval.a_expr->value = yyvsp[0].a_value; + yyval.a_expr->expr_type = A1TC_EXTENSIBLE; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 89: +#line 957 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = strdup("..."); + yyval.a_expr->value = yyvsp[0].a_value; + checkmem(yyval.a_expr->Identifier); + yyval.a_expr->expr_type = A1TC_EXTENSIBLE; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 90: +#line 969 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[0].a_expr; + ; + break;} +case 91: +#line 972 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->expr_type = yyvsp[0].a_type; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 92: +#line 978 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[0].a_expr; + checkmem(yyval.a_expr); + assert(yyval.a_expr->meta_type); + ; + break;} +case 93: +#line 986 "asn1p_y.y" +{ + int ret; + yyval.a_expr = yyvsp[-1].a_expr; + assert(yyval.a_expr->expr_type == 0); + assert(yyval.a_expr->meta_type == 0); + assert(yyval.a_expr->reference == 0); + yyval.a_expr->reference = asn1p_ref_new(yylineno); + checkmem(yyval.a_expr->reference); + ret = asn1p_ref_add_component(yyval.a_expr->reference, yyvsp[-3].tv_str, RLT_UNKNOWN); + checkmem(ret == 0); + free(yyvsp[-3].tv_str); + yyval.a_expr->expr_type = A1TC_PARAMETRIZED; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 94: +#line 1010 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->reference = yyvsp[0].a_ref; + yyval.a_expr->expr_type = A1TC_REFERENCE; + yyval.a_expr->meta_type = AMT_TYPEREF; + ; + break;} +case 95: +#line 1017 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(yylineno); + checkmem(yyval.a_expr); + yyval.a_expr->reference = yyvsp[0].a_ref; + yyval.a_expr->expr_type = A1TC_INSTANCE; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 96: +#line 1032 "asn1p_y.y" +{ + int ret; + yyval.a_ref = asn1p_ref_new(yylineno); + checkmem(yyval.a_ref); + ret = asn1p_ref_add_component(yyval.a_ref, yyvsp[0].tv_str, RLT_UNKNOWN); + checkmem(ret == 0); + free(yyvsp[0].tv_str); + ; + break;} +case 97: +#line 1040 "asn1p_y.y" +{ + int ret; + yyval.a_ref = asn1p_ref_new(yylineno); + checkmem(yyval.a_ref); + ret = asn1p_ref_add_component(yyval.a_ref, yyvsp[-2].tv_str, RLT_UNKNOWN); + checkmem(ret == 0); + ret = asn1p_ref_add_component(yyval.a_ref, yyvsp[0].tv_str, RLT_UNKNOWN); + checkmem(ret == 0); + free(yyvsp[-2].tv_str); + ; + break;} +case 98: +#line 1050 "asn1p_y.y" +{ + int ret; + yyval.a_ref = asn1p_ref_new(yylineno); + checkmem(yyval.a_ref); + ret = asn1p_ref_add_component(yyval.a_ref, yyvsp[-2].tv_str, RLT_UNKNOWN); + checkmem(ret == 0); + ret = asn1p_ref_add_component(yyval.a_ref, yyvsp[0].tv_str, RLT_lowercase); + checkmem(ret == 0); + free(yyvsp[-2].tv_str); + ; + break;} +case 99: +#line 1060 "asn1p_y.y" +{ + int ret; + yyval.a_ref = asn1p_ref_new(yylineno); + checkmem(yyval.a_ref); + ret = asn1p_ref_add_component(yyval.a_ref, yyvsp[0].tv_str, RLT_CAPITALS); + free(yyvsp[0].tv_str); + checkmem(ret == 0); + ; + break;} +case 100: +#line 1068 "asn1p_y.y" +{ + int ret; + yyval.a_ref = yyvsp[0].a_ref; + ret = asn1p_ref_add_component(yyval.a_ref, yyvsp[-2].tv_str, RLT_CAPITALS); + free(yyvsp[-2].tv_str); + checkmem(ret == 0); + /* + * Move the last element infront. + */ + { + struct asn1p_ref_component_s tmp_comp; + tmp_comp = yyval.a_ref->components[yyval.a_ref->comp_count-1]; + memmove(&yyval.a_ref->components[1], + &yyval.a_ref->components[0], + sizeof(yyval.a_ref->components[0]) + * (yyval.a_ref->comp_count - 1)); + yyval.a_ref->components[0] = tmp_comp; + } + ; + break;} +case 101: +#line 1090 "asn1p_y.y" +{ + int ret; + yyval.a_ref = asn1p_ref_new(yylineno); + checkmem(yyval.a_ref); + ret = asn1p_ref_add_component(yyval.a_ref, yyvsp[0].a_refcomp.name, yyvsp[0].a_refcomp.lex_type); + free(yyvsp[0].a_refcomp.name); + checkmem(ret == 0); + ; + break;} +case 102: +#line 1098 "asn1p_y.y" +{ + int ret; + yyval.a_ref = yyvsp[-2].a_ref; + ret = asn1p_ref_add_component(yyval.a_ref, yyvsp[0].a_refcomp.name, yyvsp[0].a_refcomp.lex_type); + free(yyvsp[0].a_refcomp.name); + checkmem(ret == 0); + ; + break;} +case 105: +#line 1112 "asn1p_y.y" +{ + yyval.a_refcomp.lex_type = RLT_AmpUppercase; + yyval.a_refcomp.name = yyvsp[0].tv_str; + ; + break;} +case 106: +#line 1117 "asn1p_y.y" +{ + yyval.a_refcomp.lex_type = RLT_Amplowercase; + yyval.a_refcomp.name = yyvsp[0].tv_str; + ; + break;} +case 107: +#line 1130 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-2].a_expr; + assert(yyval.a_expr->Identifier == NULL); + yyval.a_expr->Identifier = yyvsp[-3].tv_str; + yyval.a_expr->meta_type = AMT_VALUE; + yyval.a_expr->value = yyvsp[0].a_value; + ; + break;} +case 108: +#line 1140 "asn1p_y.y" +{ asn1p_lexer_hack_push_opaque_state(); ; + break;} +case 109: +#line 1141 "asn1p_y.y" +{ + yyval.a_value = asn1p_value_frombuf(yyvsp[0].tv_opaque.buf, yyvsp[0].tv_opaque.len, 0); + checkmem(yyval.a_value); + yyval.a_value->type = ATV_UNPARSED; + ; + break;} +case 110: +#line 1146 "asn1p_y.y" +{ + yyval.a_value = _convert_bitstring2binary(yyvsp[0].tv_str, 'B'); + checkmem(yyval.a_value); + ; + break;} +case 111: +#line 1150 "asn1p_y.y" +{ + yyval.a_value = _convert_bitstring2binary(yyvsp[0].tv_str, 'H'); + checkmem(yyval.a_value); + ; + break;} +case 112: +#line 1154 "asn1p_y.y" +{ + yyval.a_value = asn1p_value_frombuf(yyvsp[0].tv_opaque.buf, yyvsp[0].tv_opaque.len, 0); + checkmem(yyval.a_value); + ; + break;} +case 113: +#line 1158 "asn1p_y.y" +{ + yyval.a_value = yyvsp[0].a_value; + ; + break;} +case 114: +#line 1161 "asn1p_y.y" +{ + yyval.a_value = yyvsp[0].a_value; + ; + break;} +case 115: +#line 1167 "asn1p_y.y" +{ + asn1p_ref_t *ref; + int ret; + ref = asn1p_ref_new(yylineno); + checkmem(ref); + ret = asn1p_ref_add_component(ref, yyvsp[0].tv_str, RLT_lowercase); + checkmem(ret == 0); + yyval.a_value = asn1p_value_fromref(ref, 0); + checkmem(yyval.a_value); + free(yyvsp[0].tv_str); + ; + break;} +case 116: +#line 1178 "asn1p_y.y" +{ + asn1p_ref_t *ref; + int ret; + ref = asn1p_ref_new(yylineno); + checkmem(ref); + ret = asn1p_ref_add_component(ref, yyvsp[-2].tv_str, RLT_UNKNOWN); + checkmem(ret == 0); + ret = asn1p_ref_add_component(ref, yyvsp[0].tv_str, RLT_lowercase); + checkmem(ret == 0); + yyval.a_value = asn1p_value_fromref(ref, 0); + checkmem(yyval.a_value); + free(yyvsp[-2].tv_str); + free(yyvsp[0].tv_str); + ; + break;} +case 117: +#line 1195 "asn1p_y.y" +{ + yyval.tv_opaque.len = yyvsp[0].tv_opaque.len + 2; + yyval.tv_opaque.buf = malloc(yyval.tv_opaque.len + 1); + checkmem(yyval.tv_opaque.buf); + yyval.tv_opaque.buf[0] = '{'; + yyval.tv_opaque.buf[1] = ' '; + memcpy(yyval.tv_opaque.buf + 2, yyvsp[0].tv_opaque.buf, yyvsp[0].tv_opaque.len); + yyval.tv_opaque.buf[yyval.tv_opaque.len] = '\0'; + free(yyvsp[0].tv_opaque.buf); + ; + break;} +case 118: +#line 1205 "asn1p_y.y" +{ + int newsize = yyvsp[-1].tv_opaque.len + yyvsp[0].tv_opaque.len; + char *p = malloc(newsize + 1); + checkmem(p); + memcpy(p , yyvsp[-1].tv_opaque.buf, yyvsp[-1].tv_opaque.len); + memcpy(p + yyvsp[-1].tv_opaque.len, yyvsp[0].tv_opaque.buf, yyvsp[0].tv_opaque.len); + p[newsize] = '\0'; + free(yyvsp[-1].tv_opaque.buf); + free(yyvsp[0].tv_opaque.buf); + yyval.tv_opaque.buf = p; + yyval.tv_opaque.len = newsize; + ; + break;} +case 119: +#line 1220 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_BOOLEAN; ; + break;} +case 120: +#line 1221 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_NULL; ; + break;} +case 121: +#line 1222 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_REAL; ; + break;} +case 122: +#line 1223 "asn1p_y.y" +{ yyval.a_type = yyvsp[0].a_type; ; + break;} +case 123: +#line 1224 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_OCTET_STRING; ; + break;} +case 124: +#line 1225 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_OBJECT_IDENTIFIER; ; + break;} +case 125: +#line 1226 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_RELATIVE_OID; ; + break;} +case 126: +#line 1227 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_EXTERNAL; ; + break;} +case 127: +#line 1228 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_EMBEDDED_PDV; ; + break;} +case 128: +#line 1229 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_CHARACTER_STRING; ; + break;} +case 129: +#line 1230 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_UTCTime; ; + break;} +case 130: +#line 1231 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_GeneralizedTime; ; + break;} +case 131: +#line 1238 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_INTEGER; ; + break;} +case 132: +#line 1239 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_ENUMERATED; ; + break;} +case 133: +#line 1240 "asn1p_y.y" +{ yyval.a_type = ASN_BASIC_BIT_STRING; ; + break;} +case 134: +#line 1244 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->expr_type = yyvsp[0].a_type; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 135: +#line 1250 "asn1p_y.y" +{ + if(yyvsp[0].a_expr) { + yyval.a_expr = yyvsp[0].a_expr; + } else { + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + } + yyval.a_expr->expr_type = yyvsp[-1].a_type; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 136: +#line 1263 "asn1p_y.y" +{ yyval.a_type = ASN_STRING_BMPString; ; + break;} +case 137: +#line 1264 "asn1p_y.y" +{ + yyval.a_type = ASN_STRING_GeneralString; + return yyerror("GeneralString is not supported"); + ; + break;} +case 138: +#line 1268 "asn1p_y.y" +{ + yyval.a_type = ASN_STRING_GraphicString; + return yyerror("GraphicString is not supported"); + ; + break;} +case 139: +#line 1272 "asn1p_y.y" +{ yyval.a_type = ASN_STRING_IA5String; ; + break;} +case 140: +#line 1273 "asn1p_y.y" +{ yyval.a_type = ASN_STRING_ISO646String; ; + break;} +case 141: +#line 1274 "asn1p_y.y" +{ yyval.a_type = ASN_STRING_NumericString; ; + break;} +case 142: +#line 1275 "asn1p_y.y" +{ yyval.a_type = ASN_STRING_PrintableString; ; + break;} +case 143: +#line 1276 "asn1p_y.y" +{ + yyval.a_type = ASN_STRING_T61String; + return yyerror("T61String not implemented yet"); + ; + break;} +case 144: +#line 1280 "asn1p_y.y" +{ yyval.a_type = ASN_STRING_TeletexString; ; + break;} +case 145: +#line 1281 "asn1p_y.y" +{ yyval.a_type = ASN_STRING_UniversalString; ; + break;} +case 146: +#line 1282 "asn1p_y.y" +{ yyval.a_type = ASN_STRING_UTF8String; ; + break;} +case 147: +#line 1283 "asn1p_y.y" +{ + yyval.a_type = ASN_STRING_VideotexString; + return yyerror("VideotexString is no longer supported"); + ; + break;} +case 148: +#line 1287 "asn1p_y.y" +{ yyval.a_type = ASN_STRING_VisibleString; ; + break;} +case 149: +#line 1288 "asn1p_y.y" +{ yyval.a_type = ASN_STRING_ObjectDescriptor; ; + break;} +case 150: +#line 1292 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-1].a_expr; + assert(yyval.a_expr->expr_type == A1TC_INVALID); + yyval.a_expr->expr_type = ASN_CONSTR_CHOICE; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 151: +#line 1298 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-1].a_expr; + assert(yyval.a_expr->expr_type == A1TC_INVALID); + yyval.a_expr->expr_type = ASN_CONSTR_SEQUENCE; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 152: +#line 1304 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-1].a_expr; + assert(yyval.a_expr->expr_type == A1TC_INVALID); + yyval.a_expr->expr_type = ASN_CONSTR_SET; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 153: +#line 1310 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->constraints = yyvsp[-2].a_constr; + yyval.a_expr->expr_type = ASN_CONSTR_SEQUENCE_OF; + yyval.a_expr->meta_type = AMT_TYPE; + TQ_ADD(&(yyval.a_expr->members), yyvsp[0].a_expr, next); + ; + break;} +case 154: +#line 1318 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->constraints = yyvsp[-2].a_constr; + yyval.a_expr->expr_type = ASN_CONSTR_SET_OF; + yyval.a_expr->meta_type = AMT_TYPE; + TQ_ADD(&(yyval.a_expr->members), yyvsp[0].a_expr, next); + ; + break;} +case 155: +#line 1326 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->expr_type = ASN_CONSTR_ANY; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 156: +#line 1332 "asn1p_y.y" +{ + int ret; + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->reference = asn1p_ref_new(yylineno); + ret = asn1p_ref_add_component(yyval.a_expr->reference, + yyvsp[0].tv_str, RLT_lowercase); + checkmem(ret == 0); + yyval.a_expr->expr_type = ASN_CONSTR_ANY; + yyval.a_expr->meta_type = AMT_TYPE; + ; + break;} +case 157: +#line 1349 "asn1p_y.y" +{ yyval.a_constr = 0; ; + break;} +case 158: +#line 1350 "asn1p_y.y" +{ yyval.a_constr = yyvsp[0].a_constr; ; + break;} +case 164: +#line 1358 "asn1p_y.y" +{ + /* + * This is a special case, for compatibility purposes. + * It goes without parenthesis. + */ + int ret; + yyval.a_constr = asn1p_constraint_new(yylineno); + checkmem(yyval.a_constr); + yyval.a_constr->type = ACT_CT_SIZE; + ret = asn1p_constraint_insert(yyval.a_constr, yyvsp[-1].a_constr); + checkmem(ret == 0); + ; + break;} +case 165: +#line 1370 "asn1p_y.y" +{ + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_SET, yyvsp[0].a_constr, 0); + ; + break;} +case 166: +#line 1373 "asn1p_y.y" +{ + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_SET, yyvsp[-1].a_constr, yyvsp[0].a_constr); + ; + break;} +case 167: +#line 1379 "asn1p_y.y" +{ + yyval.a_constr = yyvsp[-1].a_constr; + ; + break;} +case 168: +#line 1385 "asn1p_y.y" +{ + yyval.a_constr = yyvsp[0].a_constr; + ; + break;} +case 169: +#line 1388 "asn1p_y.y" +{ + asn1p_constraint_t *ct; + ct = asn1p_constraint_new(yylineno); + checkmem(ct); + ct->type = ACT_EL_EXT; + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_CSV, yyvsp[-2].a_constr, ct); + ; + break;} +case 170: +#line 1395 "asn1p_y.y" +{ + asn1p_constraint_t *ct; + ct = asn1p_constraint_new(yylineno); + checkmem(ct); + ct->type = ACT_EL_EXT; + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_CSV, yyvsp[-4].a_constr, ct); + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_CSV, yyvsp[-4].a_constr, yyvsp[0].a_constr); + ; + break;} +case 171: +#line 1403 "asn1p_y.y" +{ + yyval.a_constr = asn1p_constraint_new(yylineno); + checkmem(yyval.a_constr); + yyval.a_constr->type = ACT_EL_EXT; + ; + break;} +case 172: +#line 1408 "asn1p_y.y" +{ + asn1p_constraint_t *ct; + ct = asn1p_constraint_new(yylineno); + checkmem(ct); + ct->type = ACT_EL_EXT; + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_CSV, ct, yyvsp[0].a_constr); + ; + break;} +case 173: +#line 1417 "asn1p_y.y" +{ yyval.a_constr = yyvsp[0].a_constr; ; + break;} +case 174: +#line 1420 "asn1p_y.y" +{ yyval.a_constr = yyvsp[0].a_constr; ; + break;} +case 175: +#line 1421 "asn1p_y.y" +{ + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_UNI, yyvsp[-2].a_constr, yyvsp[0].a_constr); + ; + break;} +case 176: +#line 1427 "asn1p_y.y" +{ yyval.a_constr = yyvsp[0].a_constr; ; + break;} +case 177: +#line 1429 "asn1p_y.y" +{ + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_INT, yyvsp[-2].a_constr, yyvsp[0].a_constr); + ; + break;} +case 178: +#line 1435 "asn1p_y.y" +{ yyval.a_constr = yyvsp[0].a_constr; ; + break;} +case 179: +#line 1436 "asn1p_y.y" +{ + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_EXC, yyvsp[-2].a_constr, yyvsp[0].a_constr); + ; + break;} +case 180: +#line 1442 "asn1p_y.y" +{ + yyval.a_constr = asn1p_constraint_new(yylineno); + checkmem(yyval.a_constr); + yyval.a_constr->type = ACT_EL_VALUE; + yyval.a_constr->value = yyvsp[0].a_value; + ; + break;} +case 181: +#line 1448 "asn1p_y.y" +{ + yyval.a_constr = asn1p_constraint_new(yylineno); + checkmem(yyval.a_constr); + yyval.a_constr->type = yyvsp[-1].a_ctype; + yyval.a_constr->range_start = yyvsp[-2].a_value; + yyval.a_constr->range_stop = yyvsp[0].a_value; + ; + break;} +case 182: +#line 1455 "asn1p_y.y" +{ + int ret; + yyval.a_constr = asn1p_constraint_new(yylineno); + checkmem(yyval.a_constr); + yyval.a_constr->type = yyvsp[-3].a_ctype; + ret = asn1p_constraint_insert(yyval.a_constr, yyvsp[-1].a_constr); + checkmem(ret == 0); + ; + break;} +case 183: +#line 1463 "asn1p_y.y" +{ + yyval.a_constr = yyvsp[0].a_constr; + ; + break;} +case 184: +#line 1466 "asn1p_y.y" +{ + yyval.a_constr = yyvsp[0].a_constr; + ; + break;} +case 185: +#line 1472 "asn1p_y.y" +{ yyval.a_ctype = ACT_EL_RANGE; ; + break;} +case 186: +#line 1473 "asn1p_y.y" +{ yyval.a_ctype = ACT_EL_RLRANGE; ; + break;} +case 187: +#line 1474 "asn1p_y.y" +{ yyval.a_ctype = ACT_EL_LLRANGE; ; + break;} +case 188: +#line 1475 "asn1p_y.y" +{ yyval.a_ctype = ACT_EL_ULRANGE; ; + break;} +case 189: +#line 1479 "asn1p_y.y" +{ + yyval.a_ctype = ACT_CT_SIZE; + ; + break;} +case 190: +#line 1482 "asn1p_y.y" +{ + yyval.a_ctype = ACT_CT_FROM; + ; + break;} +case 191: +#line 1488 "asn1p_y.y" +{ + yyval.a_value = yyvsp[0].a_value; + ; + break;} +case 192: +#line 1491 "asn1p_y.y" +{ + asn1p_ref_t *ref; + int ret; + ref = asn1p_ref_new(yylineno); + checkmem(ref); + ret = asn1p_ref_add_component(ref, yyvsp[0].tv_str, RLT_lowercase); + checkmem(ret == 0); + yyval.a_value = asn1p_value_fromref(ref, 0); + checkmem(yyval.a_value); + free(yyvsp[0].tv_str); + ; + break;} +case 193: +#line 1502 "asn1p_y.y" +{ + yyval.a_value = asn1p_value_frombuf(yyvsp[0].tv_opaque.buf, yyvsp[0].tv_opaque.len, 0); + checkmem(yyval.a_value); + ; + break;} +case 194: +#line 1506 "asn1p_y.y" +{ + yyval.a_value = asn1p_value_fromint(123); + checkmem(yyval.a_value); + yyval.a_value->type = ATV_MIN; + ; + break;} +case 195: +#line 1511 "asn1p_y.y" +{ + yyval.a_value = asn1p_value_fromint(321); + checkmem(yyval.a_value); + yyval.a_value->type = ATV_MAX; + ; + break;} +case 196: +#line 1516 "asn1p_y.y" +{ + yyval.a_value = asn1p_value_fromint(0); + checkmem(yyval.a_value); + yyval.a_value->type = ATV_FALSE; + ; + break;} +case 197: +#line 1521 "asn1p_y.y" +{ + yyval.a_value = asn1p_value_fromint(1); + checkmem(yyval.a_value); + yyval.a_value->type = ATV_TRUE; + ; + break;} +case 198: +#line 1529 "asn1p_y.y" +{ + CONSTRAINT_INSERT(yyval.a_constr, ACT_CT_WCOMPS, yyvsp[-1].a_constr, 0); + ; + break;} +case 199: +#line 1535 "asn1p_y.y" +{ + yyval.a_constr = yyvsp[0].a_constr; + ; + break;} +case 200: +#line 1538 "asn1p_y.y" +{ + CONSTRAINT_INSERT(yyval.a_constr, ACT_CT_WCOMPS, yyvsp[-2].a_constr, yyvsp[0].a_constr); + ; + break;} +case 201: +#line 1544 "asn1p_y.y" +{ + yyval.a_constr = asn1p_constraint_new(yylineno); + checkmem(yyval.a_constr); + yyval.a_constr->type = ACT_EL_EXT; + ; + break;} +case 202: +#line 1549 "asn1p_y.y" +{ + yyval.a_constr = asn1p_constraint_new(yylineno); + checkmem(yyval.a_constr); + yyval.a_constr->type = ACT_EL_VALUE; + yyval.a_constr->value = asn1p_value_frombuf(yyvsp[-2].tv_str, strlen(yyvsp[-2].tv_str), 0); + yyval.a_constr->presence = yyvsp[0].a_pres; + ; + break;} +case 203: +#line 1562 "asn1p_y.y" +{ yyval.a_pres = ACPRES_DEFAULT; ; + break;} +case 204: +#line 1563 "asn1p_y.y" +{ yyval.a_pres = yyvsp[0].a_pres; ; + break;} +case 205: +#line 1567 "asn1p_y.y" +{ + yyval.a_pres = ACPRES_PRESENT; + ; + break;} +case 206: +#line 1570 "asn1p_y.y" +{ + yyval.a_pres = ACPRES_ABSENT; + ; + break;} +case 207: +#line 1573 "asn1p_y.y" +{ + yyval.a_pres = ACPRES_OPTIONAL; + ; + break;} +case 208: +#line 1579 "asn1p_y.y" +{ + yyval.a_constr = yyvsp[0].a_constr; + ; + break;} +case 209: +#line 1582 "asn1p_y.y" +{ + yyval.a_constr = yyvsp[0].a_constr; + ; + break;} +case 210: +#line 1591 "asn1p_y.y" +{ + asn1p_ref_t *ref = asn1p_ref_new(yylineno); + asn1p_constraint_t *ct; + int ret; + ret = asn1p_ref_add_component(ref, yyvsp[-1].tv_str, 0); + checkmem(ret == 0); + ct = asn1p_constraint_new(yylineno); + checkmem(yyval.a_constr); + ct->type = ACT_EL_VALUE; + ct->value = asn1p_value_fromref(ref, 0); + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_CRC, ct, 0); + ; + break;} +case 211: +#line 1606 "asn1p_y.y" +{ + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_CRC, yyvsp[-3].a_constr, yyvsp[-1].a_constr); + ; + break;} +case 212: +#line 1612 "asn1p_y.y" +{ + yyval.a_constr = asn1p_constraint_new(yylineno); + checkmem(yyval.a_constr); + yyval.a_constr->type = ACT_EL_VALUE; + yyval.a_constr->value = asn1p_value_fromref(yyvsp[0].a_ref, 0); + ; + break;} +case 213: +#line 1618 "asn1p_y.y" +{ + asn1p_constraint_t *ct; + ct = asn1p_constraint_new(yylineno); + checkmem(ct); + ct->type = ACT_EL_VALUE; + ct->value = asn1p_value_fromref(yyvsp[0].a_ref, 0); + CONSTRAINT_INSERT(yyval.a_constr, ACT_CA_CSV, yyvsp[-2].a_constr, ct); + ; + break;} +case 214: +#line 1632 "asn1p_y.y" +{ + char *p = malloc(strlen(yyvsp[0].tv_str) + 2); + int ret; + *p = '@'; + strcpy(p + 1, yyvsp[0].tv_str); + yyval.a_ref = asn1p_ref_new(yylineno); + ret = asn1p_ref_add_component(yyval.a_ref, p, 0); + checkmem(ret == 0); + free(p); + free(yyvsp[0].tv_str); + ; + break;} +case 215: +#line 1643 "asn1p_y.y" +{ + char *p = malloc(strlen(yyvsp[0].tv_str) + 3); + int ret; + p[0] = '@'; + p[1] = '.'; + strcpy(p + 2, yyvsp[0].tv_str); + yyval.a_ref = asn1p_ref_new(yylineno); + ret = asn1p_ref_add_component(yyval.a_ref, p, 0); + checkmem(ret == 0); + free(p); + free(yyvsp[0].tv_str); + ; + break;} +case 216: +#line 1659 "asn1p_y.y" +{ + yyval.tv_str = yyvsp[0].tv_str; + ; + break;} +case 217: +#line 1662 "asn1p_y.y" +{ + int l1 = strlen(yyvsp[-2].tv_str); + int l3 = strlen(yyvsp[0].tv_str); + yyval.tv_str = malloc(l1 + 1 + l3 + 1); + memcpy(yyval.tv_str, yyvsp[-2].tv_str, l1); + yyval.tv_str[l1] = '.'; + memcpy(yyval.tv_str + l1 + 1, yyvsp[0].tv_str, l3); + yyval.tv_str[l1 + 1 + l3] = '\0'; + ; + break;} +case 218: +#line 1680 "asn1p_y.y" +{ yyval.a_marker = EM_NOMARK; ; + break;} +case 219: +#line 1681 "asn1p_y.y" +{ yyval.a_marker = yyvsp[0].a_marker; ; + break;} +case 220: +#line 1685 "asn1p_y.y" +{ + yyval.a_marker = EM_OPTIONAL; + ; + break;} +case 221: +#line 1688 "asn1p_y.y" +{ + yyval.a_marker = EM_DEFAULT; + /* FIXME: store DefaultValue somewhere */ + ; + break;} +case 222: +#line 1695 "asn1p_y.y" +{ + ; + break;} +case 223: +#line 1697 "asn1p_y.y" +{ + ; + break;} +case 224: +#line 1699 "asn1p_y.y" +{ asn1p_lexer_hack_push_opaque_state(); ; + break;} +case 225: +#line 1699 "asn1p_y.y" +{ + ; + break;} +case 226: +#line 1720 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + ; + break;} +case 227: +#line 1724 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-1].a_expr; + ; + break;} +case 228: +#line 1730 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + TQ_ADD(&(yyval.a_expr->members), yyvsp[0].a_expr, next); + ; + break;} +case 229: +#line 1735 "asn1p_y.y" +{ + yyval.a_expr = yyvsp[-2].a_expr; + TQ_ADD(&(yyval.a_expr->members), yyvsp[0].a_expr, next); + ; + break;} +case 230: +#line 1742 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->expr_type = A1TC_UNIVERVAL; + yyval.a_expr->meta_type = AMT_VALUE; + yyval.a_expr->Identifier = yyvsp[0].tv_str; + ; + break;} +case 231: +#line 1749 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->expr_type = A1TC_UNIVERVAL; + yyval.a_expr->meta_type = AMT_VALUE; + yyval.a_expr->Identifier = yyvsp[-3].tv_str; + yyval.a_expr->value = yyvsp[-1].a_value; + ; + break;} +case 232: +#line 1757 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->expr_type = A1TC_UNIVERVAL; + yyval.a_expr->meta_type = AMT_VALUE; + yyval.a_expr->Identifier = yyvsp[-3].tv_str; + yyval.a_expr->value = yyvsp[-1].a_value; + ; + break;} +case 233: +#line 1765 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->expr_type = A1TC_UNIVERVAL; + yyval.a_expr->meta_type = AMT_VALUE; + yyval.a_expr->value = yyvsp[0].a_value; + ; + break;} +case 234: +#line 1772 "asn1p_y.y" +{ + yyval.a_expr = asn1p_expr_new(asn1p_lineno); + checkmem(yyval.a_expr); + yyval.a_expr->Identifier = strdup("..."); + checkmem(yyval.a_expr->Identifier); + yyval.a_expr->expr_type = A1TC_EXTENSIBLE; + yyval.a_expr->meta_type = AMT_VALUE; + ; + break;} +case 235: +#line 1783 "asn1p_y.y" +{ + yyval.a_value = asn1p_value_fromint(yyvsp[0].a_int); + checkmem(yyval.a_value); + ; + break;} +case 236: +#line 1787 "asn1p_y.y" +{ + yyval.a_value = asn1p_value_fromint(yyvsp[0].a_int); + checkmem(yyval.a_value); + ; + break;} +case 237: +#line 1818 "asn1p_y.y" +{ memset(&yyval.a_tag, 0, sizeof(yyval.a_tag)); ; + break;} +case 238: +#line 1819 "asn1p_y.y" +{ yyval.a_tag = yyvsp[0].a_tag; ; + break;} +case 239: +#line 1823 "asn1p_y.y" +{ + yyval.a_tag = yyvsp[0].a_tag; + yyval.a_tag.tag_mode = TM_DEFAULT; + ; + break;} +case 240: +#line 1827 "asn1p_y.y" +{ + yyval.a_tag = yyvsp[-1].a_tag; + yyval.a_tag.tag_mode = TM_IMPLICIT; + ; + break;} +case 241: +#line 1831 "asn1p_y.y" +{ + yyval.a_tag = yyvsp[-1].a_tag; + yyval.a_tag.tag_mode = TM_EXPLICIT; + ; + break;} +case 242: +#line 1838 "asn1p_y.y" +{ + checkmem(yyvsp[0].tv_str); + yyval.tv_str = yyvsp[0].tv_str; + ; + break;} +case 243: +#line 1842 "asn1p_y.y" +{ + checkmem(yyvsp[0].tv_str); + yyval.tv_str = yyvsp[0].tv_str; + ; + break;} +case 244: +#line 1849 "asn1p_y.y" +{ + checkmem(yyvsp[0].tv_str); + yyval.tv_str = yyvsp[0].tv_str; + ; + break;} +case 245: +#line 1856 "asn1p_y.y" +{ + checkmem(yyvsp[0].tv_str); + yyval.tv_str = yyvsp[0].tv_str; + ; + break;} +case 246: +#line 1863 "asn1p_y.y" +{ + memset(&yyval.tv_nametag, 0, sizeof(yyval.tv_nametag)); + yyval.tv_nametag.name = yyvsp[0].tv_str; + ; + break;} +case 247: +#line 1867 "asn1p_y.y" +{ + yyval.tv_nametag.name = yyvsp[-1].tv_str; + yyval.tv_nametag.tag = yyvsp[0].a_tag; + ; + break;} +} + /* the action file gets copied in in place of this dollarsign */ +#line 543 "/usr/share/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +#ifdef YYLSP_NEEDED + yylsp -= yylen; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + + *++yyvsp = yyval; + +#ifdef YYLSP_NEEDED + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } +#endif + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + +yyerrlab: /* here on detecting error */ + + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ + { + ++yynerrs; + +#ifdef YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (yyn > YYFLAG && yyn < YYLAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; + } + } + yyerror(msg); + free(msg); + } + else + yyerror ("parse error; also virtual memory exceeded"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror("parse error"); + } + + goto yyerrlab1; +yyerrlab1: /* here on error raised explicitly by an action */ + + if (yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (yychar == YYEOF) + YYABORT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); +#endif + + yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + +yyerrdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif + +yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; +#ifdef YYLSP_NEEDED + yylsp--; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + +yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting error token, "); +#endif + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + yystate = yyn; + goto yynewstate; + + yyacceptlab: + /* YYACCEPT comes here. */ + if (yyfree_stacks) + { + free (yyss); + free (yyvs); +#ifdef YYLSP_NEEDED + free (yyls); +#endif + } + return 0; + + yyabortlab: + /* YYABORT comes here. */ + if (yyfree_stacks) + { + free (yyss); + free (yyvs); +#ifdef YYLSP_NEEDED + free (yyls); +#endif + } + return 1; +} +#line 1874 "asn1p_y.y" + + + +/* + * Convert Xstring ('0101'B or '5'H) to the binary vector. + */ +static asn1p_value_t * +_convert_bitstring2binary(char *str, int base) { + asn1p_value_t *val; + int slen; + int memlen; + int baselen; + int bits; + uint8_t *binary_vector; + uint8_t *bv_ptr; + uint8_t cur_val; + + assert(str); + assert(str[0] == '\''); + + switch(base) { + case 'B': + baselen = 1; + break; + case 'H': + baselen = 4; + break; + default: + assert(base == 'B' || base == 'H'); + errno = EINVAL; + return NULL; + } + + slen = strlen(str); + assert(str[slen - 1] == base); + assert(str[slen - 2] == '\''); + + memlen = slen / (8 / baselen); /* Conservative estimate */ + + bv_ptr = binary_vector = malloc(memlen + 1); + if(bv_ptr == NULL) + /* ENOMEM */ + return NULL; + + cur_val = 0; + bits = 0; + while(*(++str) != '\'') { + switch(baselen) { + case 1: + switch(*str) { + case '1': + cur_val |= 1 << (7 - (bits % 8)); + case '0': + break; + default: + assert(!"_y UNREACH1"); + case ' ': case '\r': case '\n': + continue; + } + break; + case 4: + switch(*str) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + cur_val |= (*str - '0') << (4 - (bits % 8)); + break; + case 'A': case 'B': case 'C': + case 'D': case 'E': case 'F': + cur_val |= ((*str - 'A') + 10) + << (4 - (bits % 8)); + break; + default: + assert(!"_y UNREACH2"); + case ' ': case '\r': case '\n': + continue; + } + break; + } + + bits += baselen; + if((bits % 8) == 0) { + *bv_ptr++ = cur_val; + cur_val = 0; + } + } + + *bv_ptr = cur_val; + assert((bv_ptr - binary_vector) <= memlen); + + val = asn1p_value_frombits(binary_vector, bits, 0); + if(val == NULL) { + free(binary_vector); + } + + return val; +} + +extern char *asn1p_text; + +int +yyerror(const char *msg) { + fprintf(stderr, + "ASN.1 grammar parse error " + "near line %d (token \"%s\"): %s\n", + asn1p_lineno, asn1p_text, msg); + return -1; +} + + diff --git a/libasn1parser/asn1p_y.h b/libasn1parser/asn1p_y.h new file mode 100644 index 00000000..61679e3d --- /dev/null +++ b/libasn1parser/asn1p_y.h @@ -0,0 +1,132 @@ +typedef union { + asn1p_t *a_grammar; + asn1p_module_flags_e a_module_flags; + asn1p_module_t *a_module; + asn1p_expr_type_e a_type; /* ASN.1 Type */ + asn1p_expr_t *a_expr; /* Constructed collection */ + asn1p_constraint_t *a_constr; /* Constraint */ + enum asn1p_constraint_type_e a_ctype;/* Constraint type */ + asn1p_xports_t *a_xports; /* IMports/EXports */ + asn1p_oid_t *a_oid; /* Object Identifier */ + asn1p_oid_arc_t a_oid_arc; /* Single OID's arc */ + struct asn1p_type_tag_s a_tag; /* A tag */ + asn1p_ref_t *a_ref; /* Reference to custom type */ + asn1p_wsyntx_t *a_wsynt; /* WITH SYNTAX contents */ + asn1p_wsyntx_chunk_t *a_wchunk; /* WITH SYNTAX chunk */ + struct asn1p_ref_component_s a_refcomp; /* Component of a reference */ + asn1p_value_t *a_value; /* Number, DefinedValue, etc */ + struct asn1p_param_s a_parg; /* A parameter argument */ + asn1p_paramlist_t *a_plist; /* A pargs list */ + enum asn1p_expr_marker_e a_marker; /* OPTIONAL/DEFAULT */ + enum asn1p_constr_pres_e a_pres; /* PRESENT/ABSENT/OPTIONAL */ + asn1_integer_t a_int; + char *tv_str; + struct { + char *buf; + int len; + } tv_opaque; + struct { + char *name; + struct asn1p_type_tag_s tag; + } tv_nametag; +} YYSTYPE; +#define TOK_PPEQ 257 +#define TOK_opaque 258 +#define TOK_bstring 259 +#define TOK_cstring 260 +#define TOK_hstring 261 +#define TOK_identifier 262 +#define TOK_number 263 +#define TOK_number_negative 264 +#define TOK_typereference 265 +#define TOK_objectclassreference 266 +#define TOK_typefieldreference 267 +#define TOK_valuefieldreference 268 +#define TOK_ABSENT 269 +#define TOK_ABSTRACT_SYNTAX 270 +#define TOK_ALL 271 +#define TOK_ANY 272 +#define TOK_APPLICATION 273 +#define TOK_AUTOMATIC 274 +#define TOK_BEGIN 275 +#define TOK_BIT 276 +#define TOK_BMPString 277 +#define TOK_BOOLEAN 278 +#define TOK_BY 279 +#define TOK_CHARACTER 280 +#define TOK_CHOICE 281 +#define TOK_CLASS 282 +#define TOK_COMPONENT 283 +#define TOK_COMPONENTS 284 +#define TOK_CONSTRAINED 285 +#define TOK_CONTAINING 286 +#define TOK_DEFAULT 287 +#define TOK_DEFINITIONS 288 +#define TOK_DEFINED 289 +#define TOK_EMBEDDED 290 +#define TOK_ENCODED 291 +#define TOK_END 292 +#define TOK_ENUMERATED 293 +#define TOK_EXPLICIT 294 +#define TOK_EXPORTS 295 +#define TOK_EXTENSIBILITY 296 +#define TOK_EXTERNAL 297 +#define TOK_FALSE 298 +#define TOK_FROM 299 +#define TOK_GeneralizedTime 300 +#define TOK_GeneralString 301 +#define TOK_GraphicString 302 +#define TOK_IA5String 303 +#define TOK_IDENTIFIER 304 +#define TOK_IMPLICIT 305 +#define TOK_IMPLIED 306 +#define TOK_IMPORTS 307 +#define TOK_INCLUDES 308 +#define TOK_INSTANCE 309 +#define TOK_INTEGER 310 +#define TOK_ISO646String 311 +#define TOK_MAX 312 +#define TOK_MIN 313 +#define TOK_MINUS_INFINITY 314 +#define TOK_NULL 315 +#define TOK_NumericString 316 +#define TOK_OBJECT 317 +#define TOK_ObjectDescriptor 318 +#define TOK_OCTET 319 +#define TOK_OF 320 +#define TOK_OPTIONAL 321 +#define TOK_PATTERN 322 +#define TOK_PDV 323 +#define TOK_PLUS_INFINITY 324 +#define TOK_PRESENT 325 +#define TOK_PrintableString 326 +#define TOK_PRIVATE 327 +#define TOK_REAL 328 +#define TOK_RELATIVE_OID 329 +#define TOK_SEQUENCE 330 +#define TOK_SET 331 +#define TOK_SIZE 332 +#define TOK_STRING 333 +#define TOK_SYNTAX 334 +#define TOK_T61String 335 +#define TOK_TAGS 336 +#define TOK_TeletexString 337 +#define TOK_TRUE 338 +#define TOK_TYPE_IDENTIFIER 339 +#define TOK_UNIQUE 340 +#define TOK_UNIVERSAL 341 +#define TOK_UniversalString 342 +#define TOK_UTCTime 343 +#define TOK_UTF8String 344 +#define TOK_VideotexString 345 +#define TOK_VisibleString 346 +#define TOK_WITH 347 +#define TOK_UNION 348 +#define TOK_INTERSECTION 349 +#define TOK_EXCEPT 350 +#define TOK_TwoDots 351 +#define TOK_ThreeDots 352 +#define TOK_tag 353 + + +extern YYSTYPE asn1p_lval; diff --git a/libasn1parser/asn1p_y.y b/libasn1parser/asn1p_y.y new file mode 100644 index 00000000..822a8efb --- /dev/null +++ b/libasn1parser/asn1p_y.y @@ -0,0 +1,1982 @@ +%{ + +#include +#include +#include +#include +#include + +#include "asn1parser.h" + +#define YYPARSE_PARAM param +#define YYERROR_VERBOSE + +int yylex(void); +int yyerror(const char *msg); +void asn1p_lexer_hack_push_opaque_state(void); +void asn1p_lexer_hack_enable_with_syntax(void); +#define yylineno asn1p_lineno +extern int asn1p_lineno; + + +static asn1p_value_t * + _convert_bitstring2binary(char *str, int base); + +#define checkmem(ptr) do { \ + if(!(ptr)) \ + return yyerror("Memory failure"); \ + } while(0) + +#define CONSTRAINT_INSERT(root, constr_type, arg1, arg2) do { \ + if(arg1->type != constr_type) { \ + int __ret; \ + root = asn1p_constraint_new(yylineno); \ + checkmem(root); \ + root->type = constr_type; \ + __ret = asn1p_constraint_insert(root, \ + arg1); \ + checkmem(__ret == 0); \ + } else { \ + root = arg1; \ + } \ + if(arg2) { \ + int __ret \ + = asn1p_constraint_insert(root, arg2); \ + checkmem(__ret == 0); \ + } \ + } while(0) + +%} + + +/* + * Token value definition. + * a_*: ASN-specific types. + * tv_*: Locally meaningful types. + */ +%union { + asn1p_t *a_grammar; + asn1p_module_flags_e a_module_flags; + asn1p_module_t *a_module; + asn1p_expr_type_e a_type; /* ASN.1 Type */ + asn1p_expr_t *a_expr; /* Constructed collection */ + asn1p_constraint_t *a_constr; /* Constraint */ + enum asn1p_constraint_type_e a_ctype;/* Constraint type */ + asn1p_xports_t *a_xports; /* IMports/EXports */ + asn1p_oid_t *a_oid; /* Object Identifier */ + asn1p_oid_arc_t a_oid_arc; /* Single OID's arc */ + struct asn1p_type_tag_s a_tag; /* A tag */ + asn1p_ref_t *a_ref; /* Reference to custom type */ + asn1p_wsyntx_t *a_wsynt; /* WITH SYNTAX contents */ + asn1p_wsyntx_chunk_t *a_wchunk; /* WITH SYNTAX chunk */ + struct asn1p_ref_component_s a_refcomp; /* Component of a reference */ + asn1p_value_t *a_value; /* Number, DefinedValue, etc */ + struct asn1p_param_s a_parg; /* A parameter argument */ + asn1p_paramlist_t *a_plist; /* A pargs list */ + enum asn1p_expr_marker_e a_marker; /* OPTIONAL/DEFAULT */ + enum asn1p_constr_pres_e a_pres; /* PRESENT/ABSENT/OPTIONAL */ + asn1_integer_t a_int; + char *tv_str; + struct { + char *buf; + int len; + } tv_opaque; + struct { + char *name; + struct asn1p_type_tag_s tag; + } tv_nametag; +}; + +/* + * Token types returned by scanner. + */ +%token TOK_PPEQ /* "::=", Pseudo Pascal EQuality */ +%token TOK_opaque /* opaque data (driven from .y) */ +%token TOK_bstring +%token TOK_cstring +%token TOK_hstring +%token TOK_identifier +%token TOK_number +%token TOK_number_negative +%token TOK_typereference +%token TOK_objectclassreference /* "CLASS1" */ +%token TOK_typefieldreference /* "&Pork" */ +%token TOK_valuefieldreference /* "&id" */ + +/* + * Token types representing ASN.1 standard keywords. + */ +%token TOK_ABSENT +%token TOK_ABSTRACT_SYNTAX +%token TOK_ALL +%token TOK_ANY +%token TOK_APPLICATION +%token TOK_AUTOMATIC +%token TOK_BEGIN +%token TOK_BIT +%token TOK_BMPString +%token TOK_BOOLEAN +%token TOK_BY +%token TOK_CHARACTER +%token TOK_CHOICE +%token TOK_CLASS +%token TOK_COMPONENT +%token TOK_COMPONENTS +%token TOK_CONSTRAINED +%token TOK_CONTAINING +%token TOK_DEFAULT +%token TOK_DEFINITIONS +%token TOK_DEFINED +%token TOK_EMBEDDED +%token TOK_ENCODED +%token TOK_END +%token TOK_ENUMERATED +%token TOK_EXPLICIT +%token TOK_EXPORTS +%token TOK_EXTENSIBILITY +%token TOK_EXTERNAL +%token TOK_FALSE +%token TOK_FROM +%token TOK_GeneralizedTime +%token TOK_GeneralString +%token TOK_GraphicString +%token TOK_IA5String +%token TOK_IDENTIFIER +%token TOK_IMPLICIT +%token TOK_IMPLIED +%token TOK_IMPORTS +%token TOK_INCLUDES +%token TOK_INSTANCE +%token TOK_INTEGER +%token TOK_ISO646String +%token TOK_MAX +%token TOK_MIN +%token TOK_MINUS_INFINITY +%token TOK_NULL +%token TOK_NumericString +%token TOK_OBJECT +%token TOK_ObjectDescriptor +%token TOK_OCTET +%token TOK_OF +%token TOK_OPTIONAL +%token TOK_PATTERN +%token TOK_PDV +%token TOK_PLUS_INFINITY +%token TOK_PRESENT +%token TOK_PrintableString +%token TOK_PRIVATE +%token TOK_REAL +%token TOK_RELATIVE_OID +%token TOK_SEQUENCE +%token TOK_SET +%token TOK_SIZE +%token TOK_STRING +%token TOK_SYNTAX +%token TOK_T61String +%token TOK_TAGS +%token TOK_TeletexString +%token TOK_TRUE +%token TOK_TYPE_IDENTIFIER +%token TOK_UNIQUE +%token TOK_UNIVERSAL +%token TOK_UniversalString +%token TOK_UTCTime +%token TOK_UTF8String +%token TOK_VideotexString +%token TOK_VisibleString +%token TOK_WITH + +%left '|' TOK_UNION +%left '^' TOK_INTERSECTION +%left TOK_EXCEPT + +/* Misc tags */ +%token TOK_TwoDots /* .. */ +%token TOK_ThreeDots /* ... */ +%token TOK_tag /* [0] */ + + +/* + * Types defined herein. + */ +%type ModuleList +%type ModuleSpecification +%type ModuleSpecificationBody +%type ModuleSpecificationElement +%type optModuleSpecificationBody /* Optional */ +%type optModuleSpecificationFlags +%type ModuleSpecificationFlags /* Set of FL */ +%type ModuleSpecificationFlag /* Single FL */ +%type ImportsDefinition +%type ImportsBundleSet +%type ImportsBundle +%type ImportsList +%type ExportsDefinition +%type ExportsBody +%type ImportsElement +%type ExportsElement +%type DataTypeMember +%type ExtensionAndException +%type TypeDeclaration +%type ComplexTypeReference +%type ComplexTypeReferenceAmpList +%type ComplexTypeReferenceElement +%type ClassFieldIdentifier +%type ClassFieldName +%type ClassFieldList +%type ClassField +%type ClassDeclaration +%type ConstrainedTypeDeclaration +%type DataTypeReference /* Type1 ::= Type2 */ +%type DefinedTypeRef +%type ValueSetDefinition /* Val INTEGER ::= {1|2} */ +%type ValueDefinition /* val INTEGER ::= 1*/ +%type optValueSetBody +%type InlineOrDefinedValue +%type DefinedValue +%type SignedNumber +%type ConstructedType +%type ConstructedDataTypeDefinition +//%type optUniverationDefinition +%type UniverationDefinition +%type UniverationList +%type UniverationElement +%type TypeRefName +%type ObjectClassReference +%type TaggedIdentifier +%type Identifier +%type ParameterArgumentName +%type ParameterArgumentList +%type ActualParameter +%type ActualParameterList +%type ObjectIdentifier /* OID */ +%type optObjectIdentifier /* Optional OID */ +%type ObjectIdentifierBody +%type ObjectIdentifierElement +%type BasicType +%type BasicTypeId +%type BasicTypeId_UniverationCompatible +%type BasicString +%type Opaque +//%type StringValue +%type Tag /* [UNIVERSAL 0] IMPLICIT */ +%type optTag /* [UNIVERSAL 0] IMPLICIT */ +%type optConstraints +%type Constraints +%type SingleConstraint /* (SIZE(2)) */ +%type ConstraintElementSet /* 1..2,...,3 */ +%type ConstraintSubtypeElement /* 1..2 */ +%type ConstraintElementIntersection +%type ConstraintElementException +%type ConstraintElementUnion +%type ConstraintElement +%type SimpleTableConstraint +%type TableConstraint +%type WithComponents +%type WithComponentsList +%type WithComponentsElement +%type ComponentRelationConstraint +%type AtNotationList +%type AtNotationElement +%type ConstraintValue +%type ConstraintSpec +%type ConstraintRangeSpec +%type optWithSyntax +%type WithSyntax +%type WithSyntaxFormat +%type WithSyntaxFormatToken +%type optMarker Marker +%type optUnique +%type optPresenceConstraint PresenceConstraint +%type ComponentIdList + + +%% + + +ParsedGrammar: + ModuleList { + *(void **)param = $1; + } + ; + +ModuleList: + ModuleSpecification { + $$ = asn1p_new(); + checkmem($$); + TQ_ADD(&($$->modules), $1, mod_next); + } + | ModuleList ModuleSpecification { + $$ = $1; + TQ_ADD(&($$->modules), $2, mod_next); + } + ; + +/* + * ASN module definition. + * === EXAMPLE === + * MySyntax DEFINITIONS AUTOMATIC TAGS ::= + * BEGIN + * ... + * END + * === EOF === + */ + +ModuleSpecification: + TypeRefName optObjectIdentifier TOK_DEFINITIONS + optModuleSpecificationFlags + TOK_PPEQ TOK_BEGIN + optModuleSpecificationBody + TOK_END { + + if($7) { + $$ = $7; + } else { + /* There's a chance that a module is just plain empty */ + $$ = asn1p_module_new(); + } + checkmem($$); + + $$->Identifier = $1; + $$->module_oid = $2; + $$->module_flags = $4; + } + ; + +/* + * Object Identifier Definition + * { iso member-body(2) 3 } + */ +optObjectIdentifier: + { $$ = 0; } + | ObjectIdentifier { $$ = $1; } + ; + +ObjectIdentifier: + '{' ObjectIdentifierBody '}' { + $$ = $2; + } + | '{' '}' { + $$ = 0; + } + ; + +ObjectIdentifierBody: + ObjectIdentifierElement { + $$ = asn1p_oid_new(); + asn1p_oid_add_arc($$, &$1); + if($1.name) + free($1.name); + } + | ObjectIdentifierBody ObjectIdentifierElement { + $$ = $1; + asn1p_oid_add_arc($$, &$2); + if($2.name) + free($2.name); + } + ; + +ObjectIdentifierElement: + Identifier { /* iso */ + $$.name = $1; + $$.number = -1; + } + | Identifier '(' TOK_number ')' { /* iso(1) */ + $$.name = $1; + $$.number = $3; + } + | TOK_number { /* 1 */ + $$.name = 0; + $$.number = $1; + } + ; + +/* + * Optional module flags. + */ +optModuleSpecificationFlags: + { $$ = MSF_NOFLAGS; } + | ModuleSpecificationFlags { + $$ = $1; + } + ; + +/* + * Module flags. + */ +ModuleSpecificationFlags: + ModuleSpecificationFlag { + $$ = $1; + } + | ModuleSpecificationFlags ModuleSpecificationFlag { + $$ = $1 | $2; + } + ; + +/* + * Single module flag. + */ +ModuleSpecificationFlag: + TOK_EXPLICIT TOK_TAGS { + $$ = MSF_EXPLICIT_TAGS; + } + | TOK_IMPLICIT TOK_TAGS { + $$ = MSF_IMPLICIT_TAGS; + } + | TOK_AUTOMATIC TOK_TAGS { + $$ = MSF_AUTOMATIC_TAGS; + } + | TOK_EXTENSIBILITY TOK_IMPLIED { + $$ = MSF_EXTENSIBILITY_IMPLIED; + } + ; + +/* + * Optional module body. + */ +optModuleSpecificationBody: + { $$ = 0; } + | ModuleSpecificationBody { + assert($1); + $$ = $1; + } + ; + +/* + * ASN.1 Module body. + */ +ModuleSpecificationBody: + ModuleSpecificationElement { + $$ = $1; + } + | ModuleSpecificationBody ModuleSpecificationElement { + $$ = $1; + +#ifdef MY_IMPORT +#error MY_IMPORT DEFINED ELSEWHERE! +#endif +#define MY_IMPORT(foo,field) do { \ + if(TQ_FIRST(&($2->foo))) { \ + TQ_ADD(&($$->foo), \ + TQ_REMOVE(&($2->foo), field), \ + field); \ + assert(TQ_FIRST(&($2->foo)) == 0); \ + } } while(0) + + MY_IMPORT(imports, xp_next); + MY_IMPORT(exports, xp_next); + MY_IMPORT(members, next); +#undef MY_IMPORT + + } + ; + +/* + * One of the elements of ASN.1 module specification. + */ +ModuleSpecificationElement: + ImportsDefinition { + $$ = $1; + } + | ExportsDefinition { + $$ = asn1p_module_new(); + checkmem($$); + if($1) { + TQ_ADD(&($$->exports), $1, xp_next); + } else { + /* "EXPORTS ALL;" ? */ + } + } + | DataTypeReference { + $$ = asn1p_module_new(); + checkmem($$); + assert($1->expr_type != A1TC_INVALID); + assert($1->meta_type != AMT_INVALID); + TQ_ADD(&($$->members), $1, next); + } + | ValueDefinition { + $$ = asn1p_module_new(); + checkmem($$); + assert($1->expr_type != A1TC_INVALID); + assert($1->meta_type != AMT_INVALID); + TQ_ADD(&($$->members), $1, next); + } + /* + * Value set definition + * === EXAMPLE === + * EvenNumbers INTEGER ::= { 2 | 4 | 6 | 8 } + * === EOF === + */ + | ValueSetDefinition { + $$ = asn1p_module_new(); + checkmem($$); + assert($1->expr_type != A1TC_INVALID); + assert($1->meta_type != AMT_INVALID); + TQ_ADD(&($$->members), $1, next); + } + + /* + * Erroneous attemps + */ + | BasicString { + return yyerror( + "Attempt to redefine a standard basic type, " + "use -ftypesXY to switch back " + "to older version of ASN.1 standard"); + } + ; + +/* + * === EXAMPLE === + * IMPORTS Type1, value FROM Module { iso standard(0) } ; + * === EOF === + */ +ImportsDefinition: + TOK_IMPORTS ImportsBundleSet ';' { + $$ = $2; + } + /* + * Some error cases. + */ + | TOK_IMPORTS TOK_FROM /* ... */ { + return yyerror("Empty IMPORTS list"); + } + ; + +ImportsBundleSet: + ImportsBundle { + $$ = asn1p_module_new(); + checkmem($$); + TQ_ADD(&($$->imports), $1, xp_next); + } + | ImportsBundleSet ImportsBundle { + $$ = $1; + TQ_ADD(&($$->imports), $2, xp_next); + } + ; + +ImportsBundle: + ImportsList TOK_FROM TypeRefName optObjectIdentifier { + $$ = $1; + $$->from = $3; + $$->from_oid = $4; + checkmem($$); + } + ; + +ImportsList: + ImportsElement { + $$ = asn1p_xports_new(); + checkmem($$); + TQ_ADD(&($$->members), $1, next); + } + | ImportsList ',' ImportsElement { + $$ = $1; + TQ_ADD(&($$->members), $3, next); + } + ; + +ImportsElement: + TypeRefName { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->Identifier = $1; + $$->expr_type = A1TC_REFERENCE; + } + | Identifier { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->Identifier = $1; + $$->expr_type = A1TC_REFERENCE; + } + ; + +ExportsDefinition: + TOK_EXPORTS ExportsBody ';' { + $$ = $2; + } + | TOK_EXPORTS TOK_ALL ';' { + $$ = 0; + } + | TOK_EXPORTS ';' { + /* Empty EXPORTS clause effectively prohibits export. */ + $$ = asn1p_xports_new(); + checkmem($$); + } + ; + +ExportsBody: + ExportsElement { + $$ = asn1p_xports_new(); + assert($$); + TQ_ADD(&($$->members), $1, next); + } + | ExportsBody ',' ExportsElement { + $$ = $1; + TQ_ADD(&($$->members), $3, next); + } + ; + +ExportsElement: + TypeRefName { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->Identifier = $1; + $$->expr_type = A1TC_EXPORTVAR; + } + | Identifier { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->Identifier = $1; + $$->expr_type = A1TC_EXPORTVAR; + } + ; + + +ValueSetDefinition: + TypeRefName DefinedTypeRef TOK_PPEQ '{' optValueSetBody '}' { + $$ = $2; + assert($$->Identifier == 0); + $$->Identifier = $1; + $$->meta_type = AMT_VALUESET; + // take care of optValueSetBody + } + ; + +DefinedTypeRef: + ComplexTypeReference { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->reference = $1; + $$->expr_type = A1TC_REFERENCE; + $$->meta_type = AMT_TYPEREF; + } + | BasicTypeId { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->expr_type = $1; + $$->meta_type = AMT_TYPE; + } + ; + +optValueSetBody: + { } + | ConstraintElementSet { + } + ; + + +/* + * Data Type Reference. + * === EXAMPLE === + * Type3 ::= CHOICE { a Type1, b Type 2 } + * === EOF === + */ + +DataTypeReference: + /* + * Optionally tagged type definition. + */ + TypeRefName TOK_PPEQ optTag TOK_TYPE_IDENTIFIER { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->Identifier = $1; + $$->tag = $3; + $$->expr_type = A1TC_TYPEID; + $$->meta_type = AMT_TYPE; + } + | TypeRefName TOK_PPEQ optTag ConstrainedTypeDeclaration { + $$ = $4; + $$->Identifier = $1; + $$->tag = $3; + assert($$->expr_type); + assert($$->meta_type); + } + | TypeRefName TOK_PPEQ ClassDeclaration { + $$ = $3; + $$->Identifier = $1; + assert($$->expr_type == A1TC_CLASSDEF); + assert($$->meta_type == AMT_OBJECT); + } + /* + * Parametrized declaration: + * === EXAMPLE === + * SIGNED { ToBeSigned } ::= SEQUENCE { + * toBeSigned ToBeSigned, + * algorithm AlgorithmIdentifier, + * signature BIT STRING + * } + * === EOF === + */ + | TypeRefName '{' ParameterArgumentList '}' + TOK_PPEQ ConstrainedTypeDeclaration { + $$ = $6; + assert($$->Identifier == 0); + $$->Identifier = $1; + $$->params = $3; + $$->meta_type = AMT_PARAMTYPE; + } + ; + +ParameterArgumentList: + ParameterArgumentName { + int ret; + $$ = asn1p_paramlist_new(yylineno); + checkmem($$); + ret = asn1p_paramlist_add_param($$, $1.governor, $1.argument); + checkmem(ret == 0); + if($1.governor) asn1p_ref_free($1.governor); + if($1.argument) free($1.argument); + } + | ParameterArgumentList ',' ParameterArgumentName { + int ret; + $$ = $1; + ret = asn1p_paramlist_add_param($$, $3.governor, $3.argument); + checkmem(ret == 0); + if($3.governor) asn1p_ref_free($3.governor); + if($3.argument) free($3.argument); + } + ; + +ParameterArgumentName: + TypeRefName { + $$.governor = NULL; + $$.argument = $1; + } + | TypeRefName ':' Identifier { + int ret; + $$.governor = asn1p_ref_new(yylineno); + ret = asn1p_ref_add_component($$.governor, $1, 0); + checkmem(ret == 0); + $$.argument = $3; + } + | BasicTypeId ':' Identifier { + int ret; + $$.governor = asn1p_ref_new(yylineno); + ret = asn1p_ref_add_component($$.governor, + ASN_EXPR_TYPE2STR($1), 1); + checkmem(ret == 0); + $$.argument = $3; + } + ; + +ActualParameterList: + ActualParameter { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + TQ_ADD(&($$->members), $1, next); + } + | ActualParameterList ',' ActualParameter { + $$ = $1; + TQ_ADD(&($$->members), $3, next); + } + ; + +ActualParameter: + TypeDeclaration { + $$ = $1; + } + | Identifier { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->Identifier = $1; + $$->expr_type = A1TC_REFERENCE; + $$->meta_type = AMT_VALUE; + } + ; + +/* + * A collection of constructed data type members. + */ +ConstructedDataTypeDefinition: + DataTypeMember { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + TQ_ADD(&($$->members), $1, next); + } + | ConstructedDataTypeDefinition ',' DataTypeMember { + $$ = $1; + TQ_ADD(&($$->members), $3, next); + } + ; + +ClassDeclaration: + TOK_CLASS '{' ClassFieldList '}' optWithSyntax { + $$ = $3; + checkmem($$); + $$->with_syntax = $5; + assert($$->expr_type == A1TC_CLASSDEF); + assert($$->meta_type == AMT_OBJECT); + } + ; + +optUnique: + { $$ = 0; } + | TOK_UNIQUE { $$ = 1; } + ; + +ClassFieldList: + ClassField { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->expr_type = A1TC_CLASSDEF; + $$->meta_type = AMT_OBJECT; + TQ_ADD(&($$->members), $1, next); + } + | ClassFieldList ',' ClassField { + $$ = $1; + TQ_ADD(&($$->members), $3, next); + } + ; + +ClassField: + ClassFieldIdentifier optMarker { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->Identifier = $1.name; + $$->expr_type = A1TC_CLASSFIELD; + $$->meta_type = AMT_OBJECTFIELD; + $$->marker = $2; + } + | ClassFieldIdentifier ConstrainedTypeDeclaration optUnique { + $$ = $2; + $$->Identifier = $1.name; + $$->unique = $3; + } + | ClassFieldIdentifier ClassFieldIdentifier optMarker optUnique { + int ret; + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->Identifier = $1.name; + $$->reference = asn1p_ref_new(yylineno); + checkmem($$->reference); + ret = asn1p_ref_add_component($$->reference, + $2.name, $2.lex_type); + checkmem(ret == 0); + $$->expr_type = A1TC_CLASSFIELD; + $$->meta_type = AMT_OBJECTFIELD; + $$->marker = $3; + $$->unique = $4; + } + ; + +optWithSyntax: + { $$ = 0; } + | WithSyntax { + $$ = $1; + } + ; + +WithSyntax: + TOK_WITH TOK_SYNTAX '{' + { asn1p_lexer_hack_enable_with_syntax(); } + WithSyntaxFormat + '}' { + $$ = $5; + } + ; + +WithSyntaxFormat: + WithSyntaxFormatToken { + $$ = asn1p_wsyntx_new(); + TQ_ADD(&($$->chunks), $1, next); + } + | WithSyntaxFormat WithSyntaxFormatToken { + $$ = $1; + TQ_ADD(&($$->chunks), $2, next); + } + ; + +WithSyntaxFormatToken: + TOK_opaque { + $$ = asn1p_wsyntx_chunk_frombuf($1.buf, $1.len, 0); + } + | ClassFieldIdentifier { + asn1p_ref_t *ref; + int ret; + ref = asn1p_ref_new(yylineno); + checkmem(ref); + ret = asn1p_ref_add_component(ref, $1.name, $1.lex_type); + checkmem(ret == 0); + $$ = asn1p_wsyntx_chunk_fromref(ref, 0); + } + ; + +/* + * A data type member goes like this + * === + * memb1 [0] Type1 { a(1), b(2) } (2) + * === + * Therefore, we propose a split. + * ^^^^^^^^^ ^^^^^^^^^^ + * ^TaggedIdentifier ^TypeDeclaration + * ^ConstrainedTypeDeclaration + */ + +/* + * A member of a constructed data type ("a" or "b" in above example). + */ +DataTypeMember: + TaggedIdentifier ConstrainedTypeDeclaration { + $$ = $2; + assert($$->Identifier == 0); + $$->Identifier = $1.name; + $$->tag = $1.tag; + } + | ExtensionAndException { + $$ = $1; + } + ; + +ConstrainedTypeDeclaration: + TypeDeclaration optConstraints optMarker { + $$ = $1; + $$->constraints = $2; + $$->marker = $3; + } + ; + +ExtensionAndException: + TOK_ThreeDots { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->Identifier = strdup("..."); + checkmem($$->Identifier); + $$->expr_type = A1TC_EXTENSIBLE; + $$->meta_type = AMT_TYPE; + } + | TOK_ThreeDots '!' DefinedValue { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->Identifier = strdup("..."); + checkmem($$->Identifier); + $$->value = $3; + $$->expr_type = A1TC_EXTENSIBLE; + $$->meta_type = AMT_TYPE; + } + | TOK_ThreeDots '!' SignedNumber { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->Identifier = strdup("..."); + $$->value = $3; + checkmem($$->Identifier); + $$->expr_type = A1TC_EXTENSIBLE; + $$->meta_type = AMT_TYPE; + } + ; + +TypeDeclaration: + BasicType { + $$ = $1; + } + | BasicString { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->expr_type = $1; + $$->meta_type = AMT_TYPE; + } + | ConstructedType { + $$ = $1; + checkmem($$); + assert($$->meta_type); + } + /* + * A parametrized assignment. + */ + | TypeRefName '{' ActualParameterList '}' { + int ret; + $$ = $3; + assert($$->expr_type == 0); + assert($$->meta_type == 0); + assert($$->reference == 0); + $$->reference = asn1p_ref_new(yylineno); + checkmem($$->reference); + ret = asn1p_ref_add_component($$->reference, $1, RLT_UNKNOWN); + checkmem(ret == 0); + free($1); + $$->expr_type = A1TC_PARAMETRIZED; + $$->meta_type = AMT_TYPE; + } + /* + * A DefinedType reference. + * "CLASS1.&id.&id2" + * or + * "Module.Type" + * or + * "Module.identifier" + * or + * "Type" + */ + | ComplexTypeReference { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->reference = $1; + $$->expr_type = A1TC_REFERENCE; + $$->meta_type = AMT_TYPEREF; + } + | TOK_INSTANCE TOK_OF ComplexTypeReference { + $$ = asn1p_expr_new(yylineno); + checkmem($$); + $$->reference = $3; + $$->expr_type = A1TC_INSTANCE; + $$->meta_type = AMT_TYPE; + } + ; + +/* + * A type name consisting of several components. + * === EXAMPLE === + * === EOF === + */ +ComplexTypeReference: + TOK_typereference { + int ret; + $$ = asn1p_ref_new(yylineno); + checkmem($$); + ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN); + checkmem(ret == 0); + free($1); + } + | TOK_typereference '.' TypeRefName { + int ret; + $$ = asn1p_ref_new(yylineno); + checkmem($$); + ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN); + checkmem(ret == 0); + ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN); + checkmem(ret == 0); + free($1); + } + | TOK_typereference '.' Identifier { + int ret; + $$ = asn1p_ref_new(yylineno); + checkmem($$); + ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN); + checkmem(ret == 0); + ret = asn1p_ref_add_component($$, $3, RLT_lowercase); + checkmem(ret == 0); + free($1); + } + | ObjectClassReference { + int ret; + $$ = asn1p_ref_new(yylineno); + checkmem($$); + ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS); + free($1); + checkmem(ret == 0); + } + | ObjectClassReference '.' ComplexTypeReferenceAmpList { + int ret; + $$ = $3; + ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS); + free($1); + checkmem(ret == 0); + /* + * Move the last element infront. + */ + { + struct asn1p_ref_component_s tmp_comp; + tmp_comp = $$->components[$$->comp_count-1]; + memmove(&$$->components[1], + &$$->components[0], + sizeof($$->components[0]) + * ($$->comp_count - 1)); + $$->components[0] = tmp_comp; + } + } + ; + +ComplexTypeReferenceAmpList: + ComplexTypeReferenceElement { + int ret; + $$ = asn1p_ref_new(yylineno); + checkmem($$); + ret = asn1p_ref_add_component($$, $1.name, $1.lex_type); + free($1.name); + checkmem(ret == 0); + } + | ComplexTypeReferenceAmpList '.' ComplexTypeReferenceElement { + int ret; + $$ = $1; + ret = asn1p_ref_add_component($$, $3.name, $3.lex_type); + free($3.name); + checkmem(ret == 0); + } + ; + +ComplexTypeReferenceElement: ClassFieldName; +ClassFieldIdentifier: ClassFieldName; + +ClassFieldName: + /* "&Type1" */ + TOK_typefieldreference { + $$.lex_type = RLT_AmpUppercase; + $$.name = $1; + } + /* "&id" */ + | TOK_valuefieldreference { + $$.lex_type = RLT_Amplowercase; + $$.name = $1; + } + ; + + +/* + * === EXAMPLE === + * value INTEGER ::= 1 + * === EOF === + */ +ValueDefinition: + Identifier DefinedTypeRef TOK_PPEQ InlineOrDefinedValue { + $$ = $2; + assert($$->Identifier == NULL); + $$->Identifier = $1; + $$->meta_type = AMT_VALUE; + $$->value = $4; + } + ; + +InlineOrDefinedValue: + '{' { asn1p_lexer_hack_push_opaque_state(); } + Opaque /* '}' */ { + $$ = asn1p_value_frombuf($3.buf, $3.len, 0); + checkmem($$); + $$->type = ATV_UNPARSED; + } + | TOK_bstring { + $$ = _convert_bitstring2binary($1, 'B'); + checkmem($$); + } + | TOK_hstring { + $$ = _convert_bitstring2binary($1, 'H'); + checkmem($$); + } + | TOK_cstring { + $$ = asn1p_value_frombuf($1.buf, $1.len, 0); + checkmem($$); + } + | SignedNumber { + $$ = $1; + } + | DefinedValue { + $$ = $1; + } + ; + +DefinedValue: + Identifier { + asn1p_ref_t *ref; + int ret; + ref = asn1p_ref_new(yylineno); + checkmem(ref); + ret = asn1p_ref_add_component(ref, $1, RLT_lowercase); + checkmem(ret == 0); + $$ = asn1p_value_fromref(ref, 0); + checkmem($$); + free($1); + } + | TypeRefName '.' Identifier { + asn1p_ref_t *ref; + int ret; + ref = asn1p_ref_new(yylineno); + checkmem(ref); + ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN); + checkmem(ret == 0); + ret = asn1p_ref_add_component(ref, $3, RLT_lowercase); + checkmem(ret == 0); + $$ = asn1p_value_fromref(ref, 0); + checkmem($$); + free($1); + free($3); + } + ; + +Opaque: + TOK_opaque { + $$.len = $1.len + 2; + $$.buf = malloc($$.len + 1); + checkmem($$.buf); + $$.buf[0] = '{'; + $$.buf[1] = ' '; + memcpy($$.buf + 2, $1.buf, $1.len); + $$.buf[$$.len] = '\0'; + free($1.buf); + } + | Opaque TOK_opaque { + int newsize = $1.len + $2.len; + char *p = malloc(newsize + 1); + checkmem(p); + memcpy(p , $1.buf, $1.len); + memcpy(p + $1.len, $2.buf, $2.len); + p[newsize] = '\0'; + free($1.buf); + free($2.buf); + $$.buf = p; + $$.len = newsize; + } + ; + +BasicTypeId: + TOK_BOOLEAN { $$ = ASN_BASIC_BOOLEAN; } + | TOK_NULL { $$ = ASN_BASIC_NULL; } + | TOK_REAL { $$ = ASN_BASIC_REAL; } + | BasicTypeId_UniverationCompatible { $$ = $1; } + | TOK_OCTET TOK_STRING { $$ = ASN_BASIC_OCTET_STRING; } + | TOK_OBJECT TOK_IDENTIFIER { $$ = ASN_BASIC_OBJECT_IDENTIFIER; } + | TOK_RELATIVE_OID { $$ = ASN_BASIC_RELATIVE_OID; } + | TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; } + | TOK_EMBEDDED TOK_PDV { $$ = ASN_BASIC_EMBEDDED_PDV; } + | TOK_CHARACTER TOK_STRING { $$ = ASN_BASIC_CHARACTER_STRING; } + | TOK_UTCTime { $$ = ASN_BASIC_UTCTime; } + | TOK_GeneralizedTime { $$ = ASN_BASIC_GeneralizedTime; } + ; + +/* + * A type identifier which may be used with "{ a(1), b(2) }" clause. + */ +BasicTypeId_UniverationCompatible: + TOK_INTEGER { $$ = ASN_BASIC_INTEGER; } + | TOK_ENUMERATED { $$ = ASN_BASIC_ENUMERATED; } + | TOK_BIT TOK_STRING { $$ = ASN_BASIC_BIT_STRING; } + ; + +BasicType: + BasicTypeId { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->expr_type = $1; + $$->meta_type = AMT_TYPE; + } + | BasicTypeId_UniverationCompatible UniverationDefinition { + if($2) { + $$ = $2; + } else { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + } + $$->expr_type = $1; + $$->meta_type = AMT_TYPE; + } + ; + +BasicString: + TOK_BMPString { $$ = ASN_STRING_BMPString; } + | TOK_GeneralString { + $$ = ASN_STRING_GeneralString; + return yyerror("GeneralString is not supported"); + } + | TOK_GraphicString { + $$ = ASN_STRING_GraphicString; + return yyerror("GraphicString is not supported"); + } + | TOK_IA5String { $$ = ASN_STRING_IA5String; } + | TOK_ISO646String { $$ = ASN_STRING_ISO646String; } + | TOK_NumericString { $$ = ASN_STRING_NumericString; } + | TOK_PrintableString { $$ = ASN_STRING_PrintableString; } + | TOK_T61String { + $$ = ASN_STRING_T61String; + return yyerror("T61String not implemented yet"); + } + | TOK_TeletexString { $$ = ASN_STRING_TeletexString; } + | TOK_UniversalString { $$ = ASN_STRING_UniversalString; } + | TOK_UTF8String { $$ = ASN_STRING_UTF8String; } + | TOK_VideotexString { + $$ = ASN_STRING_VideotexString; + return yyerror("VideotexString is no longer supported"); + } + | TOK_VisibleString { $$ = ASN_STRING_VisibleString; } + | TOK_ObjectDescriptor { $$ = ASN_STRING_ObjectDescriptor; } + ; + +ConstructedType: + TOK_CHOICE '{' ConstructedDataTypeDefinition '}' { + $$ = $3; + assert($$->expr_type == A1TC_INVALID); + $$->expr_type = ASN_CONSTR_CHOICE; + $$->meta_type = AMT_TYPE; + } + | TOK_SEQUENCE '{' ConstructedDataTypeDefinition '}' { + $$ = $3; + assert($$->expr_type == A1TC_INVALID); + $$->expr_type = ASN_CONSTR_SEQUENCE; + $$->meta_type = AMT_TYPE; + } + | TOK_SET '{' ConstructedDataTypeDefinition '}' { + $$ = $3; + assert($$->expr_type == A1TC_INVALID); + $$->expr_type = ASN_CONSTR_SET; + $$->meta_type = AMT_TYPE; + } + | TOK_SEQUENCE optConstraints TOK_OF TypeDeclaration { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->constraints = $2; + $$->expr_type = ASN_CONSTR_SEQUENCE_OF; + $$->meta_type = AMT_TYPE; + TQ_ADD(&($$->members), $4, next); + } + | TOK_SET optConstraints TOK_OF TypeDeclaration { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->constraints = $2; + $$->expr_type = ASN_CONSTR_SET_OF; + $$->meta_type = AMT_TYPE; + TQ_ADD(&($$->members), $4, next); + } + | TOK_ANY { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->expr_type = ASN_CONSTR_ANY; + $$->meta_type = AMT_TYPE; + } + | TOK_ANY TOK_DEFINED TOK_BY Identifier { + int ret; + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->reference = asn1p_ref_new(yylineno); + ret = asn1p_ref_add_component($$->reference, + $4, RLT_lowercase); + checkmem(ret == 0); + $$->expr_type = ASN_CONSTR_ANY; + $$->meta_type = AMT_TYPE; + } + ; + +/* + * Data type constraints. + */ +optConstraints: + { $$ = 0; } + | Constraints { $$ = $1; } + ; + +Union: '|' | TOK_UNION; +Intersection: '^' | TOK_INTERSECTION; +Except: TOK_EXCEPT; + +Constraints: + TOK_SIZE '(' ConstraintElementSet ')' { + /* + * This is a special case, for compatibility purposes. + * It goes without parenthesis. + */ + int ret; + $$ = asn1p_constraint_new(yylineno); + checkmem($$); + $$->type = ACT_CT_SIZE; + ret = asn1p_constraint_insert($$, $3); + checkmem(ret == 0); + } + | SingleConstraint { + CONSTRAINT_INSERT($$, ACT_CA_SET, $1, 0); + } + | Constraints SingleConstraint { + CONSTRAINT_INSERT($$, ACT_CA_SET, $1, $2); + } + ; + +SingleConstraint: + '(' ConstraintElementSet ')' { + $$ = $2; + } + ; + +ConstraintElementSet: + ConstraintElement { + $$ = $1; + } + | ConstraintElement ',' TOK_ThreeDots { + asn1p_constraint_t *ct; + ct = asn1p_constraint_new(yylineno); + checkmem(ct); + ct->type = ACT_EL_EXT; + CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct); + } + | ConstraintElement ',' TOK_ThreeDots ',' ConstraintElement { + asn1p_constraint_t *ct; + ct = asn1p_constraint_new(yylineno); + checkmem(ct); + ct->type = ACT_EL_EXT; + CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct); + CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, $5); + } + | TOK_ThreeDots { + $$ = asn1p_constraint_new(yylineno); + checkmem($$); + $$->type = ACT_EL_EXT; + } + | TOK_ThreeDots ',' ConstraintElement { + asn1p_constraint_t *ct; + ct = asn1p_constraint_new(yylineno); + checkmem(ct); + ct->type = ACT_EL_EXT; + CONSTRAINT_INSERT($$, ACT_CA_CSV, ct, $3); + } + ; + +ConstraintElement: ConstraintElementUnion { $$ = $1; } ; + +ConstraintElementUnion: + ConstraintElementIntersection { $$ = $1; } + | ConstraintElementUnion Union ConstraintElementIntersection { + CONSTRAINT_INSERT($$, ACT_CA_UNI, $1, $3); + } + ; + +ConstraintElementIntersection: + ConstraintElementException { $$ = $1; } + | ConstraintElementIntersection Intersection + ConstraintElementException { + CONSTRAINT_INSERT($$, ACT_CA_INT, $1, $3); + } + ; + +ConstraintElementException: + ConstraintSubtypeElement { $$ = $1; } + | ConstraintElementException Except ConstraintSubtypeElement { + CONSTRAINT_INSERT($$, ACT_CA_EXC, $1, $3); + } + ; + +ConstraintSubtypeElement: + ConstraintValue { + $$ = asn1p_constraint_new(yylineno); + checkmem($$); + $$->type = ACT_EL_VALUE; + $$->value = $1; + } + | ConstraintValue ConstraintRangeSpec ConstraintValue { + $$ = asn1p_constraint_new(yylineno); + checkmem($$); + $$->type = $2; + $$->range_start = $1; + $$->range_stop = $3; + } + | ConstraintSpec '(' ConstraintElementSet ')' { + int ret; + $$ = asn1p_constraint_new(yylineno); + checkmem($$); + $$->type = $1; + ret = asn1p_constraint_insert($$, $3); + checkmem(ret == 0); + } + | TableConstraint { + $$ = $1; + } + | WithComponents { + $$ = $1; + } + ; + +ConstraintRangeSpec: + TOK_TwoDots { $$ = ACT_EL_RANGE; } + | TOK_TwoDots '<' { $$ = ACT_EL_RLRANGE; } + | '<' TOK_TwoDots { $$ = ACT_EL_LLRANGE; } + | '<' TOK_TwoDots '<' { $$ = ACT_EL_ULRANGE; } + ; + +ConstraintSpec: + TOK_SIZE { + $$ = ACT_CT_SIZE; + } + | TOK_FROM { + $$ = ACT_CT_FROM; + } + ; + +ConstraintValue: + SignedNumber { + $$ = $1; + } + | Identifier { + asn1p_ref_t *ref; + int ret; + ref = asn1p_ref_new(yylineno); + checkmem(ref); + ret = asn1p_ref_add_component(ref, $1, RLT_lowercase); + checkmem(ret == 0); + $$ = asn1p_value_fromref(ref, 0); + checkmem($$); + free($1); + } + | TOK_cstring { + $$ = asn1p_value_frombuf($1.buf, $1.len, 0); + checkmem($$); + } + | TOK_MIN { + $$ = asn1p_value_fromint(123); + checkmem($$); + $$->type = ATV_MIN; + } + | TOK_MAX { + $$ = asn1p_value_fromint(321); + checkmem($$); + $$->type = ATV_MAX; + } + | TOK_FALSE { + $$ = asn1p_value_fromint(0); + checkmem($$); + $$->type = ATV_FALSE; + } + | TOK_TRUE { + $$ = asn1p_value_fromint(1); + checkmem($$); + $$->type = ATV_TRUE; + } + ; + +WithComponents: + TOK_WITH TOK_COMPONENTS '{' WithComponentsList '}' { + CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $4, 0); + } + ; + +WithComponentsList: + WithComponentsElement { + $$ = $1; + } + | WithComponentsList ',' WithComponentsElement { + CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $1, $3); + } + ; + +WithComponentsElement: + TOK_ThreeDots { + $$ = asn1p_constraint_new(yylineno); + checkmem($$); + $$->type = ACT_EL_EXT; + } + | Identifier optConstraints optPresenceConstraint { + $$ = asn1p_constraint_new(yylineno); + checkmem($$); + $$->type = ACT_EL_VALUE; + $$->value = asn1p_value_frombuf($1, strlen($1), 0); + $$->presence = $3; + } + ; + +/* + * presence constraint for WithComponents + */ +optPresenceConstraint: + { $$ = ACPRES_DEFAULT; } + | PresenceConstraint { $$ = $1; } + ; + +PresenceConstraint: + TOK_PRESENT { + $$ = ACPRES_PRESENT; + } + | TOK_ABSENT { + $$ = ACPRES_ABSENT; + } + | TOK_OPTIONAL { + $$ = ACPRES_OPTIONAL; + } + ; + +TableConstraint: + SimpleTableConstraint { + $$ = $1; + } + | ComponentRelationConstraint { + $$ = $1; + } + ; + +/* + * "{ExtensionSet}" + */ +SimpleTableConstraint: + '{' TypeRefName '}' { + asn1p_ref_t *ref = asn1p_ref_new(yylineno); + asn1p_constraint_t *ct; + int ret; + ret = asn1p_ref_add_component(ref, $2, 0); + checkmem(ret == 0); + ct = asn1p_constraint_new(yylineno); + checkmem($$); + ct->type = ACT_EL_VALUE; + ct->value = asn1p_value_fromref(ref, 0); + CONSTRAINT_INSERT($$, ACT_CA_CRC, ct, 0); + } + ; + +ComponentRelationConstraint: + SimpleTableConstraint '{' AtNotationList '}' { + CONSTRAINT_INSERT($$, ACT_CA_CRC, $1, $3); + } + ; + +AtNotationList: + AtNotationElement { + $$ = asn1p_constraint_new(yylineno); + checkmem($$); + $$->type = ACT_EL_VALUE; + $$->value = asn1p_value_fromref($1, 0); + } + | AtNotationList ',' AtNotationElement { + asn1p_constraint_t *ct; + ct = asn1p_constraint_new(yylineno); + checkmem(ct); + ct->type = ACT_EL_VALUE; + ct->value = asn1p_value_fromref($3, 0); + CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct); + } + ; + +/* + * @blah + */ +AtNotationElement: + '@' ComponentIdList { + char *p = malloc(strlen($2) + 2); + int ret; + *p = '@'; + strcpy(p + 1, $2); + $$ = asn1p_ref_new(yylineno); + ret = asn1p_ref_add_component($$, p, 0); + checkmem(ret == 0); + free(p); + free($2); + } + | '@' '.' ComponentIdList { + char *p = malloc(strlen($3) + 3); + int ret; + p[0] = '@'; + p[1] = '.'; + strcpy(p + 2, $3); + $$ = asn1p_ref_new(yylineno); + ret = asn1p_ref_add_component($$, p, 0); + checkmem(ret == 0); + free(p); + free($3); + } + ; + +/* identifier "." ... */ +ComponentIdList: + Identifier { + $$ = $1; + } + | ComponentIdList '.' Identifier { + int l1 = strlen($1); + int l3 = strlen($3); + $$ = malloc(l1 + 1 + l3 + 1); + memcpy($$, $1, l1); + $$[l1] = '.'; + memcpy($$ + l1 + 1, $3, l3); + $$[l1 + 1 + l3] = '\0'; + } + ; + + + +/* + * MARKERS + */ + +optMarker: + { $$ = EM_NOMARK; } + | Marker { $$ = $1; } + ; + +Marker: + TOK_OPTIONAL { + $$ = EM_OPTIONAL; + } + | TOK_DEFAULT DefaultValue { + $$ = EM_DEFAULT; + /* FIXME: store DefaultValue somewhere */ + } + ; + +DefaultValue: + ConstraintValue { + } + | BasicTypeId { + } + | '{' { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ { + } + ; + +/* + * Universal enumeration definition to use in INTEGER and ENUMERATED. + * === EXAMPLE === + * Gender ::= ENUMERATED { unknown(0), male(1), female(2) } + * Temperature ::= INTEGER { absolute-zero(-273), freezing(0), boiling(100) } + * === EOF === + */ +/* +optUniverationDefinition: + { $$ = 0; } + | UniverationDefinition { + $$ = $1; + } + ; +*/ + +UniverationDefinition: + '{' '}' { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + } + | '{' UniverationList '}' { + $$ = $2; + } + ; + +UniverationList: + UniverationElement { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + TQ_ADD(&($$->members), $1, next); + } + | UniverationList ',' UniverationElement { + $$ = $1; + TQ_ADD(&($$->members), $3, next); + } + ; + +UniverationElement: + Identifier { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->expr_type = A1TC_UNIVERVAL; + $$->meta_type = AMT_VALUE; + $$->Identifier = $1; + } + | Identifier '(' SignedNumber ')' { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->expr_type = A1TC_UNIVERVAL; + $$->meta_type = AMT_VALUE; + $$->Identifier = $1; + $$->value = $3; + } + | Identifier '(' DefinedValue ')' { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->expr_type = A1TC_UNIVERVAL; + $$->meta_type = AMT_VALUE; + $$->Identifier = $1; + $$->value = $3; + } + | SignedNumber { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->expr_type = A1TC_UNIVERVAL; + $$->meta_type = AMT_VALUE; + $$->value = $1; + } + | TOK_ThreeDots { + $$ = asn1p_expr_new(asn1p_lineno); + checkmem($$); + $$->Identifier = strdup("..."); + checkmem($$->Identifier); + $$->expr_type = A1TC_EXTENSIBLE; + $$->meta_type = AMT_VALUE; + } + ; + +SignedNumber: + TOK_number { + $$ = asn1p_value_fromint($1); + checkmem($$); + } + | TOK_number_negative { + $$ = asn1p_value_fromint($1); + checkmem($$); + } + ; + +/* + * SEQUENCE definition. + * === EXAMPLE === + * Struct1 ::= SEQUENCE { + * memb1 Struct2, + * memb2 SEQUENCE OF { + * memb2-1 Struct 3 + * } + * } + * === EOF === + */ + + + +/* + * SET definition. + * === EXAMPLE === + * Person ::= SET { + * name [0] PrintableString (SIZE(1..20)), + * country [1] PrintableString (SIZE(1..20)) DEFAULT default-country, + * } + * === EOF === + */ + +optTag: + { memset(&$$, 0, sizeof($$)); } + | Tag { $$ = $1; } + ; + +Tag: + TOK_tag { + $$ = $1; + $$.tag_mode = TM_DEFAULT; + } + | TOK_tag TOK_IMPLICIT { + $$ = $1; + $$.tag_mode = TM_IMPLICIT; + } + | TOK_tag TOK_EXPLICIT { + $$ = $1; + $$.tag_mode = TM_EXPLICIT; + } + ; + +TypeRefName: + TOK_typereference { + checkmem($1); + $$ = $1; + } + | TOK_objectclassreference { + checkmem($1); + $$ = $1; + } + ; + +ObjectClassReference: + TOK_objectclassreference { + checkmem($1); + $$ = $1; + } + ; + +Identifier: + TOK_identifier { + checkmem($1); + $$ = $1; + } + ; + +TaggedIdentifier: + Identifier { + memset(&$$, 0, sizeof($$)); + $$.name = $1; + } + | Identifier Tag { + $$.name = $1; + $$.tag = $2; + } + ; + + +%% + + +/* + * Convert Xstring ('0101'B or '5'H) to the binary vector. + */ +static asn1p_value_t * +_convert_bitstring2binary(char *str, int base) { + asn1p_value_t *val; + int slen; + int memlen; + int baselen; + int bits; + uint8_t *binary_vector; + uint8_t *bv_ptr; + uint8_t cur_val; + + assert(str); + assert(str[0] == '\''); + + switch(base) { + case 'B': + baselen = 1; + break; + case 'H': + baselen = 4; + break; + default: + assert(base == 'B' || base == 'H'); + errno = EINVAL; + return NULL; + } + + slen = strlen(str); + assert(str[slen - 1] == base); + assert(str[slen - 2] == '\''); + + memlen = slen / (8 / baselen); /* Conservative estimate */ + + bv_ptr = binary_vector = malloc(memlen + 1); + if(bv_ptr == NULL) + /* ENOMEM */ + return NULL; + + cur_val = 0; + bits = 0; + while(*(++str) != '\'') { + switch(baselen) { + case 1: + switch(*str) { + case '1': + cur_val |= 1 << (7 - (bits % 8)); + case '0': + break; + default: + assert(!"_y UNREACH1"); + case ' ': case '\r': case '\n': + continue; + } + break; + case 4: + switch(*str) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + cur_val |= (*str - '0') << (4 - (bits % 8)); + break; + case 'A': case 'B': case 'C': + case 'D': case 'E': case 'F': + cur_val |= ((*str - 'A') + 10) + << (4 - (bits % 8)); + break; + default: + assert(!"_y UNREACH2"); + case ' ': case '\r': case '\n': + continue; + } + break; + } + + bits += baselen; + if((bits % 8) == 0) { + *bv_ptr++ = cur_val; + cur_val = 0; + } + } + + *bv_ptr = cur_val; + assert((bv_ptr - binary_vector) <= memlen); + + val = asn1p_value_frombits(binary_vector, bits, 0); + if(val == NULL) { + free(binary_vector); + } + + return val; +} + +extern char *asn1p_text; + +int +yyerror(const char *msg) { + fprintf(stderr, + "ASN.1 grammar parse error " + "near line %d (token \"%s\"): %s\n", + asn1p_lineno, asn1p_text, msg); + return -1; +} + + diff --git a/libasn1parser/asn1parser.c b/libasn1parser/asn1parser.c new file mode 100644 index 00000000..b5d9e1e4 --- /dev/null +++ b/libasn1parser/asn1parser.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include +#include + +#include "asn1parser.h" +#include "asn1p_list.h" + +int asn1p_parse(void **param); + +void *asn1p__scan_bytes(const char *, int len); +void *asn1p__delete_buffer(void *); +void *asn1p_restart(FILE *); + +extern int asn1p_lineno; + +static int _asn1p_set_flags(enum asn1p_flags flags); +static int _asn1p_assign_filename(asn1p_t *a, const char *fname); + +/* + * Parse the given buffer. + */ +asn1p_t * +asn1p_parse_buffer(const char *buffer, int size /* = -1 */, enum asn1p_flags flags) { + asn1p_t *a = 0; + void *ap; + void *ybuf; + int ret; + + if(_asn1p_set_flags(flags)) { + /* EINVAL */ + return 0; + } + + if(size < 0) + size = strlen(buffer); + + ybuf = asn1p__scan_bytes(buffer, size); + if(!ybuf) { + assert(ybuf); + return 0; + } + + asn1p_lineno = 1; + + ap = (void *)&a; + ret = asn1p_parse(ap); + + asn1p__delete_buffer(ybuf); + + if(ret == 0) { + assert(a); + if(_asn1p_assign_filename(a, "-")) + return NULL; /* FIXME: destroy (a) */ + } else { + assert(a == NULL); + } + + return a; +} + + +/* + * Parse the file identified by its name. + */ +asn1p_t * +asn1p_parse_file(const char *filename, enum asn1p_flags flags) { + struct stat sb; + asn1p_t *a = 0; + void *ap; + FILE *fp; + int ret; + + if(_asn1p_set_flags(flags)) { + /* EINVAL */ + return 0; + } + + fp = fopen(filename, "r"); + if(fp == NULL) { + perror(filename); + return NULL; + } + + if(fstat(fileno(fp), &sb) + || !S_ISREG(sb.st_mode)) { + fclose(fp); + fprintf(stderr, "%s file not recognized: Bad file format\n", + filename); + errno = EINVAL; + return NULL; + } + + asn1p_lineno = 1; + + asn1p_restart(fp); + + ap = (void *)&a; + ret = asn1p_parse(ap); + + fclose(fp); + + if(ret == 0) { + assert(a); + if(_asn1p_assign_filename(a, filename)) + return NULL; /* FIXME: destroy (a) */ + } else { + assert(a == NULL); + } + + return a; +} + +extern int asn1p_lexer_types_year; +extern int asn1p_lexer_constructs_year; +extern int asn1p__flex_debug; + +static int +_asn1p_set_flags(enum asn1p_flags flags) { + + asn1p_lexer_types_year = 0; + asn1p_lexer_constructs_year = 0; + asn1p__flex_debug = 0; + + /* + * Enable debugging in lexer. + */ + if(flags & A1P_LEXER_DEBUG) { + flags &= ~A1P_LEXER_DEBUG; + asn1p__flex_debug = 1; + } + + /* + * Restrict embedded types to ASN.1:1988 version of standard. + */ + if(flags & A1P_TYPES_RESTRICT_TO_1988) { + flags &= ~A1P_TYPES_RESTRICT_TO_1988; + asn1p_lexer_types_year = 1988; + } + + /* + * Restrict embedded types to ASN.1:1988 version of standard. + */ + if(flags & A1P_TYPES_RESTRICT_TO_1988) { + flags &= ~A1P_TYPES_RESTRICT_TO_1988; + asn1p_lexer_types_year = 1988; + } + + /* + * Check that we haven't missed an unknown flag. + */ + if(flags) { + errno = EINVAL; + return -1; + } + + return 0; +} + +static int +_asn1p_assign_filename(asn1p_t *a, const char *fname) { + asn1p_module_t *mod; + TQ_FOR(mod, &(a->modules), mod_next) { + mod->source_file_name = strdup(fname); + if(mod->source_file_name == NULL) + return -1; + } + return 0; +} diff --git a/libasn1parser/asn1parser.h b/libasn1parser/asn1parser.h new file mode 100644 index 00000000..b4c72f8b --- /dev/null +++ b/libasn1parser/asn1parser.h @@ -0,0 +1,73 @@ +/* + * This is a parser of the ASN.1 grammar. + */ +#ifndef ASN1PARSER_H +#define ASN1PARSER_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_SYS_TYPES_H +#include +#endif /* HAVE_SYS_TYPES_H */ +#ifdef HAVE_INTTYPES_H +#include /* POSIX 1003.1-2001, C99 */ +#else /* HAVE_INTTYPES_H */ +#ifdef HAVE_STDINT_H +#include /* SUSv2+ */ +#endif /* HAVE_STDINT_H */ +#endif /* HAVE_INTTYPES_H */ + +/* + * Basic integer type used in numerous places. + * ASN.1 does not define any limits on this number, so it must be sufficiently + * large to accomodate typical inputs. It does not have to be a dynamically + * allocated type with potentially unlimited width: consider the width of + * an integer defined here as one of the "compiler limitations". + * NOTE: this is NOT a type for ASN.1 "INTEGER" type representation, this + * type is used by the compiler itself to handle large integer values + * specified inside ASN.1 grammar. + */ +typedef intmax_t asn1_integer_t; + +#include +#include /* Object identifiers (OIDs) */ +#include /* References to custom types */ +#include /* Value definition */ +#include /* Parametrization */ +#include /* Type Constraints */ +#include /* IMports/EXports */ +#include /* ASN.1 definition module */ +#include /* CLASS-related stuff */ +#include /* A single ASN.1 expression */ + +/* + * Parser flags. + */ +enum asn1p_flags { + A1P_NOFLAGS, + /* + * Enable verbose debugging output from lexer. + */ + A1P_LEXER_DEBUG = 0x0001, + /* + * Embedded types restricted to ASN.1:1988 + */ + A1P_TYPES_RESTRICT_TO_1988 = 0x0010, + /* + * Embedded constructs (concepts) restricted to ASN.1:1990 + */ + A1P_CONSTRUCTS_RESTRICT_TO_1990 = 0x0020, +}; + +/* + * Perform low-level parsing of ASN.1 module[s] + * and return a list of module trees. + */ +asn1p_t *asn1p_parse_file(const char *filename, + enum asn1p_flags); +asn1p_t *asn1p_parse_buffer(const char *buffer, int size /* = -1 */, + enum asn1p_flags); + +#endif /* ASN1PARSER_H */ diff --git a/libasn1parser/expr-h.pl b/libasn1parser/expr-h.pl new file mode 100755 index 00000000..c00128a0 --- /dev/null +++ b/libasn1parser/expr-h.pl @@ -0,0 +1,49 @@ +#!/usr/bin/perl + + +print<) { + chomp; + next if(/TYPE_MAX/); + next unless(/^[ \t]+(ASN_[A-Z]+_([A-Za-z0-9_]+))/); + + print "\t[ $1 ]\t = "; + + $_ = $2; + if($_ eq "RELATIVE_OID") { + print '"RELATIVE-OID"'; + } else { + s/_/ /; + print '"'.$_.'"'; + } + + print ",\n"; +} + +print<= sizeof(asn1p_expr_type2str) \\ + / sizeof(asn1p_expr_type2str[0])) \\ + ? (char *)0 \\ + : asn1p_expr_type2str[(type)] \\ + ) + +#endif /* ASN1_PARSER_EXPR_STR_H */ +EOM -- cgit v1.2.3