<commit_before>/* /% C %/ */
/***********************************************************************
 * cint (C/C++ interpreter)
 ************************************************************************
 * Source file loadfile.c
 ************************************************************************
 * Description:
 *  Loading source file
 ************************************************************************
 * Copyright(c) 1995~2005  <NAME>
 *
 * For the licensing terms see the file COPYING
 *
 ************************************************************************/

/* Define one of following */
#define G__OLDIMPLEMENTATION1922 /* keep opening all header files for +V +P */

#include <string>
#include <list>

#ifdef _WIN32
#include "process.h"
#endif

#if defined(G__ROOT)
#include "RConfigure.h"
#endif

#if defined(G__HAVE_CONFIG)
#include "configcint.h"
#endif

#include "common.h"
#include "Api.h"
#include "FastAllocString.h"

#ifndef G__TESTMAIN
#include <sys/stat.h>
#endif

#ifdef G__WIN32
#include <windows.h>
#endif

#define G__OLDIMPLEMENTATION1849

#ifdef G__SHAREDLIB
extern std::list<G__DLLINIT>* G__initpermanentsl;
#endif

extern "C" {

/******************************************************************
* Define G__EDU_VERSION for CINT C++ educational version.
* If G__EDU_VERSION is defined, CINT will search ./include and
* ./stl directory for standard header files.
******************************************************************/
/* #define G__EDU_VERSION */

static G__IgnoreInclude G__ignoreinclude = (G__IgnoreInclude)NULL;

/******************************************************************
* G__set_ignoreinclude
******************************************************************/
void G__set_ignoreinclude(G__IgnoreInclude ignoreinclude)
{
  G__ignoreinclude = ignoreinclude;
}

static int G__kindofheader = G__USERHEADER;

static int G__copyflag = 0;

int (*G__ScriptCompiler) G__P((G__CONST char*,G__CONST char*)) = 0;

/******************************************************************
* G__RegisterScriptCompiler()
******************************************************************/
void G__RegisterScriptCompiler(int(*p2f) G__P((G__CONST char*,G__CONST char*)))
{
  G__ScriptCompiler = p2f;
}

/******************************************************************
* G__copytotmpfile()
******************************************************************/
static FILE* G__copytotmpfile(char *prepname)
{
  FILE *ifp;
  FILE *ofp;
  ifp = fopen(prepname,"rb");
  if(!ifp) {
    G__genericerror("Internal error: G__copytotmpfile() 1\n");
    return((FILE*)NULL);
  }
  ofp = fopen(G__tmpnam(0),"w+b");
  if(!ofp) {
    G__genericerror("Internal error: G__copytotmpfile() 2\n");
    fclose(ifp);
    return((FILE*)NULL);
  }
  G__copyfile(ofp,ifp);
  fclose(ifp);
  fseek(ofp,0L,SEEK_SET);
  return(ofp);
}

/******************************************************************
* G__copysourcetotmp()
******************************************************************/
static void G__copysourcetotmp(char *prepname,G__input_file *pifile, int fentry)
{
  if(G__copyflag && 0==prepname[0]) {
    FILE *fpout;
    fpout = fopen(G__tmpnam(0),"w+b");
    if(!fpout) {
      G__genericerror("Internal error: can not open tmpfile.");
      return;
    }
    /*strcpy(prepname,"(tmpfile)");*/
    sprintf(prepname,"(tmp%d)",fentry);
    G__copyfile(fpout,pifile->fp);
    fseek(fpout,0L,SEEK_SET);
    G__srcfile[fentry].prepname = (char*)malloc(strlen(prepname)+1);
    strcpy(G__srcfile[fentry].prepname,prepname);
    G__srcfile[fentry].fp = fpout;
    fclose(pifile->fp);
    pifile->fp = fpout;
  }
}

/**************************************************************************
* G__setcopyflag()
**************************************************************************/
void G__setcopyflag(int flag)
{
  G__copyflag = flag;
}

/******************************************************************
* G__ispreprocessfilekey
******************************************************************/
static int G__ispreprocessfilekey(char *filename)
{
  struct G__Preprocessfilekey *pkey;
  /* char *p; */

  pkey = &G__preprocessfilekey;

  /* check match of the keystring */
  while(pkey->next) {
    if(pkey->keystring && strstr(filename,pkey->keystring)) {
       return(1);
    }
    pkey=pkey->next;
  }

  /* No match */
  return(0);
}

/******************************************************************
* G__include_file()
*
* Keyword '#include' is read in G__exec_statement();
* G__include_file() read include filename, and load it.
*
*   #include   <stdio.h>    \n
*            ^---------------^       do nothing
*
*   #include  comment   "header.h" comment   \n
*            ^--------------------------------^    load "header.h"
*
******************************************************************/
int G__include_file()
{
  int result;
  int c;
  G__FastAllocString filename(G__MAXFILENAME);
  int i=0;
  int storeit=0;
  /* char sysinclude[G__MAXFILENAME]; */
  int store_cpp;
  int store_globalcomp;
  int expandflag=0;
  static int G__gcomplevel=0;

  while((c=G__fgetc())!='\n' && c!='\r'
        && c!='#'&& c!=-1
        ) {
    switch(c) {
    case '<':
      if(storeit==0) storeit=1;
      break;
    case '>':
      storeit = -1;
      G__kindofheader=G__SYSHEADER;
      break;
    case '\"':
      switch(storeit) {
      case 0:
        storeit=1;
        break;
      case 1:
        storeit = -1;
        G__kindofheader=G__USERHEADER;
        break;
      }
      break;
    default:
      if(!isspace(c)) {
        if(1==storeit) {
          filename.Set(i++, c);
          filename.Set(i, 0);
        }
        else if(-1!=storeit) {
          storeit=1;
          expandflag=1;
          filename.Set(i++, c);
          filename.Set(i, 0);
        }
      }
      else if(expandflag) {
        storeit = -1;
      }
      break;
    }
  }

  if(expandflag) {
    /* Following stupid code is written to avoid HP-UX CC -O bug */
    struct G__var_array *var;
    int ig15;
    int hash;
    G__hash(filename,hash,ig15);
    var = G__getvarentry(filename,hash,&ig15,&G__global,G__p_local);
    if(var) {
      filename = *(char**)var->p[ig15];
      G__kindofheader=G__USERHEADER;
    }
    else {
       G__fprinterr(G__serr,"Error: cannot expand #include %s",filename());
      G__genericerror(NULL);
      if('#'==c) G__fignoreline();
      return(G__LOADFILE_FAILURE);
    }
  }

  store_cpp=G__cpp;
  G__cpp=G__include_cpp;

  if(G__USERHEADER==G__kindofheader) {
    store_globalcomp = G__globalcomp;
    if(++G__gcomplevel>=G__gcomplevellimit) G__globalcomp=G__NOLINK;
    result = G__loadfile(filename);
    --G__gcomplevel;
    G__globalcomp=store_globalcomp;
  }
  else {
    /* <xxx.h> , 'xxx.h' */
    store_globalcomp=G__globalcomp;
    /* G__globalcomp=G__NOLINK; */
    if(++G__gcomplevel>=G__gcomplevellimit) G__globalcomp=G__NOLINK;
    result = G__loadfile(filename);
    --G__gcomplevel;
    G__globalcomp=store_globalcomp;
  }
  G__kindofheader = G__USERHEADER;

  G__cpp=store_cpp;

  if('#'==c) {
    if(G__LOADFILE_FAILURE==result && G__ispragmainclude) {
      G__ispragmainclude=0;
      c = G__fgetname(filename, 0, "\n\r");
      store_globalcomp = G__globalcomp;
      if(++G__gcomplevel>=G__gcomplevellimit) G__globalcomp=G__NOLINK;
      if('\n'!=c && '\r'!=c) result = G__include_file();
      --G__gcomplevel;
      G__globalcomp=store_globalcomp;
    }
    else {
      G__fignoreline();
    }
  }

  return(result);
}

/******************************************************************
* G__getmakeinfo()
*
******************************************************************/
const char *G__getmakeinfo(const char *item)
{
  G__FastAllocString makeinfo(G__MAXFILENAME);
  FILE *fp;
  G__FastAllocString line(G__LARGEBUF);
  G__FastAllocString argbuf(G__LARGEBUF);
  char *arg[G__MAXARG];
  int argn;
  char *p;
  static G__FastAllocString buf(G__ONELINE);

  buf[0]='\0';

#ifdef G__HAVE_CONFIG
  if (!strcmp(item,"CPP")) return G__CFG_CXX;
  else if (!strcmp(item,"CC")) return G__CFG_CC;
  else if (!strcmp(item,"DLLPOST")) return G__CFG_SOEXT;
  else if (!strcmp(item,"CSRCPOST")) return ".c";
  else if (!strcmp(item,"CPPSRCPOST")) return ".cxx";
  else if (!strcmp(item,"CHDRPOST")) return ".h";
  else if (!strcmp(item,"CPPHDRPOST")) return ".h";
  else if (!strcmp(item,"INPUTMODE")) return G__CFG_INPUTMODE;
  else if (!strcmp(item,"INPUTMODELOCK")) return G__CFG_INPUTMODELOCK;
  else if (!strcmp(item,"CPREP")) return G__CFG_CPP;
  else if (!strcmp(item,"CPPPREP")) return G__CFG_CPP;
  else {
     printf("G__getmakeinfo for G__HAVE_CONFIG: %s not implemented yet!\n",
              item);
     return "";
  }
#elif defined(G__NOMAKEINFO)
  return("");
#endif

  /****************************************************************
  * Environment variable overrides MAKEINFO file if exists.
  ****************************************************************/
  if((p=getenv(item)) && p[0] && !isspace(p[0])) {
    buf = p;
    return(buf);
  }

  /****************************************************************
  * Get information from MAKEINFO file.
  ****************************************************************/
  /* Get $CINTSYSDIR/MAKEINFO file name */
  if(G__getcintsysdir()) return(buf);
#ifdef G__VMS
  makeinfo.Format("%s%s/MAKEINFO.txt",G__cintsysdir);
#else
  makeinfo.Format("%s/%s/MAKEINFO",G__cintsysdir, G__CFG_COREVERSION);
#endif

  /* Open MAKEINFO file */
  fp = fopen(makeinfo,"r");
  if(!fp) {
     G__fprinterr(G__serr,"Error: cannot open %s\n",makeinfo());
    G__fprinterr(G__serr,
     "!!! There are examples of MAKEINFO files under %s/platform/ !!!\n"
            ,G__cintsysdir);
    G__fprinterr(G__serr,
            "Please refer to these examples and create for your platform\n");
    return(buf);
  }

  /* Read the MAKEINFO file */
  while(G__readline_FastAlloc(fp,line,argbuf,&argn,arg)) {
    if(argn>2 && strcmp(arg[1],item)==0) {
      p = strchr(arg[0],'=');
      if(p) {
        do {
          ++p;
        } while(isspace(*p));
        buf = p;
        fclose(fp);
        return(buf);
      }
      else {
        G__fprinterr(G__serr,"MAKEINFO syntax error\n");
      }
    }
  }
  fclose(fp);
  return(buf);
}

/******************************************************************
* G__getmakeinfo1()
*
* TO BE FIXED. ONE SHOULD CALL getmakeinfo instead
*
*
******************************************************************/
const char *G__getmakeinfo1(const char *item)
{
  return G__getmakeinfo(item);
  //char *buf = (char*)G__getmakeinfo(item);
//#ifndef G__HAVE_CONFIG
//  char *p = buf;
//  while(*p && !isspace(*p)) ++p;
//  *p = 0;
//#endif
//  return(buf);
}

/******************************************************************
* G__SetCINTSYSDIR()
*
******************************************************************/
void G__SetCINTSYSDIR(char *cintsysdir)
{
  strcpy(G__cintsysdir,cintsysdir);
}

/******************************************************************
 * G__SetUseCINTSYSDIR()
 ******************************************************************/
static int G__UseCINTSYSDIR=0;
void G__SetUseCINTSYSDIR(int UseCINTSYSDIR)
{
  G__UseCINTSYSDIR=UseCINTSYSDIR;
}

/******************************************************************
* G__getcintsysdir()
*
*  print out error message for unsupported capability.
******************************************************************/
int G__getcintsysdir()
{
  const char *env;
  if('*'==G__cintsysdir[0]) {
#if defined(G__ROOT)
# ifdef ROOTBUILD
    env = "cint";
# else
#  ifdef CINTINCDIR
    env = CINTINCDIR;
#  else
    if(G__UseCINTSYSDIR) env=getenv("CINTSYSDIR");
    else                 env=getenv("ROOTSYS");
#  endif
# endif
#elif defined(G__WILDC)
    env=getenv("WILDCDIR");
    if(!env) env=getenv("CINTSYSDIR");
    if(!env) env="C:\\WILDC";
#else
    env=getenv("CINTSYSDIR");
# ifdef CINTSYSDIR
    if(!env || !env[0]) env = CINTSYSDIR;
# endif
# ifdef G__CFG_DATADIRCINT
    if(!env || !env[0]) env = G__CFG_DATADIRCINT;
# endif
#endif
    if(env) {
#ifdef G__ROOT
#ifdef G__VMS
/*      sprintf(G__cintsysdir,env);
      strcpy(&G__cintsysdir[strlen(G__cintsysdir)-1],".cint]");*/
      sprintf(G__cintsysdir,"%s[cint]",env);
#else /* G__VMS */
# ifdef ROOTBUILD
      sprintf(G__cintsysdir, "%s", env);
# else /* ROOTBUILD */
#  ifdef CINTINCDIR
      sprintf(G__cintsysdir, "%s", CINTINCDIR);
#  else
      if(G__UseCINTSYSDIR) strcpy(G__cintsysdir,env);
      else                 sprintf(G__cintsysdir, "%s/cint", env);
#  endif
# endif /* ROOTBUILD */
#endif /* G__VMS */

#else /* G__ROOT */
      strcpy(G__cintsysdir,env);
#endif /* G__ROOT */
      return(EXIT_SUCCESS);
    }
    else {
#ifdef G__EDU_VERSION
      sprintf(G__cintsysdir,".");
      return(EXIT_SUCCESS);
#else
#ifdef G__WIN32
      HMODULE hmodule=0;
      if(GetModuleFileName(hmodule,G__cintsysdir,G__MAXFILENAME)) {
        char *p = (char*)G__strrstr(G__cintsysdir,(char*)G__psep);
        if(p) *p = 0;
# ifdef G__ROOT
        p = (char*)G__strrstr(G__cintsysdir,(char*)G__psep);
        if(p) *p = 0;
        strcat(G__cintsysdir,G__psep);
        strcat(G__cintsysdir,"cint");
# endif
        return(EXIT_SUCCESS);
      }
#endif
#if defined(G__ROOT)
      G__fprinterr(G__serr,"Warning: environment variable ROOTSYS is not set. Standard include files ignored\n");
#elif defined(G__WILDC)
      G__fprinterr(G__serr,"Warning: environment variable WILDCDIR is not set. Standard include files ignored\n");
#else
      G__fprinterr(G__serr,"Warning: environment variable CINTSYSDIR is not set. Standard include files ignored\n");
#endif
      G__cintsysdir[0]='\0';
      return(EXIT_FAILURE);
#endif
    }
  }
  return(EXIT_SUCCESS);
}

/******************************************************************
* G__isfilebusy()
******************************************************************/
int G__isfilebusy(int ifn)
{
  struct G__ifunc_table_internal *ifunc;
  int flag=0;
  int i1;
  int i2;

  /*********************************************************************
  * check global function busy status
  *********************************************************************/
  ifunc = &G__ifunc;
  while(ifunc) {
    for(i1=0;i1<ifunc->allifunc;i1++) {
      if( 0!=ifunc->busy[i1] && ifunc->pentry[i1]->filenum>=ifn ) {
        G__fprinterr(G__serr,"Function %s() busy. loaded after \"%s\"\n"
                ,ifunc->funcname[i1],G__srcfile[ifn].filename);
        flag++;
      }
    }
    ifunc=ifunc->next;
  }

  /*********************************************************************
  * check member function busy status
  *********************************************************************/
  if(0==G__nfile || ifn<0 || G__nfile<=ifn ||
     (struct G__dictposition*)NULL==G__srcfile[ifn].dictpos ||
     -1==G__srcfile[ifn].dictpos->tagnum) return(flag);
  for(i2=G__srcfile[ifn].dictpos->tagnum;i2<G__struct.alltag;i2++) {
    ifunc = G__struct.memfunc[i2];
    while(ifunc) {
      for(i1=0;i1<ifunc->allifunc;i1++) {
        if(0!=ifunc->busy[i1]&&ifunc->pentry[i1]->filenum>=ifn) {
          G__fprinterr(G__serr,"Function %s() busy. loaded after\"%s\"\n"
                  ,ifunc->funcname[i1],G__srcfile[ifn].filename);
          flag++;
        }
      }
      ifunc=ifunc->next;
    }
  }

  return(flag);
}

/******************************************************************
* G__matchfilename(i,filename)
******************************************************************/
int G__matchfilename(int i1,const char *filename)
{
#if  !defined(__CINT__)

  if (G__srcfile[i1].filename==0) {
    return 0;
  }
  if((strcmp(G__srcfile[i1].filename,filename)==0)) {
     return(1);
  }

#ifdef G__WIN32
   G__FastAllocString i1name(_MAX_PATH);
   G__FastAllocString fullfile(_MAX_PATH);
  _fullpath( i1name, G__srcfile[i1].filename, _MAX_PATH );
  _fullpath( fullfile, filename, _MAX_PATH );
  if((stricmp(i1name, fullfile)==0)) return 1;
#else
  struct stat statBufItem;
  struct stat statBuf;
  if (   ( 0 == stat( filename, & statBufItem ) )
      && ( 0 == stat( G__srcfile[i1].filename, & statBuf ) )
      && ( statBufItem.st_dev == statBuf.st_dev )     // Files on same device
      && ( statBufItem.st_ino == statBuf.st_ino )     // Files on same inode (but this is not unique on AFS so we need the next 2 test
      && ( statBufItem.st_size == statBuf.st_size )   // Files of same size
      && ( statBufItem.st_mtime == statBuf.st_mtime ) // Files modified at the same time
     ) {
     return 1;
  }
#endif
  return 0;

#else /* PHILIPPE28 */

  char *filenamebase;
  if((strcmp(G__srcfile[i1].filename,filename)==0)) return(1);
  filenamebase = (char*)G__strrstr(G__srcfile[i1].filename,"./");
  if(filenamebase) {
    char *parentdir = (char*)G__strrstr(G__srcfile[i1].filename,"../");
    if(!parentdir && strcmp(filename,filenamebase+2)==0) {
      G__FastAllocString buf(G__ONELINE);
#if defined(G__WIN32)
      char *p;
#endif
      if(filenamebase==G__srcfile[i1].filename) return(1);
#if defined(G__WIN32)
      GetCurrentDirectory(G__ONELINE,buf);
      p=buf;
      while((p=strchr(p,'\\'))) *p='/';
      if(strlen(buf)>1 && ':'==buf[1]) {
        G__FastAllocString buf2(buf+2);
        buf.Swap(buf2);
      }
#elif defined(G__POSIX) || defined(G__ROOT)
      getcwd(buf,G__ONELINE);
#else
      buf[0] = 0;
#endif
      if(strncmp(buf,G__srcfile[i1].filename
                 ,filenamebase-G__srcfile[i1].filename-1)==0) return(1);
    }
  }
  return(0);
#endif /* PHILIPPE28 */
}

/******************************************************************
* G__stripfilename(filename)
******************************************************************/
const char* G__stripfilename(const char *filename)
{
  const char *filenamebase;
  if(!filename) return("");
  filenamebase = G__strrstr(filename,"./");
  if(filenamebase) {
    const char *parentdir = G__strrstr(filename,"../");
    G__FastAllocString buf(G__ONELINE);
#if defined(G__WIN32)
    char *p;
#endif
    if(parentdir) return(filename);
    if(filenamebase==filename) return(filenamebase+2);
#if defined(G__WIN32)
    GetCurrentDirectory(G__ONELINE,buf);
    p=buf;
    while((p=strchr(p,'\\'))) *p='/';
    if(strlen(buf)>1 && ':'==buf[1]) {
      G__FastAllocString buf2(buf+2);
      buf.Swap(buf2);
    }
#elif defined(G__POSIX) || defined(G__ROOT)
    if (!getcwd(buf,G__ONELINE)) {
       G__fprinterr(G__serr, "Error retrieving CWD\n");
       buf[0] = 0;
    }
#else
    buf[0] = 0;
#endif
    if(strncmp(buf,filename,filenamebase-filename-1)==0)
      return(filenamebase+2);
    else
      return(filename);
  }
  else return(filename);
}

/******************************************************************
* G__smart_unload()
******************************************************************/
void G__smart_unload(int ifn)
{
  struct G__dictposition *dictpos= G__srcfile[ifn].dictpos;
  struct G__dictposition *hasonlyfunc = G__srcfile[ifn].hasonlyfunc;
  struct G__ifunc_table_internal *ifunc;
  struct G__var_array *var;
  int nfile;
  int allsl;

  if(G__nfile == hasonlyfunc->nfile) {
    var = &G__global;
    while(var->next) var=var->next;
    if(var == hasonlyfunc->var && var->allvar == hasonlyfunc->ig15) {
      G__scratch_upto(G__srcfile[ifn].dictpos);
      return;
    }
  }

  /* disable functions */
  ifunc = G__get_ifunc_internal(dictpos->ifunc);
  ifn = dictpos->ifn;
  while(ifunc && (ifunc!=G__get_ifunc_internal(hasonlyfunc->ifunc) || ifn!=hasonlyfunc->ifn)) {
    ifunc->hash[ifn] = 0;
    if(++ifn>=G__MAXIFUNC) {
      ifunc = ifunc->next;
      ifn = 0;
    }
  }

  /* disable file entry */
  for(nfile=dictpos->nfile;nfile<hasonlyfunc->nfile;nfile++) {
    G__srcfile[nfile].hash = 0;
    G__srcfile[nfile].filename[0] = 0;
    if(G__srcfile[nfile].fp) fclose(G__srcfile[nfile].fp);
    G__srcfile[nfile].fp = 0;
  }

  /* unload shared library */
  for(allsl=dictpos->allsl;allsl<hasonlyfunc->allsl;allsl++) {
    G__smart_shl_unload(allsl);
  }
}


/******************************************************************
* G__unloadfile(filename)
*
*  1) check if function is busy. If busy return -1
*  2) Unload file and return 0
*
******************************************************************/
int G__unloadfile(const char *filename)
{<commit_msg>Make sure the list of library is recalculated whenever G__smart_unload is used; This fixes Savannah #66900<commit_after>/* /% C %/ */
/***********************************************************************
 * cint (C/C++ interpreter)
 ************************************************************************
 * Source file loadfile.c
 ************************************************************************
 * Description:
 *  Loading source file
 ************************************************************************
 * Copyright(c) 1995~2005  <NAME>
 *
 * For the licensing terms see the file COPYING
 *
 ************************************************************************/

/* Define one of following */
#define G__OLDIMPLEMENTATION1922 /* keep opening all header files for +V +P */

#include <string>
#include <list>

#ifdef _WIN32
#include "process.h"
#endif

#if defined(G__ROOT)
#include "RConfigure.h"
#endif

#if defined(G__HAVE_CONFIG)
#include "configcint.h"
#endif

#include "common.h"
#include "Api.h"
#include "FastAllocString.h"

#ifndef G__TESTMAIN
#include <sys/stat.h>
#endif

#ifdef G__WIN32
#include <windows.h>
#endif

#define G__OLDIMPLEMENTATION1849

#ifdef G__SHAREDLIB
extern std::list<G__DLLINIT>* G__initpermanentsl;
#endif

extern "C" {

/******************************************************************
* Define G__EDU_VERSION for CINT C++ educational version.
* If G__EDU_VERSION is defined, CINT will search ./include and
* ./stl directory for standard header files.
******************************************************************/
/* #define G__EDU_VERSION */

static G__IgnoreInclude G__ignoreinclude = (G__IgnoreInclude)NULL;

/******************************************************************
* G__set_ignoreinclude
******************************************************************/
void G__set_ignoreinclude(G__IgnoreInclude ignoreinclude)
{
  G__ignoreinclude = ignoreinclude;
}

static int G__kindofheader = G__USERHEADER;

static int G__copyflag = 0;

int (*G__ScriptCompiler) G__P((G__CONST char*,G__CONST char*)) = 0;

/******************************************************************
* G__RegisterScriptCompiler()
******************************************************************/
void G__RegisterScriptCompiler(int(*p2f) G__P((G__CONST char*,G__CONST char*)))
{
  G__ScriptCompiler = p2f;
}

/******************************************************************
* G__copytotmpfile()
******************************************************************/
static FILE* G__copytotmpfile(char *prepname)
{
  FILE *ifp;
  FILE *ofp;
  ifp = fopen(prepname,"rb");
  if(!ifp) {
    G__genericerror("Internal error: G__copytotmpfile() 1\n");
    return((FILE*)NULL);
  }
  ofp = fopen(G__tmpnam(0),"w+b");
  if(!ofp) {
    G__genericerror("Internal error: G__copytotmpfile() 2\n");
    fclose(ifp);
    return((FILE*)NULL);
  }
  G__copyfile(ofp,ifp);
  fclose(ifp);
  fseek(ofp,0L,SEEK_SET);
  return(ofp);
}

/******************************************************************
* G__copysourcetotmp()
******************************************************************/
static void G__copysourcetotmp(char *prepname,G__input_file *pifile, int fentry)
{
  if(G__copyflag && 0==prepname[0]) {
    FILE *fpout;
    fpout = fopen(G__tmpnam(0),"w+b");
    if(!fpout) {
      G__genericerror("Internal error: can not open tmpfile.");
      return;
    }
    /*strcpy(prepname,"(tmpfile)");*/
    sprintf(prepname,"(tmp%d)",fentry);
    G__copyfile(fpout,pifile->fp);
    fseek(fpout,0L,SEEK_SET);
    G__srcfile[fentry].prepname = (char*)malloc(strlen(prepname)+1);
    strcpy(G__srcfile[fentry].prepname,prepname);
    G__srcfile[fentry].fp = fpout;
    fclose(pifile->fp);
    pifile->fp = fpout;
  }
}

/**************************************************************************
* G__setcopyflag()
**************************************************************************/
void G__setcopyflag(int flag)
{
  G__copyflag = flag;
}

/******************************************************************
* G__ispreprocessfilekey
******************************************************************/
static int G__ispreprocessfilekey(char *filename)
{
  struct G__Preprocessfilekey *pkey;
  /* char *p; */

  pkey = &G__preprocessfilekey;

  /* check match of the keystring */
  while(pkey->next) {
    if(pkey->keystring && strstr(filename,pkey->keystring)) {
       return(1);
    }
    pkey=pkey->next;
  }

  /* No match */
  return(0);
}

/******************************************************************
* G__include_file()
*
* Keyword '#include' is read in G__exec_statement();
* G__include_file() read include filename, and load it.
*
*   #include   <stdio.h>    \n
*            ^---------------^       do nothing
*
*   #include  comment   "header.h" comment   \n
*            ^--------------------------------^    load "header.h"
*
******************************************************************/
int G__include_file()
{
  int result;
  int c;
  G__FastAllocString filename(G__MAXFILENAME);
  int i=0;
  int storeit=0;
  /* char sysinclude[G__MAXFILENAME]; */
  int store_cpp;
  int store_globalcomp;
  int expandflag=0;
  static int G__gcomplevel=0;

  while((c=G__fgetc())!='\n' && c!='\r'
        && c!='#'&& c!=-1
        ) {
    switch(c) {
    case '<':
      if(storeit==0) storeit=1;
      break;
    case '>':
      storeit = -1;
      G__kindofheader=G__SYSHEADER;
      break;
    case '\"':
      switch(storeit) {
      case 0:
        storeit=1;
        break;
      case 1:
        storeit = -1;
        G__kindofheader=G__USERHEADER;
        break;
      }
      break;
    default:
      if(!isspace(c)) {
        if(1==storeit) {
          filename.Set(i++, c);
          filename.Set(i, 0);
        }
        else if(-1!=storeit) {
          storeit=1;
          expandflag=1;
          filename.Set(i++, c);
          filename.Set(i, 0);
        }
      }
      else if(expandflag) {
        storeit = -1;
      }
      break;
    }
  }

  if(expandflag) {
    /* Following stupid code is written to avoid HP-UX CC -O bug */
    struct G__var_array *var;
    int ig15;
    int hash;
    G__hash(filename,hash,ig15);
    var = G__getvarentry(filename,hash,&ig15,&G__global,G__p_local);
    if(var) {
      filename = *(char**)var->p[ig15];
      G__kindofheader=G__USERHEADER;
    }
    else {
       G__fprinterr(G__serr,"Error: cannot expand #include %s",filename());
      G__genericerror(NULL);
      if('#'==c) G__fignoreline();
      return(G__LOADFILE_FAILURE);
    }
  }

  store_cpp=G__cpp;
  G__cpp=G__include_cpp;

  if(G__USERHEADER==G__kindofheader) {
    store_globalcomp = G__globalcomp;
    if(++G__gcomplevel>=G__gcomplevellimit) G__globalcomp=G__NOLINK;
    result = G__loadfile(filename);
    --G__gcomplevel;
    G__globalcomp=store_globalcomp;
  }
  else {
    /* <xxx.h> , 'xxx.h' */
    store_globalcomp=G__globalcomp;
    /* G__globalcomp=G__NOLINK; */
    if(++G__gcomplevel>=G__gcomplevellimit) G__globalcomp=G__NOLINK;
    result = G__loadfile(filename);
    --G__gcomplevel;
    G__globalcomp=store_globalcomp;
  }
  G__kindofheader = G__USERHEADER;

  G__cpp=store_cpp;

  if('#'==c) {
    if(G__LOADFILE_FAILURE==result && G__ispragmainclude) {
      G__ispragmainclude=0;
      c = G__fgetname(filename, 0, "\n\r");
      store_globalcomp = G__globalcomp;
      if(++G__gcomplevel>=G__gcomplevellimit) G__globalcomp=G__NOLINK;
      if('\n'!=c && '\r'!=c) result = G__include_file();
      --G__gcomplevel;
      G__globalcomp=store_globalcomp;
    }
    else {
      G__fignoreline();
    }
  }

  return(result);
}

/******************************************************************
* G__getmakeinfo()
*
******************************************************************/
const char *G__getmakeinfo(const char *item)
{
  G__FastAllocString makeinfo(G__MAXFILENAME);
  FILE *fp;
  G__FastAllocString line(G__LARGEBUF);
  G__FastAllocString argbuf(G__LARGEBUF);
  char *arg[G__MAXARG];
  int argn;
  char *p;
  static G__FastAllocString buf(G__ONELINE);

  buf[0]='\0';

#ifdef G__HAVE_CONFIG
  if (!strcmp(item,"CPP")) return G__CFG_CXX;
  else if (!strcmp(item,"CC")) return G__CFG_CC;
  else if (!strcmp(item,"DLLPOST")) return G__CFG_SOEXT;
  else if (!strcmp(item,"CSRCPOST")) return ".c";
  else if (!strcmp(item,"CPPSRCPOST")) return ".cxx";
  else if (!strcmp(item,"CHDRPOST")) return ".h";
  else if (!strcmp(item,"CPPHDRPOST")) return ".h";
  else if (!strcmp(item,"INPUTMODE")) return G__CFG_INPUTMODE;
  else if (!strcmp(item,"INPUTMODELOCK")) return G__CFG_INPUTMODELOCK;
  else if (!strcmp(item,"CPREP")) return G__CFG_CPP;
  else if (!strcmp(item,"CPPPREP")) return G__CFG_CPP;
  else {
     printf("G__getmakeinfo for G__HAVE_CONFIG: %s not implemented yet!\n",
              item);
     return "";
  }
#elif defined(G__NOMAKEINFO)
  return("");
#endif

  /****************************************************************
  * Environment variable overrides MAKEINFO file if exists.
  ****************************************************************/
  if((p=getenv(item)) && p[0] && !isspace(p[0])) {
    buf = p;
    return(buf);
  }

  /****************************************************************
  * Get information from MAKEINFO file.
  ****************************************************************/
  /* Get $CINTSYSDIR/MAKEINFO file name */
  if(G__getcintsysdir()) return(buf);
#ifdef G__VMS
  makeinfo.Format("%s%s/MAKEINFO.txt",G__cintsysdir);
#else
  makeinfo.Format("%s/%s/MAKEINFO",G__cintsysdir, G__CFG_COREVERSION);
#endif

  /* Open MAKEINFO file */
  fp = fopen(makeinfo,"r");
  if(!fp) {
     G__fprinterr(G__serr,"Error: cannot open %s\n",makeinfo());
    G__fprinterr(G__serr,
     "!!! There are examples of MAKEINFO files under %s/platform/ !!!\n"
            ,G__cintsysdir);
    G__fprinterr(G__serr,
            "Please refer to these examples and create for your platform\n");
    return(buf);
  }

  /* Read the MAKEINFO file */
  while(G__readline_FastAlloc(fp,line,argbuf,&argn,arg)) {
    if(argn>2 && strcmp(arg[1],item)==0) {
      p = strchr(arg[0],'=');
      if(p) {
        do {
          ++p;
        } while(isspace(*p));
        buf = p;
        fclose(fp);
        return(buf);
      }
      else {
        G__fprinterr(G__serr,"MAKEINFO syntax error\n");
      }
    }
  }
  fclose(fp);
  return(buf);
}

/******************************************************************
* G__getmakeinfo1()
*
* TO BE FIXED. ONE SHOULD CALL getmakeinfo instead
*
*
******************************************************************/
const char *G__getmakeinfo1(const char *item)
{
  return G__getmakeinfo(item);
  //char *buf = (char*)G__getmakeinfo(item);
//#ifndef G__HAVE_CONFIG
//  char *p = buf;
//  while(*p && !isspace(*p)) ++p;
//  *p = 0;
//#endif
//  return(buf);
}

/******************************************************************
* G__SetCINTSYSDIR()
*
******************************************************************/
void G__SetCINTSYSDIR(char *cintsysdir)
{
  strcpy(G__cintsysdir,cintsysdir);
}

/******************************************************************
 * G__SetUseCINTSYSDIR()
 ******************************************************************/
static int G__UseCINTSYSDIR=0;
void G__SetUseCINTSYSDIR(int UseCINTSYSDIR)
{
  G__UseCINTSYSDIR=UseCINTSYSDIR;
}

/******************************************************************
* G__getcintsysdir()
*
*  print out error message for unsupported capability.
******************************************************************/
int G__getcintsysdir()
{
  const char *env;
  if('*'==G__cintsysdir[0]) {
#if defined(G__ROOT)
# ifdef ROOTBUILD
    env = "cint";
# else
#  ifdef CINTINCDIR
    env = CINTINCDIR;
#  else
    if(G__UseCINTSYSDIR) env=getenv("CINTSYSDIR");
    else                 env=getenv("ROOTSYS");
#  endif
# endif
#elif defined(G__WILDC)
    env=getenv("WILDCDIR");
    if(!env) env=getenv("CINTSYSDIR");
    if(!env) env="C:\\WILDC";
#else
    env=getenv("CINTSYSDIR");
# ifdef CINTSYSDIR
    if(!env || !env[0]) env = CINTSYSDIR;
# endif
# ifdef G__CFG_DATADIRCINT
    if(!env || !env[0]) env = G__CFG_DATADIRCINT;
# endif
#endif
    if(env) {
#ifdef G__ROOT
#ifdef G__VMS
/*      sprintf(G__cintsysdir,env);
      strcpy(&G__cintsysdir[strlen(G__cintsysdir)-1],".cint]");*/
      sprintf(G__cintsysdir,"%s[cint]",env);
#else /* G__VMS */
# ifdef ROOTBUILD
      sprintf(G__cintsysdir, "%s", env);
# else /* ROOTBUILD */
#  ifdef CINTINCDIR
      sprintf(G__cintsysdir, "%s", CINTINCDIR);
#  else
      if(G__UseCINTSYSDIR) strcpy(G__cintsysdir,env);
      else                 sprintf(G__cintsysdir, "%s/cint", env);
#  endif
# endif /* ROOTBUILD */
#endif /* G__VMS */

#else /* G__ROOT */
      strcpy(G__cintsysdir,env);
#endif /* G__ROOT */
      return(EXIT_SUCCESS);
    }
    else {
#ifdef G__EDU_VERSION
      sprintf(G__cintsysdir,".");
      return(EXIT_SUCCESS);
#else
#ifdef G__WIN32
      HMODULE hmodule=0;
      if(GetModuleFileName(hmodule,G__cintsysdir,G__MAXFILENAME)) {
        char *p = (char*)G__strrstr(G__cintsysdir,(char*)G__psep);
        if(p) *p = 0;
# ifdef G__ROOT
        p = (char*)G__strrstr(G__cintsysdir,(char*)G__psep);
        if(p) *p = 0;
        strcat(G__cintsysdir,G__psep);
        strcat(G__cintsysdir,"cint");
# endif
        return(EXIT_SUCCESS);
      }
#endif
#if defined(G__ROOT)
      G__fprinterr(G__serr,"Warning: environment variable ROOTSYS is not set. Standard include files ignored\n");
#elif defined(G__WILDC)
      G__fprinterr(G__serr,"Warning: environment variable WILDCDIR is not set. Standard include files ignored\n");
#else
      G__fprinterr(G__serr,"Warning: environment variable CINTSYSDIR is not set. Standard include files ignored\n");
#endif
      G__cintsysdir[0]='\0';
      return(EXIT_FAILURE);
#endif
    }
  }
  return(EXIT_SUCCESS);
}

/******************************************************************
* G__isfilebusy()
******************************************************************/
int G__isfilebusy(int ifn)
{
  struct G__ifunc_table_internal *ifunc;
  int flag=0;
  int i1;
  int i2;

  /*********************************************************************
  * check global function busy status
  *********************************************************************/
  ifunc = &G__ifunc;
  while(ifunc) {
    for(i1=0;i1<ifunc->allifunc;i1++) {
      if( 0!=ifunc->busy[i1] && ifunc->pentry[i1]->filenum>=ifn ) {
        G__fprinterr(G__serr,"Function %s() busy. loaded after \"%s\"\n"
                ,ifunc->funcname[i1],G__srcfile[ifn].filename);
        flag++;
      }
    }
    ifunc=ifunc->next;
  }

  /*********************************************************************
  * check member function busy status
  *********************************************************************/
  if(0==G__nfile || ifn<0 || G__nfile<=ifn ||
     (struct G__dictposition*)NULL==G__srcfile[ifn].dictpos ||
     -1==G__srcfile[ifn].dictpos->tagnum) return(flag);
  for(i2=G__srcfile[ifn].dictpos->tagnum;i2<G__struct.alltag;i2++) {
    ifunc = G__struct.memfunc[i2];
    while(ifunc) {
      for(i1=0;i1<ifunc->allifunc;i1++) {
        if(0!=ifunc->busy[i1]&&ifunc->pentry[i1]->filenum>=ifn) {
          G__fprinterr(G__serr,"Function %s() busy. loaded after\"%s\"\n"
                  ,ifunc->funcname[i1],G__srcfile[ifn].filename);
          flag++;
        }
      }
      ifunc=ifunc->next;
    }
  }

  return(flag);
}

/******************************************************************
* G__matchfilename(i,filename)
******************************************************************/
int G__matchfilename(int i1,const char *filename)
{
#if  !defined(__CINT__)

  if (G__srcfile[i1].filename==0) {
    return 0;
  }
  if((strcmp(G__srcfile[i1].filename,filename)==0)) {
     return(1);
  }

#ifdef G__WIN32
   G__FastAllocString i1name(_MAX_PATH);
   G__FastAllocString fullfile(_MAX_PATH);
  _fullpath( i1name, G__srcfile[i1].filename, _MAX_PATH );
  _fullpath( fullfile, filename, _MAX_PATH );
  if((stricmp(i1name, fullfile)==0)) return 1;
#else
  struct stat statBufItem;
  struct stat statBuf;
  if (   ( 0 == stat( filename, & statBufItem ) )
      && ( 0 == stat( G__srcfile[i1].filename, & statBuf ) )
      && ( statBufItem.st_dev == statBuf.st_dev )     // Files on same device
      && ( statBufItem.st_ino == statBuf.st_ino )     // Files on same inode (but this is not unique on AFS so we need the next 2 test
      && ( statBufItem.st_size == statBuf.st_size )   // Files of same size
      && ( statBufItem.st_mtime == statBuf.st_mtime ) // Files modified at the same time
     ) {
     return 1;
  }
#endif
  return 0;

#else /* PHILIPPE28 */

  char *filenamebase;
  if((strcmp(G__srcfile[i1].filename,filename)==0)) return(1);
  filenamebase = (char*)G__strrstr(G__srcfile[i1].filename,"./");
  if(filenamebase) {
    char *parentdir = (char*)G__strrstr(G__srcfile[i1].filename,"../");
    if(!parentdir && strcmp(filename,filenamebase+2)==0) {
      G__FastAllocString buf(G__ONELINE);
#if defined(G__WIN32)
      char *p;
#endif
      if(filenamebase==G__srcfile[i1].filename) return(1);
#if defined(G__WIN32)
      GetCurrentDirectory(G__ONELINE,buf);
      p=buf;
      while((p=strchr(p,'\\'))) *p='/';
      if(strlen(buf)>1 && ':'==buf[1]) {
        G__FastAllocString buf2(buf+2);
        buf.Swap(buf2);
      }
#elif defined(G__POSIX) || defined(G__ROOT)
      getcwd(buf,G__ONELINE);
#else
      buf[0] = 0;
#endif
      if(strncmp(buf,G__srcfile[i1].filename
                 ,filenamebase-G__srcfile[i1].filename-1)==0) return(1);
    }
  }
  return(0);
#endif /* PHILIPPE28 */
}

/******************************************************************
* G__stripfilename(filename)
******************************************************************/
const char* G__stripfilename(const char *filename)
{
  const char *filenamebase;
  if(!filename) return("");
  filenamebase = G__strrstr(filename,"./");
  if(filenamebase) {
    const char *parentdir = G__strrstr(filename,"../");
    G__FastAllocString buf(G__ONELINE);
#if defined(G__WIN32)
    char *p;
#endif
    if(parentdir) return(filename);
    if(filenamebase==filename) return(filenamebase+2);
#if defined(G__WIN32)
    GetCurrentDirectory(G__ONELINE,buf);
    p=buf;
    while((p=strchr(p,'\\'))) *p='/';
    if(strlen(buf)>1 && ':'==buf[1]) {
      G__FastAllocString buf2(buf+2);
      buf.Swap(buf2);
    }
#elif defined(G__POSIX) || defined(G__ROOT)
    if (!getcwd(buf,G__ONELINE)) {
       G__fprinterr(G__serr, "Error retrieving CWD\n");
       buf[0] = 0;
    }
#else
    buf[0] = 0;
#endif
    if(strncmp(buf,filename,filenamebase-filename-1)==0)
      return(filenamebase+2);
    else
      return(filename);
  }
  else return(filename);
}

/******************************************************************
* G__smart_unload()
******************************************************************/
void G__smart_unload(int ifn)
{
  struct G__dictposition *dictpos= G__srcfile[ifn].dictpos;
  struct G__dictposition *hasonlyfunc = G__srcfile[ifn].hasonlyfunc;
  struct G__ifunc_table_internal *ifunc;
  struct G__var_array *var;
  int nfile;
  int allsl;

  if(G__nfile == hasonlyfunc->nfile) {
    var = &G__global;
    while(var->next) var=var->next;
    if(var == hasonlyfunc->var && var->allvar == hasonlyfunc->ig15) {
      G__scratch_upto(G__srcfile[ifn].dictpos);
      return;
    }
  }

  /* disable functions */
  ifunc = G__get_ifunc_internal(dictpos->ifunc);
  ifn = dictpos->ifn;
  while(ifunc && (ifunc!=G__get_ifunc_internal(hasonlyfunc->ifunc) || ifn!=hasonlyfunc->ifn)) {
    ifunc->hash[ifn] = 0;
    if(++ifn>=G__MAXIFUNC) {
      ifunc = ifunc->next;
      ifn = 0;
    }
  }

  /* disable file entry */
  ++G__srcfile_serial;
  for(nfile=dictpos->nfile;nfile<hasonlyfunc->nfile;nfile++) {
    G__srcfile[nfile].hash = 0;
    G__srcfile[nfile].filename[0] = 0;
    if(G__srcfile[nfile].fp) fclose(G__srcfile[nfile].fp);
    G__srcfile[nfile].fp = 0;
  }

  /* unload shared library */
  for(allsl=dictpos->allsl;allsl<hasonlyfunc->allsl;allsl++) {
    G__smart_shl_unload(allsl);
  }
}


/******************************************************************
* G__unloadfile(filename)
*
*  1) check if function is busy. If busy return -1
*  2) Unload file and return 0
*
******************************************************************/
int G__unloadfile(const char *filename)
{
{'fraction_non_alphanumeric': 0.2918875147232038, 'fraction_numerical': 0.009594621122889673, 'mean_word_length': 4.176298742537788, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 115, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5078537', 'n_tokens_mistral': 14117, 'n_tokens_neox': 13680, 'n_words': 2330}