/*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:; } }
/*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; }