?? asn_pproc.c
字號:
/*****************************************************************************
File: asn_pproc.c
Contents: Functions to pre-process ASN.1 files as part of the ASN_GEN
program.
System: ASN development.
Created:
Author: Charles W. Gardiner <gardiner@bbn.com>
Remarks:
COPYRIGHT 1995 BBN Systems and Technologies, A Division of Bolt Beranek
and Newman Inc.
150 CambridgePark Drive
Cambridge, Ma. 02140
617-873-4000
*****************************************************************************/
const char asn_pproc_rcsid[]="$Header: /nfs/sub-rosa/u2/IOS_Project/ASN/Dev/rcs/cmd/asn_gen/asn_pproc.c,v 1.21 1995/09/25 22:10:11 gardiner Exp $";
char asn_pproc_id[] = "@(#)asn_pproc.c 282P";
#include "includes.h"
#include "asn_obj.h"
#include "asn_gen.h"
static struct import_table
{
char *name;
struct import_item
{
struct import_item *next;
char *module;
} item;
} *imtbp; /* pointer to entry for imported file currently being read */
static struct import_table *add_import_item(struct import_table *, char *);
static void encr_xform(int, char *),
free_imports(),
get_exports(int),
get_fnames(int),
putout(FILE *, char *);
static int is_imported(char *),
pre_proc_get_token(int, FILE *, char *),
pre_proc_glob(int, FILE *, char *, char **, char *, int *, long *),
pre_proc_def(int, FILE *, char *, char **, char *, int *, long),
pre_proc_item(int, FILE *, char *, char **, char *, int *, int, long),
was_imported(char *);
static FILE *make_substr();
static char encrypted_w[] = "ENCRYPTED", exports_w[] = "EXPORTS",
signed_w[] = "SIGNED";
static struct name_area import_area =
{"import_area", sizeof(struct import_table), 20, 4000 };
char tobesigned[] = "{\n toBeSigned %sToBeSigned,\n",
tabledef[] =
"%sAlgorithmIdentifier ::= SEQUENCE {\n\
algorithm OBJECT IDENTIFIER TABLE %s,\n\
parameters ANY DEFINED BY algorithm OPTIONAL}\n\n",
objtobesigned[] = "%sToBeSigned ::= SEQUENCE ",
signedname[] = "Signed%s ",
signeddef[] = "::= SEQUENCE {\n",
tagclass[] = " %s SEQUENCE,\n",
thatword[] = " %s %s,\n",
algsig[] =
" algorithm %sAlgorithmIdentifier,\n\
signature BIT STRING }\n\n",
of_opener[] = "%s ::= %s %s %s\n\n",
sub_opener[] = "%s ::= %s {\n",
signed_sub_opener[] = "%s ::= %s";
void pre_proc(int fd, FILE *str, int in_sub)
{
/**
Function: Preprocesses file fd to translate SIGNED macro and produce file str
Inputs: fd is file descriptor for ASN.1 file. IF this is non-zero, we are in
an imported file
str is the stream descriptor for the output
locstate is used for recursiveness
Outputs: ASN.1 code written to 'str'
Procedure:
1. Starting with lots of things cleared, DO forever
IF no token AND no more tokens, break out of DO
Switch on locstate
2. Case GLOBAL
IF processing global state returns GLOBAL state, return
Case IN_DEFINITION
IF processing the definition returns GLOBAL state
Clean up a few variables
Case IN_ITEM
IF in a sub-item AND pre-processing the items returns GLOBAL
state, return
**/
char linebuf[2*BSIZE], *linend = linebuf, *elinebuf = &linebuf[sizeof(linebuf)];
int signflag,
active; /* -1= in main file, 0= in imported file but not imported class
1= in imported file in an imported class, no details needed
2= " " " " " " " , but details needed */
ulong loctag;
long loctype, glob_type;
if (!in_sub) *classname = 0;
for (signflag = loctag = 0, active = glob_type = loctype = -1,
*token = *linebuf = *itemname = 0; pre_proc_get_token(fd, str, linebuf); )
{
switch (state)
{
case PRE_GLOBAL:
if (!strcmp(token, equals)) syntax(definitions_w);
if (!strcmp(token, definitions_w)) state = GLOBAL;
else *token = 0; /* discard up to DEFINITIONS */
break;
case GLOBAL:
if ((state = pre_proc_glob(fd, str, linebuf, &linend, elinebuf,
&active, &glob_type)) == GLOBAL) return;
break;
case IN_DEFINITION: /* got ::= */
if ((state = pre_proc_def(fd, str, linebuf, &linend, elinebuf,
&active, glob_type)) == GLOBAL)
{
active = glob_type = loctype = -1;
fflush(str);
*subclass = *classname = *(linend = linebuf) = 0;
}
break;
case IN_ITEM:
case SUB_ITEM:
if ((state = pre_proc_item(fd, str, linebuf, &linend, elinebuf,
&active, in_sub, glob_type)) == GLOBAL && in_sub) return;
glob_type = -1;
break;
default:
fatal(4, (char *)state);
}
}
if (linend > linebuf) fprintf(str, "%s\n", linebuf);
if (!fd) free_imports();
}
static int pre_proc_get_token(int fd, FILE *str, char *linebuf)
{
static int loopcount;
if (!*token) loopcount = 0;
else if (loopcount++ > 20)
{
putout(str, linebuf);
fflush(str);
fatal(22, token);
}
if (!*token && !get_token(fd, token, (char)0)) return 0;
return 1;
}
static int pre_proc_glob(int fd, FILE *str, char *linebuf, char **linendp,
char *elinebuf, int *activep, long *glob_typep)
{
/**
1. DO
IF token is '::='
IF not in definitions class, set state to IN_DEFINITION
ELSE IF not in an imported file
Print token with RETURN
Clear class name and token
2. ELSE IF token is IMPORTS
IF have already started, error
Get all the file names
IF at top level
FOR each file in the import table
Add the name to the i_names list
Open the file for reading
Call pre_proc with that fd (this may add to the import
table)
Close input file
Put out an extra line end
3. ELSE IF token is EXPORTS, put export items in export area
ELSE IF token is BEGIN, do nothing
ELSE IF token is a known tag, save its type
ELSE IF token is a name defined to be a universal type
IF haven't a class name, error
Replace the token with the universal name
ELSE IF token is a brace, error
ELSE IF have no local classname AND token looks like one
Copy token to local class name
IF classname is upper case, append token to linebuf and clear token
WHILE state is GLOBAL AND there's a next token
Return state
**/
char *c, locclass[128];
int locstate, tmp;
struct name_table *ntbp;
do /* step 1 */
{
if (!strcmp(token, equals))
{
if (strcmp(classname, definitions_w)) state = IN_DEFINITION;
else
{
if (!fd) fprintf(str, "%s ::=\n\n", linebuf);
*token = *classname = *(*linendp = linebuf) = 0;
}
}
else if (!strcmp(token, imports_w)) /* step 2 */
{
cat(classname, token);
if (real_start) syntax(token);
*token = 0;
get_fnames(fd);
if (!fd)
{
for(imtbp = (struct import_table *)import_area.area;
imtbp->name; imtbp++)
{
if (!strcmp(imtbp->name, source)) continue;
if (add_include_name(imtbp->name))
{
if ((tmp = find_file(imtbp->name)) < 0)
fatal(2, imtbp->name);
printf("File %s\n", imtbp->name);
cat(locclass, classname);
locstate = state;
pre_proc(tmp, str, 0);
fflush(str);
close(tmp);
state = locstate;
cat(classname, locclass);
*token = 0;
}
}
imtbp = (struct import_table *)0;
printf("Main file\n");
}
if (*activep) putout(str, "\n");
if (!fd) real_start = ftell(str);
*classname = 0;
}
else if (!strcmp(token, exports_w)) /* step 3 */
{
get_exports(fd);
*locclass = *classname = *token = 0;
}
else if (!strcmp(token, begin_w)) *token = 0;
else if ((tmp = find_type(token)) != ASN_NOTYPE)
get_expected(fd, (*glob_typep = tmp), token);
else if ((ntbp = find_name(token)) && ntbp->name && ntbp->type <
ASN_APPL_SPEC)
{
if (!*classname)
{
cat(classname, token);
fatal(17, token);
}
c = cat(token, find_typestring(ntbp->type));
if (ntbp->type == ASN_OBJ_ID) cat(c, " IDENTIFIER");
else if (ntbp->type == ASN_BITSTRING || ntbp->type ==
ASN_OCTETSTRING) cat(c, " STRING");
ntbp->pos = -2; /* so it won't appear in unused list */
*glob_typep = ntbp->type;
}
else if (*token == '{' || *token == '}') syntax(token);
else if (!*classname && *token >= 'A')
{
cat(classname, token);
if (strcmp(token, definitions_w) && strcmp(token, implicit_w) &&
strcmp(token, explicit_w) && isreserved(token))
syntax("invalid class");
}
if (fd && *classname > ' ') *activep = is_imported(classname);
if (*classname <= 'Z' && *activep && *token && (*linendp > linebuf ||
*token > ' ') &&
(*linendp = cat(cat(*linendp, token),
((!token == '{')? "\n ": " "))) >= elinebuf) syntax(linebuf);
*token = 0;
}
while (state == GLOBAL && pre_proc_get_token(fd, str, linebuf));
return state;
}
static int pre_proc_def(int fd, FILE *str, char *linebuf, char **linendp,
char *elinebuf, int *activep, long glob_type)
{
/**
1. DO
IF token is ENCRYPTED, call encrypted transformation
IF token is SIGNED
Set signed flag
Get next token to put out
ELSE IF token is TABLE
IF signed flag set
Get table name
Clear token
2. ELSE IF token is '{' OR OF
IF (it's an OF OR is imported) AND linebuf has data
Put linebuf out
IF token is OF
IF active, put out OF
IF next token is not a universal type
IF active, put out token
Clear token
Set state to GLOBAL
ELSE
IF next token is '{'
Make a synthetic name
IF active
Print that with a line end
IF details needed, print sub_opener with
synthetic name and universal type name
Clear token
Set state to GLOBAL
ELSE IF in an imported file
Print token
Skip to next '}'
IF active AND not imported
IF linebuf has data AND not a glob_type
Put out the linebuf
IF signed flag is set
Put out tobesigned lines
IF have a table, put out tabledef lines
Put out objtobesigned line
IF state isn't GLOBAL, set state to IN_ITEM
3. ELSE IF token is open parenthesis or bracket, bump count
ELSE IF token is close parenthesis or bracket
IF decrementing count goes < 0, error
ELSE IF token is numeric
Add object to ub table
Clear linebuf
ELSE IF token is alphabetic but not a reserved word
IF have subclass OR type, i.e. definition is complete
Set state to GLOBAL
IF type is universal constructed, error
ELSE set subclass from token
4. IF classname is upper case
IF just switched to GLOBAL state
IF active
IF in an imported file AND token is capital letter
Add token as an imported item so it will be
included as child of this 'false' item
Print 1 or 2 blank lines
Clear assorted variables to enter global state, BUT keep
token, since it starts the next definition
ELSE
IF active,
Append token to linebuf
IF item is a choice, set active to 2 to force getting
contents of item
ELSE throw away the token
WHILE state is IN_DEFINITION AND there's another token
Return state
**/
int loctype, signflag, tmp, brackets, parens;
char *c, table[128];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -