Initial revision

git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@2 59561ff5-6e30-0410-9f3c-9617f08c8826
This commit is contained in:
vlm 2004-06-03 03:38:44 +00:00
parent 4cc3ff02fa
commit fa67ddcad9
277 changed files with 55557 additions and 0 deletions

1
AUTHORS Normal file
View File

@ -0,0 +1 @@
Lev Walkin <vlm@lionet.info>

31
BUGS Normal file
View File

@ -0,0 +1,31 @@
0. ASN.1 grammar parser is written mostly with respect to constructing a tree,
so a tree destruction is not fully supported and certain memory leaks are
known. Not a huge problem for run-once programs like a compiler.
NOTE: This statement does not apply to the target code _produced_
by the compiler.
1. REAL type is not supported yet.
2. For purposes of compilation, INTEGER type is modelled using a large
static type (asn_integer_t), but defined as any positive or negative value
by ASN.1. Not a problem as most specifications use very small values anyway.
NOTE: This statement does not apply to the target code _produced_
by the compiler.
3. ASN Macros are prohibited by the current ASN.1 standard,
and are not supported.
4. Multiple tags applied at the same level are not supported:
BadTags ::= [0] EXPLICIT [2] IMPLICIT OtherType
The same thing could be achieved by using the indirection:
GoodTags ::= [0] EXPLICIT OtherTypePtr
OtherTypePtr ::= [2] IMPLICIT OtherType
5. Mixed definite/indefinite length in a _single_ BER tags sequence is not
supported. Should not be a problem in the real world. Please note that it
is still possible, for example, to encode a wrapper structure using definite
length, and encode its substructure member using indefinite length. The BER
decoder is perfectly capable of decoding such sequences.

27
COPYING Normal file
View File

@ -0,0 +1,27 @@
/*-
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/

130
ChangeLog Normal file
View File

@ -0,0 +1,130 @@
0.8.10: 2004-Jun-02
* Added const qualifier where necessary.
* Changed position of outmost_tag fetcher within asn1_TYPE_descriptor_t
structure.
0.8.9: 2004-May-26
* Added *_{get|set}_arcs_*() functions for OBJECT IDENTIFIER
and RELATIVE-OID, together with test cases.
0.8.8: 2004-May-09
* Introduced subtype constraints support (incomplete!).
* Fixed compiler. If the last member of the SEQUENCE is OPTIONAL
and absent in the encoding, and the type is extensible (...) or
EXTENSIBILITY IMPLIED flag is set, then the structure could not
be correctly decoded. (Severity: high, Security impact: low).
* Compiler: fixed recursive ASN.1 types inclusion (Severity: low,
Security impact: none).
* Parser: IMPORTS/FROM fixes, now allowing multiple sections.
* Code compiled and checked on PowerPC (@MacOS X). No major portability
issues experienced.
0.8.7: 2004-Apr-11 T-version-0-8-7
* Fixed SEQUENCE BER decoder: if the last member of the SEQUENCE is
OPTIONAL and absent in the encoding, RC_FAIL was returned instead
of RC_OK (Severity: high, Security impact: low).
* Added test case to check the above problem.
* Added test case to check -fnative-integers mode.
0.8.6: 2004-Apr-03 T-version-0-8-6
* Fixed compiler output for embedded ASN.1 structures.
0.8.5: 2004-Mar-28 T-version-0-8-5
* Fixed ber_tlv_length() computation problem (Severity: blocker,
Security impact: none).
Reported by <vss@high.net.ru>
0.8.4: 2004-Mar-22
* Removed RC_ITAG enumeration element from BER decoder.
This return code did not have much practical value.
0.8.3: 2004-Mar-14 T-version-0-8-3
* Fixed SET::BER decoder: restart after reaching a buffer boundary
weas broken (Severity: blocker, Security impact: low).
* Fixed OCTET STRING::BER decoder: restart after reaching a buffer
boundary was broken (Severity: blocker, Security impact: low).
Reported by <vss@high.net.ru>
* Added test cases to check decoders restartability.
* Slightly more general INTEGER2long decoder.
* Allowed nested /* C-type */ comments, as per X.680:2002.
0.8.2: 2004-Mar-01 T-version-0-8-2
* Fixed SEQUENCE BER decoder: an OPTIONAL element was required, where
should not have been (Severity: major; Security impact: low).
* Fixed print_struct pointer inheritance.
* Added -fno-c99 and -funnamed-unions
0.8.1: 2004-Feb-22
* -R switch to asn1c: Omit support code, compile only the tables.
* Introduced NativeInteger pseudotype.
* Corrected the informal print_struct()'s output format.
0.8.0: 2004-Feb-03 T-version-0-8-0
* Some documentation is created (a .pdf and a short manual page).
* Last touches to the code.
0.7.9: 2004-Feb-01 T-version-0-7-9
* Human readable printing support.
* Support for implicit (standard) constraints.
0.7.8: 2004-Jan-31
* SET now rejects duplicate fields in the data stream.
0.7.7: 2004-Jan-25
* Added types: GeneralizedTime and UTCTime.
0.7.6: 2004-Jan-24 T-version-0-7-6
* DER encoding of a SET OF now involves dynamic sorting.
0.7.5: 2004-Jan-24 T-version-0-7-5
* DER encoding of a SET with untagged CHOICE
now involves dynamic sorting.
0.7.0: 2004-Jan-19 T-version-0-7-0
* A bunch of DER encoders is implemented.
0.6.6: 2004-Jan-11
* Implemented CHOICE decoder.
* Implemented destructors support.
0.6.5: 2004-Jan-03
* Implemented SET decoder.
* Implemented SET OF and SEQUENCE OF decoders.
0.6.4: 2003-Dec-31
* Implemented BOOLEAN, NULL, ENUMERATED decoders.
* Implemented OCTET STRING decoder.
* Implemented BIT STRING decoder.
0.6: 2003-Dec-30
* First decoding of a BER-encoded structure!
0.5: 2003-Dec-28
* Framework and most of the compiler backbone coding done.
0.1: 2003-Nov-28
* Programming started.

14
INSTALL Normal file
View File

@ -0,0 +1,14 @@
QUICK START INSTALLATION
========================
./configure # Configure the build infrastructure for your platform
make # Build the libraries and the compiler
make check # Ensure that the code is still behaving well
# after compiling on your platform
make install # Install the compiler into standard location
QUICK USAGE GUIDE
=================
For usage guide and more information please refer to README file.

9
MANIFEST Normal file
View File

@ -0,0 +1,9 @@
libasn1compiler
libasn1parser
libasn1print
libasn1fix
skeletons
examples
tests
asn1c
doc

8
Makefile.am Normal file
View File

@ -0,0 +1,8 @@
SUBDIRS = \
libasn1parser libasn1print \
libasn1fix libasn1compiler \
skeletons examples tests \
doc asn1c
EXTRA_DIST = BUGS MANIFEST

430
Makefile.in Normal file
View File

@ -0,0 +1,430 @@
# 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@
SUBDIRS = \
libasn1parser libasn1print \
libasn1fix libasn1compiler \
skeletons examples tests \
doc asn1c
EXTRA_DIST = BUGS MANIFEST
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
uninstall-info-recursive all-recursive install-data-recursive \
install-exec-recursive installdirs-recursive install-recursive \
uninstall-recursive check-recursive installcheck-recursive
DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \
Makefile.am Makefile.in NEWS TODO aclocal.m4 config.guess \
config.h.in config.sub configure configure.in depcomp \
install-sh ltconfig ltmain.sh missing mkinstalldirs
DIST_SUBDIRS = $(SUBDIRS)
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
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 Makefile
Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && \
CONFIG_HEADERS= CONFIG_LINKS= \
CONFIG_FILES=$@ $(SHELL) ./config.status
$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
config.h: stamp-h
@if test ! -f $@; then \
rm -f stamp-h; \
$(MAKE) stamp-h; \
else :; fi
stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h stamp-hT
@echo timestamp > stamp-hT 2> /dev/null
cd $(top_builddir) \
&& CONFIG_FILES= CONFIG_HEADERS=config.h \
$(SHELL) ./config.status
@mv stamp-hT stamp-h
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/./stamp-h.in
@if test ! -f $@; then \
rm -f $(srcdir)/./stamp-h.in; \
$(MAKE) $(srcdir)/./stamp-h.in; \
else :; fi
$(srcdir)/./stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
@rm -f $(srcdir)/./stamp-h.in $(srcdir)/./stamp-h.inT
@echo timestamp > $(srcdir)/./stamp-h.inT 2> /dev/null
cd $(top_srcdir) && $(AUTOHEADER)
@mv $(srcdir)/./stamp-h.inT $(srcdir)/./stamp-h.in
distclean-hdr:
-rm -f config.h
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
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: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
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)config.h.in$$unique$(LISP)$$tags" \
|| etags $(ETAGS_ARGS) $$tags config.h.in $$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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = .
# Avoid unsightly `./'.
distdir = $(PACKAGE)-$(VERSION)
GZIP_ENV = --best
distdir: $(DISTFILES)
-chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
mkdir $(distdir)
@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
for subdir in $(SUBDIRS); do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
-chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
-chmod -R a+w $(distdir) > /dev/null 2>&1; rm -rf $(distdir)
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
chmod a-w $(distdir)
dc_install_base=`CDPATH=: && cd $(distdir)/=inst && pwd` \
&& cd $(distdir)/=build \
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& (test `find $$dc_install_base -type f -print | wc -l` -le 1 \
|| (echo "Error: files left after uninstall" 1>&2; \
exit 1) ) \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& $(MAKE) $(AM_MAKEFLAGS) distclean \
&& rm -f $(distdir).tar.gz \
&& (test `find . -type f -print | wc -l` -eq 0 \
|| (echo "Error: files left after distclean" 1>&2; \
exit 1) )
-chmod -R a+w $(distdir) > /dev/null 2>&1; rm -rf $(distdir)
@echo "$(distdir).tar.gz is ready for distribution" | \
sed 'h;s/./=/g;p;x;p;x'
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
dist-all: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
-chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
distclean: distclean-recursive
-rm -f config.status config.cache config.log
distclean-am: clean-am distclean-generic distclean-hdr distclean-libtool \
distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
clean-generic clean-libtool clean-recursive dist dist-all \
distcheck distclean distclean-generic distclean-hdr \
distclean-libtool distclean-recursive distclean-tags distdir \
dvi dvi-am dvi-recursive info info-am info-recursive install \
install-am install-data install-data-am install-data-recursive \
install-exec install-exec-am install-exec-recursive \
install-info install-info-am install-info-recursive install-man \
install-recursive install-strip installcheck installcheck-am \
installdirs installdirs-am installdirs-recursive \
maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-generic \
mostlyclean-libtool mostlyclean-recursive tags tags-recursive \
uninstall uninstall-am uninstall-info-am \
uninstall-info-recursive uninstall-recursive
# 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:

0
NEWS Normal file
View File

69
README Normal file
View File

