special cases and other things in wxPython, and since I plan on making several more, I've decided to put the SWIG sources in wxPython's CVS instead of relying on maintaining patches. This effectivly becomes a fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still doesn't have some things I rely on in 1.1, not to mention that my custom patches would all have to be redone, I felt that this is the easier road to take. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15307 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			587 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			587 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*******************************************************************************
 | 
						|
 * Simplified Wrapper and Interface Generator  (SWIG)
 | 
						|
 * 
 | 
						|
 * Author : David Beazley
 | 
						|
 *
 | 
						|
 * Department of Computer Science        
 | 
						|
 * University of Chicago
 | 
						|
 * 1100 E 58th Street
 | 
						|
 * Chicago, IL  60637
 | 
						|
 * beazley@cs.uchicago.edu
 | 
						|
 *
 | 
						|
 * Please read the file LICENSE for the copyright and terms by which SWIG
 | 
						|
 * can be used and distributed.
 | 
						|
 *******************************************************************************/
 | 
						|
 | 
						|
#include "internal.h"
 | 
						|
#include <stdlib.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <ctype.h>
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
 * $Header$
 | 
						|
 *
 | 
						|
 * File : include.cxx
 | 
						|
 *
 | 
						|
 * Code for including files into a wrapper file.
 | 
						|
 *
 | 
						|
 *******************************************************************************/
 | 
						|
 | 
						|
/* Delimeter used in accessing files and directories */
 | 
						|
 | 
						|
#ifdef MACSWIG
 | 
						|
#define  DELIMETER  ':'
 | 
						|
#else
 | 
						|
#define  DELIMETER  '/'
 | 
						|
#endif
 | 
						|
 | 
						|
/* Linked list containing search directories */
 | 
						|
 | 
						|
struct   Dnode {
 | 
						|
  char    *dirname;
 | 
						|
  Dnode   *next;
 | 
						|
};
 | 
						|
 | 
						|
Dnode   ihead, iz;
 | 
						|
int     include_init = 0;
 | 
						|
 | 
						|
/* Linked list containing included files */
 | 
						|
 | 
						|
struct  Inode {
 | 
						|
  char    *name;
 | 
						|
  Inode   *next;
 | 
						|
};
 | 
						|
 | 
						|
Inode  *include_list = 0;
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void add_directory(char *dirname)
 | 
						|
//
 | 
						|
// Adds a directory to the SWIG search path.
 | 
						|
// 
 | 
						|
// Inputs : dirname  = Pathname
 | 
						|
//
 | 
						|
// Output : None
 | 
						|
//
 | 
						|
// Side Effects : Adds dirname to linked list of pathnames.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void add_directory(char *dirname) {
 | 
						|
  Dnode  *d;
 | 
						|
 | 
						|
  if (!include_init) {
 | 
						|
    ihead.next = &iz;
 | 
						|
    iz.next = &iz;
 | 
						|
    iz.dirname = new char[2];
 | 
						|
    iz.dirname[0] = 0;
 | 
						|
    include_init = 1;
 | 
						|
  }
 | 
						|
 | 
						|
  d = new Dnode;
 | 
						|
  d->dirname = new char[strlen(dirname)+1];
 | 
						|
  strcpy(d->dirname,dirname);
 | 
						|
  d->next = ihead.next;
 | 
						|
  ihead.next = d;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// int add_iname(char *name)
 | 
						|
// 
 | 
						|
// Adds an include file to the list of processed files.  If already present,
 | 
						|
// returns 1. 
 | 
						|
//
 | 
						|
// Inputs : name  = filename
 | 
						|
//
 | 
						|
// Output : 0 on success, 1 on failure.
 | 
						|
//
 | 
						|
