This document provides comprehensive guidance for GitHub Copilot when working on the asn1c (ASN.1 to C compiler) project to ensure high-quality, consistent, and maintainable code contributions.
asn1c is a sophisticated ASN.1 to C compiler that generates C++ compatible C source code for serializing and deserializing ASN.1-based data formats. This is a mature, production-grade project with complex parsing, code generation, and encoding/decoding capabilities.
- Languages: C (C90/C99), with generated code compatible with C++
- Build System: GNU Autotools (autoconf/automake)
- Standards: ASN.1, BER/DER, PER, OER, XER, JER encoding standards
- Target Domains: PKI/X.509, telecommunications, automotive (V2X), networking protocols
- Follow the
.clang-formatconfiguration (Google style base with custom modifications) - Use 4-space indentation, no tabs
- Maximum 2 empty lines between functions
- Always break after definition return type for top-level functions
- No space before parentheses:
function()notfunction () - Prefer explicit over implicit: use
!= 0instead of implicit boolean conversion
// Functions: lowercase with underscores
int parse_asn1_module(const char *filename);
// Types: suffix with _t, use descriptive names
typedef struct asn1p_expr_s asn1p_expr_t;
// Constants: ALL_CAPS with underscores
#define ASN_STRING_MAX_SIZE 1024
// Variables: lowercase with underscores
int current_line_number;
char *module_name;- Always check return values of
malloc(),calloc(),strdup() - Use
assert()for internal consistency checks - Prefer stack allocation for small, fixed-size buffers
- Free memory in reverse order of allocation
- Set pointers to NULL after freeing
// Return -1 for errors, 0 for success, positive for specific cases
int function_name(args) {
if(!args) return -1;
// ... processing ...
if(error_condition) {
fprintf(stderr, "Error: %s\n", error_msg);
return -1;
}
return 0; // success
}- asn1c/: Main compiler executable
- libasn1parser/: ASN.1 syntax parser (lex/yacc based)
- libasn1fix/: Semantic analysis and tree transformation
- libasn1compiler/: Code generation engine
- libasn1print/: Pretty-printing utilities
- skeletons/: Runtime support code templates
- tests/: Comprehensive test suite
asn1p_expr_t: ASN.1 expression tree nodesarg_t: Compiler arguments and contextasn1c_ioc_table_t: Information Object Classesasn1p_constraint_t: ASN.1 constraints
# Initial setup (first time only)
autoreconf -iv
./configure
# Build
make
# Testing (may take several minutes)
make check
make distcheck
# For development, faster partial builds:
make -C asn1c # build just the compiler
make -C tests/tests-asn1c-compiler check # run specific test suite- Always add tests for new features in appropriate
tests/subdirectory - Use existing test patterns and naming conventions
- Test edge cases, especially for ASN.1 constraint validation
- Include both positive and negative test cases
- tests-asn1c-compiler/: Parser and compiler tests
- tests-skeletons/: Runtime library tests
- tests-c-compiler/: Generated code compilation tests
- tests-randomized/: Fuzzing and stress tests
- Types: SEQUENCE, SET, CHOICE, INTEGER, OCTET STRING, etc.
- Constraints: SIZE, FROM, WITH COMPONENT, etc.
- Encoding Rules: BER/DER (byte-oriented), PER/UPER (bit-oriented), XER (XML)
- Information Object Classes: Parameterized types and constraints
- Generated code follows consistent naming:
TypeName_t,TypeName_encode_der() - Runtime functions use consistent prefixes:
ber_,per_,xer_,oer_,jer_ - Constraint validation functions:
TypeName_constraint()
- Incorrect tag handling in BER/DER encoding
- Buffer overflow in PER encoding/decoding
- Improper constraint validation
- Memory leaks in choice type handling
- Parser Changes: Update both lexer (.l) and parser (.y) files consistently
- Code Generation: Add skeleton templates in
skeletons/if needed - Encoding Support: Implement all relevant encoding rules (BER, PER, OER, XER, JER)
- Documentation: Update man pages in
doc/man/and usage documentation
- Reproduce First: Add a test case that demonstrates the issue
- Minimal Changes: Prefer surgical fixes over broad refactoring
- Regression Testing: Ensure
make checkpasses completely - Edge Cases: Consider boundary conditions and malformed input
- Follows existing code style and patterns
- Includes appropriate error handling
- Has corresponding test coverage
- Doesn't break existing functionality (
make check) - Updates documentation if changing user-facing behavior
- Uses consistent naming conventions
- Properly handles memory allocation/deallocation
- Double-free errors (common in cleanup paths)
- Memory leaks in error conditions
- Use-after-free when sharing ASN.1 expression trees
- Buffer overruns in string manipulation
- Incorrect precedence in constraint expressions
- Missing semantic validation in the fix phase
- Improper handling of forward references
- Tag conflicts in CHOICE types
- Inconsistent function naming in generated code
- Missing bounds checking in array access
- Incorrect handling of optional elements
- Platform-specific assumptions (endianness, integer sizes)
# Print ASN.1 syntax tree after parsing
asn1c -E module.asn1
# Print after semantic fixing
asn1c -E -F module.asn1
# Print generated code without saving
asn1c -P module.asn1- Use
DEBUG()macro for conditional debug output - Add
assert()statements for invariant checking - Use
fprintf(stderr, ...)for error reporting - Enable ASN_DEBUG during development builds
- Minimize dynamic memory allocation in generated code
- Use stack allocation for small, bounded structures
- Optimize common cases (simple INTEGER, short strings)
- Avoid redundant constraint checking
- Cache frequently-used lookups (symbol tables)
- Minimize string copying and concatenation
- Use efficient data structures for large ASN.1 modules
The project uses GitHub Actions CI that:
- Builds on Ubuntu with standard GNU toolchain
- Runs full test suite (
make check) - Performs distribution testing (
make distcheck) - Must pass before merge
Ensure all contributions:
- Build cleanly without warnings
- Pass all existing tests
- Include new tests for new functionality
- Don't break the distribution build
When working on this project, prioritize correctness and maintainability over clever optimizations. The ASN.1 standards are complex and subtle, so careful adherence to specifications and thorough testing are essential.