示例#1
0
/*FUNCTION*/
void reader_ProcessIncludeFiles(pReadObject pRo,
                                pSourceLine *pLine
  ){
/*noverbatim

The file read is inserted into the plce where the include statement was.

CUT*/
#define FNLEN 1024
  pSourceLine p;
  char *s,*file_name;
  CFT_NODE Node;
  char szBuffer[FNLEN];
  void *fp;
  int isImport; /* true if the statement is import and not include */
  pImportedFileList pIFL;
  long IncludeCounter;

  IncludeCounter = 1000;
  cft_GetEx(pRo->pConfig,"maxinclude",&Node,&s,&IncludeCounter,NULL,NULL); 
  p = *pLine;
  while( p ){
    s = p->line;
    while( isspace(*s) )s++;
    if( (((!strnicmp(s,"include",7)) && (s+=7) && !(isImport=0) ) ||
        ((!strnicmp(s,"import" ,6)) && (s+=6) &&  (isImport=1) )) &&
        /* there should be at least one space after the keyword */
        isspace(*s) ){
      if( --IncludeCounter == 0 ){
        REPORT(p->szFileName ,p->lLineNumber ,READER_ERROR_TOOMANY_INCLUDE,NULL);
        return;
        }
      while( isspace(*s) )s++;
      if( *s == '"' ){
        /* include user files relative to the current source file */
        s++;
        file_name = s; /* start of the file name */
        while( *s && *s != '"' )s++; /* find the end of the file name */
        if( *s != '"' ){
          REPORT(p->szFileName ,p->lLineNumber ,READER_ERROR_INCLUDE_SYNTAX,NULL);
          p = p->next;
          continue;
          }
        *s = (char)0;
        s++;
        while( isspace(*s) )s++;
        if( *s && *s != '\n' ){
          REPORT(p->szFileName ,p->lLineNumber ,READER_ERROR_INCLUDE_SYNTAX,NULL);
          p = p->next;
          continue;
          }
        file_name = reader_RelateFile(pRo,p->szFileName,file_name);
        /* here we have to modify the file name to handle the ../ and other constructs to be
           relative to the actual file */
        }else{
        /* include installed standard file at standard location */
        file_name = s;
        while( *s && ! isspace(*s) )s++; /* find the end of the file name */
        if( *s ){
          *s = (char)0;
          s++;
          }else *s = (char)0;
        while( isspace(*s) )s++;
        if( *s && *s != '\n' ){
          REPORT(p->szFileName ,p->lLineNumber ,READER_ERROR_INCLUDE_SYNTAX,NULL);
          p = p->next;
          continue;
          }

        if( GlobalDebugDisplayFlag ){
          fprintf(stderr,"Searching installed module header file '%s' ...\n",file_name);
          }
        /* here we try to iterate all the configuration defines include directories and
           try if there is an openable file in one of the. If there is the first is
           used */
        fp = NULL;
        for( cft_GetEx(pRo->pConfig,"include",&Node,&s,NULL,NULL,NULL);  
             ! cft_GetEx(pRo->pConfig,NULL,&Node,&s,NULL,NULL,NULL) ; 
             Node = cft_EnumNext(pRo->pConfig,Node) ){
          if( ! strcmp(cft_GetKey(pRo->pConfig,Node),"include") ){
            if( s && strlen(s) > FNLEN )REPORT(p->szFileName ,p->lLineNumber ,READER_ERROR_INCLUDE_SYNTAX,NULL);
            if( s )strcpy(szBuffer,s); else *szBuffer = (char)0;
            strcat(szBuffer,file_name);
            fp = pRo->fpOpenFile(szBuffer,pRo->pFileHandleClass);  /* open a file for reading (just for test: can we?) */
            if( GlobalDebugDisplayFlag ){
              fprintf(stderr,"Checking installed module header file location '%s' Result=%s\n",szBuffer, fp ? "OK" : "FAILED" );
              }
            if( fp != NULL )break;
            }
          }

        if( fp == NULL ){/* if there was no file openable during the search */
          REPORT(p->szFileName ,p->lLineNumber ,READER_ERROR_INCLUDE_FILE,NULL);
          goto NotInclude;
          }
        pRo->fpCloseFile(fp,pRo->pFileHandleClass);/* close the file because it was opened */
        file_name = pRo->memory_allocating_function(strlen(szBuffer)+1,pRo->pMemorySegment);
        if( file_name == NULL )REPORT(p->szFileName ,p->lLineNumber ,READER_ERROR_MEMORY_LOW,NULL);
        strcpy(file_name,szBuffer);
        }
      /* file_name now points to a file openable by fpOpenFile */
      if( isImport ){
        /* check that this file was not included yet. */
        pIFL = pRo->pImportList;
        while( pIFL ){
          if( ! strcmp(file_name,pIFL->pszFileName) ){
            *pLine = (*pLine)->next; /* unlink the line including the import statement */
            p = *pLine;
            goto NextP;
            }
          pIFL = pIFL->next;
          }
        }
      /* if it is not import or if the file was not included yet then put the name of the file
         on the included file list. This puts an included file on this list as many times as
         it is included, but it does not matter. */
      pIFL = pRo->memory_allocating_function(sizeof(ImportedFileList),pRo->pMemorySegment);
      if( pIFL == NULL )REPORT(p->szFileName ,p->lLineNumber ,READER_ERROR_MEMORY_LOW,NULL);
      pIFL->next = pRo->pImportList;
      pIFL->pszFileName = file_name;
      pRo->pImportList = pIFL;
      *pLine = (*pLine)->next; /* unlink the line containing the 'include' statement */
      if( GlobalDebugDisplayFlag ){
        fprintf(stderr,"Including file '%s'\n",file_name);
        }
      reader_ReadLines_r(pRo,file_name,pLine);
      /* release the line containing the include statement */
      pRo->memory_releasing_function(p->line,pRo->pMemorySegment);
      pRo->memory_releasing_function(p,pRo->pMemorySegment);
      /* file_name is not released, because that buffer is
         referenced several times. That buffer is released when the
         whole reader segment is released. */
      p = *pLine;
      }else
NotInclude:
    if( p ){
      pLine = &(p->next);
      p = *pLine;
      }
NextP:;
    }
  }