@ -0,0 +1,69 @@
WHAT TO READ?
=============
For quick installation tips read INSTALL.
For more complete documentation on this compiler and on using the
results of compilation please look into ./doc directory.
An excellent book on ASN.1 is written by Olivier Dubuisson:
"ASN.1 Communication between heterogeneous systems", ISBN:0-12-6333361-0.
QUICK START
===========
After building [and installing] the compiler (see INSTALL), you may use
the asn1c command to compile the ASN.1 specification:
asn1c <spec.asn1>
If several specifications contain interdependencies, all of them must be
specified:
asn1c <spec1.asn1> <spec2.asn1> ...
The ./examples directory contains several ASN.1 modules and a script to
extract ASN.1 modules from RFC documents. To compile X.509 PKI module:
./asn1c/asn1c -P ./examples/*PKIX*93*.asn1
In this example, -P option is used to instruct the compiler to print the
compiled text on the standard output instead of creating multiple .c
and .h files for every ASN.1 type found inside the specified files.
This is useful for debugging and tests automation.
The compiler -E and -EF options are used for testing the parser and
the semantic fixer, respectively. These options will instruct the compiler
to dump out the parsed (and fixed) ASN.1 specification as it was
"understood" by the compiler. It might be useful for checking
whether a particular syntactic construction is properly supported
by the compiler.
asn1c -EF <spec-to-test.asn1>
MODEL OF OPERATION
==================
The asn1c compiler works by processing the ASN.1 module specification
in several stages:
1. In the first stage, the ASN.1 file is parsed.
(Parsing produces an ASN.1 syntax tree for the subsequent levels.)
2. In the second stage, the syntax tree is "fixed".
(Fixing is done by checking the tree for semantic errors
and by transforming the tree into the canonical representation.)
3. In the third stage, the syntax tree is compiled into the target language.
There are several command-line options reserved for printing the results
after each stage of operation:
<parser> => print (-E)
<parser> => <fixer> => print (-E -F)
<parser> => <fixer> => <compiler> => print (-P)
<parser> => <fixer> => <compiler> => save-compiled [default]
--
Lev Walkin
vlm@lionet.info

18
TODO Normal file
View File

@ -0,0 +1,18 @@
MAJOR:
1. Support for the explicit subtype constraints:
Name ::= IA5String (FROM("A".."Z"))
Status: in progress.
2. Support for Information Object Classes.
Status: support for parsing IOCs is mostly present. Support for slicing
the IOCs to produce "views" is not yet designed.
3. Support for PER encoding. Requires advanced subtype constraints support (#1)
4. Support for XER encoding.
MISC:
1. Make sure asn1_DEF_<TYPE>_tags is not an empty structure.

998
aclocal.m4 vendored Normal file
View File

@ -0,0 +1,998 @@
# aclocal.m4 generated automatically by aclocal 1.5
# Copyright 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
# This file 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.
# Do all the work for Automake. This macro actually does too much --
# some checks are only needed if your package does certain things.
# But this isn't really a big deal.
# serial 5
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# We require 2.13 because we rely on SHELL being computed by configure.
AC_PREREQ([2.13])
# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
# -----------------------------------------------------------
# If MACRO-NAME is provided do IF-PROVIDED, else IF-NOT-PROVIDED.
# The purpose of this macro is to provide the user with a means to
# check macros which are provided without letting her know how the
# information is coded.
# If this macro is not defined by Autoconf, define it here.
ifdef([AC_PROVIDE_IFELSE],
[],
[define([AC_PROVIDE_IFELSE],
[ifdef([AC_PROVIDE_$1],
[$2], [$3])])])
# AM_INIT_AUTOMAKE(PACKAGE,VERSION, [NO-DEFINE])
# ----------------------------------------------
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_REQUIRE([AC_PROG_INSTALL])dnl
# test to see if srcdir already configured
if test "`CDPATH=:; cd $srcdir && pwd`" != "`pwd`" &&
test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run \"make distclean\" there first])
fi
# Define the identity of the package.
PACKAGE=$1
AC_SUBST(PACKAGE)dnl
VERSION=$2
AC_SUBST(VERSION)dnl
ifelse([$3],,
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])
# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow
# the ones we care about.
ifdef([m4_pattern_allow],
[m4_pattern_allow([^AM_[A-Z]+FLAGS])])dnl
# Autoconf 2.50 always computes EXEEXT. However we need to be
# compatible with 2.13, for now. So we always define EXEEXT, but we
# don't compute it.
AC_SUBST(EXEEXT)
# Similar for OBJEXT -- only we only use OBJEXT if the user actually
# requests that it be used. This is a bit dumb.
: ${OBJEXT=o}
AC_SUBST(OBJEXT)
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG(ACLOCAL, aclocal)
AM_MISSING_PROG(AUTOCONF, autoconf)
AM_MISSING_PROG(AUTOMAKE, automake)
AM_MISSING_PROG(AUTOHEADER, autoheader)
AM_MISSING_PROG(MAKEINFO, makeinfo)
AM_MISSING_PROG(AMTAR, tar)
AM_PROG_INSTALL_SH
AM_PROG_INSTALL_STRIP
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_PROVIDE_IFELSE([AC_PROG_][CC],
[_AM_DEPENDENCIES(CC)],
[define([AC_PROG_][CC],
defn([AC_PROG_][CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_][CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_][CXX],
defn([AC_PROG_][CXX])[_AM_DEPENDENCIES(CXX)])])dnl
])
#
# Check to make sure that the build environment is sane.
#
# serial 3
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftest.file
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftest.file`
fi
rm -f conftest.file
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT(yes)])
# serial 2
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it supports --run.
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
am_missing_run="$MISSING --run "
else
am_missing_run=
am_backtick='`'
AC_MSG_WARN([${am_backtick}missing' script is too old or missing])
fi
])
# AM_AUX_DIR_EXPAND
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run. This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
# fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
# fails if $ac_aux_dir is absolute,
# fails when called from a subdirectory in a VPATH build with
# a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
# harmless because $srcdir is `.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
# MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH. The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND], [
# expand $ac_aux_dir to an absolute path
am_aux_dir=`CDPATH=:; cd $ac_aux_dir && pwd`
])
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
install_sh=${install_sh-"$am_aux_dir/install-sh"}
AC_SUBST(install_sh)])
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in `make install-strip', and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# serial 4 -*- Autoconf -*-
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ---------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX" or "OBJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
[$1], CXX, [depcc="$CXX" am_compiler_list=],
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc']
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
for depmode in $am_compiler_list; do
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
echo '#include "conftest.h"' > conftest.c
echo 'int i;' > conftest.h
echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
case $depmode in
nosideeffect)
# after this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
none) break ;;
esac
# We check with `-c' and `-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this.
if depmode=$depmode \
source=conftest.c object=conftest.o \
depfile=conftest.Po tmpdepfile=conftest.TPo \
$SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
grep conftest.h conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
$1DEPMODE="depmode=$am_cv_$1_dependencies_compiler_type"
AC_SUBST([$1DEPMODE])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
AC_DEFUN([AM_SET_DEPDIR],
[rm -f .deps 2>/dev/null
mkdir .deps 2>/dev/null
if test -d .deps; then
DEPDIR=.deps
else
# MS-DOS does not allow filenames that begin with a dot.
DEPDIR=_deps
fi
rmdir .deps 2>/dev/null
AC_SUBST(DEPDIR)
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE(dependency-tracking,
[ --disable-dependency-tracking Speeds up one-time builds
--enable-dependency-tracking Do not reject slow dependency extractors])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
pushdef([subst], defn([AC_SUBST]))
subst(AMDEPBACKSLASH)
popdef([subst])
])
# Generate code to set up dependency tracking.
# This macro should only be invoked once -- use via AC_REQUIRE.
# Usage:
# AM_OUTPUT_DEPENDENCY_COMMANDS
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each `.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],[
AC_OUTPUT_COMMANDS([
test x"$AMDEP_TRUE" != x"" ||
for mf in $CONFIG_FILES; do
case "$mf" in
Makefile) dirpart=.;;
*/Makefile) dirpart=`echo "$mf" | sed -e 's|/[^/]*$||'`;;
*) continue;;
esac
grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
# Extract the definition of DEP_FILES from the Makefile without
# running `make'.
DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
test -z "$DEPDIR" && continue
# When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n -e '/^U = / s///p' < "$mf"`
test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
# We invoke sed twice because it is the simplest approach to
# changing $(DEPDIR) to its actual value in the expansion.
for file in `sed -n -e '
/^DEP_FILES = .*\\\\$/ {
s/^DEP_FILES = //
:loop
s/\\\\$//
p
n
/\\\\$/ b loop
p
}
/^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`echo "$file" | sed -e 's|/[^/]*$||'`
$ac_aux_dir/mkinstalldirs "$dirpart/$fdir" > /dev/null 2>&1
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
], [AMDEP_TRUE="$AMDEP_TRUE"
ac_aux_dir="$ac_aux_dir"])])
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
doit:
@echo done
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include='#'
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# We grep out `Entering directory' and `Leaving directory'
# messages which can occur if `w' ends up in MAKEFLAGS.
# In particular we don't look at `^make:' because GNU make might
# be invoked under some other name (usually "gmake"), in which
# case it prints its new name instead of `make'.
if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then
am__include=include
am__quote=
_am_result=GNU
fi
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
am__include=.include
am__quote='"'
_am_result=BSD
fi
fi
AC_SUBST(am__include)
AC_SUBST(am__quote)
AC_MSG_RESULT($_am_result)
rm -f confinc confmf
])
# serial 3
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
#
# FIXME: Once using 2.50, use this:
# m4_match([$1], [^TRUE\|FALSE$], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_DEFUN([AM_CONDITIONAL],
[ifelse([$1], [TRUE],
[errprint(__file__:__line__: [$0: invalid condition: $1
])dnl
m4exit(1)])dnl
ifelse([$1], [FALSE],
[errprint(__file__:__line__: [$0: invalid condition: $1
])dnl
m4exit(1)])dnl
AC_SUBST([$1_TRUE])
AC_SUBST([$1_FALSE])
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi])
# Add --enable-maintainer-mode option to configure.
# From Jim Meyering
# serial 1
AC_DEFUN([AM_MAINTAINER_MODE],
[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
dnl maintainer-mode is disabled by default
AC_ARG_ENABLE(maintainer-mode,
[ --enable-maintainer-mode enable make rules and dependencies not useful
(and sometimes confusing) to the casual installer],
USE_MAINTAINER_MODE=$enableval,
USE_MAINTAINER_MODE=no)
AC_MSG_RESULT([$USE_MAINTAINER_MODE])
AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
MAINT=$MAINTAINER_MODE_TRUE
AC_SUBST(MAINT)dnl
]
)
# serial 40 AC_PROG_LIBTOOL
AC_DEFUN(AC_PROG_LIBTOOL,
[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
# Save cache, so that ltconfig can load it
AC_CACHE_SAVE
# Actually configure libtool. ac_aux_dir is where install-sh is found.
CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
|| AC_MSG_ERROR([libtool configure failed])
# Reload cache, that may have been modified by ltconfig
AC_CACHE_LOAD
# This can be used to rebuild libtool when needed
LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
# Always use our own libtool.
LIBTOOL='$(SHELL) $(top_builddir)/libtool'
AC_SUBST(LIBTOOL)dnl
# Redirect the config.log output again, so that the ltconfig log is not
# clobbered by the next message.
exec 5>>./config.log
])
AC_DEFUN(AC_LIBTOOL_SETUP,
[AC_PREREQ(2.13)dnl
AC_REQUIRE([AC_ENABLE_SHARED])dnl
AC_REQUIRE([AC_ENABLE_STATIC])dnl
AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
AC_REQUIRE([AC_PROG_RANLIB])dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_LD])dnl
AC_REQUIRE([AC_PROG_NM])dnl
AC_REQUIRE([AC_PROG_LN_S])dnl
dnl
case "$target" in
NONE) lt_target="$host" ;;
*) lt_target="$target" ;;
esac
# Check for any special flags to pass to ltconfig.
libtool_flags="--cache-file=$cache_file"
test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
[libtool_flags="$libtool_flags --enable-dlopen"])
ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
[libtool_flags="$libtool_flags --enable-win32-dll"])
AC_ARG_ENABLE(libtool-lock,
[ --disable-libtool-lock avoid locking (might break parallel builds)])
test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
case "$lt_target" in
*-*-irix6*)
# Find out which ABI we are using.
echo '[#]line __oline__ "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case "`/usr/bin/file conftest.o`" in
*32-bit*)
LD="${LD-ld} -32"
;;
*N32*)
LD="${LD-ld} -n32"
;;
*64-bit*)
LD="${LD-ld} -64"
;;
esac
fi
rm -rf conftest*
;;
*-*-sco3.2v5*)
# On SCO OpenServer 5, we need -belf to get full-featured binaries.
SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -belf"
AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
[AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
if test x"$lt_cv_cc_needs_belf" != x"yes"; then
# this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
CFLAGS="$SAVE_CFLAGS"
fi
;;
ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
[*-*-cygwin* | *-*-mingw*)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
])
esac
])
# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
# AC_ENABLE_SHARED - implement the --enable-shared flag
# Usage: AC_ENABLE_SHARED[(DEFAULT)]
# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
# `yes'.
AC_DEFUN(AC_ENABLE_SHARED, [dnl
define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
AC_ARG_ENABLE(shared,
changequote(<<, >>)dnl
<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
changequote([, ])dnl
[p=${PACKAGE-default}
case "$enableval" in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
for pkg in $enableval; do
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS="$ac_save_ifs"
;;
esac],
enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
])
# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_ENABLE_SHARED(no)])
# AC_ENABLE_STATIC - implement the --enable-static flag
# Usage: AC_ENABLE_STATIC[(DEFAULT)]
# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
# `yes'.
AC_DEFUN(AC_ENABLE_STATIC, [dnl
define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
AC_ARG_ENABLE(static,
changequote(<<, >>)dnl
<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
changequote([, ])dnl
[p=${PACKAGE-default}
case "$enableval" in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
for pkg in $enableval; do
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS="$ac_save_ifs"
;;
esac],
enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
])
# AC_DISABLE_STATIC - set the default static flag to --disable-static
AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_ENABLE_STATIC(no)])
# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
# `yes'.
AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
AC_ARG_ENABLE(fast-install,
changequote(<<, >>)dnl
<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
changequote([, ])dnl
[p=${PACKAGE-default}
case "$enableval" in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
for pkg in $enableval; do
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS="$ac_save_ifs"
;;
esac],
enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
])
# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_ENABLE_FAST_INSTALL(no)])
# AC_PROG_LD - find the path to the GNU or non-GNU linker
AC_DEFUN(AC_PROG_LD,
[AC_ARG_WITH(gnu-ld,
[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
ac_prog=ld
if test "$ac_cv_prog_gcc" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by GCC])
ac_prog=`($CC -print-prog-name=ld) 2>&5`
case "$ac_prog" in
# Accept absolute paths.
changequote(,)dnl
[\\/]* | [A-Za-z]:[\\/]*)
re_direlt='/[^/][^/]*/\.\./'
changequote([,])dnl
# Canonicalize the path of ld
ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
done
test -z "$LD" && LD="$ac_prog"
;;
"")
# If it fails, then pretend we aren't using GCC.
ac_prog=ld
;;
*)
# If it is relative, then search for the first ld in PATH.
with_gnu_ld=unknown
;;
esac
elif test "$with_gnu_ld" = yes; then
AC_MSG_CHECKING([for GNU ld])
else
AC_MSG_CHECKING([for non-GNU ld])
fi
AC_CACHE_VAL(ac_cv_path_LD,
[if test -z "$LD"; then
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
ac_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some GNU ld's only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
test "$with_gnu_ld" != no && break
else
test "$with_gnu_ld" != yes && break
fi
fi
done
IFS="$ac_save_ifs"
else
ac_cv_path_LD="$LD" # Let the user override the test with a path.
fi])
LD="$ac_cv_path_LD"
if test -n "$LD"; then
AC_MSG_RESULT($LD)
else
AC_MSG_RESULT(no)
fi
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
AC_PROG_LD_GNU
])
AC_DEFUN(AC_PROG_LD_GNU,
[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
ac_cv_prog_gnu_ld=yes
else
ac_cv_prog_gnu_ld=no
fi])
])
# AC_PROG_NM - find the path to a BSD-compatible name lister
AC_DEFUN(AC_PROG_NM,
[AC_MSG_CHECKING([for BSD-compatible nm])
AC_CACHE_VAL(ac_cv_path_NM,
[if test -n "$NM"; then
# Let the user override the test.
ac_cv_path_NM="$NM"
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
# Check to see if the nm accepts a BSD-compat flag.
# Adding the `sed 1q' prevents false positives on HP-UX, which says:
# nm: unknown option "B" ignored
if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
ac_cv_path_NM="$ac_dir/nm -B"
break
elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
ac_cv_path_NM="$ac_dir/nm -p"
break
else
ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
continue # so that we can try to find one that supports BSD flags
fi
fi
done
IFS="$ac_save_ifs"
test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
fi])
NM="$ac_cv_path_NM"
AC_MSG_RESULT([$NM])
])
# AC_CHECK_LIBM - check for math library
AC_DEFUN(AC_CHECK_LIBM,
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
LIBM=
case "$lt_target" in
*-*-beos* | *-*-cygwin*)
# These system don't have libm
;;
*-ncr-sysv4.3*)
AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
;;
*)
AC_CHECK_LIB(m, main, LIBM="-lm")
;;
esac
])
# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
# the libltdl convenience library, adds --enable-ltdl-convenience to
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
# to be `${top_builddir}/libltdl'. Make sure you start DIR with
# '${top_builddir}/' (note the single quotes!) if your package is not
# flat, and, if you're not using automake, define top_builddir as
# appropriate in the Makefiles.
AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
case "$enable_ltdl_convenience" in
no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
"") enable_ltdl_convenience=yes
ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
esac
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
])
# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
# the libltdl installable library, and adds --enable-ltdl-install to
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
# to be `${top_builddir}/libltdl'. Make sure you start DIR with
# '${top_builddir}/' (note the single quotes!) if your package is not
# flat, and, if you're not using automake, define top_builddir as
# appropriate in the Makefiles.
# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_CHECK_LIB(ltdl, main,
[test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
[if test x"$enable_ltdl_install" = xno; then
AC_MSG_WARN([libltdl not installed, but installation disabled])
else
enable_ltdl_install=yes
fi
])
if test x"$enable_ltdl_install" = x"yes"; then
ac_configure_args="$ac_configure_args --enable-ltdl-install"
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
else
ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
LIBLTDL="-lltdl"
INCLTDL=
fi
])
dnl old names
AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
dnl This is just to silence aclocal about the macro not being used
ifelse([AC_DISABLE_FAST_INSTALL])dnl
# Like AC_CONFIG_HEADER, but automatically create stamp file.
# serial 3
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. We must strip everything past the first ":",
# and everything past the last "/".
AC_PREREQ([2.12])
AC_DEFUN([AM_CONFIG_HEADER],
[ifdef([AC_FOREACH],dnl
[dnl init our file count if it isn't already
m4_ifndef([_AM_Config_Header_Index], m4_define([_AM_Config_Header_Index], [0]))
dnl prepare to store our destination file list for use in config.status
AC_FOREACH([_AM_File], [$1],
[m4_pushdef([_AM_Dest], m4_patsubst(_AM_File, [:.*]))
m4_define([_AM_Config_Header_Index], m4_incr(_AM_Config_Header_Index))
dnl and add it to the list of files AC keeps track of, along
dnl with our hook
AC_CONFIG_HEADERS(_AM_File,
dnl COMMANDS, [, INIT-CMDS]
[# update the timestamp
echo timestamp >"AS_ESCAPE(_AM_DIRNAME(]_AM_Dest[))/stamp-h]_AM_Config_Header_Index["
][$2]m4_ifval([$3], [, [$3]]))dnl AC_CONFIG_HEADERS
m4_popdef([_AM_Dest])])],dnl
[AC_CONFIG_HEADER([$1])
AC_OUTPUT_COMMANDS(
ifelse(patsubst([$1], [[^ ]], []),
[],
[test -z "$CONFIG_HEADERS" || echo timestamp >dnl
patsubst([$1], [^\([^:]*/\)?.*], [\1])stamp-h]),dnl
[am_indx=1
for am_file in $1; do
case " \$CONFIG_HEADERS " in
*" \$am_file "*)
am_dir=\`echo \$am_file |sed 's%:.*%%;s%[^/]*\$%%'\`
if test -n "\$am_dir"; then
am_tmpdir=\`echo \$am_dir |sed 's%^\(/*\).*\$%\1%'\`
for am_subdir in \`echo \$am_dir |sed 's%/% %'\`; do
am_tmpdir=\$am_tmpdir\$am_subdir/
if test ! -d \$am_tmpdir; then
mkdir \$am_tmpdir
fi
done
fi
echo timestamp > "\$am_dir"stamp-h\$am_indx
;;
esac
am_indx=\`expr \$am_indx + 1\`
done])
])]) # AM_CONFIG_HEADER
# _AM_DIRNAME(PATH)
# -----------------
# Like AS_DIRNAME, only do it during macro expansion
AC_DEFUN([_AM_DIRNAME],
[m4_if(m4_regexp([$1], [^.*[^/]//*[^/][^/]*/*$]), -1,
m4_if(m4_regexp([$1], [^//\([^/]\|$\)]), -1,
m4_if(m4_regexp([$1], [^/.*]), -1,
[.],
m4_patsubst([$1], [^\(/\).*], [\1])),
m4_patsubst([$1], [^\(//\)\([^/].*\|$\)], [\1])),
m4_patsubst([$1], [^\(.*[^/]\)//*[^/][^/]*/*$], [\1]))[]dnl
]) # _AM_DIRNAME
# AM_PROG_LEX
# Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT
AC_DEFUN([AM_PROG_LEX],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
AC_CHECK_PROGS(LEX, flex lex, [${am_missing_run}flex])
dnl AC_PROG_LEX
AC_DECL_YYTEXT])

25
asn1c/Makefile.am Normal file
View File

@ -0,0 +1,25 @@
SUBDIRS = . tests
AM_CFLAGS = @ADD_CFLAGS@
AM_CPPFLAGS = \
-I${top_srcdir}/libasn1compiler \
-I${top_srcdir}/libasn1parser \
-I${top_srcdir}/libasn1print \
-I${top_srcdir}/libasn1fix \
-DDATADIR=\"${pkgdatadir}\"
LDADD = \
${top_builddir}/libasn1parser/libasn1parser.la \
${top_builddir}/libasn1fix/libasn1fix.la \
${top_builddir}/libasn1print/libasn1print.la \
${top_builddir}/libasn1compiler/libasn1compiler.la
bin_PROGRAMS = asn1c
dist_man1_MANS = asn1c.1
check_SCRIPTS = check-parsing.sh
TESTS = check-parsing.sh
EXTRA_DIST = check-parsing.sh
CLEANFILES = .check-parsing.*.tmp

556
asn1c/Makefile.in Normal file
View File

@ -0,0 +1,556 @@
# 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@
SUBDIRS = . tests
AM_CFLAGS = @ADD_CFLAGS@
AM_CPPFLAGS = \
-I${top_srcdir}/libasn1compiler \
-I${top_srcdir}/libasn1parser \
-I${top_srcdir}/libasn1print \
-I${top_srcdir}/libasn1fix \
-DDATADIR=\"${pkgdatadir}\"
LDADD = \
${top_builddir}/libasn1parser/libasn1parser.la \
${top_builddir}/libasn1fix/libasn1fix.la \
${top_builddir}/libasn1print/libasn1print.la \
${top_builddir}/libasn1compiler/libasn1compiler.la
bin_PROGRAMS = asn1c
dist_man1_MANS = asn1c.1
check_SCRIPTS = check-parsing.sh
TESTS = check-parsing.sh
EXTRA_DIST = check-parsing.sh
CLEANFILES = .check-parsing.*.tmp
subdir = asn1c
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
bin_PROGRAMS = asn1c$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
asn1c_SOURCES = asn1c.c
asn1c_OBJECTS = asn1c.$(OBJEXT)
asn1c_LDADD = $(LDADD)
asn1c_DEPENDENCIES = ${top_builddir}/libasn1parser/libasn1parser.la \
${top_builddir}/libasn1fix/libasn1fix.la \
${top_builddir}/libasn1print/libasn1print.la \
${top_builddir}/libasn1compiler/libasn1compiler.la
asn1c_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)/asn1c.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@
DIST_SOURCES = asn1c.c
NROFF = nroff
MANS = $(dist_man1_MANS)
RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
uninstall-info-recursive all-recursive install-data-recursive \
install-exec-recursive installdirs-recursive install-recursive \
uninstall-recursive check-recursive installcheck-recursive
DIST_COMMON = README $(dist_man1_MANS) Makefile.am Makefile.in
DIST_SUBDIRS = $(SUBDIRS)
SOURCES = asn1c.c
all: all-recursive
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu asn1c/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
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
|| test -f $$p1 \
; then \
f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$f"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$f; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
rm -f $(DESTDIR)$(bindir)/$$f; \
done
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
asn1c$(EXEEXT): $(asn1c_OBJECTS) $(asn1c_DEPENDENCIES)
@rm -f asn1c$(EXEEXT)
$(LINK) $(asn1c_LDFLAGS) $(asn1c_OBJECTS) $(asn1c_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1c.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@
uninstall-info-am:
man1dir = $(mandir)/man1
install-man1: $(man1_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(man1dir)
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
$(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
done
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
rm -f $(DESTDIR)$(man1dir)/$$inst; \
done
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
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: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
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
for subdir in $(SUBDIRS); do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-recursive
all-am: Makefile $(PROGRAMS) $(MANS)
installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir)
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am: install-man
install-exec-am: install-binPROGRAMS
install-info: install-info-recursive
install-man: install-man1
installcheck-am:
maintainer-clean: maintainer-clean-recursive
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
uninstall-am: uninstall-binPROGRAMS uninstall-info-am uninstall-man
uninstall-info: uninstall-info-recursive
uninstall-man: uninstall-man1
.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-TESTS check-am \
clean clean-binPROGRAMS clean-generic clean-libtool \
clean-recursive distclean distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-recursive \
distclean-tags distdir dvi dvi-am dvi-recursive info info-am \
info-recursive install install-am install-binPROGRAMS \
install-data install-data-am install-data-recursive \
install-exec install-exec-am install-exec-recursive \
install-info install-info-am install-info-recursive install-man \
install-man1 install-recursive install-strip installcheck \
installcheck-am installdirs installdirs-am \
installdirs-recursive maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
tags tags-recursive uninstall uninstall-am \
uninstall-binPROGRAMS uninstall-info-am \
uninstall-info-recursive uninstall-man uninstall-man1 \
uninstall-recursive
# 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:

1
asn1c/README Normal file
View File

@ -0,0 +1 @@
The ASN.1 Compiler

99
asn1c/asn1c.1 Normal file
View File

@ -0,0 +1,99 @@
.de Id
..
.Id $Id"
.TH ASN1C 1 "\*(Dt" "ASN.1 Compiler" "ASN.1 Compiler"
.SH NAME
asn1c \- ASN.1 Compiler
.ND ASN.1 compiler
.SH SYNOPSIS
.B asn1c
.RI "[ " option " | " filename " ].\|.\|."
.SH DESCRIPTION
asn1c is a tool to compile the ASN.1 specifications into C language structures
and accompanying routines to perform data encoding and decoding.
.SH OPTIONS
.TP
.B Overall Options
\-E
\-F
\-L
\-N
\-P
.RI "\-S " directory
\-R
.TP
.B Language Options
.br
\-ftypes88
\-fnative-integers
\-fno-c99
\-funnamed-unions
.TP
.B Warning Options
.br
\-Werror
\-Wdebug-lexer
\-Wdebug-fixer
\-Wdebug-compiler
.SH OVERALL OPTIONS
.TP
.B \-E
Stop after the parsing stage. The output is reconstructed ASN.1
specification code, which is sent to the standard output.
.TP
.B \-F
Used together with \c
.B \-E\c
, instructs the compiler to stop after the ASN.1 syntax
tree fixing stage and dump the reconstructed ASN.1 specification
to the standard output.
.TP
.B \-L
Generate "-- #line" comments in
.B -E
output.
.TP
.B \-N
Do not generate certain type of comments in
.B -E
output.
.TP
.B \-P
Dump the compiled output to the standard output instead of creating the
target language files on disk.
.TP
.B \-S directory
Use the specified directory with ASN.1 skeleton files.
.TP
.B \-R
Restrict the compiler to generate only the ASN.1 tables,
omitting the usual support code.
.SH LANGUAGE OPTIONS
.TP
.B \-ftypes88
Use only ASN.1:1988 embedded types.
.TP
.B \-fnative-integers
Use native machine's integer types whenever possible,
instead of the complex ASN.1 INTEGER and ENUMERATED types.
.TP
.B \-fno-c99
Disable use of certain C99 extensions, like designated initializers.
.TP
.B \-funnamed-unions
Enable unnamed unions in structures definitions.
.SH WARNING OPTIONS
.TP
.B \-Werror
Treat warnings as errors; abort if any warning is produced.
.TP
.B \-Wdebug-lexer
Enable lexer debugging during the ASN.1 parsing stage.
.TP
.B \-Wdebug-fixer
Enable ASN.1 syntax tree fixer debugging during the fixing stage.
.TP
.B \-Wdebug-compiler
Enable debugging during the actual compile time.
.SH AUTHORS
Lev Walkin <vlm@lionet.info>

267
asn1c/asn1c.c Normal file
View File

@ -0,0 +1,267 @@
/*
* This is the program that connects the libasn1* libraries together.
* It uses them in turn to parse, fix and then compile or print the ASN.1 tree.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h> /* for stat(2) */
#include <unistd.h>
#include <libgen.h> /* for basename(3) */
#include <sysexits.h> /* for EX_USAGE */
#include <assert.h>
#include <errno.h>
#include <asn1parser.h> /* Parse the ASN.1 file and build a tree */
#include <asn1fix.h> /* Fix the ASN.1 tree */
#include <asn1print.h> /* Print the ASN.1 tree */
#include <asn1compiler.h> /* Compile the ASN.1 tree */
static void usage(char *av0); /* Print the Usage screen and exit(EX_USAGE) */
int
main(int ac, char **av) {
enum asn1p_flags asn1_parser_flags = A1P_NOFLAGS;
enum asn1f_flags asn1_fixer_flags = A1F_NOFLAGS;
enum asn1c_flags asn1_compiler_flags = A1C_NOFLAGS;
int print_arg__print_out = 0; /* Don't compile, just print parsed */
int print_arg__fix_n_print = 0; /* Fix and print */
enum asn1print_flags_e print_arg__flags = APF_NOFLAGS;
int warnings_as_errors = 0; /* Treat warnings as errors */
char *skeletons_dir = NULL; /* Directory with supplementary stuff */
asn1p_t *asn = 0; /* An ASN.1 parsed tree */
int ret; /* Return value from misc functions */
int ch; /* Command line character */
int i; /* Index in some loops */
/*
* Process command-line options.
*/
while((ch = getopt(ac, av, "EFf:LNPRS:W:")) != -1)
switch(ch) {
case 'E':
print_arg__print_out = 1;
break;
case 'F':
print_arg__fix_n_print = 1;
break;
case 'f':
if(strcmp(optarg, "types88") == 0) {
asn1_parser_flags |= A1P_TYPES_RESTRICT_TO_1988;
} else if(strcmp(optarg, "constr90") == 0) {
asn1_parser_flags |= A1P_CONSTRUCTS_RESTRICT_TO_1990;
} else if(strcmp(optarg, "native-integers") == 0) {
asn1_compiler_flags |= A1C_USE_NATIVE_INTEGERS;
} else if(strcmp(optarg, "no-c99") == 0) {
asn1_compiler_flags |= A1C_NO_C99;
} else if(strcmp(optarg, "unnamed-unions") == 0) {
asn1_compiler_flags |= A1C_UNNAMED_UNIONS;
} else {
fprintf(stderr, "-f%s: Invalid argument\n", optarg);
exit(EX_USAGE);
}
break;
case 'L':
print_arg__flags = APF_LINE_COMMENTS;
break;
case 'N':
print_arg__flags = APF_NO_SOURCE_COMMENTS;
break;
case 'P':
asn1_compiler_flags |= A1C_PRINT_COMPILED;
break;
case 'R':
asn1_compiler_flags |= A1C_OMIT_SUPPORT_CODE;
break;
case 'S':
skeletons_dir = optarg;
break;
case 'W':
if(strcmp(optarg, "error") == 0) {
warnings_as_errors = 1;
break;
} else if(strcmp(optarg, "debug-lexer") == 0) {
asn1_parser_flags |= A1P_LEXER_DEBUG;
break;
} else if(strcmp(optarg, "debug-fixer") == 0) {
asn1_fixer_flags |= A1F_DEBUG;
break;
} else if(strcmp(optarg, "debug-compiler") == 0) {
asn1_compiler_flags |= A1C_DEBUG;
break;
} else {
fprintf(stderr, "-W%s: Invalid argument\n", optarg);
exit(EX_USAGE);
}
break;
default:
usage(av[0]);
}
/*
* Validate the options combination.
*/
if(!print_arg__print_out) {
if(print_arg__fix_n_print) {
fprintf(stderr, "Error: -F requires -E\n");
exit(EX_USAGE);
}
}
/*
* Ensure that there are some input files present.
*/
if(ac > optind) {
ac -= optind;
av += optind;
} else {
fprintf(stderr, "%s: No input files specified\n",
basename(av[0]));
exit(1);
}
/*
* Iterate over input files and parse each.
* All syntax trees from all files will be bundled together.
*/
for(i = 0; i < ac; i++) {
asn1p_t *new_asn;
new_asn = asn1p_parse_file(av[i], asn1_parser_flags);
if(new_asn == NULL) {
fprintf(stderr, "Cannot parse \"%s\"\n", av[i]);
exit(EX_DATAERR);
}
/*
* Bundle the parsed tree with existing one.
*/
if(asn) {
asn1p_module_t *mod;
while((mod = TQ_REMOVE(&(new_asn->modules), mod_next)))
TQ_ADD(&(asn->modules), mod, mod_next);
asn1p_free(new_asn);
} else {
asn = new_asn;
}
}
/*
* Dump the parsed ASN.1 tree if -E specified and -F is not given.
*/
if(print_arg__print_out && !print_arg__fix_n_print) {
if(asn1print(asn, print_arg__flags))
exit(EX_SOFTWARE);
return 0;
}
/*
* Process the ASN.1 specification: perform semantic checks,
* expand references, etc, etc.
* This function will emit necessary warnings and error messages.
*/
ret = asn1f_process(asn, asn1_fixer_flags,
NULL /* default fprintf(stderr) */);
switch(ret) {
case 1:
if(!warnings_as_errors)
/* Fall through */
case 0:
break; /* All clear */
case -1:
exit(EX_DATAERR); /* Fatal failure */
}
/*
* Dump the parsed ASN.1 tree if -E specified and -F is given.
*/
if(print_arg__print_out && print_arg__fix_n_print) {
if(asn1print(asn, print_arg__flags))
exit(EX_SOFTWARE);
return 0;
}
/*
* Make sure the skeleton directory is out there.
*/
if(skeletons_dir == NULL) {
struct stat sb;
skeletons_dir = DATADIR;
if((av[-optind][0] == '.' || av[-optind][1] == '/')
&& stat(skeletons_dir, &sb)) {
/*
* The default skeletons directory does not exist,
* compute it from my file name:
* ./asn1c/asn1c -> ./skeletons
*/
char *p;
int len;
p = dirname(av[-optind]);
len = strlen(p) + sizeof("/../skeletons");
skeletons_dir = alloca(len);
snprintf(skeletons_dir, len, "%s/../skeletons", p);
if(stat(skeletons_dir, &sb)) {
fprintf(stderr,
"WARNING: skeletons are neither in "
"\"%s\" nor in \"%s\"!\n",
DATADIR, skeletons_dir);
if(warnings_as_errors)
exit(EX_SOFTWARE);
}
}
}
/*
* Compile the ASN.1 tree into a set of source files
* of another language.
*/
if(asn1_compile(asn, skeletons_dir, asn1_compiler_flags)) {
exit(EX_SOFTWARE);
}
return 0;
}
/*
* Print the usage screen and exit(EX_USAGE).
*/
static void
usage(char *av0) {
fprintf(stderr,
"ASN.1 Compiler, v" VERSION "\n"
"Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>\n"
"Usage: %s [options] ...\n"
"Where [options] are:\n"
"\t-E\tRun only the ASN.1 parser and print out the tree\n"
"\t-F\tDuring -E operation, also perform tree fixing\n"
"\t-L\tGenerate \"-- #line\" comments in -E output\n"
"\t-N\tDo not generate certain type of comments in -E output\n"
"\n"
"\t-P \tConcatenate and print the compiled text\n"
"\t-S <dir>\tDirectory with support (skeleton?) files\n"
"\t \t(Default is \"%s\")\n"
"\t-R \tRestrict output (tables only, no support code)\n"
"\n"
"\t-ftypes88\tUse only ASN.1:1988 embedded types\n"
/*
"\t-fconstr90\tUse only ASN.1:1990 constructs (not available)\n"
*/
"\t-fnative-integers\tUse native integers where possible\n"
"\t-fno-c99\tDisable C99 extensions\n"
"\t-funnamed-unions\tEnable unnamed unions in structures\n"
"\n"
"\t-Werror \tTreat warnings as errors; abort if any warning\n"
"\t-Wdebug-lexer\tEnable verbose debugging output from lexer\n"
"\t-Wdebug-fixer\tDebug ASN.1 semantics processor\n"
"\t-Wdebug-compiler\tDebug ASN.1 compiler\n"
,
basename(av0), DATADIR
);
exit(EX_USAGE);
}

18
asn1c/check-parsing.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/sh
tmpfile=".check-parsing.$$.tmp"
ec=0
for ref in ../tests/*.asn1.-*; do
src=`echo "$ref" | sed -e 's/\.-[a-zA-Z]*$//'`
flags=`echo "$ref" | sed -e 's/.*\.-//'`
echo "Checking $src against $ref"
./asn1c "-$flags" "$src" > "$tmpfile" || ec=$?
if [ $? = 0 ]; then
diff "$ref" "$tmpfile" || ec=$?
fi
rm -f "$tmpfile"
done
exit $ec

10
asn1c/tests/Makefile.am Normal file
View File

@ -0,0 +1,10 @@
check_SCRIPTS = ./check-assembly.sh
TESTS_ENVIRONMENT= ./check-assembly.sh
TESTS = check-*.c
EXTRA_DIST = ${check_SCRIPTS} check-*.c
clean:
for t in test-*; do rm -rf $$t; done

284
asn1c/tests/Makefile.in Normal file
View File

@ -0,0 +1,284 @@
# 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@
check_SCRIPTS = ./check-assembly.sh
TESTS_ENVIRONMENT = ./check-assembly.sh
TESTS = check-*.c
EXTRA_DIST = ${check_SCRIPTS} check-*.c
subdir = asn1c/tests
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
DIST_COMMON = README Makefile.am Makefile.in
all: all-am
.SUFFIXES:
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 asn1c/tests/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
uninstall-info-am:
tags: TAGS
TAGS:
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_SCRIPTS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-generic distclean-libtool
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-generic mostlyclean-libtool
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-TESTS check-am clean clean-generic \
clean-libtool distclean distclean-generic distclean-libtool \
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-generic \
mostlyclean-libtool uninstall uninstall-am uninstall-info-am
clean:
for t in test-*; do rm -rf $$t; done
# 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:

6
asn1c/tests/README Normal file
View File

@ -0,0 +1,6 @@
This is a very funny test automation. The name of the check-*.c file is used
as a pointer to the file in ../..//tests/*-*.asn1. This file is compiled
using the asn1c from above directory. Then, everything is build together
in a temporary directory with a check-*.c used as a testing engine.

141
asn1c/tests/check-22.c Normal file
View File

@ -0,0 +1,141 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T1.h>
uint8_t buf1[] = {
32 | 16, /* [UNIVERSAL 16], constructed */
12, /* L */
/* INTEGER a */
((2 << 6) + 0), /* [0], primitive */
2, /* L */
150,
70,
/* b [1] EXPLICIT CHOICE */
32 | ((2 << 6) + 1), /* [1] */
3, /* L */
((2 << 6) + 1), /* [1] */
1,
'i',
/* UTF8String c */
((2 << 6) + 2), /* [2], primitive */
1, /* L */
'x'
};
uint8_t buf2[128];
int buf2_pos;
static int
buf2_fill(const void *buffer, size_t size, void *app_key) {
if(buf2_pos + size > sizeof(buf2))
return -1;
memcpy(buf2 + buf2_pos, buffer, size);
buf2_pos += size;
return 0;
}
static void
check(int is_ok, uint8_t *buf, int size, int consumed) {
T1_t t, *tp;
ber_dec_rval_t rval;
der_enc_rval_t erval;
int i;
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "Buf %p\n", buf);
rval = ber_decode(&asn1_DEF_T1, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
if(is_ok) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(t.a.size == 2);
assert(t.b.present == b_PR_n);
assert(t.b.choice.n.size == 1);
assert(t.b.choice.n.buf[0] == 'i');
assert(t.c.size == 1);
assert(t.c.buf[0] == 'x');
} else {
if(rval.code == RC_OK) {
assert(t.a.size != 2
|| t.b.present != b_PR_n
|| t.b.choice.n.size != 1
|| t.c.size != 1
);
}
assert(rval.consumed <= consumed);
return;
}
fprintf(stderr, "=> Re-creating using DER encoder <=\n");
/*
* Try to re-create using DER encoding.
*/
buf2_pos = 0;
erval = der_encode(&asn1_DEF_T1, tp, buf2_fill, 0);
assert(erval.encoded != -1);
if(erval.encoded != sizeof(buf1)) {
printf("%d != %d\n", (int)erval.encoded, (int)sizeof(buf1));
}
assert(erval.encoded == sizeof(buf1));
for(i = 0; i < sizeof(buf1); i++) {
if(buf1[i] != buf2[i]) {
fprintf(stderr, "Recreated buffer content mismatch:\n");
fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
i,
buf1[i], buf2[i],
buf1[i], buf2[i]
);
}
assert(buf1[i] == buf2[i]);
}
fprintf(stderr, "=== PRINT ===\n");
asn_fprint(stderr, &asn1_DEF_T1, tp);
fprintf(stderr, "=== EOF ===\n");
}
static void
try_corrupt(uint8_t *buf, int size) {
uint8_t *tmp;
int i;
fprintf(stderr, "\nCorrupting...\n");
tmp = alloca(size);
for(i = 0; i < 1000; i++) {
int loc;
memcpy(tmp, buf, size);
/* Corrupt random _non-value_ location. */
do { loc = random() % size; } while(tmp[loc] >= 70);
do { tmp[loc] ^= random(); } while(tmp[loc] == buf[loc]);
fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
i, loc, buf[loc], tmp[loc]);
check(0, tmp, size, size);
}
}
int
main(int ac, char **av) {
check(1, buf1, sizeof(buf1), sizeof(buf1));
try_corrupt(buf1, sizeof(buf1));
check(1, buf1, sizeof(buf1) + 10, sizeof(buf1));
return 0;
}

94
asn1c/tests/check-24.c Normal file
View File

@ -0,0 +1,94 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
uint8_t buf1[] = {
32 | ((2 << 6) + 5), /* [5], constructed */
17, /* L */
32 | 16, /* [UNIVERSAL 16], constructed */
15, /* L */
/* INTEGER a */
2, /* [UNIVERSAL 2] */
2, /* L */
150,
70,
/* INTEGER b */
((2 << 6) + 0), /* [0] */
1, /* L */
123,
/* INTEGER c */
((2 << 6) + 1), /* [1] */
1, /* L */
123,
/* INTEGER d */
32 | ((2 << 6) + 5), /* [5], constructed */
3,
2,
1, /* L */
123,
};
static void
check(int is_ok, uint8_t *buf, int size, int consumed) {
T_t t, *tp;
ber_dec_rval_t rval;
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "Buf %p\n", buf);
rval = ber_decode(&asn1_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
if(is_ok) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
} else {
if(rval.code == RC_OK) {
assert(t.a.size != 2
|| (!t.b || t.b->size != 1)
|| (!t.c || t.c->size != 1)
|| t.d.size != 1
);
}
assert(rval.consumed <= consumed);
}
}
static void
try_corrupt(uint8_t *buf, int size) {
uint8_t *tmp;
int i;
fprintf(stderr, "\nCorrupting...\n");
tmp = alloca(size);
for(i = 0; i < 1000; i++) {
int loc;
memcpy(tmp, buf, size);
/* Corrupt random _non-value_ location. */
do { loc = random() % size; } while(tmp[loc] >= 70);
do { tmp[loc] ^= random(); } while(tmp[loc] == buf[loc]);
fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
i, loc, buf[loc], tmp[loc]);
check(0, tmp, size, size);
}
}
int
main(int ac, char **av) {
check(1, buf1, sizeof(buf1), sizeof(buf1));
try_corrupt(buf1, sizeof(buf1));
return 0;
}

252
asn1c/tests/check-25.c Normal file
View File

@ -0,0 +1,252 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
uint8_t buf1[] = {
32 | 16, /* [UNIVERSAL 16], constructed */
128, /* L */
/* a INTEGER */
2, /* [UNIVERSAL 2] */
2, /* L */
150,
70,
/* b BOOLEAN */
128 | 2, /* [2] */
1, /* L */
0xff,
/* c NULL */
5, /* [UNIVERSAL 5] */
0, /* L */
/* d ENUMERATED */
10, /* [UNIVERSAL 10] */
1, /* L */
222,
4, /* [UNIVERSAL 4] */
3, /* L */
'x',
'y',
'z',
/* f OCTET STRING */
32 | 4, /* [UNIVERSAL 4], constructed */
128, /* L indefinite */
4, /* [UNIVERSAL 4], primitive */
2,
'l',
'o',
32 | 4, /* [UNIVERSAL 4], recursively constructed */
128,
4,
1,
'v',
4,
2,
'e',
'_',
0,
0,
4, /* [UNIVERSAL 4], primitive */
2,
'i',
't',
0,
0,
/* g BIT STRING */
3, /* [UNIVERSAL 3], primitive */
3, /* L */
2, /* Skip 2 bits */
147,
150, /* => 148 */
/* h BIT STRING */
32 | 3, /* [UNIVERSAL 3], constructed */
128, /* L indefinite */
3, /* [UNIVERSAL 3], primitive */
3, /* L */
0, /* Skip 0 bits */
140,
141,
3, /* [UNIVERSAL 3], primitive */
2, /* L */
1, /* Skip 1 bit */
143, /* => 142 */
0, /* End of f */
0,
0, /* End of the whole structure */
0,
/* Three bytes of planned leftover */
111, 222, 223
};
static void
check(int is_ok, uint8_t *buf, int size, int consumed) {
T_t t, *tp;
ber_dec_rval_t rval;
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "Buf %p (%d)\n", buf, (int)size);
rval = ber_decode(&asn1_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d, expected %d\n",
(int)rval.code, (int)rval.consumed, (int)consumed);
if(is_ok) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(strcmp(t.e->buf, "xyz") == 0);
assert(strcmp(t.f->buf, "love_it") == 0);
assert(t.g->size == 3);
assert(t.g->buf[0] == 2);
assert(t.g->buf[1] == 147);
assert(t.g->buf[2] == 148);
printf("%d\n", t.h->buf[3]);
assert(t.h->size == 4);
assert(t.h->buf[0] == 1);
assert(t.h->buf[1] == 140);
assert(t.h->buf[2] == 141);
assert(t.h->buf[3] == 142);
} else {
if(rval.code == RC_OK) {
assert(t.a.size != 2
|| !t.d
|| t.d->size != 1
|| !t.e
|| t.e->size != 3
|| !t.f
|| t.f->size != 7
|| !t.g
|| t.g->size != 3
|| !t.h
|| t.h->size != 4
);
}
fprintf(stderr, "%d %d\n", (int)rval.consumed, (int)consumed);
assert(rval.consumed <= consumed);
}
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
}
static void
try_corrupt(uint8_t *buf, int size, int allow_consume) {
uint8_t *tmp;
int i;
fprintf(stderr, "\nCorrupting...\n");
tmp = alloca(size);
for(i = 0; i < 1000; i++) {
int loc;
memcpy(tmp, buf, size);
/* Corrupt random _non-value_ location. */
do { loc = random() % size; } while(
loc == 44 /* bit skips */
|| loc == 51 /* bit skips */
|| loc == 56 /* bit skips */
|| tmp[loc] >= 70);
do { tmp[loc] = buf[loc] ^ random(); } while(
(tmp[loc] == buf[loc])
|| (buf[loc] == 0 && tmp[loc] == 0x80));
fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
i, loc, buf[loc], tmp[loc]);
check(0, tmp, size, allow_consume);
}
}
static void
partial_read(uint8_t *buf, int size) {
T_t t, *tp;
ber_dec_rval_t rval;
int i1, i2;
uint8_t *buf1 = alloca(size);
uint8_t *buf2 = alloca(size);
uint8_t *buf3 = alloca(size);
fprintf(stderr, "\nPartial read sequence...\n");
/*
* Divide the space (size) into three blocks in various combinations:
* |<----->i1<----->i2<----->|
* ^ buf ^ buf+size
* Try to read block by block.
*/
for(i1 = 0; i1 < size; i1++) {
for(i2 = i1; i2 < size; i2++) {
uint8_t *chunk1 = buf;
int size1 = i1;
uint8_t *chunk2 = buf + size1;
int size2 = i2 - i1;
uint8_t *chunk3 = buf + size1 + size2;
int size3 = size - size1 - size2;
fprintf(stderr, "\n%d:{%d, %d, %d}...\n",
size, size1, size2, size3);
memset(buf1, 0, size);
memset(buf2, 0, size);
memset(buf3, 0, size);
memcpy(buf1, chunk1, size1);
memcpy(buf2, chunk2, size2);
memcpy(buf3, chunk3, size3);
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "=> Chunk 1 (%d):\n", size1);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf1, size1);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size1);
if(rval.consumed < size1) {
int leftover = size1 - rval.consumed;
memcpy(buf2, buf1 + rval.consumed, leftover);
memcpy(buf2 + leftover, chunk2, size2);
size2 += leftover;
}
fprintf(stderr, "=> Chunk 2 (%d):\n", size2);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf2, size2);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size2);
if(rval.consumed < size2) {
int leftover = size2 - rval.consumed;
memcpy(buf3, buf2 + rval.consumed, leftover);
memcpy(buf3 + leftover, chunk3, size3);
size3 += leftover;
}
fprintf(stderr, "=> Chunk 3 (%d):\n", size3);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf3, size3);
assert(rval.code == RC_OK);
assert(rval.consumed == size3);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
}
}
}
int
main(int ac, char **av) {
/* Check that the full buffer may be decoded normally */
check(1, buf1, sizeof(buf1), sizeof(buf1) - 3);
/* Check that some types of buffer corruptions will lead to failure */
try_corrupt(buf1, sizeof(buf1) - 3, sizeof(buf1) - 3);
/* Split the buffer in parts and check decoder restartability */
partial_read(buf1, sizeof(buf1) - 3);
return 0;
}

116
asn1c/tests/check-30.c Normal file
View File

@ -0,0 +1,116 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
uint8_t buf1[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
8, /* L */
/* a INTEGER */
64 | 3, /* [APPLICATION 3] */
1, /* L */
96,
/* b IA5String */
22, /* [UNIVERSAL 22] */
3, /* L */
'x',
'y',
'z'
};
/*
* This buffer aims at checking the duplication.
*/
uint8_t buf2[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
8, /* L */
/* a INTEGER */
64 | 3, /* [APPLICATION 3] */
1, /* L */
96,
/* a INTEGER _again_ */
64 | 3, /* [APPLICATION 3] */
1, /* L */
97,
};
static void
check(int is_ok, uint8_t *buf, int size, int consumed) {
T_t t, *tp;
ber_dec_rval_t rval;
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "Buf %p\n", buf);
rval = ber_decode(&asn1_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
if(is_ok) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(t.a.size == 1);
assert(t.a.buf[0] == 96);
assert(t.b.size == 3);
assert(t.c == 0);
assert(strcmp(t.b.buf, "xyz") == 0);
} else {
if(rval.code == RC_OK) {
assert(t.a.size != 1
|| t.b.size != 3
|| !t.c
);
}
assert(rval.consumed <= consumed);
}
}
static void
try_corrupt(uint8_t *buf, int size) {
uint8_t *tmp;
int i;
fprintf(stderr, "\nCorrupting...\n");
tmp = alloca(size);
for(i = 0; i < 1000; i++) {
int loc;
memcpy(tmp, buf, size);
/* Corrupt random _non-value_ location. */
do { loc = random() % size; } while(tmp[loc] >= 70);
do { tmp[loc] = buf[loc] ^ random(); } while(
(tmp[loc] == buf[loc])
|| (buf[loc] == 0 && tmp[loc] == 0x80));
fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
i, loc, buf[loc], tmp[loc]);
check(0, tmp, size, size);
}
}
int
main(int ac, char **av) {
fprintf(stderr, "Must succeed:\n");
check(1, buf1, sizeof(buf1) + 20, sizeof(buf1));
fprintf(stderr, "\nMust fail:\n");
check(0, buf2, sizeof(buf2) + 1, 5);
fprintf(stderr, "\nPseudo-random buffer corruptions must fail\n");
try_corrupt(buf1, sizeof(buf1));
return 0;
}

175
asn1c/tests/check-31.c Normal file
View File

@ -0,0 +1,175 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <Forest.h>
uint8_t buf1[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
128, /* L, indefinite */
32 | 16, /* [UNIVERSAL 16], constructed */
6, /* L */
/* height INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
100,
/* width INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
80,
32 | 16, /* [UNIVERSAL 16], constructed */
6, /* L */
/* height INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
110,
/* width INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
82,
0, /* End of forest */
0
};
uint8_t buf1_reconstr[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
16, /* L */
32 | 16, /* [UNIVERSAL 16], constructed */
6, /* L */
/* height INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
100,
/* width INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
80,
32 | 16, /* [UNIVERSAL 16], constructed */
6, /* L */
/* height INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
110,
/* width INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
82
};
int buf_pos;
int bytes_compare(const void *bufferp, size_t size, void *key) {
const uint8_t *buffer = bufferp;
assert(buf_pos + size <= sizeof(buf1_reconstr));
fprintf(stderr, " writing %d (%d)\n", (int)size, buf_pos + (int)size);
for(; size; buf_pos++, size--, buffer++) {
if(buf1_reconstr[buf_pos] != *buffer) {
fprintf(stderr,
"Byte %d is different: %d != %d (%x != %x)\n",
buf_pos,
*buffer, buf1_reconstr[buf_pos],
*buffer, buf1_reconstr[buf_pos]
);
assert(buf1_reconstr[buf_pos] == *buffer);
}
}
return 0;
}
static void
check(int is_ok, uint8_t *buf, int size, int consumed) {
Forest_t t, *tp;
ber_dec_rval_t rval;
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "Buf %p\n", buf);
rval = ber_decode(&asn1_DEF_Forest, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
if(is_ok) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(t.list.count == 2);
assert(t.list.array[0]->height.size == 1);
assert(t.list.array[0]->width.size == 1);
assert(t.list.array[1]->height.size == 1);
assert(t.list.array[1]->width.size == 1);
} else {
if(rval.code == RC_OK) {
assert(t.list.count != 2
|| t.list.array[0]->height.size != 1
|| t.list.array[0]->width.size != 1
|| t.list.array[1]->height.size != 1
|| t.list.array[1]->width.size != 1
);
}
assert(rval.consumed <= consumed);
return;
}
/*
* Try to re-create the buffer.
*/
buf_pos = 0;
der_encode(&asn1_DEF_Forest, &t,
bytes_compare, buf1_reconstr);
assert(buf_pos == sizeof(buf1_reconstr));
asn_fprint(stderr, &asn1_DEF_Forest, &t);
asn1_DEF_Forest.free_struct(&asn1_DEF_Forest, &t, 1);
}
static void
try_corrupt(uint8_t *buf, int size) {
uint8_t *tmp;
int i;
fprintf(stderr, "\nCorrupting...\n");
tmp = alloca(size);
for(i = 0; i < 1000; i++) {
int loc;
memcpy(tmp, buf, size);
/* Corrupt random _non-value_ location. */
do { loc = random() % size; } while(tmp[loc] >= 70);
do { tmp[loc] = buf[loc] ^ random(); } while(
(tmp[loc] == buf[loc])
|| (buf[loc] == 0 && tmp[loc] == 0x80));
fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
i, loc, buf[loc], tmp[loc]);
check(0, tmp, size, size);
}
}
int
main(int ac, char **av) {
check(1, buf1, sizeof(buf1), sizeof(buf1));
try_corrupt(buf1, sizeof(buf1));
check(1, buf1, sizeof(buf1) + 20, sizeof(buf1));
return 0;
}

21
asn1c/tests/check-32.c Normal file
View File

@ -0,0 +1,21 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <Programming.h>
int
main(int ac, char **av) {
Programming_t p;
memset(&p, 0, sizeof(p));
/*
* No plans to fill it up: just checking whether it compiles or not.
*/
return 0;
}

21
asn1c/tests/check-33.c Normal file
View File

@ -0,0 +1,21 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
int
main(int ac, char **av) {
T_t t;
memset(&t, 0, sizeof(t));
/*
* No plans to fill it up: just checking whether it compiles or not.
*/
return 0;
}

277
asn1c/tests/check-35.c Normal file
View File

@ -0,0 +1,277 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
uint8_t buf1[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
13, /* L */
/* b CHOICE { b2 ObjectDescriptor }*/
7, /* [UNIVERSAL 7] */
1, /* L */
'z',
/* c BOOLEAN */
1, /* [UNIVERSAL 1] */
0, /* L */
/* a NumericString */
18, /* [UNIVERSAL 18] */
2, /* L */
'n',
's',
/* d.r-oid RELATIVE-OID */
13, /* [UNIVERSAL 13] */
2, /* L */
85,
79,
};
uint8_t buf1_reconstr[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
14, /* L */
/* c BOOLEAN */
1, /* [UNIVERSAL 1] */
1, /* L */
0,
/* b CHOICE { b2 ObjectDescriptor }*/
7, /* [UNIVERSAL 7] */
1, /* L */
'z',
/* d.r-oid RELATIVE-OID */
13, /* [UNIVERSAL 1] */
2, /* L */
85,
79,
/* a NumericString */
18, /* [UNIVERSAL 18] */
2, /* L */
'n',
's'
};
uint8_t buf2[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
13, /* L */
/* a NumericString */
18, /* [UNIVERSAL 18] */
2, /* L */
'n',
's',
/* c BOOLEAN */
1, /* [UNIVERSAL 1] */
1, /* L */
2, /* True */
/* b CHOICE { b1 IA5String }*/
22, /* [UNIVERSAL 22] */
1, /* L */
'z',
/* d.oid RELATIVE-OID */
6, /* [UNIVERSAL 6] */
1, /* L */
81,
};
uint8_t buf2_reconstr[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
13, /* L */
/* c BOOLEAN */
1, /* [UNIVERSAL 1] */
1, /* L */
0xff, /* Canonical True */
/* d.oid RELATIVE-OID */
6, /* [UNIVERSAL 6] */
1, /* L */
81,
/* a NumericString */
18, /* [UNIVERSAL 18] */
2, /* L */
'n',
's',
/* b CHOICE { b1 IA5String }*/
22, /* [UNIVERSAL 22] */
1, /* L */
'z'
};
static void
check(T_t *tp, uint8_t *buf, int size, int consumed) {
ber_dec_rval_t rval;
tp = memset(tp, 0, sizeof(*tp));
fprintf(stderr, "Buf %p (%d)\n", buf, size);
rval = ber_decode(&asn1_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(strcmp(tp->a.buf, "ns") == 0);
assert(strcmp(tp->b.choice.b1.buf, "z") == 0
&& strcmp(tp->b.choice.b2.buf, "z") == 0);
}
int buf_pos;
int buf_size;
uint8_t *buf;
static int
buf_fill(const void *buffer, size_t size, void *app_key) {
if(buf_pos + size > buf_size) {
fprintf(stderr, "%d + %d > %d\n", buf_pos, (int)size, buf_size);
return -1;
}
memcpy(buf + buf_pos, buffer, size);
buf_pos += size;
fprintf(stderr, " written %d (%d)\n", (int)size, buf_pos);
return 0;
}
void
compare(T_t *tp, uint8_t *cmp_buf, int cmp_buf_size) {
der_enc_rval_t erval;
int i;
buf_size = cmp_buf_size + 100;
buf = alloca(buf_size);
buf_pos = 0;
/*
* Try to re-create using DER encoding.
*/
erval = der_encode(&asn1_DEF_T, tp, buf_fill, 0);
assert(erval.encoded != -1);
if(erval.encoded != cmp_buf_size) {
printf("%d != %d\n", erval.encoded, cmp_buf_size);
}
assert(erval.encoded == cmp_buf_size);
for(i = 0; i < cmp_buf_size; i++) {
if(buf[i] != cmp_buf[i]) {
fprintf(stderr, "Recreated buffer content mismatch:\n");
fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
i,
buf[i], cmp_buf[i],
buf[i], cmp_buf[i]
);
}
assert(buf[i] == cmp_buf[i]);
}
}
static void
partial_read(uint8_t *buf, int size) {
T_t t, *tp;
ber_dec_rval_t rval;
int i1, i2;
uint8_t *buf1 = alloca(size);
uint8_t *buf2 = alloca(size);
uint8_t *buf3 = alloca(size);
fprintf(stderr, "\nPartial read sequence...\n");
/*
* Divide the space (size) into three blocks in various combinations:
* |<----->i1<----->i2<----->|
* ^ buf ^ buf+size
* Try to read block by block.
*/
for(i1 = 0; i1 < size; i1++) {
for(i2 = i1; i2 < size; i2++) {
uint8_t *chunk1 = buf;
int size1 = i1;
uint8_t *chunk2 = buf + size1;
int size2 = i2 - i1;
uint8_t *chunk3 = buf + size1 + size2;
int size3 = size - size1 - size2;
fprintf(stderr, "\n%d:{%d, %d, %d}...\n",
size, size1, size2, size3);
memset(buf1, 0, size);
memset(buf2, 0, size);
memset(buf3, 0, size);
memcpy(buf1, chunk1, size1);
memcpy(buf2, chunk2, size2);
memcpy(buf3, chunk3, size3);
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "=> Chunk 1 (%d):\n", size1);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf1, size1);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size1);
if(rval.consumed < size1) {
int leftover = size1 - rval.consumed;
memcpy(buf2, buf1 + rval.consumed, leftover);
memcpy(buf2 + leftover, chunk2, size2);
size2 += leftover;
}
fprintf(stderr, "=> Chunk 2 (%d):\n", size2);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf2, size2);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size2);
if(rval.consumed < size2) {
int leftover = size2 - rval.consumed;
memcpy(buf3, buf2 + rval.consumed, leftover);
memcpy(buf3 + leftover, chunk3, size3);
size3 += leftover;
}
fprintf(stderr, "=> Chunk 3 (%d):\n", size3);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf3, size3);
assert(rval.code == RC_OK);
assert(rval.consumed == size3);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
}
}
}
int
main(int ac, char **av) {
T_t t;
check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Split the buffer in parts and check decoder restartability */
partial_read(buf1, sizeof(buf1));
return 0;
}

315
asn1c/tests/check-41.c Normal file
View File

@ -0,0 +1,315 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
uint8_t buf0[] = {
32 | ((2 << 6) + 1), /* [1], constructed */
18,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
16, /* L */
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
};
uint8_t buf0_reconstr[] = {
32 | ((2 << 6) + 1), /* [1], constructed */
18,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
16, /* L */
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
};
uint8_t buf1[] = {
32 | (2 << 6), /* [0], constructed */
0x80 | 1, /* L */
134,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
0x80 | 1, /* L */
128,
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
/* alpha [1] IMPLICIT INTEGER OPTIONAL */
(2 << 6) + 1, /* [1] */
1, /* L */
75,
};
uint8_t buf1_reconstr[] = {
32 | (2 << 6), /* [0], constructed */
0x80 | 1, /* L */
134,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
0x80 | 1, /* L */
128,
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
/* alpha [1] IMPLICIT INTEGER OPTIONAL */
(2 << 6) + 1, /* [1] */
1, /* L */
75,
};
uint8_t buf2[] = {
32 | ((2 << 6) + 1), /* [1], constructed */
0x80 | 1, /* L */
134,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
0x80 | 1, /* L */
128,
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
/* beta [2] IMPLICIT INTEGER OPTIONAL */
(2 << 6) + 2, /* [2] */
1, /* L */
75,
};
uint8_t buf2_reconstr[] = {
32 | ((2 << 6) + 1), /* [1], constructed */
0x80 | 1, /* L */
134,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
0x80 | 1, /* L */
128,
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
/* beta [2] IMPLICIT INTEGER OPTIONAL */
(2 << 6) + 2, /* [2] */
1, /* L */
75,
};
static void
check(T_t *tp, uint8_t *buf, int size, int consumed) {
ber_dec_rval_t rval;
tp = memset(tp, 0, sizeof(*tp));
fprintf(stderr, "Buf %p (%d)\n", buf, size);
rval = ber_decode(&asn1_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
/*
assert(tp->string.size == 128);
assert(strncmp(tp->string.buf, "zz") == 0);
assert(strcmp(tp->b.choice.b1.buf, "z") == 0
&& strcmp(tp->b.choice.b2.buf, "z") == 0);
*/
}
int buf_pos;
int buf_size;
uint8_t *buf;
static int
buf_fill(const void *buffer, size_t size, void *app_key) {
if(buf_pos + size > buf_size) {
fprintf(stderr, "%d + %d > %d\n", buf_pos, (int)size, buf_size);
return -1;
}
memcpy(buf + buf_pos, buffer, size);
buf_pos += size;
fprintf(stderr, " written %d (%d)\n", (int)size, buf_pos);
return 0;
}
void
compare(T_t *tp, uint8_t *cmp_buf, int cmp_buf_size) {
der_enc_rval_t erval;
int i;
buf_size = cmp_buf_size + 100;
buf = alloca(buf_size);
buf_pos = 0;
/*
* Try to re-create using DER encoding.
*/
erval = der_encode(&asn1_DEF_T, tp, buf_fill, 0);
assert(erval.encoded != -1);
if(erval.encoded != cmp_buf_size) {
printf("%d != %d\n", erval.encoded, cmp_buf_size);
}
assert(erval.encoded == cmp_buf_size);
for(i = 0; i < cmp_buf_size; i++) {
if(buf[i] != cmp_buf[i]) {
fprintf(stderr, "Recreated buffer content mismatch:\n");
fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
i,
buf[i], cmp_buf[i],
buf[i], cmp_buf[i]
);
}
assert(buf[i] == cmp_buf[i]);
}
}
static void
partial_read(uint8_t *buf, int size) {
T_t t, *tp;
ber_dec_rval_t rval;
int i1, i2;
uint8_t *buf1 = alloca(size);
uint8_t *buf2 = alloca(size);
uint8_t *buf3 = alloca(size);
fprintf(stderr, "\nPartial read sequence...\n");
/*
* Divide the space (size) into three blocks in various combinations:
* |<----->i1<----->i2<----->|
* ^ buf ^ buf+size
* Try to read block by block.
*/
for(i1 = 0; i1 < size; i1++) {
for(i2 = i1; i2 < size; i2++) {
uint8_t *chunk1 = buf;
int size1 = i1;
uint8_t *chunk2 = buf + size1;
int size2 = i2 - i1;
uint8_t *chunk3 = buf + size1 + size2;
int size3 = size - size1 - size2;
fprintf(stderr, "\n%d:{%d, %d, %d}...\n",
size, size1, size2, size3);
memset(buf1, 0, size);
memset(buf2, 0, size);
memset(buf3, 0, size);
memcpy(buf1, chunk1, size1);
memcpy(buf2, chunk2, size2);
memcpy(buf3, chunk3, size3);
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "=> Chunk 1 (%d):\n", size1);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf1, size1);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size1);
if(rval.consumed < size1) {
int leftover = size1 - rval.consumed;
memcpy(buf2, buf1 + rval.consumed, leftover);
memcpy(buf2 + leftover, chunk2, size2);
size2 += leftover;
}
fprintf(stderr, "=> Chunk 2 (%d):\n", size2);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf2, size2);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size2);
if(rval.consumed < size2) {
int leftover = size2 - rval.consumed;
memcpy(buf3, buf2 + rval.consumed, leftover);
memcpy(buf3 + leftover, chunk3, size3);
size3 += leftover;
}
fprintf(stderr, "=> Chunk 3 (%d):\n", size3);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf3, size3);
assert(rval.code == RC_OK);
assert(rval.consumed == size3);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
}
}
}
int
main(int ac, char **av) {
T_t t;
/* Check exact buf0 */
check(&t, buf0, sizeof(buf0), sizeof(buf0));
compare(&t, buf0_reconstr, sizeof(buf0_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Check exact buf1 */
check(&t, buf1, sizeof(buf1), sizeof(buf1));
compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Check slightly more than buf1 */
check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Check exact buf2 */
check(&t, buf2, sizeof(buf2), sizeof(buf2));
compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Check slightly more than buf2 */
check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Split the buffer in parts and check decoder restartability */
partial_read(buf0, sizeof(buf0));
return 0;
}

24
asn1c/tests/check-43.c Normal file
View File

@ -0,0 +1,24 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <Test-structure-1.h>
#include <Sets.h>
int
main(int ac, char **av) {
Test_structure_1_t ts1;
Sets_t s1;
memset(&ts1, 0, sizeof(ts1));
memset(&s1, 0, sizeof(s1));
/*
* No plans to fill it up: just checking whether it compiles or not.
*/
return 0;
}

56
asn1c/tests/check-assembly.sh Executable file
View File

@ -0,0 +1,56 @@
#!/bin/sh
#
# This script is designed to quickly create lots of files in underlying
# test-* directories, do lots of other magic stuff and exit cleanly.
#
# Compute the .asn1 spec name by the given file name.
source=$(echo "$1" | sed -e 's/.*\///')
testno=`echo "$source" | cut -f2 -d'-' | cut -f1 -d'.'`
args=$(echo "$source" | sed -e 's/\.c$//')
testdir=test-${args}
OFS=$IFS
IFS="."
set $args
shift
IFS=$OFS
if [ ! -d $testdir ]; then
mkdir $testdir || exit $?
fi
cd $testdir || exit $?
ln -fs ../$source || exit $?
# Compile the corresponding .asn1 spec.
set -x
../../asn1c \
-S ../../../skeletons \
-Wdebug-compiler "$@" \
../../../tests/${testno}-*.asn1 || exit $?
set +x
# Create a Makefile for the project.
cat > Makefile <<EOM
CFLAGS=-I. -Wall -g ${CFLAGS} -DEMIT_ASN_DEBUG
SRCS=`echo *.c`
OBJS=\${SRCS:.c=.o}
check-executable: \${OBJS}
\${CC} \${CFLAGS} -o check-executable \${OBJS}
.SUFFIXES:
.SUFFIXES: .c .o
.c.o:
\${CC} \${CFLAGS} -o \$@ -c \$<
check: check-executable
./check-executable
clean:
@rm -f *.o
EOM
# Perform building and checking
make check || exit $?
# Uncomment this to jeopardize debugging
# make clean

1314
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

81
config.h.in Normal file
View File

@ -0,0 +1,81 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtoimax' function. */
#undef HAVE_STRTOIMAX
/* Define to 1 if you have the `strtoll' function. */
#undef HAVE_STRTOLL
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
/* Version number of package */
#undef VERSION
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#undef YYTEXT_POINTER
/* Define to `int64_t' if <sys/types.h> does not define. */
#undef intmax_t
/* Define to `long' if <sys/types.h> does not define. */
#undef off_t
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t

1410
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

6937
configure vendored Executable file

File diff suppressed because it is too large Load Diff

95
configure.in Normal file
View File

@ -0,0 +1,95 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(libasn1parser/asn1p_y.y)
AC_CANONICAL_SYSTEM
AC_PREREQ(2.53)
AM_INIT_AUTOMAKE(asn1c, 0.8.10)
AC_SUBST(PATH)
AM_MAINTAINER_MODE
AM_PROG_LIBTOOL
dnl *** Autoconf support ***
AC_ARG_ENABLE(autoconf,
[ --disable-autoconf disable automatic generation of configure script ],
enable_autoconf=$enableval, enable_autoconf=yes
)
AC_PATH_PROG(AUTOCONF, autoconf, @echo autoconf not available)
AC_PATH_PROG(AUTOHEADER, autoheader, @echo autoheader not available)
if test -z "$AUTOCONF"; then enable_autoconf=no ; fi
if test -z "$AUTOHEADER"; then enable_autoconf=no ; fi
if test x$enable_autoconf = xyes; then
CONFIGURE_DEPENDS="configure.in aclocal.m4"
fi
AC_SUBST(CONFIGURE_DEPENDS)
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_YACC
AM_PROG_LEX
AC_PATH_PROG(AR, ar, ar, $PATH:/usr/ucb:/usr/ccs/bin)
dnl *** Building mingw32 with cygwin compiler ***
case "$build" in
*cygwin*)
case "$target" in
*mingw*)
CC="$CC -mno-cygwin"
esac ;;
esac
AC_ARG_ENABLE(autoconf,
[ --enable-Werror abort compilation after any C compiler warning],
ADD_CFLAGS="-Werror")
AC_SUBST(ADD_CFLAGS)
dnl Add these flags if we're using GCC.
case "$GCC" in
yes)
CFLAGS="$CFLAGS -Wall"
CFLAGS="$CFLAGS -Wshadow"
CFLAGS="$CFLAGS -Wcast-qual"
CFLAGS="$CFLAGS -Wcast-align"
CFLAGS="$CFLAGS -Wmissing-prototypes"
CFLAGS="$CFLAGS -Wmissing-declarations"
CFLAGS="$CFLAGS -Wredundant-decls"
CFLAGS="$CFLAGS -Wnested-externs"
;;
esac
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(errno.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_BIGENDIAN
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_STRUCT_TM
AC_CHECK_TYPE(intmax_t, int64_t)
AC_CHECK_FUNCS(strtoimax strtoll)
AM_CONFIG_HEADER(config.h)
AC_OUTPUT( \
libasn1compiler/Makefile \
skeletons/tests/Makefile \
libasn1parser/Makefile \
libasn1print/Makefile \
asn1c/tests/Makefile \
libasn1fix/Makefile \
skeletons/Makefile \
examples/Makefile \
tests/Makefile \
asn1c/Makefile \
doc/Makefile \
Makefile \
)

411
depcomp Executable file
View File

@ -0,0 +1,411 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
# Copyright 1999, 2000 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 to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# `libtool' can also be set to `yes' or `no'.
depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. This file always lives in the current directory.
# Also, the AIX compiler puts `$object:' at the start of each line;
# $object doesn't have directory information.
stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
outname="$stripped.o"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 AIX compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
tmpdepfile1="$object.d"
tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'`
if test "$libtool" = yes; then
"$@" -Wc,-MD
else
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
if test -f "$tmpdepfile1"; then
tmpdepfile="$tmpdepfile1"
else
tmpdepfile="$tmpdepfile2"
fi
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a space and a tab in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
test -z "$dashmflag" && dashmflag=-M
( IFS=" "
case " $* " in
*" --mode=compile "*) # this is libtool, let us make it quiet
for arg
do # cycle over the arguments
case "$arg" in
"--mode=compile")
# insert --quiet before "--mode=compile"
set fnord "$@" --quiet
shift # fnord
;;
esac
set fnord "$@" "$arg"
shift # fnord
shift # "$arg"
done
;;
esac
"$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
) &
proc=$!
"$@"
stat=$?
wait "$proc"
if test "$stat" != 0; then exit $stat; fi
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
# X makedepend
(
shift
cleared=no
for arg in "$@"; do
case $cleared in no)
set ""; shift
cleared=yes
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift;;
-*)
;;
*)
set fnord "$@" "$arg"; shift;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@"
) &
proc=$!
"$@"
stat=$?
wait "$proc"
if test "$stat" != 0; then exit $stat; fi
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tail +3 "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
( IFS=" "
case " $* " in
*" --mode=compile "*)
for arg
do # cycle over the arguments
case $arg in
"--mode=compile")
# insert --quiet before "--mode=compile"
set fnord "$@" --quiet
shift # fnord
;;
esac
set fnord "$@" "$arg"
shift # fnord
shift # "$arg"
done
;;
esac
"$@" -E |
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
) &
proc=$!
"$@"
stat=$?
wait "$proc"
if test "$stat" != 0; then exit $stat; fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
( IFS=" "
case " $* " in
*" --mode=compile "*)
for arg
do # cycle over the arguments
case $arg in
"--mode=compile")
# insert --quiet before "--mode=compile"
set fnord "$@" --quiet
shift # fnord
;;
esac
set fnord "$@" "$arg"
shift # fnord
shift # "$arg"
done
;;
esac
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
) &
proc=$!
"$@"
stat=$?
wait "$proc"
if test "$stat" != 0; then exit $stat; fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0

