windows-nt/Source/XPSP1/NT/ds/security/asn1/asn1c/hackdir.c
2020-09-26 16:20:57 +08:00

422 lines
11 KiB
C

/* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */
/* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */
#include "precomp.h"
#include "hackdir.h"
#ifdef MS_DIRECTIVE
int g_fPrivateDir_FieldNameToken = 0;
int g_fPrivateDir_TypeNameToken = 0;
int g_fPrivateDir_ValueNameToken = 0;
int g_fPrivateDir_SLinked = 0;
int g_fPrivateDir_DLinked = 0;
int g_fPrivateDir_Public = 0;
int g_fPrivateDir_Intx = 0;
int g_fPrivateDir_LenPtr = 0;
int g_fPrivateDir_Pointer = 0;
int g_fPrivateDir_Array = 0;
int g_fPrivateDir_NoCode = 0;
int g_fPrivateDir_NoMemCopy = 0;
int g_fPrivateDir_OidPacked = 0;
int g_fPrivateDir_OidArray = 0;
char g_szPrivateDirectedFieldName[64];
char g_szPrivateDirectedTypeName[64];
char g_szPrivateDirectedValueName[64];
int My_toupper ( int ch )
{
if ('a' <= ch && ch <= 'z')
{
ch = (ch - 'a' + 'A');
}
return ch;
}
int PrivateDirectives_MatchSymbol ( int *p, char *psz )
{
int c = *p;
int fMatched = 1;
while (*psz != '\0')
{
if (My_toupper(c) != *psz++)
{
fMatched = 0;
break;
}
c = PrivateDirectives_Input();
}
*p = c;
return fMatched;
}
void PrivateDirectives_SkipSpace ( int *p )
{
int c = *p;
while (isspace(c))
{
c = PrivateDirectives_Input();
}
*p = c;
}
void PrivateDirectives_GetSymbol ( int *p, char *psz )
{
int c = *p;
while (c == '_' || isalnum(c))
{
*psz++ = (char)c;
c = PrivateDirectives_Input();
}
*psz = '\0';
*p = c;
}
void PrivateDirectives_IgnoreSymbol ( int *p )
{
int c = *p;
while (c == '_' || isalnum(c))
{
c = PrivateDirectives_Input();
}
*p = c;
}
void GetMicrosoftDirective ( int *p )
{
int c = *p;
// loop through to get all directives
while (c != g_chDirectiveEnd)
{
if (c == g_chDirectiveAND)
{
c = PrivateDirectives_Input();
PrivateDirectives_SkipSpace(&c);
}
switch (My_toupper(c))
{
case 'A': // possible ARRAY
if (PrivateDirectives_MatchSymbol(&c, "ARRAY"))
{
g_fPrivateDir_Array = 1;
}
break;
case 'D': // possible DLINKED
if (PrivateDirectives_MatchSymbol(&c, "DLINKED"))
{
g_fPrivateDir_DLinked = 1;
}
break;
case 'F': // possible FNAME
if (PrivateDirectives_MatchSymbol(&c, "FIELD"))
{
// c should be a space now
PrivateDirectives_SkipSpace(&c);
// c should be a double quote now
if (c == '"')
{
c = PrivateDirectives_Input();
}
// c should be the first char of name
PrivateDirectives_GetSymbol(&c, &g_szPrivateDirectedFieldName[0]);
g_fPrivateDir_FieldNameToken = 0;
}
break;
case 'I': // possible INTX
if (PrivateDirectives_MatchSymbol(&c, "INTX"))
{
g_fPrivateDir_Intx = 1;
}
break;
case 'L': // possible LENPTR
if (PrivateDirectives_MatchSymbol(&c, "LENPTR"))
{
g_fPrivateDir_LenPtr = 1;
}
break;
case 'N': // possible NO MEMCPY (or NOMEMCPY) or NO CODE (or NOCODE)
if (PrivateDirectives_MatchSymbol(&c, "NO"))
{
// skip over possible spaces
PrivateDirectives_SkipSpace(&c);
switch (My_toupper(c))
{
case 'C':
if (PrivateDirectives_MatchSymbol(&c, "CODE")) // CODE
{
g_fPrivateDir_NoCode = 1;
}
break;
case 'M':
if (PrivateDirectives_MatchSymbol(&c, "MEMCPY")) // MEMCPY
{
g_fPrivateDir_NoMemCopy = 1;
}
break;
}
}
break;
case 'O': // possible OID ARRAY (or OIDARRAY) or OID PACKED (or OIDPACKED)
if (PrivateDirectives_MatchSymbol(&c, "OID"))
{
// skip over possible spaces
PrivateDirectives_SkipSpace(&c);
switch (My_toupper(c))
{
case 'A':
if (PrivateDirectives_MatchSymbol(&c, "ARRAY")) // ARRAY
{
g_fPrivateDir_OidArray = 1;
}
break;
case 'P':
if (PrivateDirectives_MatchSymbol(&c, "PACKED")) // PACKED
{
g_fPrivateDir_OidPacked = 1;
}
break;
}
}
break;
case 'P': // possible POINTER or PUBLIC
c = PrivateDirectives_Input();
switch (My_toupper(c))
{
case 'O':
if (PrivateDirectives_MatchSymbol(&c, "OINTER")) // POINTER
{
g_fPrivateDir_Pointer = 1;
}
break;
case 'U':
if (PrivateDirectives_MatchSymbol(&c, "UBLIC")) // PUBLIC
{
g_fPrivateDir_Public = 1;
}
break;
}
break;
case 'S': // possible SLINKED
if (PrivateDirectives_MatchSymbol(&c, "SLINKED"))
{
g_fPrivateDir_SLinked = 1;
}
break;
case 'T': // possible TNAME
if (PrivateDirectives_MatchSymbol(&c, "TYPE"))
{
// c should be a space now
PrivateDirectives_SkipSpace(&c);
// c should be a double quote now
if (c == '"')
{
c = PrivateDirectives_Input();
}
// c should be the first char of name
PrivateDirectives_GetSymbol(&c, &g_szPrivateDirectedTypeName[0]);
g_fPrivateDir_TypeNameToken = 0;
}
break;
case 'V': // possible VNAME
if (PrivateDirectives_MatchSymbol(&c, "VALUE"))
{
// c should be a space now
PrivateDirectives_SkipSpace(&c);
// c should be a double quote now
if (c == '"')
{
c = PrivateDirectives_Input();
}
// c should be the first char of name
PrivateDirectives_GetSymbol(&c, &g_szPrivateDirectedValueName[0]);
g_fPrivateDir_ValueNameToken = 0;
}
break;
default:
goto MyExit;
}
// determine if we should stay in the loop
// skip over the ending double quote
if (c == '"')
{
c = PrivateDirectives_Input();
}
// skip over unknown directives
PrivateDirectives_IgnoreSymbol(&c);
// skip over possible spaces
PrivateDirectives_SkipSpace(&c);
}
// now, c is >. we need to advance to --
c = PrivateDirectives_Input();
// now, c should be -
MyExit:
// return the current character
*p = c;
}
void GetPrivateDirective ( int *p )
{
GetMicrosoftDirective(p);
}
typedef struct Verbatim_s
{
struct Verbatim_s *next;
char pszVerbatim[1];
}
Verbatim_t;
Verbatim_t *g_VerbatimList = NULL;
void RememberVerbatim(char *pszVerbatim)
{
int cb = strlen(pszVerbatim) + 1;
Verbatim_t *p = (Verbatim_t *) malloc(sizeof(Verbatim_t) + cb);
if (p)
{
memcpy(p->pszVerbatim, pszVerbatim, cb);
p->next = NULL;
if (g_VerbatimList)
{
Verbatim_t *q;
for (q = g_VerbatimList; q->next; q = q->next)
;
q->next = p;
}
else
{
g_VerbatimList = p;
}
}
}
void PrintVerbatim(void)
{
Verbatim_t *p;
for (p = g_VerbatimList; p; p = p->next)
{
output("/* %s */\n", p->pszVerbatim);
}
if (g_VerbatimList)
{
output("\n");
}
}
int CompareDirective(char *pszDirective, char *pszInput)
{
int rc;
int len = strlen(pszDirective);
char ch = pszInput[len];
pszInput[len] = '\0';
rc = strcmpi(pszDirective, pszInput);
pszInput[len] = ch;
return rc;
}
void SetDirective(char *pszInput)
{
// verbatim strings
const char szComment[] = "COMMENT";
if (! CompareDirective((char *) &szComment[0], pszInput))
{
pszInput += sizeof(szComment) - 1;
if (isspace(*pszInput))
{
pszInput++;
if ('"' == *pszInput++)
{
char *pszEnd = strchr(pszInput, '"');
if (pszEnd)
{
*pszEnd = '\0';
RememberVerbatim(pszInput);
*pszEnd = '"';
}
}
}
return;
}
// object identifier
if (! CompareDirective("OID ARRAY", pszInput))
{
g_fOidArray = 1;
return;
}
// set of/sequence of w/o size constraint
if (! CompareDirective("SS.basic SLINKED", pszInput))
{
g_eDefTypeRuleSS_NonSized = eTypeRules_SinglyLinkedList;
return;
}
if (! CompareDirective("SS.basic DLINKED", pszInput))
{
g_eDefTypeRuleSS_NonSized = eTypeRules_DoublyLinkedList;
return;
}
if (! CompareDirective("SS.basic LENPTR", pszInput))
{
g_eDefTypeRuleSS_NonSized = eTypeRules_LengthPointer;
return;
}
if (! CompareDirective("SS.basic ARRAY", pszInput))
{
g_eDefTypeRuleSS_NonSized = eTypeRules_FixedArray;
return;
}
// set of/sequence of w/ size constraint
if (! CompareDirective("SS.sized SLINKED", pszInput))
{
g_eDefTypeRuleSS_Sized = eTypeRules_SinglyLinkedList;
return;
}
if (! CompareDirective("SS.sized DLINKED", pszInput))
{
g_eDefTypeRuleSS_Sized = eTypeRules_DoublyLinkedList;
return;
}
if (! CompareDirective("SS.sized LENPTR", pszInput))
{
g_eDefTypeRuleSS_Sized = eTypeRules_LengthPointer;
return;
}
if (! CompareDirective("SS.sized ARRAY", pszInput))
{
g_eDefTypeRuleSS_Sized = eTypeRules_FixedArray;
return;
}
// set extra pointer type for SS construct, its struct name will be postfixed with _s
if (! CompareDirective("SS.struct EXTRA-PTR-TYPE", pszInput))
{
g_fExtraStructPtrTypeSS = 1;
return;
}
}
#endif // MS_DIRECTIVE