/ Check-in [e38c08d9]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Delete output files if this is a failed run.

Otherwise, the fail will stop a Makefile from progressing, but if you immediately run the build again, Make will think the output files are up to date, since they are newer (albeit incomplete/incorrect).

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | lemon-update-2010
Files: files | file ages | folders
SHA1: e38c08d9cdeb0476ac1a77cd3f29f547a8205835
User & Date: icculus 2010-02-14 05:34:43
Context
2010-02-14
05:42
Added option to not clip error output.

This is useful for IDEs and other tools that benefit from full path information, so they can jump directly to the error line in the source code. check-in: 90602030 user: icculus tags: lemon-update-2010

05:34
Delete output files if this is a failed run.

Otherwise, the fail will stop a Makefile from progressing, but if you immediately run the build again, Make will think the output files are up to date, since they are newer (albeit incomplete/incorrect). check-in: e38c08d9 user: icculus tags: lemon-update-2010

05:19
Added %expect directive, to consider a certain number of conflicts "correct."

This has the side effect of changing the process exit code to never overflow. check-in: d8bab8cf user: icculus tags: lemon-update-2010

Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to tool/lemon.c.

    29     29   #define PRIVATE
    30     30   
    31     31   #ifdef TEST
    32     32   #define MAXRHS 5       /* Set low to exercise exception code */
    33     33   #else
    34     34   #define MAXRHS 1000
    35     35   #endif
           36  +
           37  +static const char **made_files = NULL;
           38  +static int made_files_count = 0;
           39  +static int successful_exit = 0;
           40  +static void LemonAtExit(void)
           41  +{
           42  +    /* if we failed, delete (most) files we made, to unconfuse build tools. */
           43  +    int i;
           44  +    for (i = 0; i < made_files_count; i++) {
           45  +        if (!successful_exit) {
           46  +            remove(made_files[i]);
           47  +        }
           48  +        free((void *) made_files[i]);
           49  +    }
           50  +    free(made_files);
           51  +    made_files_count = 0;
           52  +    made_files = NULL;
           53  +}
    36     54   
    37     55   static char *msort(char*,char**,int(*)(const char*,const char*));
    38     56   
    39     57   /*
    40     58   ** Compilers are getting increasingly pedantic about type conversions
    41     59   ** as C evolves ever closer to Ada....  To work around the latest problems
    42     60   ** we have to define the following variant of strlen().
................................................................................
  1465   1483                                      "Print parser stats to standard output."},
  1466   1484       {OPT_FLAG, "x", (char*)&version, "Print the version number."},
  1467   1485       {OPT_FLAG,0,0,0}
  1468   1486     };
  1469   1487     int i;
  1470   1488     int exitcode;
  1471   1489     struct lemon lem;
         1490  +
         1491  +  atexit(LemonAtExit);
  1472   1492   
  1473   1493     OptInit(argv,options,stderr);
  1474   1494     if( version ){
  1475   1495        printf("Lemon version 1.0\n");
  1476   1496        exit(0); 
  1477   1497     }
  1478   1498     if( OptNArgs()!=1 ){
................................................................................
  1572   1592     }
  1573   1593     if( lem.nconflict != lem.nexpected ){
  1574   1594       fprintf(stderr,"%d parsing conflicts (%d expected).\n",lem.nconflict,lem.nexpected);
  1575   1595     }
  1576   1596   
  1577   1597     /* return 0 on success, 1 on failure. */
  1578   1598     exitcode = ((lem.errorcnt > 0) || (lem.nconflict != lem.nexpected)) ? 1 : 0;
         1599  +  successful_exit = (exitcode == 0);
  1579   1600     exit(exitcode);
  1580   1601     return (exitcode);
  1581   1602   }
  1582   1603   /******************** From the file "msort.c" *******************************/
  1583   1604   /*
  1584   1605   ** A generic merge-sort program.
  1585   1606   **
................................................................................
  2827   2848     lemp->outname = file_makename(lemp, suffix);
  2828   2849     fp = fopen(lemp->outname,mode);
  2829   2850     if( fp==0 && *mode=='w' ){
  2830   2851       fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname);
  2831   2852       lemp->errorcnt++;
  2832   2853       return 0;
  2833   2854     }
         2855  +
         2856  +  /* Add files we create to a list, so we can delete them if we fail. This
         2857  +  ** is to keep makefiles from getting confused. We don't include .out files,
         2858  +  ** though: this is debug information, and you don't want it deleted if there
         2859  +  ** was an error you need to track down.
         2860  +  */
         2861  +  if(( *mode=='w' ) && (strcmp(suffix, ".out") != 0)){
         2862  +    const char **ptr = (const char **)
         2863  +        realloc(made_files, sizeof (const char **) * (made_files_count + 1));
         2864  +    char *fname = strdup(lemp->outname);
         2865  +    if ((ptr == NULL) || (fname == NULL)) {
         2866  +        free(ptr);
         2867  +        free(fname);
         2868  +        memory_error();
         2869  +    }
         2870  +    made_files = ptr;
         2871  +    made_files[made_files_count++] = fname;
         2872  +  }
  2834   2873     return fp;
  2835   2874   }
  2836   2875   
  2837   2876   /* Duplicate the input file without comments and without actions 
  2838   2877   ** on rules */
  2839   2878   void Reprint(lemp)
  2840   2879   struct lemon *lemp;