3
doc/Makefile.am Normal file
View File

@ -0,0 +1,3 @@
EXTRA_DIST = *.pdf
CLEANFILES = *.*~

221
doc/Makefile.in Normal file
View File

@ -0,0 +1,221 @@
# 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@
EXTRA_DIST = *.pdf
CLEANFILES = *.*~
subdir = doc
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
DIST_COMMON = Makefile.am Makefile.in
all: all-am
.SUFFIXES:
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 doc/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
uninstall-info-am:
tags: TAGS
TAGS:
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
check: check-am
all-am: Makefile
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:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-generic distclean-libtool
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-generic mostlyclean-libtool
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool 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-generic \
mostlyclean-libtool uninstall uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

BIN
doc/asn1c-usage.pdf Normal file

Binary file not shown.

4
examples/Makefile.am Normal file
View File

@ -0,0 +1,4 @@
dist_bin_SCRIPTS = crfc2asn1.pl clyx2asn1.pl
EXTRA_DIST = *.asn1 rfc*.txt

246
examples/Makefile.in Normal file
View File

@ -0,0 +1,246 @@
# 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@
dist_bin_SCRIPTS = crfc2asn1.pl clyx2asn1.pl
EXTRA_DIST = *.asn1 rfc*.txt
subdir = examples
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
SCRIPTS = $(dist_bin_SCRIPTS)
DIST_SOURCES =
DIST_COMMON = README $(dist_bin_SCRIPTS) Makefile.am Makefile.in
all: all-am
.SUFFIXES:
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 examples/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
install-dist_binSCRIPTS: $(dist_bin_SCRIPTS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(dist_bin_SCRIPTS)'; for p in $$list; do \
f="`echo $$p|sed '$(transform)'`"; \
if test -f $$p; then \
echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/$$f"; \
$(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/$$f; \
elif test -f $(srcdir)/$$p; then \
echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/$$f"; \
$(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/$$f; \
else :; fi; \
done
uninstall-dist_binSCRIPTS:
@$(NORMAL_UNINSTALL)
@list='$(dist_bin_SCRIPTS)'; for p in $$list; do \
f="`echo $$p|sed '$(transform)'`"; \
echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
rm -f $(DESTDIR)$(bindir)/$$f; \
done
uninstall-info-am:
tags: TAGS
TAGS:
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
check: check-am
all-am: Makefile $(SCRIPTS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(bindir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-generic distclean-libtool
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-dist_binSCRIPTS
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-generic mostlyclean-libtool
uninstall-am: uninstall-dist_binSCRIPTS uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am info info-am install install-am install-data \
install-data-am install-dist_binSCRIPTS 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-generic mostlyclean-libtool uninstall uninstall-am \
uninstall-dist_binSCRIPTS uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

6
examples/README Normal file
View File

@ -0,0 +1,6 @@
This directory contains several convertors from known text formats into
the ASN.1 specifications, as well as examples of these formats and the
sample convertor's output.
Try ../asn1c/asn1c -P *PKIX*93.asn1

51
examples/clyx2asn1.pl Executable file
View File

@ -0,0 +1,51 @@
#!/usr/bin/perl
#
# $Id$
# $Author$
#
# Simple tool that fetches known ASN.1 specifications from the
# stream of LyX data.
#
if($#ARGV == -1) {
print STDERR "Extract known modules from LyX data\n";
print STDERR "Usage: cat *.lyx | $0 <ASN-Module-Name> ...\n";
exit 64;
}
# Convert arguments into a hash for quicker search.
for(my $i; $i <= $#ARGV; $i++) {
$modules{$ARGV[$i]} = $ARGV[$i].".asn1";
}
# Process incoming stream in search for ASN.1 modules.
while(<STDIN>) {
chop;
if($inmodule) {
next if(/^$/);
if(/^\\layout /) {
print O "\n";
next;
}
if(/^\\begin_inset Quotes/) {
print O '"';
next;
}
next if(/^\\/);
print O;
if(/^END$/) {
$inmodule = 0;
print O "\n";
}
} else {
next unless $modules{$_};
open(O, '> '.$modules{$_});
print O;
$inmodule = 1;
delete $modules{$_};
}
}
# Make sure noone's missing.
die "Modules not found: " . join(", ", keys %modules) . "\n" if keys %modules;

86
examples/crfc2asn1.pl Executable file
View File

@ -0,0 +1,86 @@
#!/usr/bin/perl
#
# $Id$
# $Author$
#
# Simple tool that fetches the ASN.1 specifications from the
# given set of RFC files.
#
my $inasn = 0; # Are we inside ASN.1 grammar?
my $found = 0;
if(-t STDIN && $#ARGV == -1) {
print STDERR "Rip ASN.1 specification from RFC file\n";
print STDERR "Usage: $0 <rfc-file.txt> ...\n";
print STDERR "Usage: <someprog> | $0\n";
exit(1);
}
while(<>) {
#
# Strip RFC page delimiters.
#
next if /^[A-Z].*\[Page [0-9]+\]$/;
next if /^ $/;
next if /^RFC [0-9].*[0-9]+$/;
if($inasn == 0) {
#
# The least correct way to find the start of ASN
# definition.
#
if(/^[ \t]*END[ \t]*$/) {
print STDERR
"Missed an ASN.1 grammar before line ". $. ."?\n";
exit(1);
}
my $rfcid = '';
$rfcid = $1 . '-' if($ARGV =~ /([a-z0-9]+)/i);
if(/^[ \t]+([A-Za-z0-9-]+).*DEFINITIONS.*::=/) {
my $fname = $rfcid . $1 . ".asn1";
open(O, "> $fname") or die "Can't open $fname";
select(O);
$inasn = 1;
} elsif(/^[ \t]*([A-Za-z0-9-]+).*{.*iso/) {
my $fname = $rfcid . $1 . ".asn1";
my @a = ($_);
my $i;
for($i = 0; $i < 8; $i++) {
$_ = <>;
push(@a, $_);
if(/DEFINITIONS/) {
$_ = join('', @a);
$inasn = 1;
last;
}
}
next unless $inasn;
open(O, "> $fname") or die "Can't open $fname";
select(O);
} else {
next;
}
$found++;
print "\n";
print "-- \n";
print "-- Grammar found in $ARGV by $0 at " . $. . "\n";
print "-- \n";
print "\n";
}
print;
if(/^[ \t]*END[ \t]*$/) {
select(STDOUT);
close(O);
$inasn = 0;
}
}
die "No ASN.1 specifications found\n" unless $found;

251
install-sh Executable file
View File

@ -0,0 +1,251 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

View File

@ -0,0 +1,28 @@
AM_CPPFLAGS = \
-I${top_srcdir}/libasn1parser \
-I${top_srcdir}/libasn1fix
noinst_LTLIBRARIES = libasn1compiler.la
libasn1compiler_la_LDFLAGS = -all-static
libasn1compiler_la_SOURCES = \
asn1compiler.c asn1compiler.h \
asn1c_misc.c asn1c_misc.h \
asn1c_out.c asn1c_out.h \
asn1c_lang.c asn1c_lang.h \
asn1c_save.c asn1c_save.h \
asn1c_C.c asn1c_C.h \
asn1c_internal.h
libasn1compiler_la_LIBADD = \
${top_builddir}/libasn1parser/libasn1parser.la \
${top_builddir}/libasn1fix/libasn1fix.la
check_PROGRAMS = check_compiler
TESTS = ${check_PROGRAMS}
LDADD = ${noinst_LTLIBRARIES} ${libasn1compiler_la_LIBADD}
DEPENDENCIES = ${LDADD}

424
libasn1compiler/Makefile.in Normal file
View File

@ -0,0 +1,424 @@
# 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_CPPFLAGS = \
-I${top_srcdir}/libasn1parser \
-I${top_srcdir}/libasn1fix
noinst_LTLIBRARIES = libasn1compiler.la
libasn1compiler_la_LDFLAGS = -all-static
libasn1compiler_la_SOURCES = \
asn1compiler.c asn1compiler.h \
asn1c_misc.c asn1c_misc.h \
asn1c_out.c asn1c_out.h \
asn1c_lang.c asn1c_lang.h \
asn1c_save.c asn1c_save.h \
asn1c_C.c asn1c_C.h \
asn1c_internal.h
libasn1compiler_la_LIBADD = \
${top_builddir}/libasn1parser/libasn1parser.la \
${top_builddir}/libasn1fix/libasn1fix.la
check_PROGRAMS = check_compiler
TESTS = ${check_PROGRAMS}
LDADD = ${noinst_LTLIBRARIES} ${libasn1compiler_la_LIBADD}
DEPENDENCIES = ${LDADD}
subdir = libasn1compiler
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libasn1compiler_la_DEPENDENCIES = \
${top_builddir}/libasn1parser/libasn1parser.la \
${top_builddir}/libasn1fix/libasn1fix.la
am_libasn1compiler_la_OBJECTS = asn1compiler.lo asn1c_misc.lo \
asn1c_out.lo asn1c_lang.lo asn1c_save.lo asn1c_C.lo
libasn1compiler_la_OBJECTS = $(am_libasn1compiler_la_OBJECTS)
check_PROGRAMS = check_compiler$(EXEEXT)
check_compiler_SOURCES = check_compiler.c
check_compiler_OBJECTS = check_compiler.$(OBJEXT)
check_compiler_LDADD = $(LDADD)
check_compiler_DEPENDENCIES = libasn1compiler.la \
${top_builddir}/libasn1parser/libasn1parser.la \
${top_builddir}/libasn1fix/libasn1fix.la
check_compiler_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)/asn1c_C.Plo $(DEPDIR)/asn1c_lang.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1c_misc.Plo $(DEPDIR)/asn1c_out.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1c_save.Plo $(DEPDIR)/asn1compiler.Plo \
@AMDEP_TRUE@ $(DEPDIR)/check_compiler.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@
DIST_SOURCES = $(libasn1compiler_la_SOURCES) check_compiler.c
DIST_COMMON = Makefile.am Makefile.in
SOURCES = $(libasn1compiler_la_SOURCES) check_compiler.c
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu libasn1compiler/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)
libasn1compiler.la: $(libasn1compiler_la_OBJECTS) $(libasn1compiler_la_DEPENDENCIES)
$(LINK) $(libasn1compiler_la_LDFLAGS) $(libasn1compiler_la_OBJECTS) $(libasn1compiler_la_LIBADD) $(LIBS)
clean-checkPROGRAMS:
-test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
check_compiler$(EXEEXT): $(check_compiler_OBJECTS) $(check_compiler_DEPENDENCIES)
@rm -f check_compiler$(EXEEXT)
$(LINK) $(check_compiler_LDFLAGS) $(check_compiler_OBJECTS) $(check_compiler_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1c_C.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1c_lang.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1c_misc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1c_out.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1c_save.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1compiler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/check_compiler.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@
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."
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
# 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:

2021
libasn1compiler/asn1c_C.c Normal file

File diff suppressed because it is too large Load Diff

69
libasn1compiler/asn1c_C.h Normal file
View File

@ -0,0 +1,69 @@
#ifndef ASN1_COMPILER_LANGUAGE_C_H
#define ASN1_COMPILER_LANGUAGE_C_H
#include "asn1c_lang.h"
int asn1c_lang_C_type_REFERENCE(arg_t *);
int asn1c_lang_C_type_EXTENSIBLE(arg_t *);
int asn1c_lang_C_type_SEQUENCE(arg_t *);
int asn1c_lang_C_type_SEQUENCE_OF(arg_t *);
int asn1c_lang_C_type_SET(arg_t *);
int asn1c_lang_C_type_SET_OF(arg_t *);
int asn1c_lang_C_type_CHOICE(arg_t *);
int asn1c_lang_C_type_INTEGER(arg_t *);
int asn1c_lang_C_type_ENUMERATED(arg_t *);
int asn1c_lang_C_type_SIMPLE_TYPE(arg_t *);
static asn1_language_map_t asn1_lang_C[] __attribute__ ((unused)) = {
{ AMT_TYPE, A1TC_REFERENCE, asn1c_lang_C_type_REFERENCE },
{ AMT_TYPEREF, A1TC_REFERENCE, asn1c_lang_C_type_REFERENCE },
{ AMT_TYPE, A1TC_EXTENSIBLE, asn1c_lang_C_type_EXTENSIBLE },
/*
* Constructed types
*/
{ AMT_TYPE, ASN_CONSTR_SEQUENCE, asn1c_lang_C_type_SEQUENCE },
{ AMT_TYPE, ASN_CONSTR_SEQUENCE_OF, asn1c_lang_C_type_SEQUENCE_OF },
{ AMT_TYPEREF, ASN_CONSTR_SEQUENCE_OF, asn1c_lang_C_type_SEQUENCE_OF },
{ AMT_TYPE, ASN_CONSTR_SET, asn1c_lang_C_type_SET },
{ AMT_TYPE, ASN_CONSTR_SET_OF, asn1c_lang_C_type_SET_OF },
{ AMT_TYPEREF, ASN_CONSTR_SET_OF, asn1c_lang_C_type_SET_OF },
{ AMT_TYPE, ASN_CONSTR_CHOICE, asn1c_lang_C_type_CHOICE },
/*
* Basic types
*/
{ AMT_TYPE, ASN_BASIC_BOOLEAN, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_BASIC_NULL, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_BASIC_INTEGER, asn1c_lang_C_type_INTEGER },
/* [Skipped REAL] */
{ AMT_TYPE, ASN_BASIC_ENUMERATED, asn1c_lang_C_type_ENUMERATED },
{ AMT_TYPE, ASN_BASIC_BIT_STRING, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_BASIC_OCTET_STRING, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_BASIC_OBJECT_IDENTIFIER,asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_BASIC_RELATIVE_OID, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_BASIC_CHARACTER_STRING, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_BASIC_UTCTime, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_BASIC_GeneralizedTime, asn1c_lang_C_type_SIMPLE_TYPE },
/*
* String types
*/
{ AMT_TYPE, ASN_STRING_BMPString, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_GeneralString, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_GraphicString, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_IA5String, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_ISO646String, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_NumericString, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_PrintableString,asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_TeletexString, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_T61String, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_UniversalString,asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_UTF8String, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_VideotexString,asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_VisibleString, asn1c_lang_C_type_SIMPLE_TYPE },
{ AMT_TYPE, ASN_STRING_ObjectDescriptor,asn1c_lang_C_type_SIMPLE_TYPE },
{ 0, 0, 0 }
};
#endif /* ASN1_COMPILER_LANGUAGE_C_H */

View File

@ -0,0 +1,81 @@
#ifndef _ASN1_COMPILER_INTERNAL_H_
#define _ASN1_COMPILER_INTERNAL_H_
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h> /* for fstat(2) */
#include <unistd.h> /* for unlink(2) */
#include <fcntl.h> /* for open(2) */
#include <glob.h> /* for glob(3) */
#include <libgen.h> /* for basename(3) */
#include <string.h>
#include <ctype.h> /* for isalnum(3) */
#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include "asn1compiler.h"
typedef struct arg_s {
enum asn1c_flags flags;
void (*logger_cb)(int _severity, const char *fmt, ...);
int (*default_cb)(struct arg_s *);
struct compiler_streams *target;
asn1p_t *asn;
asn1p_module_t *mod;
asn1p_expr_t *expr;
int indent_level;
int indented;
int embed;
} arg_t;
#include "asn1c_lang.h" /* Target language initialization */
#include "asn1c_misc.h" /* Miscellaneous functions */
#include "asn1c_out.h" /* Handle output during compilation */
#include "asn1c_save.h" /* Save compiled output */
#define INDENT(val) arg->indent_level += (val)
#define INDENTED(code) do { \
INDENT(+1); \
do { code; } while(0); \
INDENT(-1); \
} while(0)
#define FLAT(code) do { \
int _il = arg->indent_level; \
arg->indent_level = 0; \
do { code; } while(0); \
arg->indent_level = _il; \
} while(0)
#define EMBED(ev) do { \
REDIR(OT_TYPE_DECLS); \
arg->embed++; \
INDENTED(arg_t _tmp = *arg; \
_tmp.expr = ev; \
_tmp.default_cb(&_tmp); \
); \
arg->embed--; \
} while(0)
#define OUT(fmt, args...) asn1c_compiled_output(arg, fmt, ##args)
#define REDIR(foo) do { arg->target->target = foo; } while(0)
/*
* Logging.
*/
#define LOG(ll, fmt, args...) do { \
arg->logger_cb(ll, fmt, ##args); \
} while(0)
#define DEBUG(fmt, args...) do { \
if(arg->flags & A1C_DEBUG) \
LOG(-1, fmt, ##args); \
} while(0)
#define WARNING(fmt, args...) LOG(0, fmt, ##args);
#define FATAL(fmt, args...) LOG(1, fmt, ##args);
#endif /* _ASN1_COMPILER_INTERNAL_H_ */

View File

@ -0,0 +1,32 @@
#include "asn1c_internal.h"
#include "asn1c_C.h"
asn1_language_map_t asn1_lang_map[AMT_EXPR_META_MAX][ASN_EXPR_TYPE_MAX];
int
asn1c_with_language(asn1c_target_language_e lang) {
asn1_language_map_t *lptr;
int lsize;
if(lang != ASN1C_LANGUAGE_C) {
errno = EINVAL;
return -1;
}
lptr = asn1_lang_C;
lsize = sizeof(asn1_lang_C)/sizeof(asn1_lang_C[0]);
memset(asn1_lang_map, 0, sizeof(asn1_lang_map));
for(; lsize && lptr->expr_match; lsize--, lptr++) {
assert(lptr->meta_match > 0);
assert(lptr->meta_match < AMT_EXPR_META_MAX);
assert(lptr->expr_match > 0);
assert(lptr->expr_match < ASN_EXPR_TYPE_MAX);
asn1_lang_map[lptr->meta_match][lptr->expr_match]
= *lptr;
}
return 0;
}

View File

@ -0,0 +1,28 @@
#ifndef ASN1_COMPILER_LANGUAGE_H
#define ASN1_COMPILER_LANGUAGE_H
struct arg_s;
typedef struct asn1_language_map_s {
asn1p_expr_meta_e meta_match; /* meta_type */
asn1p_expr_type_e expr_match; /* expr_type */
/*
* A callback that would create a language-specific type declaration.
*/
int (*type_cb)(struct arg_s *arg);
} asn1_language_map_t;
extern asn1_language_map_t asn1_lang_map[AMT_EXPR_META_MAX][ASN_EXPR_TYPE_MAX];
typedef enum asn1c_target_language {
ASN1C_LANGUAGE_C,
} asn1c_target_language_e;
/*
* Initialize the compiler to generate specified target language.
*/
int asn1c_with_language(asn1c_target_language_e lang);
#endif /* ASN1_COMPILER_LANGUAGE_H */

View File

@ -0,0 +1,232 @@
#include "asn1c_internal.h"
#include <asn1fix_export.h>
#ifndef DEFFILEMODE /* Normally in <sys/stat.h> */
#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
#endif
/*
* Construct identifier from multiple parts.
* Convert unsafe characters to underscores.
*/
char *
asn1c_make_identifier(int unsafe_only_spaces, char *arg1, ...) {
static char *storage;
static int storage_size;
int nodelimiter = 0;
va_list ap;
char *str;
int size;
char *p;
if(arg1 == NULL)
return NULL;
/*
* Estimate the necessary storage size
*/
size = strlen(arg1);
va_start(ap, arg1);
while((str = va_arg(ap, char *)))
size += 1 + strlen(str);
va_end(ap);
/*
* Make sure we have this amount of storage.
*/
if(storage_size <= size) {
if(storage) free(storage);
storage = malloc(size + 1);
if(storage) {
storage_size = size;
} else {
storage_size = 0;
return NULL;
}
}
/*
* Fill-in the storage.
*/
va_start(ap, arg1);
str = arg1;
p = storage;
for(str = arg1; str; str = va_arg(ap, char *)) {
int subst_made = 0;
if(str[0] == ' ' && str[1] == '\0') {
*p++ = ' ';
nodelimiter = 1; /* No delimiter */
continue;
}
if(str != arg1 && !nodelimiter)
*p++ = '_'; /* Delimiter between tokens */
nodelimiter = 0;
for(; *str; str++) {
if(isalnum(*str)) {
*p++ = *str;
subst_made = 0;
} else if(!subst_made++) {
if(unsafe_only_spaces && !isspace(*str)) {
*p ++ = *str;
} else {
*p++ = '_';
}
}
}
}
va_end(ap);
*p = '\0';
assert((p - storage) <= storage_size);
return storage;
}
FILE *
asn1c_open_file(arg_t *arg, const char *name, const char *ext) {
int created = 1;
struct stat sb;
char *fname;
int len;
FILE *fp;
int fd;
/*
* Compute filenames.
*/
len = strlen(name) + strlen(ext) + 1;
fname = alloca(len);
snprintf(fname, len, "%s%s", name, ext);
/*
* Create files.
*/
fd = open(fname, O_CREAT | O_EXCL | O_WRONLY, DEFFILEMODE);
if(fd == -1 && errno == EEXIST) {
fd = open(fname, O_WRONLY, DEFFILEMODE);
created = 0;
}
if(fd == -1) {
perror(fname);
return NULL;
}
/*
* Check sanity.
*/
if(fstat(fd, &sb) || !S_ISREG(sb.st_mode)) {
fprintf(stderr, "%s: Not a regular file\n", fname);
if(created) unlink(fname);
close(fd);
return NULL;
}
(void)ftruncate(fd, 0);
/*
* Convert file descriptor into file pointer.
*/
fp = fdopen(fd, "w");
if(fp == NULL) {
if(created) unlink(fname);
close(fd);
}
return fp;
}
char *
asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
char *typename;
switch(expr->expr_type) {
case A1TC_REFERENCE:
typename = expr->reference->components[
expr->reference->comp_count-1].name;
if(typename[0] == '&') {
arg_t tmp = *arg;
/*
* This is a reference to a type defined in a class.
* Resolve it and use instead.
*/
tmp.expr = asn1f_class_access_ex(arg->asn, arg->mod,
arg->expr, expr->reference, &tmp.mod);
if(tmp.expr) return NULL;
return asn1c_type_name(&tmp, tmp.expr, _format);
} else if(_format == TNF_RSAFE) {
/*
* The recursion-safe format is requested.
* The problem here is that only constructed types
* might be referenced with "struct".
* Change RSAFE to CTYPE if the terminal type
* is primitive.
*/
asn1p_expr_t *terminal;
terminal = asn1f_find_terminal_type_ex(
arg->asn, arg->mod, arg->expr, NULL);
if(terminal
&& (terminal->expr_type
& (ASN_BASIC_MASK | ASN_STRING_MASK)))
_format = TNF_CTYPE;
}
break;
case ASN_CONSTR_SEQUENCE_OF:
case ASN_CONSTR_SET_OF:
if(expr->Identifier) {
typename = expr->Identifier;
} else {
asn1p_expr_t *child;
child = TQ_FIRST(&(expr->members));
typename = asn1c_type_name(arg, child, _format);
if(typename)
return typename;
_format = TNF_SAFE;
typename = child->Identifier;
}
break;
case ASN_BASIC_INTEGER:
case ASN_BASIC_ENUMERATED:
if((arg->flags & A1C_USE_NATIVE_INTEGERS)) {
switch(_format) {
case TNF_CTYPE:
case TNF_RSAFE:
return "int";
default:
if(expr->expr_type == ASN_BASIC_INTEGER)
return "NativeInteger";
else
return "NativeEnumerated";
}
}
/* Fall through */
default:
if(expr->expr_type & (ASN_BASIC_MASK | ASN_STRING_MASK)) {
if(_format == TNF_RSAFE)
_format = TNF_CTYPE;
typename = ASN_EXPR_TYPE2STR(expr->expr_type);
} else {
_format = TNF_SAFE;
typename = expr->Identifier;
}
}
switch(_format) {
case TNF_UNMODIFIED:
case TNF_INCLUDE:
return asn1c_make_identifier(1, typename, 0);
case TNF_SAFE:
return asn1c_make_identifier(0, typename, 0);
case TNF_CTYPE:
return asn1c_make_identifier(0, typename, "t", 0);
case TNF_RSAFE:
return asn1c_make_identifier(0, "struct", " ", typename, 0);
}
assert("!unreachable");
return typename;
}

View File

@ -0,0 +1,28 @@
#ifndef _ASN1_COMPILER_MISC_H_
#define _ASN1_COMPILER_MISC_H_
/*
* Make the target language identifier out of one or more names.
* The function will concatenate the names and replace unsafe characters
* with safe ones.
*/
char *asn1c_make_identifier(int unsafe_only_spaces, char *arg1, ...);
/*
* Return the type name of the specified expression.
*/
enum tnfmt {
TNF_UNMODIFIED, /* Return unmodified type name */
TNF_INCLUDE, /* Format for #include <> */
TNF_CTYPE, /* Format as normal C-ish type (append "_t") */
TNF_SAFE, /* Replace unsafe characters with _ */
TNF_RSAFE, /* Recursion-safe C type format */
};
char *asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format);
/*
* Open the arbitrary file by its base name and extension.
*/
FILE *asn1c_open_file(arg_t *arg, const char *base_part, const char *extension);
#endif /* _ASN1_COMPILER_MISC_H_ */

View File

@ -0,0 +1,75 @@
#include "asn1c_internal.h"
/*
* Add an elementary chunk of target language text
* into appropriate output stream.
*/
int
asn1c_compiled_output(arg_t *arg, const char *fmt, ...) {
const char *p;
int lf_found;
va_list ap;
out_chunk_t *m;
char *buf;
int ret;
/*
* Make sure the output has a single LF and only at the end.
*/
for(lf_found = 0, p = fmt; *p; p++) {
if(*p == '\n') {
lf_found++;
assert(p[1] == '\0');
}
}
assert(lf_found <= 1);
/*
* Print out the indentation.
*/
if(arg->indented == 0) {
int i = arg->indent_level;
arg->indented = 1;
while(i--) {
ret = asn1c_compiled_output(arg, "\t");
if(ret == -1) return -1;
}
}
/*
* Estimate necessary size.
*/
buf = "";
va_start(ap, fmt);
ret = vsnprintf(buf, 0, fmt, ap);
va_end(ap);
assert(ret >= 0);
/*
* Allocate buffer.
*/
m = calloc(1, sizeof(out_chunk_t));
if(m == NULL) return -1;
m->len = ret + 1;
m->buf = malloc(ret + 1);
if(m->buf == NULL) {
free(m);
return -1;
}
/*
* Fill the buffer.
*/
va_start(ap, fmt);
ret = vsnprintf(m->buf, m->len, fmt, ap);
assert(ret < m->len);
m->len = ret;
va_end(ap);
TQ_ADD(&(arg->target->targets[arg->target->target]), m, next);
if(lf_found)
arg->indented = 0;
return 0;
}