示例#2
0
/*FUNCTION*/
int ipreproc_LoadInternalPreprocessor(pPreprocObject pPre,
                                      char *pszPreprocessorName
  ){
/*noverbatim
The first argument is the pointer to the ScriptBasic preprocessor object to access the
configuration information and the list of loaded preprocessors to put the actual one
on the list.

The second argument is the name of the preprocessor as named in the configuration file, for example

=verbatim
preproc (
  internal (
    sample "C:\\ScriptBasic\\bin\\samplepreprocessor.dll"
    )
=noverbatim

The return value is zero or the error code.

CUT*/
#define FNLEN 1024
  char szBuffer[FNLEN];
  char *s;
  void *pDllHandle = NULL,*pFunction=NULL;
  int (*preproc)(void *,long *,void *);
  pSbProgram pProgram;
  int iError;
  pPreprocessor pThisPre;
  long lCommand;
  int bFirst;
#define PREFLEN 17
  char *pszDllExtension;
  unsigned int cbDllExtension;
  CFT_NODE Node;

  pProgram = pPre->pSB;

  pszDllExtension = cft_GetString(pProgram->pCONF,"dll");
  if( pszDllExtension == NULL ){
#ifdef WIN32
    pszDllExtension = ".dll";
#elif defined(__DARWIN__)
    pszDllExtension = ".dylib";
#elif defined(__MACOS__)
    pszDllExtension = "";
#else
    pszDllExtension = ".so";
#endif
    }
  cbDllExtension = strlen(pszDllExtension);

  /* check that the preprocessor was not loaded yet */
  for( pThisPre = pPre->pFirst ; pThisPre ; pThisPre = pThisPre->next )
    if( !strcmp(pThisPre->pszPreprocessorName,pszPreprocessorName) )return COMMAND_ERROR_SUCCESS;

  strcpy(szBuffer,"preproc.internal.");
  if( strlen(pszPreprocessorName) > FNLEN - PREFLEN )return READER_ERROR_PREPROC_LONG;
  strcpy(szBuffer+PREFLEN,pszPreprocessorName);
  s = szBuffer+PREFLEN;
  while( *s && ! isspace(*s) )s++; /* chop off optional parameters and/or NL from the end of line */
  *s = (char)0;
  s = cft_GetString(pProgram->pCONF,szBuffer);
  /* if the internal preprocessor was not configured then it still can be used if the DLL or SO file
     is copied into the modules library. */
  if( NULL == s ){
      if( ! cft_GetEx(pProgram->pCONF,"module",&Node,&s,NULL,NULL,NULL) ){
        while( 1 ){
          if( cft_GetEx(pProgram->pCONF,NULL,&Node,&s,NULL,NULL,NULL) ){
            /* if there are no more directories in the configuration */
            break;
            }
          if( ! strcmp(cft_GetKey(pProgram->pCONF,Node),"module") ){
            if( strlen(s) + strlen(pszPreprocessorName) > FNLEN )return READER_ERROR_PREPROC_LONG;
            strcpy(szBuffer,s);
            strcat(szBuffer,pszPreprocessorName);
            if( strlen(szBuffer) + cbDllExtension > FNLEN )return READER_ERROR_PREPROC_LONG;
            strcat(szBuffer,pszDllExtension);
            pDllHandle = dynlolib_LoadLibrary( szBuffer );
            if( pDllHandle != NULL )break;
            }
          Node = cft_EnumNext(pProgram->pCONF,Node);
          }
        }
    }else{
    /* if the preprocessor was configured in the config file
       not only copied into one of the module directories */
    pDllHandle = dynlolib_LoadLibrary(s);
    }
  if( pDllHandle == NULL )return READER_ERROR_PREPROC_NOTAVA;

  pFunction = dynlolib_GetFunctionByName(pDllHandle,"preproc");
  if( pFunction == NULL )return READER_ERROR_PREPROC_NOTVAL;

  bFirst = (pPre->pFirst == NULL);
  pThisPre = ipreproc_InsertPreprocessor(pPre);
  if( pThisPre == NULL  )return COMMAND_ERROR_MEMORY_LOW;
  pThisPre->pszPreprocessorName = alloc_Alloc(strlen(pszPreprocessorName)+1,pPre->pMemorySegment);
  if( pThisPre->pszPreprocessorName == NULL )return COMMAND_ERROR_MEMORY_LOW;

  strcpy(pThisPre->pszPreprocessorName,pszPreprocessorName);
  pThisPre->pDllHandle = pDllHandle;
  pThisPre->pFunction = pFunction;
  pThisPre->pEXT.lVersion = IP_INTERFACE_VERSION;
  pThisPre->pEXT.pPointer = NULL;
  pThisPre->pEXT.pMemorySegment = alloc_InitSegment(pPre->pSB->maf,pPre->pSB->mrf);
  if( pThisPre->pEXT.pMemorySegment == NULL )return COMMAND_ERROR_MEMORY_LOW;

  /* if this is the first preprocessor loaded then init
     the support function table*/
  if( bFirst ){
    pPre->EXE.pMemorySegment = pPre->pMemorySegment;
    modu_Init(&(pPre->EXE),0);
    pPre->EXE.pST->pEo = &(pPre->EXE);
    pThisPre->pEXT.pST = pPre->EXE.pST;
    }

  preproc = pFunction;
  lCommand = PreprocessorLoad;
  iError = preproc(&(pThisPre->pEXT),&lCommand,NULL);
  if( lCommand == PreprocessorUnload ){
    /* unload the current preprocessor */
    pDllHandle = pThisPre->pDllHandle;
    ipreproc_DeletePreprocessor(pPre,pThisPre);
    /* this may happen if the preprocessor is statically linked */
    if( pDllHandle )
      dynlolib_FreeLibrary(pDllHandle);
    }
  return iError;
  }