// Side Effects : Adds name to linked list.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
int add_iname(char *name) {
 | 
						|
 | 
						|
  Inode *newi, *i;
 | 
						|
 | 
						|
  //  if (WrapExtern) return 0;        // Still thinking about this patch.
 | 
						|
  if (include_list) {
 | 
						|
    /* Search list */
 | 
						|
    i = include_list;
 | 
						|
    while (i) {
 | 
						|
      if (strcmp(i->name, name) == 0) return 1;
 | 
						|
      i = i->next;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  newi = new Inode;
 | 
						|
  newi->name = new char[strlen(name)+1];
 | 
						|
  strcpy(newi->name, name);
 | 
						|
  newi->next = include_list;
 | 
						|
  include_list = newi;
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void check_suffix(char *name)
 | 
						|
// 
 | 
						|
// Checks the suffix of an include file to see if we need to handle it
 | 
						|
// differently.  C and C++ source files need a little extra help.
 | 
						|
//
 | 
						|
// Inputs : name  = include file name.
 | 
						|
//
 | 
						|
// Output : None
 | 
						|
//
 | 
						|
// Side Effects : 
 | 
						|
//          Sets ForceExtern status variable if a C/C++ source file
 | 
						|
//          is detected.
 | 
						|
//
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void check_suffix(char *name) {
 | 
						|
  char *c;
 | 
						|
 | 
						|
  if (!name) return;
 | 
						|
  if (strlen(name) == 0) return;
 | 
						|
  c = name+strlen(name)-1;
 | 
						|
  while (c != name) {
 | 
						|
    if (*c == '.') break;
 | 
						|
    c--;
 | 
						|
  }
 | 
						|
  if (c == name) return;
 | 
						|
 | 
						|
  /* Check suffixes */
 | 
						|
 | 
						|
  if (strcmp(c,".c") == 0) {
 | 
						|
    ForceExtern = 1;
 | 
						|
  } else if (strcmp(c,".C") == 0) {
 | 
						|
    ForceExtern = 1;
 | 
						|
  } else if (strcmp(c,".cc") == 0) {
 | 
						|
    ForceExtern = 1;
 | 
						|
  } else if (strcmp(c,".cxx") == 0) {
 | 
						|
    ForceExtern = 1;
 | 
						|
  } else if (strcmp(c,".c++") == 0) {
 | 
						|
    ForceExtern = 1;
 | 
						|
  } else if (strcmp(c,".cpp") == 0) {
 | 
						|
    ForceExtern = 1;
 | 
						|
  } else {
 | 
						|
    ForceExtern = 0;
 | 
						|
  }
 | 
						|
}
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// int include_file(char *name)
 | 
						|
// 
 | 
						|
// Includes a new SWIG wrapper file. Returns -1 if file not found.
 | 
						|
//
 | 
						|
// Inputs : name  = filename
 | 
						|
//
 | 
						|
// Output : 0 on success. -1 on failure.
 | 
						|
//
 | 
						|
// Side Effects : sets scanner to read from new file.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
int include_file(char *name) {
 | 
						|
 | 
						|
  FILE  *f;
 | 
						|
  char   filename[256];
 | 
						|
  int    found = 0;
 | 
						|
  Dnode  *d;
 | 
						|
  extern void scanner_file(FILE *);
 | 
						|
 | 
						|
  if (!include_init) return -1;    // Not initialized yet
 | 
						|
  if (add_iname(name)) {
 | 
						|
    if (Verbose) fprintf(stderr,"file %s already included.\n", name);
 | 
						|
    return -1;  // Already included this file
 | 
						|
  }
 | 
						|
 | 
						|
  if (Verbose) {
 | 
						|
    fprintf(stderr,"Wrapping %s...\n", name);	
 | 
						|
    fprintf(stderr,"Looking for ./%s\n", name);
 | 
						|
  }
 | 
						|
 | 
						|
  if ((f = fopen(name,"r")) != NULL) {
 | 
						|
    input_file = new char[strlen(name)+1];
 | 
						|
    strcpy(input_file,name);
 | 
						|
    scanner_file(f);
 | 
						|
    check_suffix(name);
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  // Now start searching libraries
 | 
						|
 | 
						|
  d = ihead.next;               // Start of search list
 | 
						|
  while (d != &iz) {
 | 
						|
    // Look for the wrap file in language directory
 | 
						|
    sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name);
 | 
						|
    if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
 | 
						|
    if((f = fopen(filename,"r")) != NULL) {
 | 
						|
      found = 1;
 | 
						|
    } else {
 | 
						|
      sprintf(filename,"%s%c%s", d->dirname, DELIMETER,name);
 | 
						|
      if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
 | 
						|
      if ((f = fopen(filename,"r")) != NULL) {
 | 
						|
	found = 1;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (found) {
 | 
						|
      // Found it, open it up for input
 | 
						|
      input_file = new char[strlen(filename)+1];
 | 
						|
      strcpy(input_file,filename);
 | 
						|
      scanner_file(f);
 | 
						|
      check_suffix(name);
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
    d = d->next;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!found) fprintf(stderr,"%s : Line %d. Unable to find include file %s (ignored).\n",input_file, line_number, name);
 | 
						|
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static char  buffer[1024];
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void copy_data(FILE *f1, FILE *f2)
 | 
						|
//
 | 
						|
// Copies data from file f1 to file f2.
 | 
						|
// 
 | 
						|
// Inputs : f1  = FILE 1
 | 
						|
//          f2  = FILE 2
 | 
						|
//
 | 
						|
// Output : None
 | 
						|
//
 | 
						|
// Side Effects : Closes file f1 upon exit.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void copy_data(FILE *f1, FILE *f2) {
 | 
						|
 | 
						|
  while (fgets(buffer,1023,f1)) {
 | 
						|
    fputs(buffer, f2);
 | 
						|
  }
 | 
						|
  fclose(f1);
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void copy_data(FILE *f1, String *s2)
 | 
						|
//
 | 
						|
// Copies data from file f1 to String s2.
 | 
						|
// 
 | 
						|
// Inputs : f1  = FILE 1
 | 
						|
//          s2  = String
 | 
						|
//
 | 
						|
// Output : None
 | 
						|
//
 | 
						|
// Side Effects : Closes file f1 upon exit.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void copy_data(FILE *f1, String &s2) {
 | 
						|
 | 
						|
  while (fgets(buffer,1023,f1)) {
 | 
						|
    s2 << buffer;
 | 
						|
  }
 | 
						|
  fclose(f1);
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// int insert_file(char *name, FILE *f)
 | 
						|
//
 | 
						|
// Looks for a file and inserts into file f.
 | 
						|
//
 | 
						|
// Inputs : name  = filename
 | 
						|
//          f     = FILE
 | 
						|
//
 | 
						|
// Output : 0 on success, -1 on failure.
 | 
						|
//
 | 
						|
// Side Effects : None
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
int insert_file(char *name, FILE *f_out) {
 | 
						|
 | 
						|
  FILE  *f;
 | 
						|
  char   filename[256];
 | 
						|
  int    found = 0;
 | 
						|
  Dnode  *d;
 | 
						|
 | 
						|
  if (!include_init) return -1;    // Not initialized yet
 | 
						|
  if (add_iname(name)) {
 | 
						|
    if (Verbose) fprintf(stderr,"file %s already included.\n", name);
 | 
						|
    return -1;  // Already included this file
 | 
						|
  }
 | 
						|
 | 
						|
  if (Verbose) fprintf(stderr,"Looking for ./%s\n", name);
 | 
						|
  if ((f = fopen(name,"r")) != NULL) {
 | 
						|
      copy_data(f,f_out);
 | 
						|
      return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  // Now start searching libraries
 | 
						|
 | 
						|
  d = ihead.next;               // Start of search list
 | 
						|
  while (d != &iz) {
 | 
						|
    // Look for the wrap file in language directory
 | 
						|
    sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name);
 | 
						|
    if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
 | 
						|
    if((f = fopen(filename,"r")) != NULL) {
 | 
						|
      found = 1;
 | 
						|
    } else {
 | 
						|
      sprintf(filename,"%s%c%s", d->dirname, DELIMETER, name);
 | 
						|
      if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
 | 
						|
      if ((f = fopen(filename,"r")) != NULL) {
 | 
						|
	found = 1;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (found) {
 | 
						|
	copy_data(f,f_out);
 | 
						|
	return 0;
 | 
						|
    }
 | 
						|
    d = d->next;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((!found) && (Verbose)) fprintf(stderr,"unable to find %s. (Ignored)\n",name);
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void swig_append(char *filename, FILE *f)
 | 
						|
// 
 | 
						|
// Appends the contents of filename to stream f.
 | 
						|
//
 | 
						|
// Inputs : 
 | 
						|
//          filename  = File to append
 | 
						|
//          f         = FILE handle 
 | 
						|
//
 | 
						|
// Output : None
 | 
						|
//
 | 
						|
// Side Effects : None
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void swig_append(char *filename, FILE *f) {
 | 
						|
 | 
						|
  FILE *in_file;
 | 
						|
 | 
						|
  if ((in_file = fopen(filename,"r")) == NULL) {
 | 
						|
      fprintf(stderr,"** SWIG ERROR ** file %s not found.\n",filename);
 | 
						|
      FatalError();
 | 
						|
      return;
 | 
						|
  }
 | 
						|
  while (fgets(buffer,1023,in_file)) {
 | 
						|
    fputs(buffer, f);
 | 
						|
  }
 | 
						|
  fclose(in_file);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// int get_file(char *name, String &str)
 | 
						|
//
 | 
						|
// Looks for a file and converts it into a String.  
 | 
						|
//
 | 
						|
// Inputs : name  = filename
 | 
						|
//          str   = String
 | 
						|
//
 | 
						|
// Output : 0 on success, -1 on failure.
 | 
						|
//
 | 
						|
// Side Effects : None
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
int get_file(char *name, String &str) {
 | 
						|
 | 
						|
  FILE  *f;
 | 
						|
  char   filename[256];
 | 
						|
  int    found = 0;
 | 
						|
  Dnode  *d;
 | 
						|
 | 
						|
  if (!include_init) return -1;    // Not initialized yet
 | 
						|
 | 
						|
  if (Verbose) fprintf(stderr,"Looking for %s\n", name);
 | 
						|
  if ((f = fopen(name,"r")) != NULL) {
 | 
						|
      copy_data(f,str);
 | 
						|
      return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  // Now start searching libraries
 | 
						|
 | 
						|
  d = ihead.next;               // Start of search list
 | 
						|
  while (d != &iz) {
 | 
						|
    // Look for the wrap file in language directory
 | 
						|
    sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name);
 | 
						|
    if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
 | 
						|
    if((f = fopen(filename,"r")) != NULL) {
 | 
						|
      found = 1;
 | 
						|
    } else {
 | 
						|
      sprintf(filename,"%s%c%s", d->dirname, DELIMETER, name);
 | 
						|
      if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
 | 
						|
      if ((f = fopen(filename,"r")) != NULL) {
 | 
						|
	found = 1;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (found) {
 | 
						|
	copy_data(f,str);
 | 
						|
	return 0;
 | 
						|
    }
 | 
						|
    d = d->next;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((!found)) fprintf(stderr,"SWIG Error. Unable to find %s. Possible installation problem.\n",name);
 | 
						|
  FatalError();
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
static char *libs[1000];
 | 
						|
static int   nlibs = 0;
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void library_add(char *name)
 | 
						|
//
 | 
						|
// Adds a filename to the list of libraries.   This is usually only called by
 | 
						|
// the SWIG main program.
 | 
						|
//
 | 
						|
// Inputs : name  = library name
 | 
						|
//
 | 
						|
// Outputs: None
 | 
						|
//
 | 
						|
// Side Effects : Adds the library name to the libs array above
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void library_add(char *name) {
 | 
						|
  int i;
 | 
						|
 | 
						|
  // Check to make sure it's not already added
 | 
						|
 | 
						|
  if (!(*name)) return;
 | 
						|
 | 
						|
  for (i = 0; i < nlibs; i++) {
 | 
						|
    if (strcmp(libs[i],name) == 0) return;
 | 
						|
  }
 | 
						|
 | 
						|
  libs[nlibs] = copy_string(name);
 | 
						|
  nlibs++;
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void library_insert()
 | 
						|
// 
 | 
						|
// Starts parsing all of the SWIG library files.
 | 
						|
// 
 | 
						|
// Inputs : None
 | 
						|
//
 | 
						|
// Output : None
 | 
						|
//
 | 
						|
// Side Effects : Opens and attaches all of the specified library files to
 | 
						|
//                the scanner.
 | 
						|
//
 | 
						|
// Bugs : Opens all of the files.   Will fail if there are too many open files.
 | 
						|
//
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void library_insert() {
 | 
						|
  int i;
 | 
						|
 | 
						|
  i = nlibs-1;
 | 
						|
  while (i >= 0) {
 | 
						|
    include_file(libs[i]);
 | 
						|
    i--;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// int checkout(char *filename,char *dest) 
 | 
						|
// 
 | 
						|
// Tries to check a file out of the SWIG library. If found, it will save it in
 | 
						|
// the current directory.   This is a useful mechanism for using SWIG as a code
 | 
						|
// manager and for extracting library files.
 | 
						|
//
 | 
						|
// Inputs : filename = Library file
 | 
						|
//          dest     = Destination file
 | 
						|
//
 | 
						|
// Output : 0 on success
 | 
						|
//         -1 on failure.
 | 
						|
//
 | 
						|
// Side Effects :  None
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
int checkout_file(char *filename,char *dest) {
 | 
						|
 | 
						|
  FILE *f1;
 | 
						|
  char tempn[256];
 | 
						|
 | 
						|
  // First check to see if the file already exists in current directory
 | 
						|
  f1 = fopen(dest,"r");
 | 
						|
  if (f1) {
 | 
						|
    if (Verbose)
 | 
						|
      fprintf(stderr,"Warning. Unable to check-out %s. File already exists.\n", filename);
 | 
						|
    fclose(f1);
 | 
						|
    return -1;
 | 
						|
  } 
 | 
						|
 | 
						|
  while (!f1) {
 | 
						|
    sprintf(tempn,"%s%d",dest,rand());
 | 
						|
    f1 = fopen(tempn,"r");
 | 
						|
    if (f1) {
 | 
						|
      fclose(f1);
 | 
						|
      f1 = 0;
 | 
						|
    } else {
 | 
						|
      f1 = fopen(tempn,"w");
 | 
						|
      if (!f1) {
 | 
						|
	fprintf(stderr,"Unable to open %s for writing\n", tempn);
 | 
						|
	return -1;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // Now try to insert the library file into the destination file
 | 
						|
  if ((insert_file(filename,f1)) == -1) {
 | 
						|
    fprintf(stderr,"Unable to check-out '%s'. File does not exist in SWIG library.\n",filename);
 | 
						|
    fclose(f1);
 | 
						|
    remove(tempn);       // Unsuccessful, remove file we created
 | 
						|
    return -1;
 | 
						|
  }
 | 
						|
  fclose(f1);
 | 
						|
  // Now move the file
 | 
						|
  rename(tempn,dest);
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// int checkin_file(char *dir, char *lang, char *source,char *dest) 
 | 
						|
// 
 | 
						|
// Attempts to check a file into the SWIG library.  
 | 
						|
//
 | 
						|
// Inputs : dir      = Location of the SWIG library.
 | 
						|
//          lang     = Language specific subdirectory.
 | 
						|
//          source   = Source file.
 | 
						|
//          dest     = Destination file.
 | 
						|
//
 | 
						|
// Output : 0 on success
 | 
						|
//         -1 on failure.
 | 
						|
//
 | 
						|
// Side Effects :  None
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
int checkin_file(char *dir, char *lang, char *source, char *dest) {
 | 
						|
 | 
						|
  FILE *f1;
 | 
						|
  char tempn[256];
 | 
						|
  String s;
 | 
						|
 | 
						|
  // First check to see if the file exists
 | 
						|
  
 | 
						|
  f1 = fopen(source,"r");
 | 
						|
  if (!f1) return -1;
 | 
						|
 | 
						|
  copy_data(f1,s);
 | 
						|
 | 
						|
  // Now try to open the destination file
 | 
						|
  sprintf(tempn,"%s/%s/%s", dir,lang,dest);
 | 
						|
  f1 = fopen(tempn,"w");
 | 
						|
  if (!f1) return -1;
 | 
						|
  fprintf(f1,"%s",s.get());
 | 
						|
  fclose(f1);
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
     
 | 
						|
 |