View File

@ -0,0 +1,31 @@
#ifndef _ASN1_COMPILED_OUTPUT_H_
#define _ASN1_COMPILED_OUTPUT_H_
/*
* An elementary chunk of target language text.
*/
typedef struct out_chunk {
char *buf;
int len;
TQ_ENTRY(struct out_chunk) next;
} out_chunk_t;
typedef struct compiler_streams {
enum {
OT_DEPS, /* Dependencies */
OT_TYPE_DECLS, /* Type declarations */
OT_FUNC_DECLS, /* Function declarations */
OT_STAT_DEFS, /* Static definitions */
OT_CODE, /* Some code */
OT_MAX
} target;
TQ_HEAD(out_chunk_t) targets[OT_MAX];
} compiler_streams_t;
static char *_compiler_stream2str[] __attribute__ ((unused))
= { "DEPS", "TYPE-DECLS", "FUNC-DECLS", "STAT-DEFS", "CODE" };
int asn1c_compiled_output(arg_t *arg, const char *fmt, ...);
#endif /* _ASN1_COMPILED_OUTPUT_H_ */

View File

@ -0,0 +1,225 @@
#include "asn1c_internal.h"
static int asn1c_dump_streams(arg_t *arg);
static int asn1c_print_streams(arg_t *arg);
static int asn1c_save_streams(arg_t *arg);
static int asn1c_copy_over(arg_t *arg, char *path);
int
asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
(void)datadir;
TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
TQ_FOR(arg->expr, &(arg->mod->members), next) {
if(asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb) {
if(asn1c_dump_streams(arg))
return -1;
}
}
}
/*
* Dump out the Makefile template and the rest of the support code.
*/
if((arg->flags & A1C_PRINT_COMPILED) == 0
&& (arg->flags & A1C_OMIT_SUPPORT_CODE) == 0) {
glob_t pg;
FILE *mkf;
char *p;
int i;
i = strlen(datadir) + sizeof("/*.[ch]");
p = alloca(i);
snprintf(p, i, "%s/*.[ch]", datadir);
memset(&pg, 0, sizeof(pg));
if(glob(p, GLOB_ERR
#ifdef GLOB_TILDE
| GLOB_TILDE
#endif /* GLOB_TILDE */
, NULL, &pg)) {
fprintf(stderr,
"Bad skeletons directory (-S) %s: %s\n",
datadir, strerror(errno));
return -1;
}
mkf = asn1c_open_file(arg, "Makefile.am", ".sample");
if(mkf == NULL) {
globfree(&pg);
perror("Makefile.am.sample");
return -1;
}
fprintf(mkf, "ASN_SRCS=");
TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
TQ_FOR(arg->expr, &(arg->mod->members), next) {
if(asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb) {
fprintf(mkf, "\t\\\n\t%s.c %s.h",
arg->expr->Identifier,
arg->expr->Identifier);
}
}
}
for(i = 0; i < pg.gl_pathc; i++) {
if(asn1c_copy_over(arg, pg.gl_pathv[i])) {
fprintf(mkf, ">>>ABORTED<<<");
fclose(mkf);
globfree(&pg);
return -1;
} else {
fprintf(mkf, "\t\\\n\t%s",
basename(pg.gl_pathv[i]));
}
}
fprintf(mkf, "\n\n");
fprintf(mkf, "lib_LTLIBRARIES=libsomething.la\n");
fprintf(mkf, "libsomething_la_SOURCES=${ASN_SRCS}\n");
fclose(mkf);
fprintf(stderr, "Generated Makefile.am.sample\n");
globfree(&pg);
}
return 0;
}
/*
* Dump the streams.
*/
static int
asn1c_dump_streams(arg_t *arg) {
if(arg->flags & A1C_PRINT_COMPILED) {
return asn1c_print_streams(arg);
} else {
return asn1c_save_streams(arg);
}
}
static int
asn1c_print_streams(arg_t *arg) {
compiler_streams_t *cs = arg->expr->data;
asn1p_expr_t *expr = arg->expr;
int i;
for(i = 0; i < OT_MAX; i++) {
out_chunk_t *ot;
if(TQ_FIRST(&cs->targets[i]) == NULL)
continue;
printf("\n/*** <<< %s [%s] >>> ***/\n\n",
_compiler_stream2str[i],
expr->Identifier);
TQ_FOR(ot, &(cs->targets[i]), next) {
fwrite(ot->buf, ot->len, 1, stdout);
}
}
return 0;
}
static int
asn1c_save_streams(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
compiler_streams_t *cs = expr->data;
out_chunk_t *ot;
FILE *fp_c, *fp_h;
char *header_id;
if(cs == NULL) {
fprintf(stderr, "Cannot compile %s at line %d\n",
expr->Identifier, expr->_lineno);
return -1;
}
fp_c = asn1c_open_file(arg, expr->Identifier, ".c");
fp_h = asn1c_open_file(arg, expr->Identifier, ".h");
if(fp_c == NULL || fp_h == NULL) {
if(fp_c) fclose(fp_c); /* lacks unlink() */
if(fp_h) fclose(fp_h); /* lacks unlink() */
return -1;
}
header_id = alloca(strlen(expr->Identifier) + 1);
if(1) {
char *src, *dst;
for(src = expr->Identifier, dst = header_id;
(*dst=*src); src++, dst++)
if(!isalnum(*src)) *dst = '_';
*dst = '\0';
}
fprintf(fp_h,
"#ifndef\t_%s_H_\n"
"#define\t_%s_H_\n"
"\n", header_id, header_id);
fprintf(fp_h, "#include <constr_TYPE.h>\n\n");
TQ_FOR(ot, &(cs->targets[OT_DEPS]), next)
fwrite(ot->buf, ot->len, 1, fp_h);
fprintf(fp_h, "\n");
TQ_FOR(ot, &(cs->targets[OT_TYPE_DECLS]), next)
fwrite(ot->buf, ot->len, 1, fp_h);
fprintf(fp_h, "\n");
TQ_FOR(ot, &(cs->targets[OT_FUNC_DECLS]), next)
fwrite(ot->buf, ot->len, 1, fp_h);
fprintf(fp_c, "#include <%s.h>\n\n", expr->Identifier);
TQ_FOR(ot, &(cs->targets[OT_STAT_DEFS]), next)
fwrite(ot->buf, ot->len, 1, fp_c);
TQ_FOR(ot, &(cs->targets[OT_CODE]), next)
fwrite(ot->buf, ot->len, 1, fp_c);
assert(OT_MAX == 5);
fprintf(fp_h, "\n#endif\t/* _%s_H_ */\n", header_id);
fclose(fp_c);
fclose(fp_h);
fprintf(stderr, "Compiled %s.c\n", expr->Identifier);
fprintf(stderr, "Compiled %s.h\n", expr->Identifier);
return 0;
}
static int
asn1c_copy_over(arg_t *arg, char *path) {
char *fname = basename(path);
if(symlink(path, fname)) {
if(errno == EEXIST) {
struct stat sb1, sb2;
if(stat(path, &sb1) == 0
&& stat(fname, &sb2) == 0
&& sb1.st_dev == sb2.st_dev
&& sb1.st_ino == sb2.st_ino) {
/*
* Nothing to do.
*/
fprintf(stderr,
"File %s is already here as %s\n",
path, fname);
return 0;
} else {
fprintf(stderr,
"Retaining local %s (%s suggested)\n",
fname, path);
return 0;
}
} else {
fprintf(stderr, "Symlink %s -> %s failed: %s\n",
path, fname, strerror(errno));
return -1;
}
}
fprintf(stderr, "Symlinked %s\t-> %s\n", path, fname);
return 0;
}

View File

@ -0,0 +1,6 @@
#ifndef _ASN1_SAVE_H_
#define _ASN1_SAVE_H_
int asn1c_save_compiled_output(arg_t *arg, const char *datadir);
#endif /* _ASN1_SAVE_H_ */

View File

@ -0,0 +1,160 @@
#include "asn1c_internal.h"
static void default_logger_cb(int, const char *fmt, ...);
static int asn1c_compile_expr(arg_t *arg);
static int asn1c_attach_streams(asn1p_expr_t *expr);
int
asn1_compile(asn1p_t *asn, const char *datadir, enum asn1c_flags flags) {
arg_t arg_s;
arg_t *arg = &arg_s;
int ret;
/*
* Initialize target language.
*/
ret = asn1c_with_language(ASN1C_LANGUAGE_C);
assert(ret == 0);
memset(arg, 0, sizeof(*arg));
arg->default_cb = asn1c_compile_expr;
arg->logger_cb = default_logger_cb;
arg->flags = flags;
arg->asn = asn;
/*
* Compile each individual top level structure.
*/
TQ_FOR(arg->mod, &(asn->modules), mod_next) {
TQ_FOR(arg->expr, &(arg->mod->members), next) {
compiler_streams_t *cs = NULL;
if(asn1c_attach_streams(arg->expr))
return -1;
cs = arg->expr->data;
cs->target = OT_TYPE_DECLS;
arg->target = cs;
ret = asn1c_compile_expr(arg);
if(ret) {
FATAL("Cannot compile %s (%x:%x) at line %d",
arg->expr->Identifier,
arg->expr->expr_type,
arg->expr->meta_type,
arg->expr->_lineno);
return ret;
}
}
}
DEBUG("Saving compiled data");
/*
* Save or print out the compiled result.
*/
if(asn1c_save_compiled_output(arg, datadir))
return -1;
return 0;
}
static int
asn1c_compile_expr(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
int (*type_cb)(arg_t *);
int ret;
assert(expr->meta_type >= AMT_INVALID);
assert(expr->meta_type < AMT_EXPR_META_MAX);
assert(expr->expr_type >= A1TC_INVALID);
assert(expr->expr_type < ASN_EXPR_TYPE_MAX);
type_cb = asn1_lang_map[expr->meta_type][expr->expr_type].type_cb;
if(type_cb) {
if(arg->indent_level == 0)
OUT("\n");
DEBUG("Compiling %s at line %d",
expr->Identifier,
expr->_lineno);
ret = type_cb(arg);
} else {
ret = -1;
/*
* Even if the target language compiler does not know
* how to compile the given expression, we know that
* certain expressions need not to be compiled at all.
*/
switch(expr->meta_type) {
case AMT_PARAMTYPE:
case AMT_OBJECT:
case AMT_OBJECTSET:
case AMT_VALUE:
case AMT_VALUESET:
ret = 0;
break;
default:
break;
}
switch(expr->expr_type) {
case A1TC_TYPEID:
ret = 0; /* TYPE-IDENTIFIER is a CLASS */
default:
break;
}
}
if(ret == -1) {
OUT("#error Cannot compile \"%s\" (%x/%x) at line %d\n",
arg->expr->Identifier,
arg->expr->meta_type,
arg->expr->expr_type,
arg->expr->_lineno
);
}
return ret;
}
static int
asn1c_attach_streams(asn1p_expr_t *expr) {
compiler_streams_t *cs;
int i;
if(expr->data)
return 0; /* Already attached? */
expr->data = calloc(1, sizeof(compiler_streams_t));
if(expr->data == NULL)
return -1;
cs = expr->data;
for(i = 0; i < OT_MAX; i++) {
TQ_INIT(&(cs->targets[i]));
}
return 0;
}
static void
default_logger_cb(int _severity, const char *fmt, ...) {
va_list ap;
char *pfx = "";
switch(_severity) {
case -1: pfx = "DEBUG: "; break;
case 0: pfx = "WARNING: "; break;
case 1: pfx = "FATAL: "; break;
}
fprintf(stderr, "%s", pfx);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
}

View File

@ -0,0 +1,41 @@
#ifndef ASN1_COMPILER_H
#define ASN1_COMPILER_H
#include <asn1parser.h>
enum asn1c_flags {
A1C_NOFLAGS,
/*
* Debug the compiler.
*/
A1C_DEBUG = 0x0001,
/*
* Do not split the target output in several files, just print it.
* (Note: the output is not likely to be compilable in this case).
*/
A1C_PRINT_COMPILED = 0x0002,
/*
* Generate only the tables for ASN.1 types,
* do not emit ASN.1 parsing support code.
*/
A1C_OMIT_SUPPORT_CODE = 0x0004,
/*
* Use native integers instead of INTEGER_t and ENUMERATED_t types.
*/
A1C_USE_NATIVE_INTEGERS = 0x0008,
/*
* Do not use C99 extensions.
*/
A1C_NO_C99 = 0x0010,
/*
* Enable use of unnamed unions (non-portable feature).
*/
A1C_UNNAMED_UNIONS = 0x0020,
};
/*
* Compile the ASN.1 specification.
*/
int asn1_compile(asn1p_t *asn, const char *datadir, enum asn1c_flags);
#endif /* ASN1_COMPILER_H */

View File

@ -0,0 +1,7 @@
#include "asn1compiler.h"
int
main(int ac, char **av) {
return 0;
}

36
libasn1fix/Makefile.am Normal file
View File

@ -0,0 +1,36 @@
AM_CFLAGS = @ADD_CFLAGS@
AM_CPPFLAGS = -I${top_srcdir}/libasn1parser
noinst_LTLIBRARIES = libasn1fix.la
libasn1fix_la_LDFLAGS = -all-static
libasn1fix_la_SOURCES = \
asn1fix.c asn1fix.h \
asn1fix_internal.h \
asn1fix_misc.c asn1fix_misc.h \
asn1fix_value.c asn1fix_value.h \
asn1fix_compat.c asn1fix_compat.h \
asn1fix_constr.c asn1fix_constr.h \
asn1fix_cstring.c asn1fix_cstring.h \
asn1fix_retrieve.c asn1fix_retrieve.h \
asn1fix_bitstring.c asn1fix_bitstring.h \
asn1fix_integer.c asn1fix_integer.h \
asn1fix_dereft.c asn1fix_dereft.h \
asn1fix_derefv.c asn1fix_derefv.h \
asn1fix_export.c asn1fix_export.h \
asn1fix_param.c asn1fix_param.h \
asn1fix_class.c asn1fix_class.h \
asn1fix_tags.c asn1fix_tags.h \
asn1fix_enum.c asn1fix_enum.h
libasn1fix_la_LIBADD = ${top_builddir}/libasn1parser/libasn1parser.la
check_PROGRAMS = check_fixer
LDADD = ${noinst_LTLIBRARIES} ${libasn1fix_la_LIBADD}
DEPENDENCIES = ${LDADD}
TESTS_ENVIRONMENT= ./check_fixer
TESTS = ${top_srcdir}/tests/*.asn1
## TESTS = ${check_PROGRAMS} # This is an alternate form of testing

454
libasn1fix/Makefile.in Normal file
View File

@ -0,0 +1,454 @@
# Makefile.in generated automatically by automake 1.5 from Makefile.am.
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
ADD_CFLAGS = @ADD_CFLAGS@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AWK = @AWK@
CC = @CC@
CONFIGURE_DEPENDS = @CONFIGURE_DEPENDS@
CPP = @CPP@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
EXEEXT = @EXEEXT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LEX = @LEX@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAINT = @MAINT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PATH = @PATH@
RANLIB = @RANLIB@
VERSION = @VERSION@
YACC = @YACC@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
AM_CFLAGS = @ADD_CFLAGS@
AM_CPPFLAGS = -I${top_srcdir}/libasn1parser
noinst_LTLIBRARIES = libasn1fix.la
libasn1fix_la_LDFLAGS = -all-static
libasn1fix_la_SOURCES = \
asn1fix.c asn1fix.h \
asn1fix_internal.h \
asn1fix_misc.c asn1fix_misc.h \
asn1fix_value.c asn1fix_value.h \
asn1fix_compat.c asn1fix_compat.h \
asn1fix_constr.c asn1fix_constr.h \
asn1fix_cstring.c asn1fix_cstring.h \
asn1fix_retrieve.c asn1fix_retrieve.h \
asn1fix_bitstring.c asn1fix_bitstring.h \
asn1fix_integer.c asn1fix_integer.h \
asn1fix_dereft.c asn1fix_dereft.h \
asn1fix_derefv.c asn1fix_derefv.h \
asn1fix_export.c asn1fix_export.h \
asn1fix_param.c asn1fix_param.h \
asn1fix_class.c asn1fix_class.h \
asn1fix_tags.c asn1fix_tags.h \
asn1fix_enum.c asn1fix_enum.h
libasn1fix_la_LIBADD = ${top_builddir}/libasn1parser/libasn1parser.la
check_PROGRAMS = check_fixer
LDADD = ${noinst_LTLIBRARIES} ${libasn1fix_la_LIBADD}
DEPENDENCIES = ${LDADD}
TESTS_ENVIRONMENT = ./check_fixer
TESTS = ${top_srcdir}/tests/*.asn1
subdir = libasn1fix
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libasn1fix_la_DEPENDENCIES = \
${top_builddir}/libasn1parser/libasn1parser.la
am_libasn1fix_la_OBJECTS = asn1fix.lo asn1fix_misc.lo asn1fix_value.lo \
asn1fix_compat.lo asn1fix_constr.lo asn1fix_cstring.lo \
asn1fix_retrieve.lo asn1fix_bitstring.lo asn1fix_integer.lo \
asn1fix_dereft.lo asn1fix_derefv.lo asn1fix_export.lo \
asn1fix_param.lo asn1fix_class.lo asn1fix_tags.lo \
asn1fix_enum.lo
libasn1fix_la_OBJECTS = $(am_libasn1fix_la_OBJECTS)
check_PROGRAMS = check_fixer$(EXEEXT)
check_fixer_SOURCES = check_fixer.c
check_fixer_OBJECTS = check_fixer.$(OBJEXT)
check_fixer_LDADD = $(LDADD)
check_fixer_DEPENDENCIES = libasn1fix.la \
${top_builddir}/libasn1parser/libasn1parser.la
check_fixer_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)/asn1fix.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_bitstring.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_class.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_compat.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_constr.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_cstring.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_dereft.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_derefv.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_enum.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_export.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_integer.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_misc.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_param.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_retrieve.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_tags.Plo \
@AMDEP_TRUE@ $(DEPDIR)/asn1fix_value.Plo \
@AMDEP_TRUE@ $(DEPDIR)/check_fixer.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@
DIST_SOURCES = $(libasn1fix_la_SOURCES) check_fixer.c
DIST_COMMON = Makefile.am Makefile.in
SOURCES = $(libasn1fix_la_SOURCES) check_fixer.c
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu libasn1fix/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)
libasn1fix.la: $(libasn1fix_la_OBJECTS) $(libasn1fix_la_DEPENDENCIES)
$(LINK) $(libasn1fix_la_LDFLAGS) $(libasn1fix_la_OBJECTS) $(libasn1fix_la_LIBADD) $(LIBS)
clean-checkPROGRAMS:
-test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
check_fixer$(EXEEXT): $(check_fixer_OBJECTS) $(check_fixer_DEPENDENCIES)
@rm -f check_fixer$(EXEEXT)
$(LINK) $(check_fixer_LDFLAGS) $(check_fixer_OBJECTS) $(check_fixer_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_bitstring.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_class.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_compat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_constr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_cstring.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_dereft.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_derefv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_enum.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_export.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_integer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_misc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_param.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_retrieve.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_tags.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/asn1fix_value.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/check_fixer.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@
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."
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
# 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:

354
libasn1fix/asn1fix.c Normal file
View File

@ -0,0 +1,354 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include "asn1fix.h"
#include "asn1fix_internal.h"
/* Print everything to stderr */
static void _default_error_logger(int _severity, const char *fmt, ...);
/*
* Internal check functions.
*/
static int asn1f_fix_module(arg_t *arg);
static int asn1f_fix_simple(arg_t *arg); /* For INTEGER/ENUMERATED */
static int asn1f_fix_constructed(arg_t *arg); /* For SEQUENCE/SET/CHOICE */
static int asn1f_fix_constraints(arg_t *arg); /* For subtype constraints */
/*
* Scan every module defined here in search for inconsistences.
*/
int
asn1f_process(asn1p_t *asn, enum asn1f_flags flags,
error_logger_f error_logger) {
arg_t arg;
int fatals = 0;
int warnings = 0;
/*
* Check validity of arguments.
*/
if(asn == NULL) {
errno = EINVAL;
return -1;
}
/*
* If errors handler is not specified, default to internal one.
*/
if(error_logger == 0) {
error_logger = _default_error_logger;
}
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.eh = error_logger;
if(flags & A1F_DEBUG) {
arg.debug = arg.eh;
arg.debug(-1, "Called %s() with flags %d", __func__, flags);
flags &= ~A1F_DEBUG;
}
/*
* Check that we haven't missed an unknown flag.
*/
if(flags) {
errno = EINVAL;
return -1;
}
/*
* Process each module in the list.
*/
TQ_FOR(arg.mod, &(asn->modules), mod_next) {
int ret = asn1f_fix_module(&arg);
/*
* These lines are used for illustration purposes.
* RET2RVAL() is used everywhere else.
*/
if(ret == -1) fatals++;
if(ret == 1) warnings++;
}
/*
* Compute a return value.
*/
return fatals?-1:warnings?1:0;
}
/*
* Check the internals of a single module.
*/
static int
asn1f_fix_module(arg_t *arg) {
asn1p_expr_t *expr;
int rvalue = 0;
switch((arg->mod->module_flags
& (MSF_EXPLICIT_TAGS | MSF_IMPLICIT_TAGS | MSF_AUTOMATIC_TAGS))) {
case MSF_NOFLAGS:
case MSF_EXPLICIT_TAGS:
case MSF_IMPLICIT_TAGS:
case MSF_AUTOMATIC_TAGS:
break;
default:
FATAL("Module %s defined with ambiguous global tagging mode",
arg->mod->Identifier);
RET2RVAL(-1, rvalue);
}
/*
* Do various non-recursive transformations.
* Order is not important.
*/
TQ_FOR(expr, &(arg->mod->members), next) {
int ret;
arg->expr = expr;
if(expr->meta_type == AMT_PARAMTYPE)
/* Do not process the parametrized type just yet */
continue;
DEBUG("=== Now processing \"%s\" at line %d ===",
expr->Identifier, expr->_lineno);
assert(expr->meta_type != AMT_INVALID);
/*
* 2.1 Pre-process simple types (ENUMERATED, INTEGER, etc).
*/
ret = asn1f_recurse_expr(arg, asn1f_fix_simple);
RET2RVAL(ret, rvalue);
/*
* 2.[234] Process SEQUENCE/SET/CHOICE types.
*/
ret = asn1f_recurse_expr(arg, asn1f_fix_constructed);
RET2RVAL(ret, rvalue);
/*
* 2.5.4
*/
ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_types);
RET2RVAL(ret, rvalue);
/*
* 2.5.5
*/
ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_values);
RET2RVAL(ret, rvalue);
/*
* Resolve references in constraints.
*/
ret = asn1f_recurse_expr(arg, asn1f_fix_constraints);
RET2RVAL(ret, rvalue);
/*
* 6. INTEGER value processed at 2.5.4.
*/
/*
* Make sure everybody's behaving well.
*/
assert(arg->expr == expr);
}
/*
* 5. Automatic tagging
*/
TQ_FOR(expr, &(arg->mod->members), next) {
int ret;
arg->expr = expr;
ret = asn1f_recurse_expr(arg, asn1f_fix_constr_autotag);
RET2RVAL(ret, rvalue);
assert(arg->expr == expr);
}
/*
* 8. fix BIT STRING
* 9. fix spaces in cstrings
*/
TQ_FOR(expr, &(arg->mod->members), next) {
int ret;
arg->expr = expr;
ret = asn1f_recurse_expr(arg, asn1f_fix_bit_string);
RET2RVAL(ret, rvalue);
ret = asn1f_recurse_expr(arg, asn1f_fix_cstring);
RET2RVAL(ret, rvalue);
assert(arg->expr == expr);
}
/*
* ... Check for tags distinctness.
*/
TQ_FOR(expr, &(arg->mod->members), next) {
int ret;
arg->expr = expr;
ret = asn1f_recurse_expr(arg, asn1f_check_constr_tags_distinct);
RET2RVAL(ret, rvalue);
assert(arg->expr == expr);
}
return rvalue;
}
static int
asn1f_fix_simple(arg_t *arg) {
int rvalue = 0;
int ret;
ret = asn1f_fix_enum(arg);
RET2RVAL(ret, rvalue);
ret = asn1f_fix_integer(arg);
RET2RVAL(ret, rvalue);
return rvalue;
}
static int
asn1f_fix_constructed(arg_t *arg) {
int rvalue = 0;
int ret;
switch(arg->expr->expr_type) {
case ASN_CONSTR_SEQUENCE:
case ASN_CONSTR_SET:
case ASN_CONSTR_CHOICE:
break;
default:
return 0;
}
/* Check identifier distinctness */
ret = asn1f_check_unique_expr(arg, NULL);
RET2RVAL(ret, rvalue);
/* Fix extensibility */
ret = asn1f_fix_constr_ext(arg);
RET2RVAL(ret, rvalue);
/* Fix tagging */
ret = asn1f_fix_constr_tag(arg);
RET2RVAL(ret, rvalue);
return rvalue;
}
static int
_constraint_value_resolve(arg_t *arg, asn1p_value_t **value) {
asn1p_expr_t expr;
asn1p_expr_t *tmp_expr;
asn1p_module_t *tmp_mod;
asn1p_module_t *mod_r = NULL;
int rvalue = 0;
int ret;
tmp_expr = asn1f_lookup_symbol(arg, (*value)->value.reference, &mod_r);
if(tmp_expr == NULL) {
FATAL("Cannot find symbol %s "
"used in %s subtype constraint at line %d",
asn1f_printable_reference((*value)->value.reference),
arg->expr->Identifier, arg->expr->_lineno);
assert((*value)->type == ATV_REFERENCED);
return -1;
}
memset(&expr, 0, sizeof(expr));
expr.meta_type = tmp_expr->meta_type;
expr.expr_type = tmp_expr->expr_type;
expr.Identifier = tmp_expr->Identifier;
expr.value = *value;
tmp_expr = arg->expr;
tmp_mod = arg->mod;
arg->expr = &expr;
arg->mod = mod_r;
ret = asn1f_fix_dereference_values(arg);
RET2RVAL(ret, rvalue);
arg->expr = tmp_expr;
arg->mod = tmp_mod;
assert(expr.value);
*value = expr.value;
return rvalue;
}
static int
_resolve_constraints(arg_t *arg, asn1p_constraint_t *ct) {
int rvalue = 0;
int ret;
int el;
/* Don't touch information object classes */
if(ct->type == ACT_CT_WCOMP
|| ct->type == ACT_CT_WCOMPS
|| ct->type == ACT_CA_CRC)
return 0;
if(ct->value && ct->value->type == ATV_REFERENCED) {
ret = _constraint_value_resolve(arg, &ct->value);
RET2RVAL(ret, rvalue);
}
if(ct->range_start && ct->range_start->type == ATV_REFERENCED) {
ret = _constraint_value_resolve(arg, &ct->range_start);
RET2RVAL(ret, rvalue);
}
if(ct->range_stop && ct->range_stop->type == ATV_REFERENCED) {
ret = _constraint_value_resolve(arg, &ct->range_stop);
RET2RVAL(ret, rvalue);
}
for(el = 0; el < ct->el_count; el++) {
ret = _resolve_constraints(arg, ct->elements[el]);
RET2RVAL(ret, rvalue);
}
return rvalue;
}
static int
asn1f_fix_constraints(arg_t *arg) {
int rvalue = 0;
int ret;
if(arg->expr->constraints) {
ret = _resolve_constraints(arg, arg->expr->constraints);
RET2RVAL(ret, rvalue);
}
return rvalue;
}
/*
* Print everything to stderr
*/
static void
_default_error_logger(int _severity, const char *fmt, ...) {
va_list ap;
char *pfx = "";
switch(_severity) {
case -1: pfx = "DEBUG: "; break;
case 0: pfx = "WARNING: "; break;
case 1: pfx = "FATAL: "; break;
}
fprintf(stderr, "%s", pfx);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
}

30
libasn1fix/asn1fix.h Normal file
View File

