📄 smscan.c
字号:
/*
* Copyright 1992 SynOptics Communications, Inc. All Rights Reserved.
* SynOptics grants a non-exclusive license to use, copy, modify, and
* distribute this software for any purpose and without fee, provided
* that this copyright notice and license appear on all copies and
* supporting documentation.
* SynOptics makes no representations about the suitability of this
* software for any particular purpose. The software is supplied
* "AS IS", and SynOptics makes no warranty, either express or implied,
* as to the use, operation, condition, or performance of the software.
* SynOptics retains all title and ownership in the software.
*
* file: SMSCAN.C - scanner (lexical analyser) for MIB Compiler
*
* $Revision: 1.3 $ $Date: 08 Jul 1992 17:35:54 $
* $Log: R:/MIBTOOLS/V1.0/SMIC/SRC/SMSCAN.C_V $
*
* Rev 1.3 08 Jul 1992 17:35:54 gfoster
* Removed unnecessary revision comment lines added by
* PVCS to make revision history easier to read.
*
* Rev 1.2 08 Jul 1992 16:43:54 gfoster
* Added keyword "IMPLIED".
*
* Rev 1.1 19 Jun 1992 16:19:54 gfoster
* Copyright text was reformated.
*
* Added support for environment variable for include file
* directory.
*
* Made token types for all characters needed in parser.
*
* Added checks for badly formed "::=" and "..".
*
* Rev 1.0 27 May 1992 16:05:36 gfoster
* Initial revision.
*
*/
#include <stdio.h>
#ifdef MS_DOS
#include <stdlib.h>
#endif /* MS_DOS */
#include <string.h>
#include <ctype.h>
#include "tds.h"
#include "smscdefs.h"
#include "smstdefs.h"
#include "smsydefs.h"
#include "smic.h"
#include "smtoks.h"
USHORT usInclLevel; /* current level of include files */
FILE * afhIn[MXLV]; /* file handle stack */
PSZ apszInFile[MXLV]; /* file name stack */
USHORT ausLineNo[MXLV]; /* line number stack */
USHORT ausColNo[MXLV]; /* column position stack */
INT aLexChar[MXLV]; /* input char stack */
typedef struct _KeyWordName { /* keyword definition */
PSZ pszName; /* keyword name */
SHORT sType; /* value for parser */
USHORT usStatus; /* status (see KWSTxxxx) */
struct _KeyWordName *pHashNext; /* next in hash chain */
USHORT cUse; /* use count */
} KEYWORDNAME;
/* status of keyword */
#define KWSTdef 0x8000 /* flag that name is defined */
#define KWSTbase 0x0001 /* part of ASN.1 */
#define KWSTsmi 0x0002 /* defined in SMI */
#define KWSTot 0x0004 /* OBJECT-TYPE macro */
#define KWSTotm 0x0008 /* defined in OBJECT-TYPE macro */
#define KWSTtt 0x0010 /* TRAP-TYPE macro */
#define KWSTttm 0x0020 /* defined with TRAP-TYPE macro */
/* note: this table is updated by the program */
KEYWORDNAME keyWordName[] = {
{"ACCESS", kwACCESS, KWSTbase|KWSTdef, NULL},
{"BEGIN", kwBEGIN, KWSTbase|KWSTdef, NULL},
{"Counter", kwCOUNTER, KWSTsmi, NULL},
{"DEFINITIONS", kwDEFINITIONS, KWSTbase|KWSTdef, NULL},
{"DEFVAL", kwDEFVAL, KWSTotm, NULL},
{"DESCRIPTION", kwDESCRIPTION, KWSTotm|KWSTttm, NULL},
{"END", kwEND, KWSTbase|KWSTdef, NULL},
{"ENTERPRISE", kwENTERPRISE, KWSTttm, NULL},
{"FROM", kwFROM, KWSTbase|KWSTdef, NULL},
{"Gauge", kwGAUGE, KWSTsmi, NULL},
{"IDENTIFIER", kwIDENTIFIER, KWSTbase|KWSTdef, NULL},
{"IMPLIED", kwIMPLIED, KWSTotm, NULL},
{"IMPORTS", kwIMPORTS, KWSTbase|KWSTdef, NULL},
{"INDEX", kwINDEX, KWSTotm, NULL},
{"INTEGER", kwINTEGER, KWSTbase|KWSTdef, NULL},
{"IpAddress", kwIPADDRESS, KWSTsmi, NULL},
{"NOLENGTH", kwNOLENGTH, KWSTotm, NULL},
{"NULL", kwNULL, KWSTbase|KWSTdef, NULL},
{"NetworkAddress", kwNETWORKADDRESS,KWSTsmi, NULL},
{"OBJECT", kwOBJECT, KWSTbase|KWSTdef, NULL},
{"OBJECT-TYPE", kwOBJECT_TYPE, KWSTot, NULL},
{"OCTET", kwOCTET, KWSTbase|KWSTdef, NULL},
{"OF", kwOF, KWSTbase|KWSTdef, NULL},
{"Opaque", kwOPAQUE, KWSTsmi, NULL},
{"REFERENCE", kwREFERENCE, KWSTotm|KWSTttm, NULL},
{"SEQUENCE", kwSEQUENCE, KWSTbase|KWSTdef, NULL},
{"SIZE", kwSIZE, KWSTbase|KWSTdef, NULL},
{"SMI", kwSMI, KWSTbase|KWSTdef, NULL},
{"STATUS", kwSTATUS, KWSTotm, NULL},
{"STRING", kwSTRING, KWSTbase|KWSTdef, NULL},
{"SYNTAX", kwSYNTAX, KWSTotm, NULL},
{"TRAP-TYPE", kwTRAP_TYPE, KWSTtt, NULL},
{"TimeTicks", kwTIMETICKS, KWSTsmi, NULL},
{"VARIABLES", kwVARIABLES, KWSTttm, NULL},
{"deprecated", kwDEPRECATED, KWSTotm, NULL},
{"mandatory", kwMANDATORY, KWSTotm, NULL},
{"not-accessible", kwNOT_ACCESSIBLE,KWSTotm, NULL},
{"obsolete", kwOBSOLETE, KWSTotm, NULL},
{"optional", kwOPTIONAL, KWSTotm, NULL},
{"read-only", kwREAD_ONLY, KWSTotm, NULL},
{"read-write", kwREAD_WRITE, KWSTotm, NULL},
{"write-only", kwWRITE_ONLY, KWSTotm, NULL}
};
#define SZHASH 143 /* hash table size */
KEYWORDNAME *pHash[SZHASH];
/** isKWlistSorted - check to see that keyword list is sorted
*
* returns:
* TRUE - if sorted
* FALSE - if not sorted
*/
BOOL
#ifdef __STDC__
isKWlistSorted(VOID)
#else
isKWlistSorted()
#endif /* __STDC__ */
{
SHORT i;
SHORT iLast;
iLast = sizeof(keyWordName)/sizeof(KEYWORDNAME) - 1;
for (i = 0; i < iLast; i++) {
if (strcmp(keyWordName[i].pszName, keyWordName[i+1].pszName) >= 0) {
fprintf(fhMsg, "Keywords \"%s\" and \"%s\" are out of order\n",
keyWordName[i].pszName, keyWordName[i+1].pszName);
return(FALSE);
}
}
return(TRUE);
} /* isKWlistSorted */
/** hashKW - hash keyword value
*
* call with:
* pszName - name
*
* returns:
* hash value
*/
USHORT
#ifdef __STDC__
hashKW(PSZ pszName)
#else
hashKW(pszName)
PSZ pszName;
#endif /* __STDC__ */
{
register USHORT usVal;
for (usVal = 0; *pszName != 0; pszName++) {
usVal += (pszName[0] - ' ')<<((pszName[1]&0x0a)>>1);
}
return(usVal%SZHASH);
} /* hashKW */
/** bldKWhash - build hash table for keywords
*
*/
VOID
#ifdef __STDC__
bldKWhash(VOID)
#else
bldKWhash()
#endif /* __STDC__ */
{
INT i;
USHORT iHash;
for (i = sizeof(keyWordName)/sizeof(KEYWORDNAME) - 1; i >= 0; i--) {
iHash = hashKW(keyWordName[i].pszName);
keyWordName[i].pHashNext = pHash[iHash];
pHash[iHash] = &(keyWordName[i]);
}
} /* bldKWhash */
#define MXFREQ 10
/** freqKWhash - print frequences of keyword hash collisions
*
*/
VOID
#ifdef __STDC__
freqKWhash(VOID)
#else
freqKWhash()
#endif /* __STDC__ */
{
INT i;
USHORT iHash;
USHORT acFreq[MXFREQ];
KEYWORDNAME *pKWN;
for (i = 0; i < MXFREQ; i++) {
acFreq[i] = 0;
}
for (iHash = 0; iHash < SZHASH; iHash++) {
for (i = 0, pKWN = pHash[iHash]; (pKWN != NULL) && (i < (MXFREQ-1)); i++) {
pKWN = pKWN->pHashNext;
}
acFreq[i]++;
if (i > 1) {
fprintf(fhMsg, "Hash: %d, %d hits\n", iHash, i);
for (pKWN = pHash[iHash]; pKWN != NULL; pKWN = pKWN->pHashNext) {
fprintf(fhMsg, " \"%s\"\n", pKWN->pszName);
}
}
}
for (i = 0; i < MXFREQ; i++) {
if (acFreq[i] != 0)
fprintf(fhMsg, "%3d: %d\n", i, acFreq[i]);
}
} /* freqKWhash */
/** makeKWdef - make all keywords defined
*
*/
VOID
#ifdef __STDC__
makeKWdef(VOID)
#else
makeKWdef()
#endif /* __STDC__ */
{
register USHORT i;
for (i = 0; i < (sizeof(keyWordName)/sizeof(KEYWORDNAME)); i++) {
keyWordName[i].usStatus |= KWSTdef;
}
} /* makeKWdef */
/** makeKWundef - make all (other than "BASE") keywords undefined
* and set use counts to zero
*/
VOID
#ifdef __STDC__
makeKWundef(VOID)
#else
makeKWundef()
#endif /* __STDC__ */
{
register USHORT i;
for (i = 0; i < (sizeof(keyWordName)/sizeof(KEYWORDNAME)); i++) {
keyWordName[i].cUse = 0;
if (!(keyWordName[i].usStatus & KWSTbase))
keyWordName[i].usStatus &= ~KWSTdef;
}
} /* makeKWundef */
/** getKWindex - get index of keyword
*
* call with:
* pszName - name to lookup
* fDef - if true, return only defined or base names
*
* returns:
* index of keyword or
* -1 if name not a keyword
*/
SHORT
#ifdef __STDC__
getKWindex(PSZ pszName, BOOL fDef)
#else
getKWindex(pszName, fDef)
PSZ pszName;
BOOL fDef;
#endif /* __STDC__ */
{
register USHORT iHash;
register SHORT sCmp;
KEYWORDNAME *pKWN;
static KEYWORDNAME *pKWNbase = &keyWordName[0];
iHash = hashKW(pszName);
pKWN = pHash[iHash];
while (pKWN != NULL) { /* while hash chain not empty */
if ((sCmp = strcmp(pszName, pKWN->pszName)) == 0) {
/* name match */
if (fDef && !(pKWN->usStatus & KWSTdef))
return(-1); /* item not defined */
else {
pKWN->cUse++;
return(pKWN-pKWNbase);
}
}
if (sCmp < 0) /* item not in sorted chain */
break;
pKWN = pKWN->pHashNext;
}
return(-1);
} /* getKWindex */
/** addSMIitem - add SMI name to set of defined names
*
* call with:
* pszNa - ptr to name
*
* returns:
* TRUE - name added
* FALSE - name not SMI name
*
*/
BOOL
#ifdef __STDC__
addSMIitem(PSZ pszNa)
#else
addSMIitem(pszNa)
PSZ pszNa;
#endif /* __STDC__ */
{
register SHORT i;
register USHORT usStat;
/* lookup name to see if known */
if ((i = getKWindex(pszNa, FALSE)) == -1) {
/* name not known */
return(FALSE);
}
/* get status */
usStat = keyWordName[i].usStatus;
/* check if already defined */
if (usStat & KWSTdef) {
yyerror("\"%s\" is already defined", pszNa);
return(FALSE);
}
if (usStat & KWSTsmi) {
/* item defined in SMI */
keyWordName[i].usStatus |= KWSTdef; /* mark defined */
keyWordName[i].cUse = 0;
return(TRUE);
}
if (usStat & KWSTot) {
/* OBJECT-TYPE macro - define it and all contained items */
keyWordName[i].usStatus |= KWSTdef;
keyWordName[i].cUse = 0;
for (i = 0; i < sizeof(keyWordName)/sizeof(KEYWORDNAME); i++) {
if (keyWordName[i].usStatus & KWSTotm)
keyWordName[i].usStatus |= KWSTdef;
}
return(TRUE);
}
if (usStat & KWSTtt) {
/* TRAP-TYPE macro - define it and all contained items */
keyWordName[i].usStatus |= KWSTdef;
keyWordName[i].cUse = 0;
for (i = 0; i < sizeof(keyWordName)/sizeof(KEYWORDNAME); i++) {
if (keyWordName[i].usStatus & KWSTttm)
keyWordName[i].usStatus |= KWSTdef;
}
return(TRUE);
}
if (usStat & KWSTotm) {
yyerror("\"%s\" is defined in OBJECT-TYPE macro");
return(FALSE);
}
if (usStat & KWSTttm) {
yyerror("\"%s\" is defined in TRAP-TYPE macro");
return(FALSE);
}
yyerror("INTERNAL ERROR in addSMIitem");
return(FALSE);
} /* addSMIitem */
/** checkSMIname - check to see if name is SMI item name
* (or TRAP-TYPE or OBJECT-TYPE)
*
* call with:
* pszNa - ptr to name
* pusIndx - addr to store index
*
* returns:
* name status (see SMISTxxx)
*/
USHORT
#ifdef __STDC__
checkSMIname(PSZ pszNa, USHORT *pusIndx)
#else
checkSMIname(pszNa, pusIndx)
PSZ pszNa;
USHORT *pusIndx;
#endif /* __STDC__ */
{
register SHORT i;
register USHORT usStat;
/* lookup name to see if known */
if ((i = getKWindex(pszNa, FALSE)) == -1) {
/* name not known */
return(SMISTnsmi);
}
/* get status */
usStat = keyWordName[i].usStatus;
/* check if SMI item or OBJECT-TYPE or TYPE-TYPE */
if ((usStat & (KWSTsmi | KWSTot | KWSTtt)) == 0) {
/* item not defined in SMI */
return(SMISTnsmi);
}
/* check if already defined */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -