Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

167 lines
5.1 KiB

THE IMPORT FILE HANDLER
-----------------------
The import statement permits a user to import types from
another interface file. The behavior thus is like a
pre-processor include statement in C, but semantically, the
compiler needs to process it different from just a textual
include. These aspects have to be kept in mind:
A) The import file handler must have support for the
following:
1. Multiple (nested) inclusions of import files
2. Mulitple (non-nested) inclusions of import files
In other words, the following statement must result in import
of foo2 and foo3 assuming that we are compiling foo1.idl
IMPORT "foo2" (in foo1.idl)
where foo2 has an import statement saying:
IMPORT "foo3" (in foo2.idl)
Also, a similar case must occur when the following statement appears
in foo1.idl
IMPORT "foo2" , "foo3" (in foo1.idl)
B) NIDL does not specify the number of nested import files that
the user can have. This is implementation dependent. The physical
behaviour being similar to a textual include (maybe nested) the
problem lies in the number of open import files that the system lets
the compiler keep open. Under DOS this limit can be as low as 15.
Since only one include file need be kept open at a time, the compiler
needs to manage closing of the import files, re-opening and so on.
C) The parser or lexer may need to know the line and column position
within the file to be able to report errors as close to their occurence
as possible, as also know which import file they occured in.
THE IMPORT FILE STATUS STACK
----------------------------
The import file status stack is the mechanism by which the import file
is handled. The import file handler presents a black-box like interface
to the lexer and parser.
Internally each import file stack element looks like this :
typedef struct _import_stack
{
FILE *hFile;
unsigned long ulPos;
unsigned short uLine; -| these two may be discarded
unsigned short uCol; _| if not needed
char *pName;
unsigned short uFlags;
}IMPORT_STACK;
hFile: This is the handle to the import file. This info
is current only till the file is open
ulPos: The position in the file. In case the import file
handler needs to close a file to reuse a file handle
this is the position to come back to.
uLine: The current line and column number. The error handler
may need to know the position in terms of the line
and column, to report an error. This provides the
means.
uCol: The column number for error reporting
pName: Filename to open the file with.
uFlags: Currently the only use of this is for the purpose
of identifying if the file is closed or open . If
it is closed , it needs to be opened and set to
ulPos. This is useful for occasions where deep nesting
of imports results in running out of file handles and
some may need to be closed to be re-opened later.
The stack is thus defined as:
IMPORT_STACK ImportStack[ MAX_NESTED_IMPORTS ];
In addition we need to keep track of the current import nesting level
in a variable static to the import file handler module.
More detailed interfaces are yet to be decided. Currenlty the interface
looks like:
void SetImportFile( char *pName );
To set the import file to the file whose
name is specified. The current file is
closed.
void PushImportLevel()
As a result of nested import statement, this
level of import is incremented. This is
followed by a SetImportFile call.
void PopImportLevel()
End of current import file seen. Restore
import level to previous, continue input
from the last import file,if that is not
open, open it.
unsigned short GetImportLevel()
Return the current import level. This may
be needed for housekeeping purposes or error
reporting
char *pszGetCurrentImportFName()
Return the name of the file from which the
import is in progress. May be needed for
housekeeping or error reporting.
To explain how the parser interfaces with the import file manager
here is a small grammar fragment dealing with imports and its
relevant semantic actions: (This is only representative of the
way the parser deals with the import scheme. The actual imp-
lemenation may be different. It also does not show all aspects
of the interface e.g the error reporting ).
RpcImports :
{
/***
*** No import file was seen, do nothing here
***/
}
| IMPORT
{
/***
*** PushImportLevel(); /* import prologue */
***/
}
ImportList
{
/***
*** PopImportLevel(); /* import epilogue */
***/
}
;
ImportList : ImportList ',' OneImport
{
/***
*** No action here. Action for any import is taken
*** only at the OneImport production
***/
}
| OneImport
{
/***
*** No action here. Action for any import is taken
*** only at the OneImport production
***/
}
;
OneImport : STRING RPCProg
{
/***
*** SetImportFile( $1.ptr); /* assuming $1 returns a
*** pointer to string */
***/
}
;