@ -0,0 +1,30 @@
/*
* This is the public interface for the processor (fixer) of the ASN.1 tree
* produced by the libasn1parser.
*/
#ifndef ASN1FIX_H
#define ASN1FIX_H
#include <asn1parser.h>
/*
* Operation flags for the function below.
*/
enum asn1f_flags {
A1F_NOFLAGS,
A1F_DEBUG, /* Print debugging output using (_is_fatal = -1) */
};
/*
* Perform a set of semantics checks, transformations and small fixes
* on the given tree.
* RETURN VALUES:
* -1: Some fatal problems were encountered.
* 0: No inconsistencies were found.
* 1: Some warnings were issued, but no fatal problems encountered.
*/
int asn1f_process(asn1p_t *_asn,
enum asn1f_flags,
void (*error_log_callback)(int _severity, const char *fmt, ...));
#endif /* ASN1FIX_H */

View File

@ -0,0 +1,230 @@
#include "asn1fix_internal.h"
int asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype);
static void asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value);
static int asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype);
int
asn1f_fix_bit_string(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
int r_value = 0;
int ret;
if(expr->meta_type == AMT_VALUE) {
asn1p_expr_t *ttype;
DEBUG("%s(%s) for line %d", __func__,
expr->Identifier, expr->_lineno);
ttype = asn1f_find_terminal_type(arg, expr, 0);
if(ttype && ttype->expr_type == ASN_BASIC_BIT_STRING) {
ret = asn1f_fix_bit_string_value(arg, ttype);
RET2RVAL(ret, r_value);
}
}
return r_value;
}
int
asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype) {
asn1p_expr_t *expr = arg->expr;
int r_value = 0;
DEBUG("%s(%s) for line %d", __func__,
expr->Identifier, expr->_lineno);
switch(expr->value->type) {
case ATV_UNPARSED:
/*
* Most definitely we have something like
* value BitStringType1 ::= { a, b, c }
* which could not be parsed by the LALR parser, mostly
* because it requires knowledge about BitStringType1
* during the parsing. So, here's a little hack: we create
* a buffer containing the full specification of a module,
* which contains some pre-defined INTEGER type with the
* opaque definition "{ a, b, c }" from the bit string.
*/
if(asn1f_BS_unparsed_convert(arg, expr->value, ttype)) {
r_value = -1;
break;
}
/* Fall through: remove trailing zero bits */
case ATV_BITVECTOR:
asn1f_BS_remove_trailing_zero_bits(expr->value);
break;
default:
break;
}
return r_value;
}
static void
asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value) {
int lmfb = -1; /* Last meaningful byte position */
int bits; /* Number of bits in the BIT STRING value */
int b;
assert(value->type == ATV_BITVECTOR);
bits = value->value.binary_vector.size_in_bits;
/*
* Figure out the rightmost meaningful byte.
*/
for(b = 0; b < ((bits + 7) >> 3); b++) {
uint8_t uc = value->value.binary_vector.bits[b];
if(uc && b > lmfb)
lmfb = b;
}
if(lmfb == -1) {
bits = 0;
} else {
uint8_t uc;
uc = value->value.binary_vector.bits[lmfb];
bits = (lmfb+1) * 8;
/*
* Squeeze the bit string width until the rightmost
* bit is set.
*/
for(; uc && (uc & 1) == 0; uc >>= 1)
bits--;
if(uc == 0) {
bits = lmfb * 8;
}
}
value->value.binary_vector.size_in_bits = bits;
}
static int
asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype) {
asn1p_t *asn;
asn1p_module_t *mod;
asn1p_expr_t *V;
asn1p_expr_t *bit;
asn1_integer_t aI;
uint8_t *bitbuf;
int bits;
int psize;
char *p;
int ret;
int r_value = 0;
assert(value->type == ATV_UNPARSED);
psize = value->value.string.size + 64;
p = malloc(psize);
if(p == NULL)
return -1;
ret = snprintf(p, psize,
"M DEFINITIONS ::=\nBEGIN\n"
"V ::= INTEGER %s\n"
"END\n",
value->value.string.buf
);
assert(ret < psize);
psize = ret;
asn = asn1p_parse_buffer(p, psize, A1P_NOFLAGS);
free(p);
if(asn == NULL) {
FATAL("Cannot parse BIT STRING value %s "
"defined as %s at line %d",
arg->expr->Identifier,
value->value.string.buf,
arg->expr->_lineno
);
return -1;
}
mod = TQ_FIRST(&(asn->modules));
assert(mod);
V = TQ_FIRST(&(mod->members));
assert(V);
assert(strcmp(V->Identifier, "V") == 0);
assert(TQ_FIRST(&(V->members)));
/*
* Simple loop just to fetch the maximal bit position
* out of the BIT STRING value defined as NamedBitList.
*/
aI = -1;
TQ_FOR(bit, &(V->members), next) {
asn1p_expr_t *bitdef;
bitdef = asn1f_lookup_child(ttype, bit->Identifier);
if(bitdef && bitdef->value
&& bitdef->value->type == ATV_INTEGER) {
if(bitdef->value->value.v_integer > aI)
aI = bitdef->value->value.v_integer;
}
}
if(aI > 1024 * 1024 * 8) { /* One megabyte */
FATAL("Unsupportedly large BIT STRING value \"%s\" "
"defined at line %d "
"(larger than 1MByte)",
arg->expr->Identifier,
arg->expr->_lineno
);
asn1p_free(asn);
return -1;
}
bits = aI + 1; /* Number of bits is more than a last bit position */
bitbuf = calloc(1, 1 + ((bits + 7) / 8));
if(bitbuf == NULL) {
asn1p_free(asn);
return -1;
}
TQ_FOR(bit, &(V->members), next) {
asn1p_expr_t *bitdef;
int set_bit_pos;
if(bit->value) {
WARNING("Identifier \"%s\" at line %d "
"must not have a value",
bit->Identifier, bit->_lineno);
RET2RVAL(1, r_value);
}
bitdef = asn1f_lookup_child(ttype, bit->Identifier);
if(bitdef == NULL) {
FATAL("Identifier \"%s\" at line %d is not defined "
"in the \"%s\" type definition at line %d",
bit->Identifier,
bit->_lineno,
ttype->Identifier,
ttype->_lineno
);
RET2RVAL(-1, r_value);
continue;
}
if(bitdef->value == NULL
|| bitdef->value->type != ATV_INTEGER) {
FATAL("Broken identifier "
"\"%s\" at line %d "
"referenced by \"%s\" at line %d",
bitdef->Identifier,
bitdef->_lineno,
arg->expr->Identifier,
arg->expr->_lineno
);
RET2RVAL(-1, r_value);
continue;
}
assert(bitdef->value->value.v_integer < bits);
set_bit_pos = bitdef->value->value.v_integer;
bitbuf[set_bit_pos>>3] |= 1 << (7-(set_bit_pos % 8));
}
asn1p_free(asn);
free(value->value.string.buf);
value->type = ATV_BITVECTOR;
value->value.binary_vector.bits = bitbuf;
value->value.binary_vector.size_in_bits = bits;
return r_value;
}

View File

@ -0,0 +1,6 @@
#ifndef _ASN1FIX_BIT_STRING_H_
#define _ASN1FIX_BIT_STRING_H_
int asn1f_fix_bit_string(arg_t *);
#endif /* _ASN1FIX_BIT_STRING_H_ */

237
libasn1fix/asn1fix_class.c Normal file
View File

@ -0,0 +1,237 @@
#include "asn1fix_internal.h"
typedef enum field_category {
OFC_INVALID, /* Invalid object field category */
OFC_TYPE,
OFC_FIXED_TYPE_VALUE,
OFC_VARIABLE_TYPE_VALUE,
OFC_FIXED_TYPE_VALUE_SET,
OFC_VARIABLE_TYPE_VALUE_SET,
OFC_INFORMATION_OBJECT,
OFC_INFORMATION_OBJECT_SET,
} field_category_e;
typedef enum object_category {
OC_INVALID,
OC_OBJECT,
OC_OBJECTSET,
} object_category_e;
static field_category_e asn1f_class_field_category(asn1p_expr_t *ofield);
static object_category_e asn1f_class_object_category(asn1p_expr_t *expr);
static asn1p_expr_t *
asn1f_class_dot_lookup(arg_t *arg, asn1p_expr_t *obj, asn1p_ref_t *ref);
asn1p_expr_t *
asn1f_class_access(arg_t *arg, asn1p_ref_t *ref, asn1p_module_t **mod_r) {
asn1p_expr_t *obj; /* Information Object or Object Set */
object_category_e obj_cat; /* Object category */
//field_category_e field_cat; /* Field category */
asn1p_expr_t *result;
asn1p_ref_t tmpref;
assert(ref->comp_count > 1);
DEBUG("%s(%s) for line %d", __func__,
asn1f_printable_reference(ref),
ref->_lineno);
/*
* Fetch the first part of the reference (OBJECT or ObjectSet).
* OBJECT.&<something>...
* ObjectSet.&<something>...
*/
assert(isupper(ref->components[0].name[0]));
tmpref = *ref;
tmpref.comp_count = 1;
obj = asn1f_lookup_symbol(arg, &tmpref, 0);
if(obj == NULL) {
errno = ESRCH;
return NULL;
}
/*
* Make sure the symbol lexical property (upper-case, lower-case)
* corresponds to the type of the expression returned by
* lookup_symbol().
*/
obj_cat = asn1f_class_object_category(obj);
switch(obj_cat) {
case OC_OBJECT:
case OC_OBJECTSET:
if(ref->components[0].lex_type
== (obj_cat==OC_OBJECT)
? RLT_CAPITALS
: RLT_Uppercase)
break;
/* Fall through */
case OC_INVALID:
WARNING("Symbol \"%s\" is not compatible "
"with referenced expression \"%s\" at line %d",
ref->components[0].name,
obj->Identifier, obj->_lineno);
errno = EPERM;
return NULL;
}
/*
* Find the specified field within the object.
*/
result = asn1f_class_dot_lookup(arg, obj, ref);
if(result == NULL) {
return NULL;
}
//field_cat = asn1f_class_field_category(result);
DEBUG("FILLME: %s", result->Identifier);
return result;
}
static object_category_e
asn1f_class_object_category(asn1p_expr_t *expr) {
switch(expr->meta_type) {
case AMT_OBJECT:
return OC_OBJECT;
case AMT_OBJECTSET:
return OC_OBJECTSET;
case AMT_VALUESET:
if(expr->expr_type == A1TC_REFERENCE
&& expr->reference
&& expr->reference->comp_count == 1
&& expr->reference->components[0].lex_type == RLT_CAPITALS)
{
/* FIXME: use find_terminal_type instead! */
return OC_OBJECTSET;
}
break;
default:
break;
}
return OC_INVALID;
}
static field_category_e
asn1f_class_field_category(asn1p_expr_t *ofield) {
if(ofield->Identifier[0] != '&') {
assert(ofield->Identifier[0] == '&');
return OFC_INVALID;
}
if(isupper(ofield->Identifier[1])) {
if(ofield->reference) {
enum asn1p_ref_lex_type_e lex_type
= ofield->reference->components[0].lex_type;
switch(lex_type) {
case RLT_CAPITALS:
return OFC_INFORMATION_OBJECT_SET;
case RLT_Uppercase:
return OFC_FIXED_TYPE_VALUE_SET;
case RLT_AmpUppercase:
return OFC_VARIABLE_TYPE_VALUE_SET;
default:
break;
}
} else {
if(ofield->expr_type == A1TC_CLASSFIELD)
return OFC_TYPE;
switch(ofield->meta_type) {
case AMT_TYPE:
case AMT_TYPEREF:
return OFC_FIXED_TYPE_VALUE_SET;
default:
break;
}
}
} else {
if(ofield->reference) {
enum asn1p_ref_lex_type_e lex_type
= ofield->reference->components[0].lex_type;
switch(lex_type) {
case RLT_CAPITALS:
return OFC_INFORMATION_OBJECT;
case RLT_Uppercase:
return OFC_FIXED_TYPE_VALUE;
case RLT_AmpUppercase:
return OFC_VARIABLE_TYPE_VALUE;
default:
break;
}
} else {
switch(ofield->meta_type) {
case AMT_TYPE:
case AMT_TYPEREF:
return OFC_FIXED_TYPE_VALUE;
default:
break;
}
}
}
return OFC_INVALID;
}
static asn1p_expr_t *
asn1f_class_dot_lookup(arg_t *arg, asn1p_expr_t *obj, asn1p_ref_t *ref) {
asn1p_expr_t *ofield = NULL; /* Information Object's Field */
field_category_e field_cat; /* Field category */
int comp;
assert(ref->comp_count >= 2);
for(comp = 1 /* sic! */; comp < ref->comp_count; comp++) {
int is_last_component = (comp + 1 == ref->comp_count);
char *comp_name = ref->components[comp].name;
ofield = asn1f_lookup_child(obj, comp_name);
if(ofield == NULL) {
DEBUG("Cannot find field \"%s\" in \"%s\" at line %d",
ref->components[1].name,
obj->Identifier,
obj->_lineno);
}
/*
* Compute the category of the field of
* the information object class.
*/
field_cat = asn1f_class_field_category(ofield);
switch(field_cat) {
case OFC_INVALID:
WARNING("Invalid field category of \"%s\" at line %d",
ofield->Identifier, ofield->_lineno);
errno = EPERM;
return NULL;
case OFC_TYPE:
case OFC_FIXED_TYPE_VALUE:
case OFC_VARIABLE_TYPE_VALUE:
case OFC_FIXED_TYPE_VALUE_SET:
case OFC_VARIABLE_TYPE_VALUE_SET:
if(!is_last_component) {
FATAL("Field name component \"%s\" at line %d "
"specifies non-dereferenceable thing",
comp_name, ref->_lineno);
errno = EPERM;
return NULL;
}
break;
case OFC_INFORMATION_OBJECT:
case OFC_INFORMATION_OBJECT_SET:
obj = ofield;
break;
}
}
assert(ofield);
return ofield;
}

View File

@ -0,0 +1,16 @@
#ifndef _ASN1FIX_CLASS_H_
#define _ASN1FIX_CLASS_H_
/*
* Fetch the element from the class-related stuff (thing) by its reference.
*/
asn1p_expr_t *
asn1f_class_access(arg_t *, asn1p_ref_t *, asn1p_module_t **mod_r);
/*
* Externally accessible version of above function.
*/
asn1p_expr_t *asn1f_class_access2(asn1p_t *asn, asn1p_module_t *mod,
asn1p_expr_t *expr, asn1p_ref_t *, asn1p_module_t **mod_r);
#endif /* _ASN1FIX_CLASS_H_ */

132
libasn1fix/asn1fix_compat.c Normal file
View File

@ -0,0 +1,132 @@
#include "asn1fix_internal.h"
static int asn1f_check_same_children(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);
/*
* Check that the expressions given are compatible in their type.
* ORDER DOES MATTER! (See .h).
*/
int
asn1f_check_type_compatibility(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
asn1p_expr_type_e atype, btype;
atype = a->expr_type;
btype = b->expr_type;
DEBUG("%s(%s:%x@%d, %s:%x@%d)", __func__,
a->Identifier, atype, a->_lineno,
b->Identifier, btype, b->_lineno);
/*
* Expected terminal type!
*/
assert(atype != A1TC_REFERENCE);
assert(btype != A1TC_REFERENCE);
if(atype != btype) {
/*
* Limited compatibility.
*/
if((atype == A1TC_UNIVERVAL && btype == ASN_BASIC_INTEGER)
|| (atype == A1TC_UNIVERVAL && btype == ASN_BASIC_ENUMERATED)
)
return 0;
DEBUG("\t%s and %s are not compatible",
a->Identifier, b->Identifier);
return -1; /* Fairly obviously */
}
if(a == b)
return 0; /* Fairly obviously */
switch(atype) {
case ASN_BASIC_INTEGER:
/* All integers are compatible */
return 0;
case ASN_BASIC_ENUMERATED:
/*
* Enumerations are not compatible
* unless their definitions are the same.
*/
if(asn1f_check_same_children(arg, a, b)) {
DEBUG("\tEnumerations are different %s and %s",
a->Identifier, b->Identifier);
return -1;
}
return 0;
default:
/* Compatibility is not defined yet */
DEBUG("\tCompatibility rule is not defined for %s and %s",
a->Identifier, b->Identifier);
return -1;
}
return 0;
}
/*
* Check that the children are exactly same.
*/
static int
asn1f_check_same_children(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
asn1p_expr_t *achild;
asn1p_expr_t *bchild;
achild = TQ_FIRST(&(a->members));
bchild = TQ_FIRST(&(b->members));
while(1) {
if(achild->expr_type != bchild->expr_type)
return -1;
if(achild->Identifier && bchild->Identifier) {
if(strcmp(achild->Identifier, bchild->Identifier))
return -1;
} else if(!(!achild->Identifier && !bchild->Identifier)) {
return -1;
}
if(achild->value && bchild->value) {
if(achild->value->type != bchild->value->type)
return -1;
switch(achild->value->type) {
case ATV_INTEGER:
if(achild->value->value.v_integer
!= bchild->value->value.v_integer)
return -1;
break;
case ATV_REFERENCED:
default:
DEBUG("Value %s at lines %d and "
"%d cannot be used in "
"semantical equality check",
asn1f_printable_value(achild->value),
achild->value->value.reference->_lineno,
bchild->value->value.reference->_lineno
);
return -1;
}
} else if(!(!achild->value && !bchild->value)) {
/* One of values is defined, and another is not */
return -1;
}
achild = TQ_NEXT(achild, next);
bchild = TQ_NEXT(bchild, next);
if(achild && bchild)
continue;
else if(!achild && !bchild)
break;
else
return -1;
}
DEBUG("\t%s:%x@%d and %s:%x@%d are semantically equivalent",
a->Identifier, a->expr_type, a->_lineno,
b->Identifier, b->expr_type, b->_lineno);
return 0;
}

View File

@ -0,0 +1,14 @@
#ifndef _ASN1FIX_COMPAT_H_
#define _ASN1FIX_COMPAT_H_
/*
* Check that the expressions given are compatible in their type.
* ORDER DOES MATTER!
* The compatibility is being checked as if the value of b were used
* to assign it to type a.
*/
int asn1f_check_type_compatibility(arg_t *arg,
asn1p_expr_t *a,
asn1p_expr_t *b);
#endif /* _ASN1FIX_COMPAT_H_ */

364
libasn1fix/asn1fix_constr.c Normal file
View File

@ -0,0 +1,364 @@
#include "asn1fix_internal.h"
static int _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v);
static int _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);
int
asn1f_fix_constr_ext(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
TQ_HEAD(asn1p_expr_t) root_list;
TQ_HEAD(asn1p_expr_t) ext_list;
TQ_HEAD(asn1p_expr_t) *cur_list;
int r_value = 0;
int ext_count = 0;
switch(expr->expr_type) {
case ASN_CONSTR_SEQUENCE:
case ASN_CONSTR_SET:
case ASN_CONSTR_CHOICE:
break;
default:
return 0;
}
DEBUG("%s(%s) for line %d", __func__,
expr->Identifier, expr->_lineno);
TQ_INIT(&root_list);
TQ_INIT(&ext_list);
cur_list = (void *)&root_list;
while((v = TQ_REMOVE(&(expr->members), next))) {
if(v->expr_type == A1TC_EXTENSIBLE) {
ext_count++;
switch(ext_count) {
case 1: cur_list = (void *)&ext_list; break;
case 2:
cur_list = (void *)&root_list;
if(v->value) {
FATAL("Optional extension marker "
"must not contain "
"an exception mark "
"at line %d", v->_lineno);
r_value = -1;
}
asn1p_expr_free(v);
continue;
case 3:
FATAL("Third extension marker "
"is not allowed at line %d", v->_lineno);
default:
r_value = -1;
}
}
TQ_ADD(cur_list, v, next);
}
/*
* Copy the root list and extension list back into the main list.
*/
TQ_HEAD_COPY(&(expr->members), &root_list);
while((v = TQ_REMOVE(&ext_list, next)))
TQ_ADD(&(expr->members), v, next);
if(arg->mod->module_flags & MSF_EXTENSIBILITY_IMPLIED
&& ext_count < 1) {
v = asn1p_expr_new(0);
if(v) {
v->Identifier = strdup("...");
v->expr_type = A1TC_EXTENSIBLE;
v->meta_type = AMT_TYPE;
if(v->Identifier == NULL) {
asn1p_expr_free(v);
r_value = -1;
} else {
TQ_ADD(&(expr->members), v, next);
}
} else {
r_value = -1;
}
}
return r_value;
}
int
asn1f_fix_constr_tag(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
int fl_impl_tags = 0;
int fl_auto_tags = 0;
int root_tagged = 0; /* The root component is manually tagged */
int ext_tagged = 0; /* The extensions are manually tagged */
int component_number = 0;
int r_value = 0;
switch(expr->expr_type) {
case ASN_CONSTR_SEQUENCE:
case ASN_CONSTR_SET:
case ASN_CONSTR_CHOICE:
break;
default:
return 0;
}
fl_impl_tags = (arg->mod->module_flags & MSF_IMPLICIT_TAGS);
fl_auto_tags = (arg->mod->module_flags & MSF_AUTOMATIC_TAGS);
DEBUG("%s(%s) {%d, %d} for line %d", __func__,
expr->Identifier, fl_impl_tags, fl_auto_tags, expr->_lineno);
TQ_FOR(v, &(expr->members), next) {
int must_explicit = 0;
if(v->expr_type == A1TC_EXTENSIBLE) {
component_number++;
continue;
}
if(v->tag.tag_class == TC_NOCLASS) {
continue;
} else {
switch(component_number) {
case 0: case 2:
root_tagged = 1; break;
default:
ext_tagged = 1; break;
}
}
must_explicit = _asn1f_check_if_tag_must_be_explicit(arg, v);
if(fl_impl_tags) {
if(v->tag.tag_mode != TM_EXPLICIT) {
if(must_explicit)
v->tag.tag_mode = TM_EXPLICIT;
else
v->tag.tag_mode = TM_IMPLICIT;
}
} else {
if(v->tag.tag_mode == TM_DEFAULT) {
v->tag.tag_mode = TM_EXPLICIT;
}
}
/*
* Perform a final sanity check.
*/
if(must_explicit) {
if(v->tag.tag_mode == TM_IMPLICIT) {
FATAL("%s tagged in IMPLICIT mode "
"but must be EXPLICIT at line %d",
v->Identifier, v->_lineno);
r_value = -1;
} else {
v->tag.tag_mode = TM_EXPLICIT;
}
}
}
if(ext_tagged && !root_tagged) {
FATAL("In %s at line %d: "
"extensions are tagged "
"but root components are not",
expr->Identifier, expr->_lineno);
r_value = -1;
} else if(!root_tagged && !ext_tagged && fl_auto_tags) {
expr->auto_tags_OK = 1;
}
return r_value;
}
int
asn1f_fix_constr_autotag(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
asn1_integer_t tag_value = 0;
int r_value = 0;
switch(expr->expr_type) {
case ASN_CONSTR_SEQUENCE:
case ASN_CONSTR_SET:
case ASN_CONSTR_CHOICE:
if(expr->auto_tags_OK)
break;
/* Automatic tagging is not applicable */
/* Fall through */
default:
return 0;
}
DEBUG("%s(%s) for line %d", __func__,
expr->Identifier, expr->_lineno);
TQ_FOR(v, &(expr->members), next) {
int must_explicit;
if(v->expr_type == A1TC_EXTENSIBLE)
break;
assert(v->tag.tag_class == TC_NOCLASS);
must_explicit = _asn1f_check_if_tag_must_be_explicit(arg, v);
v->tag.tag_class = TC_CONTEXT_SPECIFIC;
v->tag.tag_mode = must_explicit ? TM_EXPLICIT : TM_IMPLICIT;
v->tag.tag_value = tag_value++;
}
return r_value;
}
/*
* Check that tags are distinct.
*/
int
asn1f_check_constr_tags_distinct(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
int r_value = 0;
switch(expr->expr_type) {
case ASN_CONSTR_SEQUENCE:
case ASN_CONSTR_SET:
case ASN_CONSTR_CHOICE:
break;
default:
return 0;
}
TQ_FOR(v, &(expr->members), next) {
/*
* In every series of non-mandatory components,
* the tags must be distinct from each other AND the
* tag of the following mandatory component.
* For SET and CHOICE treat everything as a big set of
* non-mandatory components.
*/
if(expr->expr_type != ASN_CONSTR_SEQUENCE || v->marker) {
asn1p_expr_t *nv;
for(nv = v; (nv = TQ_NEXT(nv, next));) {
if(_asn1f_compare_tags(arg, v, nv))
r_value = -1;
if(expr->expr_type == ASN_CONSTR_SEQUENCE
&& !nv->marker) break;
}
}
}
return r_value;
}
static int
_asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v) {
asn1p_expr_t *reft;
reft = asn1f_find_terminal_type(arg, v, 0);
if(reft) {
switch(reft->expr_type) {
case ASN_CONSTR_CHOICE:
return 1;
default:
return 0;
}
}
return 0;
}
/*
* Check that the tags are distinct.
*/
static int
_asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
struct asn1p_type_tag_s ta, tb;
int ra, rb;
int ret;
ra = asn1f_fetch_tag(arg->asn, arg->mod, a, &ta);
rb = asn1f_fetch_tag(arg->asn, arg->mod, b, &tb);
/*
* If both tags are explicitly or implicitly given, use them.
*/
if(ra == 0 && rb == 0) {
/*
* Simple case: fetched both tags.
*/
if(ta.tag_value == tb.tag_value
&& ta.tag_class == tb.tag_class) {
char *p = (a->expr_type == A1TC_EXTENSIBLE)
?"potentially ":"";
FATAL("Component \"%s\" at line %d %shas the same tag "
"with component \"%s\" at line %d",
a->Identifier,
a->_lineno,
p,
b->Identifier,
b->_lineno
);
return -1;
} else {
/* Tags are distinct */
return 0;
}
}
/**********************************************************
* Now we must perform some very funny recursion to check
* multiple components of CHOICE type, etc.
*/
DEBUG("Comparing tags %s:%x <-> %s:%x",
a->Identifier, a->expr_type,
b->Identifier, b->expr_type);
if(a->meta_type == AMT_TYPEREF) {
asn1p_module_t *mod;
DEBUG(" %s is a type reference", a->Identifier);
a = asn1f_lookup_symbol(arg, a->reference, &mod);
if(!a) return 0; /* Already FATAL()'ed somewhere else */
WITH_MODULE(mod, ret = _asn1f_compare_tags(arg, a, b));
return ret;
}
if(a->expr_type == ASN_CONSTR_CHOICE) {
asn1p_expr_t *v;
DEBUG(" %s is a choice type (%d)", a->Identifier, a->_mark);
/*
* Iterate over members of CHOICE.
*/
//if(a->_mark & TM_RECURSION) return 0;
TQ_FOR(v, &(a->members), next) {
//a->_mark |= TM_RECURSION;
ret = _asn1f_compare_tags(arg, v, b);
//a->_mark &= ~TM_RECURSION;
if(ret) return ret;
}
return 0;
}
if(b->expr_type == ASN_CONSTR_CHOICE) {
return _asn1f_compare_tags(arg, b, a);
}
if(a->_mark & TM_RECURSION) return 0;
if(b->_mark & TM_RECURSION) return 0;
a->_mark |= TM_RECURSION;
b->_mark |= TM_RECURSION;
ret = _asn1f_compare_tags(arg, b, a);
a->_mark &= ~TM_RECURSION;
b->_mark &= ~TM_RECURSION;
return ret;
}

View File

@ -0,0 +1,24 @@
#ifndef _ASN1FIX_CONSTRUCTED_H_
#define _ASN1FIX_CONSTRUCTED_H_
/*
* Fix extensions in constructed types.
*/
int asn1f_fix_constr_ext(arg_t *);
/*
* Fix tagging in constructed types.
*/
int asn1f_fix_constr_tag(arg_t *);
/*
* Check distinctive tagging in constructed types.
*/
int asn1f_check_constr_tags_distinct(arg_t *);
/*
* Perform automatic tagging.
*/
int asn1f_fix_constr_autotag(arg_t *);
#endif /* _ASN1FIX_CONSTRUCTED_H_ */

View File

