📄 asn1print.c
字号:
#include <stdio.h>#include <string.h>#include <errno.h>#include <assert.h>#include <asn1parser.h>#include <asn1fix_export.h>#include <asn1fix_crange.h>#include "asn1print.h"#define INDENT(fmt, args...) do { \ if(!(flags & APF_NOINDENT)) { \ int __i = level; \ while(__i--) printf(" "); \ } \ printf(fmt, ##args); \ } while(0)static int asn1print_module(asn1p_t *asn, asn1p_module_t *mod, enum asn1print_flags flags);static int asn1print_oid(asn1p_oid_t *oid, enum asn1print_flags flags);static int asn1print_ref(asn1p_ref_t *ref, enum asn1print_flags flags);static int asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags);static int asn1print_params(asn1p_paramlist_t *pl,enum asn1print_flags flags);static int asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags);static int asn1print_constraint(asn1p_constraint_t *, enum asn1print_flags);static int asn1print_value(asn1p_value_t *val, enum asn1print_flags flags);static int asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1print_flags flags, int level);static int asn1print_expr_dtd(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1print_flags flags, int level);/* * Print the contents of the parsed ASN tree. */intasn1print(asn1p_t *asn, enum asn1print_flags flags) { asn1p_module_t *mod; int modno = 0; if(asn == NULL) { errno = EINVAL; return -1; } if(flags & APF_PRINT_XML_DTD) printf("<!-- XML DTD generated by asn1c-" VERSION " -->\n\n"); TQ_FOR(mod, &(asn->modules), mod_next) { if(modno++) printf("\n"); asn1print_module(asn, mod, flags); } if(flags & APF_PRINT_XML_DTD) { /* Values for BOOLEAN */ printf("<!ELEMENT true EMPTY>\n"); printf("<!ELEMENT false EMPTY>\n"); } return 0;}static intasn1print_module(asn1p_t *asn, asn1p_module_t *mod, enum asn1print_flags flags) { asn1p_expr_t *tc; if(flags & APF_PRINT_XML_DTD) printf("<!-- ASN.1 module\n"); printf("%s ", mod->Identifier); if(mod->module_oid) { asn1print_oid(mod->module_oid, flags); printf("\n"); } if(flags & APF_PRINT_XML_DTD) { if(mod->source_file_name && strcmp(mod->source_file_name, "-")) printf("found in %s", mod->source_file_name); printf(" -->\n\n"); TQ_FOR(tc, &(mod->members), next) { asn1print_expr_dtd(asn, mod, tc, flags, 0); } return 0; } printf("DEFINITIONS"); if(mod->module_flags & MSF_TAG_INSTRUCTIONS) printf(" TAG INSTRUCTIONS"); if(mod->module_flags & MSF_XER_INSTRUCTIONS) printf(" XER INSTRUCTIONS"); if(mod->module_flags & MSF_EXPLICIT_TAGS) printf(" EXPLICIT TAGS"); if(mod->module_flags & MSF_IMPLICIT_TAGS) printf(" IMPLICIT TAGS"); if(mod->module_flags & MSF_AUTOMATIC_TAGS) printf(" AUTOMATIC TAGS"); if(mod->module_flags & MSF_EXTENSIBILITY_IMPLIED) printf(" EXTENSIBILITY IMPLIED"); printf(" ::=\n"); printf("BEGIN\n\n"); TQ_FOR(tc, &(mod->members), next) { asn1print_expr(asn, mod, tc, flags, 0); if(flags & APF_DEBUG_CONSTRAINTS) printf("\n"); else printf("\n\n"); } printf("END\n"); return 0;}static intasn1print_oid(asn1p_oid_t *oid, enum asn1print_flags flags) { size_t accum = 0; int ac; (void)flags; /* Unused argument */ printf("{"); for(ac = 0; ac < oid->arcs_count; ac++) { const char *arcname = oid->arcs[ac].name; if(accum + strlen(arcname ? arcname : "") > 50) { printf("\n\t"); accum = 0; } else if(ac) { printf(" "); } if(arcname) { printf("%s", arcname); if(oid->arcs[ac].number >= 0) { printf("(%" PRIdASN ")", oid->arcs[ac].number); } accum += strlen(oid->arcs[ac].name); } else { printf("%" PRIdASN, oid->arcs[ac].number); } accum += 4; } printf(" }"); return 0;}static intasn1print_ref(asn1p_ref_t *ref, enum asn1print_flags flags) { int cc; (void)flags; /* Unused argument */ for(cc = 0; cc < ref->comp_count; cc++) { if(cc) printf("."); printf("%s", ref->components[cc].name); } return 0;}static intasn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags) { struct asn1p_type_tag_s *tag = &tc->tag; (void)flags; /* Unused argument */ if(tag->tag_class == TC_NOCLASS) return 0; printf("["); switch(tag->tag_class) { case TC_NOCLASS: assert(tag->tag_class != TC_NOCLASS); break; case TC_UNIVERSAL: printf("UNIVERSAL "); break; case TC_PRIVATE: printf("PRIVATE "); break; case TC_APPLICATION: printf("APPLICATION "); break; case TC_CONTEXT_SPECIFIC: break; } printf("%" PRIdASN "]", tag->tag_value); switch(tag->tag_mode) { case TM_DEFAULT: break; case TM_IMPLICIT: printf(" IMPLICIT"); break; case TM_EXPLICIT: printf(" EXPLICIT"); break; } return 0;}static intasn1print_value(asn1p_value_t *val, enum asn1print_flags flags) { if(val == NULL) return 0; switch(val->type) { case ATV_NOVALUE: break; case ATV_NULL: printf("NULL"); return 0; case ATV_REAL: printf("%f", val->value.v_double); return 0; case ATV_INTEGER: printf("%" PRIdASN, val->value.v_integer); return 0; case ATV_MIN: printf("MIN"); return 0; case ATV_MAX: printf("MAX"); return 0; case ATV_FALSE: printf("FALSE"); return 0; case ATV_TRUE: printf("TRUE"); return 0; case ATV_STRING: { char *p = val->value.string.buf; putchar('"'); if(strchr(p, '"')) { /* Mask quotes */ for(; *p; p++) { if(*p == '"') putchar(*p); putchar(*p); } } else { fputs(p, stdout); } putchar('"'); } return 0; case ATV_UNPARSED: fputs(val->value.string.buf, stdout); return 0; case ATV_BITVECTOR: { uint8_t *bitvector; int bits; int i; bitvector = val->value.binary_vector.bits; bits = val->value.binary_vector.size_in_bits; printf("'"); if(bits%8) { for(i = 0; i < bits; i++) { uint8_t uc; uc = bitvector[i>>3]; putchar(((uc >> (7-(i%8)))&1)?'1':'0'); } printf("'B"); } else { char hextable[16] = "0123456789ABCDEF"; for(i = 0; i < (bits>>3); i++) { putchar(hextable[bitvector[i] >> 4]); putchar(hextable[bitvector[i] & 0x0f]); } printf("'H"); } return 0; } case ATV_REFERENCED: return asn1print_ref(val->value.reference, flags); case ATV_CHOICE_IDENTIFIER: printf("%s: ", val->value.choice_identifier.identifier); return asn1print_value(val->value.choice_identifier.value, flags); } assert(val->type || !"Unknown"); return 0;}static intasn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) { int symno = 0; if(ct == 0) return 0; if(ct->type == ACT_CA_SET) printf("("); switch(ct->type) { case ACT_EL_VALUE: asn1print_value(ct->value, flags); break; case ACT_EL_RANGE: case ACT_EL_LLRANGE: case ACT_EL_RLRANGE: case ACT_EL_ULRANGE: asn1print_value(ct->range_start, flags); switch(ct->type) { case ACT_EL_RANGE: printf(".."); break; case ACT_EL_LLRANGE: printf("<.."); break; case ACT_EL_RLRANGE: printf("..<"); break; case ACT_EL_ULRANGE: printf("<..<"); break; default: printf("?..?"); break; } asn1print_value(ct->range_stop, flags); break; case ACT_EL_EXT: printf("..."); break; case ACT_CT_SIZE: case ACT_CT_FROM: switch(ct->type) { case ACT_CT_SIZE: printf("SIZE("); break; case ACT_CT_FROM: printf("FROM("); break; default: printf("??? ("); break; } assert(ct->el_count != 0); assert(ct->el_count == 1); asn1print_constraint(ct->elements[0], flags); printf(")"); break; case ACT_CT_WCOMP: case ACT_CT_WCOMPS: printf("???"); break; case ACT_CA_SET: symno++; case ACT_CA_CRC: symno++; case ACT_CA_CSV: symno++; case ACT_CA_UNI: symno++; case ACT_CA_INT: symno++; case ACT_CA_EXC: { char *symtable[] = { " EXCEPT ", " ^ ", " | ", ",", "", "(" }; unsigned int i; for(i = 0; i < ct->el_count; i++) { enum asn1print_flags nflags = flags; if(i) fputs(symtable[symno], stdout); if(ct->type == ACT_CA_CRC) fputs("{", stdout); asn1print_constraint(ct->elements[i], nflags); if(ct->type == ACT_CA_CRC) fputs("}", stdout); if(i+1 < ct->el_count && ct->type == ACT_CA_SET) fputs(")", stdout); } } break; case ACT_INVALID: assert(ct->type != ACT_INVALID); break; } if(ct->type == ACT_CA_SET) printf(")"); return 0;}static intasn1print_params(asn1p_paramlist_t *pl, enum asn1print_flags flags) { if(pl) { int i; printf("{"); for(i = 0; i < pl->params_count; i++) { if(i) printf(", "); if(pl->params[i].governor) { asn1print_ref(pl->params[i].governor, flags); printf(":"); } printf("%s", pl->params[i].argument); } printf("}"); } return 0;}static intasn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags) { if(wx) { asn1p_wsyntx_chunk_t *wc; printf(" WITH SYNTAX {"); TQ_FOR(wc, &(wx->chunks), next) { if(wc->ref) { asn1print_ref(wc->ref, flags); } else { fwrite(wc->buf, 1, wc->len, stdout); } } printf("}\n"); } return 0;}static intasn1print_crange_value(asn1cnst_edge_t *edge, int as_char) { switch(edge->type) { case ARE_MIN: printf("MIN"); break; case ARE_MAX: printf("MAX"); break; case ARE_VALUE: if(as_char) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -