Files
harbour-core/harbour/source/compiler/fixflex.c

311 lines
12 KiB
C

/* $Id$
Harbour Project source code
This file contains an external program that splits the Harbour Flex and
Bison generated source code into multiple modules so that they can be
compiled by 16-bit C compilers with a 64KB per module data size limit.
Copyright 1999 David G. Holm
www - http://www.harbour-project.org
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
their web site at http://www.gnu.org/).
V 1.5 David G. Holm Switched from using a series of if
statements for the smaller large files
to using an array of table names and a
for loop and removed yy_acclist, which
is no longer used
V 1.4 Gonzalo A. Diethelm Added RCS Id keyword
V 1.3 David G. Holm Split the two largest tables into
separate modules and the four next
largest tables into a third module
V 1.2 David G. Holm Modified to work with both C and
C++ compilers
V 1.1 David G. Holm Submitted to the Harbor Project
V 1.0 David G. Holm Original Version
*/
#include <dir.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <share.h>
#include <stdio.h>
#include <string.h>
#define BUF_SIZE 4095
void fixup (char * inbuf, char * outbuf, int c_plus_plus)
{
char * ptr;
if (c_plus_plus)
{
/* If compiling for C++, the arrays need to be extern "C" in both modules */
static char tempbuf [BUF_SIZE];
strcpy (tempbuf, "extern \"C\" ");
strcpy (outbuf, tempbuf);
strcat (outbuf, inbuf + 7);
strcat (tempbuf, inbuf + 7);
strcpy (inbuf, tempbuf);
}
else
{
/* if compiling for C, the arrays only need to be extern in lexyy.c */
strcpy (outbuf, inbuf + 7);
memcpy (inbuf, "extern", 6);
}
ptr = strchr (inbuf, '=');
if (ptr) *ptr = ';';
}
int main (int argc, char * argv [])
{
int c_plus_plus = 0, rc = 0;
char backup [MAXPATH];
if (argc < 4)
{
/* Must have at least 4 arguments. */
rc = 1;
puts ("\nUsage: FIXFLEX source dest1 dest2 dest3 [-P[+|-]]\n\n\Where source is the name of the generated FLEX source file, dest1 and dest2\n\are the names of the source files to extract the two largest flex tables into\n\and -P or -P+ is needed when compiling Harbour using C++ instead of C.\nNote: -P- may be used to indicate the default of compiling Harbour using ANSI C.");
}
else
{
int i;
size_t len;
for (i = 5; i < argc; i++)
{
if (strcmp (argv[i], "-P") == 0) c_plus_plus = 1;
if (strcmp (argv[i], "-P+") == 0) c_plus_plus = 1;
if (strcmp (argv[i], "-P-") == 0) c_plus_plus = 0;
}
/* Rename source to backup. */
strcpy (backup, argv[1]);
len = strlen (backup);
for (i = 1; i < 4; i++) if (backup [len - i] == '.') backup [len - i] = 0;
strcat (backup, ".bak");
if (rename (argv[1], backup))
{
rc = 10;
printf ("\nError %d (DOS error %02xd) renaming %s to %s.", errno, _doserrno, argv[1], backup);
}
}
if (rc == 0)
{
/* Read from backup as source. */
FILE * source = fopen (backup, "r");
if (!source)
{
rc = 11;
printf ("\nUnable to open %s for reading.", backup);
}
else
{
/* Create new source. */
FILE * replace = fopen (argv[1], "w");
if (!replace)
{
rc = 12;
printf ("\nUnable to create %s for writing (after renaming to %s).", argv[1], backup);
}
else
{
/* Create dest 1. */
FILE * dest1, * dest2, * dest3;
dest1 = fopen (argv[2], "w");
if (!dest1)
{
rc = 13;
printf ("\nUnable to create %s for writing.", argv[2]);
}
/* Create dest 2. */
dest2 = fopen (argv[3], "w");
if (!dest2)
{
rc = 17;
printf ("\nUnable to create %s for writing.", argv[3]);
}
/* Create dest 2. */
dest3 = fopen (argv[4], "w");
if (!dest3)
{
rc = 19;
printf ("\nUnable to create %s for writing.", argv[4]);
}
if (rc == 0)
{
/* Initialize. */
int copy = 0, move1 = 0, move2 = 0, move3 = 0, check_count = 6;
int defer_move = 0, defer_end = 0;
static char inbuf [BUF_SIZE + 1];
static char outbuf [sizeof (inbuf)];
do
{
/* Read from source */
fgets (inbuf, BUF_SIZE, source);
if (ferror (source))
{
rc = 14;
printf ("\nError %d (DOS error %02xd) reading from %s.", errno, _doserrno, backup);
}
else
{
char * ptr;
strcpy (outbuf, inbuf);
/* Check for stuff to copy or move to dest. */
if (check_count > 0 && !move1 && !move2 && !move3 && !copy)
{
ptr = strstr (inbuf, "yy_nxt");
if (ptr)
{
/* It's the first of the two big tables.
Move it out of source into dest1, leaving only
an extern or extern "C" declaration. */
printf("\nLocated table yy_nxt");
fixup (inbuf, outbuf, c_plus_plus);
move1 = 1;
defer_move = 1;
check_count--;
}
else
{
ptr = strstr (inbuf, "yy_chk");
if (ptr)
{
/* It's the second of the two big tables.
Move it out of source into dest2, leaving only
an extern or extern "C" declaration. */
printf("\nLocated table yy_chk");
fixup (inbuf, outbuf, c_plus_plus);
move2 = 1;
defer_move = 1;
check_count--;
}
else
{
ptr = strstr (inbuf, "#define FLEX_SCANNER");
if (ptr)
{
/* It's the start of various #defines that
need to be copied from source to dest in
order to set up the yyconst define. */
printf("\nLocated first #define to copy");
copy = 1;
check_count--;
}
else
{
#define TABLE_MAX 3
int i;
char * table [TABLE_MAX] =
{ "yy_accept", "yy_base", "yy_def" };
ptr = 0;
for( i = 0; i < TABLE_MAX && !ptr; i++ )
{
ptr = strstr (inbuf, table [i]);
if (ptr) printf("\nLocated table %s", table [i]);
}
if (ptr)
{
/* It's one of the smaller big tables.
Move them all out of source into dest3, leaving
only an extern or extern "C" declaration. */
fixup (inbuf, outbuf, c_plus_plus);
move3 = 1;
defer_move = 1;
check_count--;
}
}
}
}
}
else if (move1 || move2 || move3 || copy)
{
/* Check for stuff to end copy or move. */
ptr = strstr (inbuf, "}");
if (ptr && (move1 || move2 || move3)) defer_end = 1; /* End of table to move. */
else
{
ptr = strstr (inbuf, "#ifdef YY_USE_PROTOS");
if (ptr && copy)
{
printf("\nLocated last #define to copy");
copy = 0; /* End of #defines to copy. */
}
}
}
if (move1 || move2 || move3 || copy)
{
/* If moving or copying from source to dest, do so. */
if (copy || move1)
{
fputs (outbuf, dest1);
if (ferror (dest1))
{
rc = 15;
printf ("\nError %d (DOS error %02xd) writing to %s.", errno, _doserrno, argv[2]);
}
}
if (copy || move2)
{
fputs (outbuf, dest2);
if (ferror (dest2))
{
rc = 18;
printf ("\nError %d (DOS error %02xd) writing to %s.", errno, _doserrno, argv[3]);
}
}
if (copy || move3)
{
fputs (outbuf, dest3);
if (ferror (dest3))
{
rc = 20;
printf ("\nError %d (DOS error %02xd) writing to %s.", errno, _doserrno, argv[4]);
}
}
}
if (!feof (source) && ((!move1 && !move2 && !move3) || defer_move) && rc == 0)
{
/* If not moving to dest, then write to new source. */
fputs (inbuf, replace);
if (ferror (replace))
{
rc = 16;
printf ("\nError %d (DOS error %02xd) writing to %s (after renaming to %s).", errno, _doserrno, argv[1], backup);
}
}
/* Clean up. */
if (defer_move) defer_move = 0;
if (defer_end)
{
move1 = 0;
move2 = 0;
move3 = 0;
defer_end = 0;
}
}
} while (!feof (source) && rc == 0);
}
}
}
}
return (rc);
}