@ -0,0 +1,73 @@
#include "asn1fix_internal.h"
struct _cstring_pattern {
char *start;
int length;
};
static int _asn1f_cstring_find_line_pattern(char *s, struct _cstring_pattern *);
int
asn1f_fix_cstring(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
int r_value = 0;
if(expr->value && expr->value->type == ATV_STRING) {
struct _cstring_pattern cp;
char *buf = expr->value->value.string.buf;
int buflen = expr->value->value.string.size;
int start = 0;
DEBUG("%s(%s) for line %d", __func__,
expr->Identifier, expr->_lineno);
while(_asn1f_cstring_find_line_pattern(buf + start, &cp)) {
assert(cp.length);
memmove(cp.start, cp.start + cp.length,
buflen - ((cp.start + cp.length) - buf));
buflen -= cp.length;
start = cp.start - buf;
buf[buflen] = '\0';
}
}
return r_value;
}
/*
* If a string has a newline, the tabulation and spaces before and
* after it must be eliminated.
*/
static int
_asn1f_cstring_find_line_pattern(char *s, struct _cstring_pattern *cp) {
int newline_found = 0;
cp->start = NULL;
for(;;s++) {
switch(*s) {
case '\r': case '\n':
newline_found = 1;
/* Fall through */
case ' ': case '\t':
if(cp->start == NULL)
cp->start = s;
continue;
case '\0':
default:
if(newline_found) {
cp->length = s - cp->start;
return 1;
}
cp->start = NULL;
if(*s == '\0')
break;
continue;
}
break;
}
return 0;
}

View File

@ -0,0 +1,6 @@
#ifndef _ASN1FIX_CSTRING_H_
#define _ASN1FIX_CSTRING_H_
int asn1f_fix_cstring(arg_t *);
#endif /* _ASN1FIX_CSTRING_H_ */

View File

@ -0,0 +1,68 @@
#include "asn1fix_internal.h"
int
asn1f_fix_dereference_types(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *type_expr;
int r_value = 0;
if(expr->expr_type == A1TC_PARAMETRIZED)
return asn1f_fix_parametrized_assignment(arg);
if(expr->expr_type != A1TC_REFERENCE
|| expr->meta_type != AMT_TYPEREF) {
//assert(expr->reference == 0);
return 0; /* Just ignore it */
}
DEBUG("%s(\"%s\":%x ::= \"%s\") for line %d",
__func__, expr->Identifier, expr->expr_type,
asn1f_printable_value(expr->value),
expr->_lineno);
assert(TQ_FIRST(&(expr->members)) == 0);
assert(expr->reference);
/*
* Follow the reference.
*/
type_expr = asn1f_find_terminal_type(arg, expr, 0);
if(type_expr == NULL) {
FATAL("Unknown type \"%s\" referenced by \"%s\" at line %d",
asn1f_printable_reference(expr->reference),
expr->Identifier, expr->_lineno);
return -1;
}
/*
* Copying members of the source expression
* into the current expression.
*/
if(0) {
asn1p_expr_t *tmp_clone;
tmp_clone = asn1p_expr_clone(type_expr);
if(tmp_clone == NULL) {
FATAL("Could not clone \"%s\" at line %d",
type_expr->Identifier, type_expr->_lineno);
return -1;
}
/*
* Replace the referenced type with its definition.
*/
DEBUG("\tChanging type of \"%s\":%x to %x for line %d",
expr->Identifier,
expr->expr_type,
type_expr->expr_type,
expr->_lineno
);
expr->expr_type = type_expr->expr_type;
expr->members = tmp_clone->members;
memset(&tmp_clone->members, 0, sizeof(tmp_clone->members));
asn1p_expr_free(tmp_clone);
}
return r_value;
}

View File

@ -0,0 +1,6 @@
#ifndef _ASN1FIX_DEREFT_H_
#define _ASN1FIX_DEREFT_H_
int asn1f_fix_dereference_types(arg_t *);
#endif /* _ASN1FIX_DEREFT_H_ */

View File

@ -0,0 +1,56 @@
#include "asn1fix_internal.h"
/*
* Dereference DefinedValues:
*/
int
asn1f_fix_dereference_values(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
int r_value = 0;
if(expr->meta_type != AMT_VALUE)
return 0; /* Just ignore it */
if(expr->value == NULL)
return 0; /* Just ignore it */
if(expr->value && expr->value->type != ATV_REFERENCED)
return 0; /* Not a reference */
DEBUG("%s(%s %x ::= %s) for line %d", __func__,
expr->Identifier, expr->expr_type,
asn1f_printable_value(expr->value), expr->_lineno);
/*
* If this integer has a value, check that this value
* is an integer. If it is a reference, resolve it.
*/
if(expr->value) {
if(asn1f_value_resolve(arg, expr)) {
/* This function will emit messages */
r_value = -1;
}
if(expr->value->type != ATV_INTEGER) {
FATAL(
"INTEGER value %s at line %d: "
"Incompatible value specified: %s",
expr->Identifier,
expr->_lineno,
asn1f_printable_value(expr->value)
);
r_value = -1;
}
} else {
FATAL("Value of \"%s\" at line %d: "
"Incompatible value specified",
expr->Identifier,
expr->_lineno
);
r_value = -1;
}
return r_value;
}

View File

@ -0,0 +1,6 @@
#ifndef _ASN1FIX_DEREFV_H_
#define _ASN1FIX_DEREFV_H_
int asn1f_fix_dereference_values(arg_t *);
#endif /* _ASN1FIX_DEREFV_H_ */

136
libasn1fix/asn1fix_enum.c Normal file
View File

@ -0,0 +1,136 @@
#include "asn1fix_internal.h"
/*
* Check the validity of an enumeration.
*/
int
asn1f_fix_enum(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *ev;
asn1_integer_t max_value = -1;
int rvalue = 0;
asn1p_expr_t *ext_marker = NULL; /* "..." position */
int ret;
if(expr->expr_type != ASN_BASIC_ENUMERATED)
return 0; /* Just ignore it */
DEBUG("%s(%s)", __func__, expr->Identifier);
/*
* 1. Scan the enumeration values in search for inconsistencies.
*/
TQ_FOR(ev, &(expr->members), next) {
asn1_integer_t eval;
if(ev->value)
DEBUG("\tItem %s(%s)", ev->Identifier,
asn1f_printable_value(ev->value));
else
DEBUG("\tItem %s", ev->Identifier);
/*
* 1.1 Found an extension mark "...", check correctness.
*/
if(ev->expr_type == A1TC_EXTENSIBLE) {
if(ext_marker) {
arg->eh(1,
"Enumeration %s at line %d: "
"Second extension marker is not allowed",
expr->Identifier,
ev->_lineno);
rvalue = -1;
} else {
/*
* Remember the marker's position.
*/
ext_marker = ev;
}
continue;
} else if(ev->Identifier == NULL
|| ev->expr_type != A1TC_UNIVERVAL) {
FATAL(
"Enumeration %s at line %d: "
"Unsupported enumeration element %s",
expr->Identifier,
ev->_lineno,
ev->Identifier?ev->Identifier:"<anonymous>");
rvalue = -1;
continue;
}
/*
* 1.2 Compute the value of the enumeration element.
*/
if(ev->value) {
switch(ev->value->type) {
case ATV_INTEGER:
eval = ev->value->value.v_integer;
break;
case ATV_REFERENCED:
FATAL("HERE HERE HERE", 1);
rvalue = -1;
continue;
break;
default:
FATAL("ENUMERATED type %s at line %d "
"contain element %s(%s) at line %d",
expr->Identifier, expr->_lineno,
ev->Identifier,
asn1f_printable_value(ev->value),
ev->_lineno);
rvalue = -1;
continue;
}
} else {
eval = max_value + 1;
ev->value = asn1p_value_fromint(eval);
if(ev->value == NULL) {
rvalue = -1;
continue;
}
}
/*
* 1.3 Check the applicability of this value.
*/
if(eval <= max_value) {
if(ext_marker) {
/*
* Enumeration is allowed to be unordered
* before the first marker.
*/
FATAL(
"Enumeration %s at line %d: "
"Explicit value \"%s(%lld)\" "
"is not greater "
"than previous values (max %lld)",
expr->Identifier,
ev->_lineno,
ev->Identifier,
eval,
max_value);
rvalue = -1;
}
} else if(eval > max_value) {
max_value = eval;
}
/*
* 1.4 Check that all identifiers before the current one
* differs from it.
*/
ret = asn1f_check_unique_expr_child(arg, ev, NULL);
RET2RVAL(ret, rvalue);
}
/*
* 2. Reorder the first half (before optional "...") of the
* identifiers alphabetically.
*/
// TODO
return rvalue;
}

View File

@ -0,0 +1,6 @@
#ifndef _ASN1FIX_ENUM_H_
#define _ASN1FIX_ENUM_H_
int asn1f_fix_enum(arg_t *); /* Enumeration ::= ENUMERATED { a(1), b(2) } */
#endif /* _ASN1FIX_ENUM_H_ */

View File

@ -0,0 +1,48 @@
#include "asn1fix_internal.h"
#include "asn1fix_export.h"
asn1p_expr_t *
asn1f_lookup_symbol_ex(
asn1p_t *asn,
asn1p_module_t **module_rw,
asn1p_expr_t *expr,
asn1p_ref_t *ref) {
arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.mod = *module_rw;
arg.expr = expr;
return asn1f_lookup_symbol(&arg, ref, module_rw);
}
asn1p_expr_t *
asn1f_class_access_ex(asn1p_t *asn,
asn1p_module_t *mod,
asn1p_expr_t *expr,
asn1p_ref_t *ref,
asn1p_module_t **mod_r) {
static arg_t arg;
arg.asn = asn;
arg.mod = mod;
arg.expr = expr;
return asn1f_class_access(&arg, ref, mod_r);
}
asn1p_expr_t *
asn1f_find_terminal_type_ex(asn1p_t *asn,
asn1p_module_t *mod,
asn1p_expr_t *expr,
asn1p_module_t **mod_r) {
static arg_t arg;
arg.asn = asn;
arg.mod = mod;
arg.expr = expr;
return asn1f_find_terminal_type(&arg, expr, mod_r);
}

View File

@ -0,0 +1,32 @@
/*
* This header exports fixer procedures that are common enough to be used
* in other modules.
*/
#ifndef _ASN1FIX_EXPORT_H_
#define _ASN1FIX_EXPORT_H_
#include <asn1fix_tags.h>
/*
* Exportable version of an asn1f_lookup_symbol().
*/
asn1p_expr_t *asn1f_lookup_symbol_ex(
asn1p_t *asn,
asn1p_module_t **module_rw,
asn1p_expr_t *expr,
asn1p_ref_t *ref);
/*
* Exportable version of an asn1f_class_access().
*/
asn1p_expr_t *asn1f_class_access_ex(asn1p_t *asn, asn1p_module_t *mod,
asn1p_expr_t *expr, asn1p_ref_t *, asn1p_module_t **mod_r);
/*
* Exportable version of asn1f_find_terminal_type().
*/
asn1p_expr_t *asn1f_find_terminal_type_ex(asn1p_t *asn, asn1p_module_t *mod,
asn1p_expr_t *tc, asn1p_module_t **opt_module_r);
#endif /* _ASN1FIX_EXPORT_H_ */

View File

@ -0,0 +1,161 @@
#include "asn1fix_internal.h"
static int _compare_value(asn1p_expr_t *expr1, asn1p_expr_t *expr2) {
if(expr2->value->type == ATV_INTEGER
&& expr1->value->type == ATV_INTEGER) {
return expr2->value->value.v_integer
- expr1->value->value.v_integer;
} else {
return -1;
}
}
/*
* Check the validity of an INTEGER type.
*/
int
asn1f_fix_integer(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *iv;
int rvalue = 0;
int ret;
if(expr->expr_type != ASN_BASIC_INTEGER)
return 0; /* Just ignore it */
DEBUG("%s(\"%s\", %x) for line %d", __func__,
expr->Identifier, expr->expr_type, expr->_lineno);
/*
* Scan the integer values in search for inconsistencies.
*/
TQ_FOR(iv, &(expr->members), next) {
DEBUG("\tItem %s(%s)", iv->Identifier,
asn1f_printable_value(iv->value));
/*
* Found "...", check correctness.
*/
if(iv->expr_type == A1TC_EXTENSIBLE) {
arg->eh(1,
"INTEGER %s at line %d: "
"Extension marker is not allowed",
expr->Identifier,
iv->_lineno
);
rvalue = -1;
continue;
}
if(iv->Identifier == NULL
|| iv->expr_type != A1TC_UNIVERVAL) {
arg->eh(1,
"INTEGER %s at line %d: "
"Unsupported enumeration element %s",
expr->Identifier,
iv->_lineno,
iv->Identifier?iv->Identifier:"<Anonymous>"
);
rvalue = -1;
continue;
}
if(iv->value == NULL) {
arg->eh(1,
"INTEGER %s at line %d: "
"Value for the identifier %s "
"must be set explicitly",
expr->Identifier,
iv->_lineno,
iv->Identifier
);
rvalue = -1;
continue;
} else if(iv->value->type == ATV_REFERENCED) {
/*
* Resolve the value, once and for all.
*/
if(asn1f_value_resolve(arg, iv)) {
/* This function will emit messages */
rvalue = -1;
continue;
}
}
if(iv->value->type != ATV_INTEGER) {
arg->eh(1,
"INTEGER %s at line %d: "
"Value for the identifier %s "
"is not compatible with INTEGER type",
expr->Identifier,
iv->_lineno);
rvalue = -1;
continue;
}
/*
* Check that all identifiers are distinct.
*/
ret = asn1f_check_unique_expr_child(arg, iv, NULL);
RET2RVAL(ret, rvalue);
/*
* Check that all values are distinct.
*/
ret = asn1f_check_unique_expr_child(arg, iv, _compare_value);
RET2RVAL(ret, rvalue);
}
return rvalue;
}
static int
_asn1f_make_sure_type_is(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_type_e type) {
asn1p_module_t *mod = NULL;
asn1p_expr_t *next_expr;
int expr_type;
int ret;
expr_type = expr->expr_type;
/*
* Here we're trying to make sure that the type of the given
* expression is really what is expected.
* This is ensured in two ways.
* First, if the immediate type matches the provided one,
* this is a clear hit.
*/
if(expr_type == type)
return 0;
/*
* Otherwise, it must be either a reference or a different type.
*/
if(expr_type != A1TC_REFERENCE) {
errno = EPERM;
return -1;
}
assert(expr_type == A1TC_REFERENCE);
assert(expr->reference);
/*
* Then, it is a reference. For a reference, try to resolve type
* and try again.
*/
next_expr = asn1f_lookup_symbol(arg, expr->reference, &mod);
if(next_expr == NULL) {
errno = ESRCH;
return -1;
}
/*
* If symbol is here, recursively check that it conforms to the type.
*/
WITH_MODULE(mod, ret = _asn1f_make_sure_type_is(arg, next_expr, type));
return ret;
}

View File

@ -0,0 +1,6 @@
#ifndef _ASN1FIX_INTEGER_H_
#define _ASN1FIX_INTEGER_H_
int asn1f_fix_integer(arg_t *); /* Type1 ::= INTEGER { a(1), b(2) } */
#endif /* _ASN1FIX_INTEGER_H_ */

View File

@ -0,0 +1,106 @@
#ifndef _ASN1FIX_INTERNAL_H_
#define _ASN1FIX_INTERNAL_H_
/*
* System headers required in various modules.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> /* isupper() */
#include <errno.h>
#include <assert.h>
#include <asn1parser.h> /* Our lovely ASN.1 parser module */
/*
* A definition of a function that will log error messages.
*/
typedef void (*error_logger_f)(int _is_fatal, const char *fmt, ...);
/*
* Universal argument.
*/
typedef struct arg_s {
asn1p_t *asn;
asn1p_module_t *mod;
asn1p_expr_t *expr;
error_logger_f eh;
error_logger_f debug;
void *key; /* The next level key */
} arg_t;
/*
* Functions performing normalization of various types.
*/
#include "asn1fix_misc.h" /* Support functions */
#include "asn1fix_value.h" /* Value processing */
#include "asn1fix_cstring.h" /* Fix cstring values */
#include "asn1fix_compat.h" /* Data compatibility */
#include "asn1fix_constr.h" /* Constructed types */
#include "asn1fix_class.h" /* CLASS support */
#include "asn1fix_param.h" /* Parametrization */
#include "asn1fix_retrieve.h" /* Data retrieval */
#include "asn1fix_enum.h" /* Process ENUMERATED */
#include "asn1fix_integer.h" /* Process INTEGER */
#include "asn1fix_bitstring.h" /* Process BIT STRING */
#include "asn1fix_dereft.h" /* Dereference types */
#include "asn1fix_derefv.h" /* Dereference values */
#include "asn1fix_tags.h" /* Tags-related stuff */
/*
* Merge the return value of the called function with the already
* partially computed return value of the current function.
*/
#define RET2RVAL(ret,rv) do { \
int __ret = ret; \
switch(__ret) { \
case 0: break; \
case 1: if(rv) break; \
case -1: rv = __ret; break; \
default: \
assert(__ret >= -1 && __ret <= 1); \
rv = -1; \
} \
} while(0)
/*
* Temporary substitute module for the purposes of evaluating expression.
*/
#define WITH_MODULE(tmp_mod, expr) do { \
void *_saved_mod = arg->mod; \
arg->mod = tmp_mod; \
do { expr; } while(0); \
arg->mod = _saved_mod; \
} while(0)
#define LOG(code, fmt, args...) do { \
int _save_errno = errno; \
if(code < 0) { \
if(arg->debug) \
arg->debug(code, fmt, ##args); \
} else { \
arg->eh(code, fmt " in %s", ##args, \
arg->mod->source_file_name); \
} \
errno = _save_errno; \
} while(0)
#define DEBUG(fmt, args...) LOG(-1, fmt, ##args)
#define FATAL(fmt, args...) LOG( 1, fmt, ##args)
#define WARNING(fmt, args...) LOG( 0, fmt, ##args)
/*
* Define the symbol corresponding to the name of the current function.
*/
#if __STDC_VERSION__ < 199901
#if !(__GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3)
#define __func__ (char *)0 /* Name of the current function */
#endif /* GNUC */
/* __func__ is supposed to be defined */
#endif
#endif /* _ASN1FIX_INTERNAL_H_ */

276
libasn1fix/asn1fix_misc.c Normal file
View File

@ -0,0 +1,276 @@
#include "asn1fix_internal.h"
char const *
asn1f_printable_reference(asn1p_ref_t *ref) {
if(ref) {
asn1p_value_t v;
v.type = ATV_REFERENCED;
v.value.reference = ref;
return asn1f_printable_value(&v);
} else {
return "<no ref>";
}
}
char const *
asn1f_printable_value(asn1p_value_t *v) {
static char buf[128];
static char *managedptr;
static int managedptr_len;
int ret;
#define ENSURE(len) do { \
if(len >= managedptr_len) { \
if(managedptr) \
free(managedptr); \
managedptr = malloc(len + 1); \
if(managedptr) { \
managedptr_len = len; \
} else { \
managedptr_len = 0; \
return "<memory allocation error>"; \
} \
} \
} while(0)
if(v == NULL)
return "<no value>";
switch(v->type) {
case ATV_NOVALUE:
return "<NO VALUE>";
case ATV_REFERENCED:
{
asn1p_ref_t *ref;
char reflen;
char *ptr;
int i;
assert(v->value.reference);
ref = v->value.reference;
reflen = ref->comp_count; /* Number of dots */
for(i = 0; i < ref->comp_count; i++)
reflen += strlen(ref->components[i].name);
/*
* Make sure we have a buffer of this size.
*/
ENSURE(reflen);
/*
* Fill-up the buffer.
*/
ptr = managedptr;
for(i = 0; i < ref->comp_count; i++) {
char *nc;
if(i) *ptr++ = '.';
for(nc = ref->components[i].name; *nc; nc++)
*ptr++ = *nc;
}
*ptr++ = '\0';
assert(reflen == (ptr - managedptr));
return managedptr;
}
case ATV_REAL:
ret = snprintf(buf, sizeof(buf), "%f", v->value.v_double);
if(ret >= sizeof(buf))
memcpy(buf + sizeof(buf) - 4, "...", 4);
return buf;
case ATV_INTEGER:
ret = snprintf(buf, sizeof(buf), "%lld",
(long long)v->value.v_integer);
if(ret >= sizeof(buf))
memcpy(buf + sizeof(buf) - 4, "...", 4);
return buf;
case ATV_MIN: return "MIN";
case ATV_MAX: return "MAX";
case ATV_FALSE: return "FALSE";
case ATV_TRUE: return "TRUE";
case ATV_STRING:
case ATV_UNPARSED:
/* Buffer is guaranteed to be null-terminated */
assert(v->value.string.buf[v->value.string.size] == '\0');
return v->value.string.buf;
case ATV_BITVECTOR:
{
uint8_t *bitvector;
char *ptr;
int len;
int i;
/*
* Compute number of bytes necessary
* to represend the binary value.
*/
int bits = v->value.binary_vector.size_in_bits;
len = ((bits%8)?bits:(bits >> 2)) + sizeof("''H");
/*
* Reallocate managed buffer
*/
ENSURE(len);
/*
* Fill the buffer.
*/
ptr = managedptr;
bitvector = v->value.binary_vector.bits;
*ptr++ = '\'';
if(bits%8) {
/*
* Dump bit by bit.
*/
for(i = 0; i < bits; i++) {
uint8_t uc;
uc = bitvector[i>>3];
*ptr++ = ((uc >> (7-(i%8)))&1)?'1':'0';
}
} else {
char hextable[16] = "0123456789ABCDEF";
/*
* Dump byte by byte.
*/
for(i = 0; i < (bits >> 3); i++) {
*ptr++ = hextable[bitvector[i] >> 4];
*ptr++ = hextable[bitvector[i] & 0x0f];
}
}
*ptr++ = '\'';
*ptr++ = (bits%8)?'B':'H';
*ptr++ = 'H';
assert((ptr - managedptr) == len);
return managedptr;
}
}
return "<some complex value>";
}
/*
* Recursively invoke a given function over the given expr and all its
* children.
*/
int
asn1f_recurse_expr(arg_t *arg, int (*callback)(arg_t *arg)) {
asn1p_expr_t *expr = arg->expr;
int rvalue = 0;
int ret;
assert(expr);
/*
* Invoke the callback at this very level.
*/
ret = callback(arg);
RET2RVAL(ret, rvalue);
/*
* Recursively invoke myself
* to iterate over each element in the tree.
*/
TQ_FOR(arg->expr, &(expr->members), next) {
assert(arg->expr->expr_type != A1TC_INVALID);
ret = asn1f_recurse_expr(arg, callback);
RET2RVAL(ret, rvalue);
}
arg->expr = expr; /* Restore original position */
return rvalue;
}
/*
* Check that every child of a given expr has unique name or does not have any.
*/
int
asn1f_check_unique_expr(arg_t *arg,
int (*opt_compare)(asn1p_expr_t *a, asn1p_expr_t *b)) {
asn1p_expr_t *expr;
int rvalue = 0;
TQ_FOR(expr, &(arg->expr->members), next) {
if(expr->Identifier) {
int ret = asn1f_check_unique_expr_child(arg, expr,
opt_compare);
if(ret) rvalue = -1;
} else {
/*
* No point of comparing this child with any other:
* this one does not have a name.
*/
}
}
return rvalue;
}
/*
* Check that every preceeding child of the given expr is not
* having the name of the given one.
*/
int
asn1f_check_unique_expr_child(arg_t *arg, asn1p_expr_t *child,
int (*opt_compare)(asn1p_expr_t *a, asn1p_expr_t *b)) {
asn1p_expr_t *expr;
int rvalue = 0;
assert(child);
assert(opt_compare || child->Identifier);
TQ_FOR(expr, &(arg->expr->members), next) {
int ret;
if(expr == child)
break;
/*
* Compare according to the custom rule or default
* names comparisons.
*/
if(opt_compare) {
ret = opt_compare(expr, child);
} else {
if(expr->Identifier == NULL
|| expr->expr_type == A1TC_EXTENSIBLE)
continue;
ret = strcasecmp(expr->Identifier, child->Identifier);
}
if(ret == 0) {
char *msg;
msg = opt_compare
?"Expressions clash"
:"Identifiers name clash";
arg->eh(1,
"%s: "
"\"%s\" at line %d has similar %s with "
"\"%s\" at line %d",
msg,
expr->Identifier,
expr->_lineno,
opt_compare?"property":"name",
child->Identifier,
child->_lineno
);
rvalue = -1;
}
}
return rvalue;
}
int
asn1f_count_children(asn1p_expr_t *expr) {
asn1p_expr_t *child;
int count = 0;
TQ_FOR(child, &(expr->members), next) {
count++;
}
return count;
}

47
libasn1fix/asn1fix_misc.h Normal file
View File

@ -0,0 +1,47 @@
/*
* Miscellaneous functions necessary for several other modules.
*/
#ifndef _ASN1FIX_MISC_H_
#define _ASN1FIX_MISC_H_
/*
* Return a pointer to the locally held string with human-readable
* definition of the value.
*/
char const *asn1f_printable_value(asn1p_value_t *);
/*
* Return a pointer to the locally held string with human-readable
* definition of the reference.
*/
char const *asn1f_printable_reference(asn1p_ref_t *);
/*
* Recursively invoke a given function over the given expr and all its
* children.
*/
int asn1f_recurse_expr(arg_t *arg, int (*f)(arg_t *arg));
/*
* Check that every child of a given expr has unique name or does not have any.
* If opt_compare == NULL, the default comparison of the argument's
* names (identifiers) will be performed.
*/
int asn1f_check_unique_expr(arg_t *arg,
int (*opt_compare)(asn1p_expr_t *a, asn1p_expr_t *b));
/*
* Check that every preceeding child of the given expr is not
* having the name of the given one.
* If opt_compare == NULL, the default comparison of the argument's
* names (identifiers) will be performed.
*/
int asn1f_check_unique_expr_child(arg_t *arg, asn1p_expr_t *child,
int (*opt_compare)(asn1p_expr_t *a, asn1p_expr_t *b));
/*
* Return number of children.
*/
int asn1f_count_children(asn1p_expr_t *parent);
#endif /* _ASN1FIX_MISC_H_ */

165
libasn1fix/asn1fix_param.c Normal file
View File

@ -0,0 +1,165 @@
#include "asn1fix_internal.h"
static int asn1f_parametrize(arg_t *arg, asn1p_expr_t *ex, asn1p_expr_t *ptype);
static int asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
static asn1p_expr_t *_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
int
asn1f_fix_parametrized_assignment(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *ptype;
assert(expr->expr_type == A1TC_PARAMETRIZED);
assert(expr->reference);
DEBUG("%s(\"%s\" ::= \"%s\" { %s }) for line %d",
__func__, expr->Identifier,
asn1f_printable_reference(expr->reference),
asn1f_printable_value(expr->value),
expr->_lineno);
/*
* Find the corresponding parametrized type definition.
*/
DEBUG("Looking for parametrized type definition \"%s\"",
asn1f_printable_reference(expr->reference));
ptype = asn1f_lookup_symbol(arg, expr->reference, 0);
if(ptype == NULL) {
DEBUG("%s: missing parametrized type declaration",
asn1f_printable_reference(expr->reference));
return -1;
}
/*
* Check that the number of arguments which are expected by
* the parametrized type declaration is consistent with the
* number of arguments supplied by the parametrized assignment.
*/
if(asn1f_count_children(expr) != ptype->params->params_count) {
FATAL("Number of actual arguments %d in %s at line %d "
"is not equal to number of expected arguments "
"%d in %s at line %d",
asn1f_count_children(expr),
asn1f_printable_reference(expr->reference),
expr->_lineno,
ptype->params->params_count,
ptype->Identifier,
ptype->_lineno
);
return -1;
}
/*
* Perform an expansion of a parametrized assignment.
*/
return asn1f_parametrize(arg, expr, ptype);
}
#define SUBSTITUTE(to, from) do { \
asn1p_expr_t tmp; \
tmp = *(to); \
*(to) = *(from); \
*(from) = tmp; \
(to)->next = tmp.next; \
memset(&((from)->next), 0, \
sizeof((from)->next)); \
asn1p_expr_free(from); \
} while(0)
static int
asn1f_parametrize(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype) {
asn1p_expr_t *nex;
void *p;
int ret;
/*
* The algorithm goes like that:
* 1. Replace the expression's type with parametrized type.
* 2. For every child in the parametrized type, import it
* as a child of the expression, replacing all occurences of
* symbols which are defined as parametrized type arguments
* with the actual values.
*/
nex = asn1p_expr_clone(ptype);
if(nex == NULL) return -1;
/*
* Cleanup the new expression so there is no ptype-related
* stuff hanging around.
*/
p = strdup(expr->Identifier);
if(p) {
free(nex->Identifier);
nex->Identifier = p;
} else {
asn1p_expr_free(nex);
return -1;
}
asn1p_paramlist_free(nex->params);
nex->params = NULL;
nex->meta_type = expr->meta_type;
ret = asn1f_param_process_recursive(arg, nex, ptype, expr);
if(ret != 0) {
asn1p_expr_free(nex);
return ret;
}
SUBSTITUTE(expr, nex);
return ret;
}
static int
asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
asn1p_expr_t *child;
TQ_FOR(child, &(expr->members), next) {
asn1p_expr_t *ra;
asn1p_expr_t *ne;
ra = _referenced_argument(child->reference, ptype, actargs);
if(ra == NULL) continue;
DEBUG("Substituting parameter for %s %s at line %d",
child->Identifier,
asn1f_printable_reference(child->reference),
child->_lineno
);
assert(child->meta_type == AMT_TYPEREF);
assert(child->expr_type == A1TC_REFERENCE);
ne = asn1p_expr_clone(ra);
if(ne == NULL) return -1;
assert(ne->Identifier == 0);
ne->Identifier = strdup(child->Identifier);
if(ne->Identifier == 0) {
asn1p_expr_free(ne);
return -1;
}
SUBSTITUTE(child, ne);
}
return 0;
}
static asn1p_expr_t *
_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
asn1p_expr_t *aa;
int i;
if(ref == NULL || ref->comp_count != 1)
return NULL;
aa = TQ_FIRST(&(actargs->members));
for(i = 0; i < ptype->params->params_count;
i++, aa = TQ_NEXT(aa, next)) {
if(strcmp(ref->components[0].name,
ptype->params->params[i].argument) == 0)
return aa;
}
return NULL;
}

