#include #include #include #include #include #include #include #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 = 7; 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. */ 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. */ 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. */ copy = 1; check_count--; } else { ptr = strstr (inbuf, "yy_acclist"); if (!ptr) ptr = strstr (inbuf, "yy_accept"); if (!ptr) ptr = strstr (inbuf, "yy_base"); if (!ptr) ptr = strstr (inbuf, "yy_def"); 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) 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); }