View File

@ -0,0 +1,6 @@
#ifndef _ASN1FIX_PARAMETRIZATION_H_
#define _ASN1FIX_PARAMETRIZATION_H_
int asn1f_fix_parametrized_assignment(arg_t *arg);
#endif /* _ASN1FIX_PARAMETRIZATION_H_ */

View File

@ -0,0 +1,366 @@
#include "asn1fix_internal.h"
static asn1p_expr_t *asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, asn1p_module_t **optm, int type_or_value);
static int asn1f_compatible_with_exports(arg_t *arg, asn1p_module_t *mod, const char *name);
/*
* Lookup a child by its name.
*/
asn1p_expr_t *
asn1f_lookup_child(asn1p_expr_t *tc, const char *name) {
asn1p_expr_t *child_tc;
TQ_FOR(child_tc, &(tc->members), next) {
if(child_tc->Identifier
&& strcmp(child_tc->Identifier, name) == 0) {
return child_tc;
}
}
errno = ESRCH;
return NULL;
}
asn1p_module_t *
asn1f_lookup_in_imports(arg_t *arg, const char *name) {
asn1p_module_t *mod;
asn1p_xports_t *xp;
asn1p_expr_t *tc;
/*
* Search in which exactly module this name is defined.
*/
TQ_FOR(xp, &(arg->mod->imports), xp_next) {
TQ_FOR(tc, &(xp->members), next) {
if(strcmp(name, tc->Identifier) == 0)
break;
}
if(tc) break;
}
if(xp == NULL) {
errno = ESRCH;
return NULL;
}
/*
* Okay, right now we have a module name and, hopefully, an OID.
* Search the arg->asn for the specified module.
*/
mod = asn1f_lookup_module(arg, xp->from, xp->from_oid);
if(mod == NULL) {
/* ENOENT/ETOOMANYREFS */
return NULL;
}
/*
* Check that the EXPORTS section of this module contains
* the symbol we care about, or it is EXPORTS ALL.
*/
if(asn1f_compatible_with_exports(arg, mod, name)) {
errno = EPERM;
return NULL;
}
return mod;
}
asn1p_module_t *
asn1f_lookup_module(arg_t *arg, const char *module_name, asn1p_oid_t *oid) {
asn1p_module_t *mod;
assert(module_name);
/*
* If OID is given, the module_name is unused.
* If OID is not given, the module_name may mean
* either the real module's name, or the symbol which is the
* result of renaming. Check this first.
*/
if(oid == 0) {
asn1p_xports_t *xp;
/*
* Check inside the IMPORTS section for possible renaming.
* Renaming practically means that a module_name is mentioned
* somewhere in the IMPORTS section AND OID is given.
*/
TQ_FOR(xp, &(arg->mod->imports), xp_next) {
if(strcmp(module_name, xp->from))
continue;
if(oid) {
FATAL("Ambiguous reference: "
"%s "
"matches several modules",
module_name);
errno = ETOOMANYREFS;
return NULL;
}
/*
* Yes, there is a renaming.
* Make lookup use OID instead.
*/
oid = xp->from_oid;
}
}
/*
* Perform lookup using OID or module_name.
*/
TQ_FOR(mod, &(arg->asn->modules), mod_next) {
if(oid) {
if(mod->module_oid) {
if(asn1p_oid_compare(oid,
mod->module_oid)) {
continue;
} else {
/* Match! Even if name doesn't. */
return mod;
}
} else {
/* Not match, even if name is the same. */
continue;
}
}
if(strcmp(module_name, mod->Identifier) == 0)
return mod;
}
DEBUG("\tModule \"%s\" not found", module_name);
errno = ENOENT;
return NULL;
}
asn1p_expr_t *
asn1f_lookup_symbol(arg_t *arg, asn1p_ref_t *ref, asn1p_module_t **module_r) {
asn1p_expr_t *ref_tc; /* Referenced tc */
asn1p_module_t *src_mod;
char *modulename;
char *identifier;
/*
* First of all, a reference to a symbol may be specified
* using several possible forms:
* a) simple identifier
* v INTEGER ::= value
* b) external reference
* v INTEGER ::= Module1.value
* c) class-related stuff (the most complex stuff)
* v ::= <[A-Z][A-Z0-9a-z-]*>.&<[A-Z0-9a-z-]+>.
* All other forms are not implemented at this moment.
*/
DEBUG("%s(%s) in %s for line %d", __func__,
asn1f_printable_reference(ref),
arg->mod->Identifier,
ref->_lineno);
if(ref->comp_count == 1) {
modulename = NULL;
identifier = ref->components[0].name;
} else if(ref->comp_count == 2
&& ref->components[1].name[0] != '&') {
modulename = ref->components[0].name;
identifier = ref->components[1].name;
} else if(ref->comp_count > 1
&& isupper(ref->components[0].name[0])
&& ref->components[1].name[0] == '&') {
asn1p_expr_t *extract;
/*
* This is a reference to a CLASS-related stuff.
* Employ a separate function for that.
*/
extract = asn1f_class_access(arg, ref, module_r);
return extract;
} else {
DEBUG("\tToo many components: %d", ref->comp_count);
errno = EINVAL;
return NULL;
}
/*
* If module name is specified explicitly
* OR the current module's IMPORTS clause contains the identifier,
* fetch that module.
*/
if(modulename) {
src_mod = asn1f_lookup_module(arg, modulename, 0);
if(src_mod == NULL) {
FATAL("Module \"%s\" "
"mentioned at line %d is not found",
modulename, ref->_lineno);
return NULL;
}
/*
* Check that the EXPORTS section of this module contains
* the symbol we care about, or it is EXPORTS ALL.
*/
if(asn1f_compatible_with_exports(arg, src_mod, identifier)) {
errno = EPERM;
return NULL;
}
} else {
src_mod = asn1f_lookup_in_imports(arg, identifier);
if(src_mod == NULL && errno != ESRCH) {
/*
* Return only of the name was not found.
* If module was not found or more serious error
* encountered, just return preserving the errno.
*/
return NULL;
}
}
if(src_mod == 0) src_mod = arg->mod;
/*
* Now we know where to search for a value.
*/
TQ_FOR(ref_tc, &(src_mod->members), next) {
if(ref_tc->Identifier)
if(strcmp(ref_tc->Identifier, identifier) == 0)
break;
}
if(ref_tc == NULL) {
DEBUG("Module \"%s\" does not contain \"%s\" "
"mentioned at line %d",
src_mod->Identifier,
identifier,
ref->_lineno
);
errno = ESRCH;
return NULL;
}
if(module_r)
*module_r = src_mod;
return ref_tc;
}
asn1p_expr_t *
asn1f_find_terminal_type(arg_t *arg, asn1p_expr_t *expr,
asn1p_module_t **optm) {
return asn1f_find_terminal_thing(arg, expr, optm, 0);
}
asn1p_expr_t *
asn1f_find_terminal_value(arg_t *arg, asn1p_expr_t *expr,
asn1p_module_t **optm) {
return asn1f_find_terminal_thing(arg, expr, optm, 1);
}
static asn1p_expr_t *
asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr,
asn1p_module_t **optm, int type_or_value) {
asn1p_module_t *mod;
asn1p_ref_t *ref;
asn1p_expr_t *tc;
if(type_or_value) {
/* VALUE */
assert(expr->meta_type == AMT_VALUE);
assert(expr->value);
if(expr->value->type != ATV_REFERENCED) {
/* Expression is a terminal value itself */
if(optm) *optm = arg->mod;
return expr;
}
ref = expr->value->value.reference;
} else {
/* TYPE */
if(expr->expr_type != A1TC_REFERENCE) {
/* Expression is a terminal type itself */
if(optm) *optm = arg->mod;
return expr;
}
ref = expr->reference;
}
DEBUG("%s:%s(%s->%s) for line %d",
__func__, type_or_value?"VALUE":"TYPE",
expr->Identifier, asn1f_printable_reference(ref),
expr->_lineno);
assert(ref);
/*
* Lookup inside the type itself (ENUMERATED, INTEGER, etc).
*/
if(type_or_value) {
asn1p_expr_t *val_type_tc;
val_type_tc = asn1f_find_terminal_type(arg, expr, 0);
if(val_type_tc
&& asn1f_look_value_in_type(arg, val_type_tc, expr))
return NULL;
if(expr->value->type != ATV_REFERENCED) {
if(optm) *optm = arg->mod;
return expr;
}
assert(ref == expr->value->value.reference);
ref = expr->value->value.reference;
}
/*
* Lookup inside the default module.
*/
tc = asn1f_lookup_symbol(arg, ref, &mod);
if(tc == NULL) {
DEBUG("\tSymbol \"%s\" not found",
asn1f_printable_reference(ref));
return NULL;
}
/*
* Recursive loops detection.
*/
if(tc->_mark & TM_RECURSION) {
DEBUG("Recursion loop detected for %s at line %d",
asn1f_printable_reference(ref), ref->_lineno);
errno = EPERM;
return NULL;
}
tc->_mark |= TM_RECURSION;
WITH_MODULE(mod,
expr = asn1f_find_terminal_thing(arg, tc, optm, type_or_value));
tc->_mark &= ~TM_RECURSION;
return expr;
}
/*
* Make sure that the specified name is present or otherwise does
* not contradict with the EXPORTS clause of the specified module.
*/
static int
asn1f_compatible_with_exports(arg_t *arg, asn1p_module_t *mod, const char *name) {
asn1p_xports_t *exports;
asn1p_expr_t *item;
assert(mod);
assert(name);
exports = TQ_FIRST(&(mod->exports));
if(exports == NULL) {
/* No EXPORTS section or EXPORTS ALL; */
return 0;
}
TQ_FOR(item, &(exports->members), next) {
if(strcmp(item->Identifier, name) == 0)
return 0;
}
DEBUG("Symbol \"%s\" contradicts with EXPORTS of module %s",
name, mod->Identifier);
errno = ESRCH;
return -1;
}

View File

@ -0,0 +1,73 @@
/*
* Miscellaneous functions necessary for several other modules.
*/
#ifndef _ASN1FIX_RETRIEVE_H_
#define _ASN1FIX_RETRIEVE_H_
/*
* Simple search for the label in the descendants of the given node.
* ERRORS:
* NULL/ESRCH
*/
asn1p_expr_t *asn1f_lookup_child(asn1p_expr_t *tc, const char *name);
/*
* Return a module which contain a specified name, as stated in appropriate
* IMPORTS section of the current module (arg->mod).
*
* RETURN VALUES:
* NULL/ESRCH: The name was not found in IMPORTS section.
* NULL/EPERM: The name was not found in EXPORTS section of the source module.
* Also, NULL with errno values defined by asn1f_lookup_module().
*/
asn1p_module_t *asn1f_lookup_in_imports(arg_t *arg, const char *name);
/*
* Return a module by its name or optional OID.
*
* RETURN VALUES:
* NULL/ENOENT: No module was found by the specified name and oid
* NULL/ETOOMANYREFS: Several modules are matching the specified name and oid
*/
asn1p_module_t *asn1f_lookup_module(arg_t *arg,
const char *module_name,
asn1p_oid_t *module_oid);
/*
* Return the reference to a destination of the given reference,
* symbol lookup. Not a recursive function.
* Optional module reference may be assigned a module in which the
* particular expr was found.
*/
asn1p_expr_t *asn1f_lookup_symbol(arg_t *arg, asn1p_ref_t *ref,
asn1p_module_t **opt_module_r);
/*
* Recursively find the original type for the given expression.
* i.e.:
* If the original specification defines
* v Type1 ::= 5
* Type1 ::= Type2 (1..5)
* Type3 ::= Type4 (2..7)
* Type4 ::= INTEGER (1..10)
* Then this function, given the the first expression as an argument,
* would return an expression for Type4.
* WARNING: No attempts are made to honor constraints at this moment.
*/
asn1p_expr_t *asn1f_find_terminal_type(arg_t *arg, asn1p_expr_t *tc,
asn1p_module_t **opt_module_r);
/*
* Recursively find the original value for the given expression.
* i.e.:
* If the original specification defines
* v Type1 ::= value
* value Type2 ::= value2
* value2 Type3 ::= 3
* Then this function will return the expression for value2 if given
* the v as an argment.
*/
asn1p_expr_t *asn1f_find_terminal_value(arg_t *arg, asn1p_expr_t *tc,
asn1p_module_t **opt_module_r);
#endif /* _ASN1FIX_RETRIEVE_H_ */

47
libasn1fix/asn1fix_tags.c Normal file
View File

@ -0,0 +1,47 @@
#include "asn1fix_internal.h"
int
asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag) {
int ret;
if(expr->tag.tag_class != TC_NOCLASS) {
*tag = expr->tag;
return 0;
}
if(expr->expr_type == A1TC_EXTENSIBLE) {
memset(tag, 0, sizeof(*tag));
tag->tag_class = -1;
return 0;
}
if(expr->meta_type == AMT_TYPE) {
memset(tag, 0, sizeof(*tag));
tag->tag_class = TC_UNIVERSAL;
tag->tag_value = expr_type2uclass_value[expr->expr_type];
return (tag->tag_value == 0) ? -1 : 0;
}
if(expr->meta_type == AMT_TYPEREF) {
arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.mod = mod;
arg.expr = expr;
expr = asn1f_lookup_symbol(&arg, expr->reference, &mod);
if(expr == NULL) return -1;
if(expr->_mark & TM_RECURSION)
return -1;
expr->_mark |= TM_RECURSION;
ret = asn1f_fetch_tag(asn, mod, expr, tag);
expr->_mark &= ~TM_RECURSION;
return ret;
}
return -1;
}

View File

@ -0,0 +1,6 @@
#ifndef _ASN1FIX_TAGS_H_
#define _ASN1FIX_TAGS_H_
int asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag);
#endif /* _ASN1FIX_TAGS_H_ */

159
libasn1fix/asn1fix_value.c Normal file
View File

@ -0,0 +1,159 @@
#include "asn1fix_internal.h"
static int _asn1f_copy_value(arg_t *arg, asn1p_expr_t *to,asn1p_expr_t *from);
int
asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) {
asn1p_module_t *val_mod;
asn1p_expr_t *val_type_expr;
asn1p_expr_t *value_expr;
asn1p_expr_t *type_expr;
int ret;
/* Make sure this IS a value assignment */
assert(expr->meta_type == AMT_VALUE);
assert(expr->value);
DEBUG("%s(=\"%s\", %x)", __func__,
asn1f_printable_value(expr->value), expr->expr_type);
/*
* 1. Find the terminal type for this assignment.
*/
type_expr = asn1f_find_terminal_type(arg, expr, 0);
if(type_expr == 0) {
DEBUG("\tTerminal type for %s not found", expr->Identifier);
return -1;
}
if(asn1f_look_value_in_type(arg, type_expr, expr) == -1)
return -1;
/*
* 2. Find the terminal value also.
*/
value_expr = asn1f_find_terminal_value(arg, expr, &val_mod);
if(value_expr) {
DEBUG("\tTerminal value for %s->%s is %s at line %d",
expr->Identifier, asn1f_printable_value(expr->value),
value_expr->Identifier, value_expr->_lineno);
} else {
DEBUG("\tTerminal value for %s->%s not found",
expr->Identifier, asn1f_printable_value(expr->value));
return -1;
}
/*
* 3. Find the _type_ of a _terminal value_.
*/
WITH_MODULE(val_mod,
val_type_expr = asn1f_find_terminal_type(arg, value_expr, 0));
if(val_type_expr) {
DEBUG("\tTerminal type of value %s->%s is %s at line %d",
expr->Identifier, asn1f_printable_value(expr->value),
val_type_expr->Identifier, val_type_expr->_lineno);
} else {
DEBUG("\tTerminal type of value %s->%s not found",
expr->Identifier, asn1f_printable_value(expr->value));
return -1;
}
/*
* 4. Check compatibility between the type of the current expression
* and the type of the discovered value.
*/
ret = asn1f_check_type_compatibility(arg, type_expr, val_type_expr);
if(ret == -1) {
DEBUG("\tIncompatible type of %s at %d with %s at %d",
type_expr->Identifier, type_expr->_lineno,
val_type_expr->Identifier, val_type_expr->_lineno);
return -1;
}
if(asn1f_look_value_in_type(arg, val_type_expr, expr) == -1)
return -1;
/*
* 5. Copy value from the terminal value into the current expression.
*/
ret = _asn1f_copy_value(arg, expr, value_expr);
if(ret == -1) {
DEBUG("\tValue %s cannot be copied from line %d to line %d",
asn1f_printable_value(value_expr->value),
value_expr->_lineno, expr->_lineno);
return -1;
}
DEBUG("\tFinal value for \"%s\" at line %d is %s",
expr->Identifier, expr->_lineno,
asn1f_printable_value(expr->value));
return 0;
}
static int
_asn1f_copy_value(arg_t *arg, asn1p_expr_t *to, asn1p_expr_t *from) {
asn1p_value_t *v;
v = asn1p_value_clone(from->value);
if(v) {
asn1p_value_free(to->value);
to->value = v;
DEBUG("Copied value %s from \"%s\" on line %d "
"to \"%s\" on line %d",
asn1f_printable_value(v),
from->Identifier,
from->_lineno,
to->Identifier,
to->_lineno
);
return 0;
} else {
return -1;
}
}
int
asn1f_look_value_in_type(arg_t *arg,
asn1p_expr_t *type_expr,
asn1p_expr_t *value_expr) {
asn1p_expr_t *child_expr;
char *identifier;
if(value_expr->value->type != ATV_REFERENCED
|| value_expr->value->value.reference->comp_count != 1)
return 0;
if(type_expr->expr_type != ASN_BASIC_INTEGER
&& type_expr->expr_type != ASN_BASIC_ENUMERATED)
return 0;
DEBUG("%s(for %s in %s %x) for line %d", __func__,
asn1f_printable_value(value_expr->value),
type_expr->Identifier,
type_expr->expr_type,
value_expr->_lineno);
/*
* Look into the definitions of the type itself:
* Type1 ::= INTEGER { a(1), b(2) }
* value Type1 = b -- will assign 2
*/
identifier = value_expr->value->value.reference->components[0].name;
child_expr = asn1f_lookup_child(type_expr, identifier);
DEBUG("\tLooking into a type %s at line %d for %s at line %d: %s",
type_expr->Identifier, type_expr->_lineno,
identifier, value_expr->_lineno,
child_expr
? asn1f_printable_value(child_expr->value)
: "<not found>"
);
if(child_expr && child_expr->value) {
if(_asn1f_copy_value(arg, value_expr, child_expr))
return -1;
/* Fall through */
}
return 0;
}

View File

@ -0,0 +1,28 @@
/*
* Functions related with processing values.
*/
#ifndef _ASN1FIX_VALUE_H_
#define _ASN1FIX_VALUE_H_
/*
* Resolve the value given by reference.
* This function also takes a parameter which specifies the desired
* value's type.
*
* RETURN VALUES:
* 0: Value resolved successfully.
* -1/EPERM: Recursive looping detected.
* -1/EEXIST: Reference is not compatible with the desired type.
* -1/ESRCH: Cannot find the terminal reference.
*/
int asn1f_value_resolve(arg_t *arg, asn1p_expr_t *tc);
/*
* Check if a value in value_expr refers to the enumeration or integer element
* within the type provided. If yes, it will replace referenced value with
* the appropriate inline value.
*/
int asn1f_look_value_in_type(arg_t *arg,
asn1p_expr_t *type_expr, asn1p_expr_t *value_expr);
#endif /* _ASN1FIX_VALUE_H_ */

313
libasn1fix/check_fixer.c Normal file
View File

@ -0,0 +1,313 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <sysexits.h>
#include "asn1fix.h"
#include "asn1fix_internal.h"
static int check(const char *fname,
enum asn1p_flags parser_flags,
enum asn1f_flags fixer_flags);
static int post_fix_check(asn1p_t *asn);
static int post_fix_check_element(asn1p_module_t *mod, asn1p_expr_t *expr);
int
main(int ac, char **av) {
struct dirent *dp;
DIR *dir;
int failed = 0;
int completed = 0;
enum asn1p_flags parser_flags = A1P_NOFLAGS;
enum asn1f_flags fixer_flags = A1F_NOFLAGS;
int ret;
/*
* Just in case when one decides that some flags better be
* enabled during `ASN1_FIXER_FLAGS=1 make check` or some
* similar usage.
*/
if(getenv("ASN1_PARSER_FLAGS"))
parser_flags = atoi(getenv("ASN1_PARSER_FLAGS"));
if(getenv("ASN1_FIXER_FLAGS"))
fixer_flags = atoi(getenv("ASN1_FIXER_FLAGS"));
/*
* Go into a directory with tests.
*/
if(ac <= 1) {
fprintf(stderr, "Testing in ./tests...\n");
ret = chdir("../tests");
assert(ret == 0);
dir = opendir(".");
assert(dir);
} else {
dir = 0;
}
/*
* Scan every *.asn1 file and try to parse and fix it.
*/
if(dir) {
while((dp = readdir(dir))) {
int len = strlen(dp->d_name);
if(len && strcmp(dp->d_name + len - 5, ".asn1") == 0) {
ret = check(dp->d_name,
parser_flags, fixer_flags);
if(ret) {
fprintf(stderr,
"FAILED: %s\n",
dp->d_name);
failed++;
}
completed++;
}
}
closedir(dir);
fprintf(stderr,
"Tests COMPLETED: %d\n"
"Tests FAILED: %d\n"
,
completed, failed
);
} else {
int i;
for(i = 1; i < ac; i++) {
ret = check(av[i], parser_flags, fixer_flags);
if(ret) {
fprintf(stderr, "FAILED: %s\n", av[i]);
failed++;
}
completed++;
}
}
if(completed == 0) {
fprintf(stderr, "No tests defined?!\n");
exit(EX_NOINPUT);
}
if(failed)
exit(EX_DATAERR);
return 0;
}
static int
check(const char *fname,
enum asn1p_flags parser_flags,
enum asn1f_flags fixer_flags) {
asn1p_t *asn;
int expected_parseable; /* Is it expected to be parseable? */
int expected_fix_code; /* What code a fixer must return */
int r_value = 0;
/*
* Figure out how the processing should go by inferring
* expectations from the file name.
*/
if(strstr(fname, "-OK.")) {
expected_parseable = 1;
expected_fix_code = 0;
} else if(strstr(fname, "-NP.")) {
expected_parseable = 0;
expected_fix_code = 123; /* Does not matter */
} else if(strstr(fname, "-SE.")) {
expected_parseable = 1;
expected_fix_code = -1; /* Semantically incorrect */
} else if(strstr(fname, "-SW.")) {
expected_parseable = 1;
expected_fix_code = 1; /* Semantically suspicious */
} else {
fprintf(stderr, "%s: Invalid file name format\n", fname);
return -1;
}
fprintf(stderr, "[=> %s]\n", fname);
/*
* Perform low-level parsing.
*/
if(!expected_parseable)
fprintf(stderr, "Expecting error...\n");
asn = asn1p_parse_file(fname, parser_flags);
if(asn == NULL) {
if(expected_parseable) {
fprintf(stderr, "Cannot parse file \"%s\"\n", fname);
r_value = -1;
} else {
fprintf(stderr,
"Previous error is EXPECTED, no worry\n");
}
} else if(!expected_parseable) {
fprintf(stderr,
"The file \"%s\" is not expected to be parseable, "
"yet parsing was successfull!\n", fname);
r_value = -1;
}
/*
* Perform semantical checks and fixes.
*/
if(asn && r_value == 0) {
int ret;
if(expected_fix_code)
fprintf(stderr, "Expecting some problems...\n");
ret = asn1f_process(asn, fixer_flags, 0);
if(ret) {
if(ret == expected_fix_code) {
fprintf(stderr,
"Previous error is EXPECTED, "
"no worry\n");
} else {
fprintf(stderr,
"Cannot process file \"%s\": %d\n",
fname, ret);
r_value = -1;
}
} else if(ret != expected_fix_code) {
fprintf(stderr,
"File \"%s\" is expected "
"to be semantically incorrect, "
"yet processing was successful!\n",
fname);
r_value = -1;
}
}
/*
* Check validity of some values, if grammar has special
* instructions for that.
*/
if(asn && r_value == 0) {
if(post_fix_check(asn))
r_value = -1;
}
/*
* TODO: destroy the asn.
*/
return r_value;
}
static int
post_fix_check(asn1p_t *asn) {
asn1p_module_t *mod;
asn1p_expr_t *expr;
int r_value = 0;
TQ_FOR(mod, &(asn->modules), mod_next) {
TQ_FOR(expr, &(mod->members), next) {
assert(expr->Identifier);
if(strncmp(expr->Identifier, "check-", 6) == 0) {
if(post_fix_check_element(mod, expr))
r_value = -1;
}
}
}
return r_value;
}
static int
post_fix_check_element(asn1p_module_t *mod, asn1p_expr_t *check_expr) {
asn1p_expr_t *expr = NULL;
char *name;
asn1p_value_t *value;
if(check_expr->expr_type != ASN_BASIC_INTEGER
|| check_expr->meta_type != AMT_VALUE) {
fprintf(stderr,
"CHECKER: Unsupported type of \"%s\" value: "
"%d at line %d of %s\n",
check_expr->Identifier,
check_expr->expr_type,
check_expr->_lineno,
mod->source_file_name
);
return -1;
}
assert(check_expr->meta_type == AMT_VALUE);
value = check_expr->value;
if(value == NULL || value->type != ATV_INTEGER) {
fprintf(stderr,
"CHECKER: Unsupported value type of \"%s\": "
"%d at line %d of %s\n",
check_expr->Identifier,
value?value->type:-1,
expr->_lineno,
mod->source_file_name
);
return -1;
}
name = check_expr->Identifier + sizeof("check-") - 1;
/*
* Scan in search for the original.
*/
TQ_FOR(expr, &(mod->members), next) {
if(strcmp(expr->Identifier, name) == 0)
break;
}
if(expr == NULL) {
fprintf(stderr,
"CHECKER: Value \"%s\" requested by "
"\"check-%s\" at line %d of %s is not found!\n",
name, name, check_expr->_lineno,
mod->source_file_name
);
return -1;
}
if(0 && expr->expr_type != check_expr->expr_type) {
fprintf(stderr,
"CHECKER: Value type of \"%s\" (=%d) at line %d "
"does not have desired type %d as requested by "
"\"check-%s\" in %s\n",
expr->Identifier,
expr->expr_type,
expr->_lineno,
check_expr->expr_type,
name,
mod->source_file_name
);
return -1;
}
if(expr->value == NULL
|| expr->value->type != value->type) {
fprintf(stderr,
"CHECKER: Value of \"%s\" (\"%s\", type=%d) at line %d "
"does not have desired type %d as requested by "
"\"check-%s\" in %s\n",
expr->Identifier,
asn1f_printable_value(expr->value),
expr->value->type,
expr->_lineno,
value->type,
name,
mod->source_file_name
);
return -1;
}
assert(value->type = ATV_INTEGER);
return 0;
}

35
libasn1parser/Makefile.am Normal file
View File

@ -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}

Some files were not shown because too many files have changed in this diff Show More