Menu

mcpp library redirects stderr/stdout/stdin

2008-04-18
2013-05-28
  • Benoit Foucher

    Benoit Foucher - 2008-04-18

    Hi,

    When using the mcpp library, once mcpp_lib_main() returns, stdout/stdin/stderr don't work anymore and there are no easy and portable ways to restore the streams to their original state. To fix this, I changed the freopen() calls from the main method to fopen() calls. It would be great if this could be changed for the next mcpp release as it makes using the mcpp library difficult if the caller needs to use stderr/stdout/stdin.

    Here are the changes I made:

    diff -N -r -c mcpp-2.7/src/main.c mcpp-2.7-patched/src/main.c
    *** mcpp-2.7/src/main.c    Tue Mar 11 17:05:19 2008
    --- mcpp-2.7-patched/src/main.c    Fri Apr 18 13:03:38 2008
    ***************
    *** 371,377 ****
     
          /* Open input file, "-" means stdin.    */
          if (in_file != NULL && ! str_eq( in_file, "-")) {
    !         if (freopen( in_file, "r", fp_in) == NULL) {
                  mcpp_fprintf( ERR, "Can't open input file \"%s\".\n", in_file);
      #if MCPP_LIB
                  goto  fatal_error_exit;
    --- 371,377 ----
     
          /* Open input file, "-" means stdin.    */
          if (in_file != NULL && ! str_eq( in_file, "-")) {
    !         if ((fp_in = fopen( in_file, "r")) == NULL) {
                  mcpp_fprintf( ERR, "Can't open input file \"%s\".\n", in_file);
      #if MCPP_LIB
                  goto  fatal_error_exit;
    ***************
    *** 384,390 ****
          }
          /* Open output file, "-" means stdout.  */
          if (out_file != NULL && ! str_eq( out_file, "-")) {
    !         if (freopen( out_file, "w", fp_out) == NULL) {
                  mcpp_fprintf( ERR, "Can't open output file \"%s\".\n", out_file);
      #if MCPP_LIB
                  goto  fatal_error_exit;
    --- 384,390 ----
          }
          /* Open output file, "-" means stdout.  */
          if (out_file != NULL && ! str_eq( out_file, "-")) {
    !         if ((fp_out = fopen( out_file, "w")) == NULL) {
                  mcpp_fprintf( ERR, "Can't open output file \"%s\".\n", out_file);
      #if MCPP_LIB
                  goto  fatal_error_exit;
    ***************
    *** 394,400 ****
              }
          }
          if (option_flags.q) {                   /* Redirect diagnostics */
    !         if (freopen( "mcpp.err", "a", fp_err) == NULL) {
                  mcpp_fprintf( OUT, "Can't open \"mcpp.err\"\n");
      #if MCPP_LIB
                  goto  fatal_error_exit;
    --- 394,400 ----
              }
          }
          if (option_flags.q) {                   /* Redirect diagnostics */
    !         if ((fp_err = fopen( "mcpp.err", "a")) == NULL) {
                  mcpp_fprintf( OUT, "Can't open \"mcpp.err\"\n");
      #if MCPP_LIB
                  goto  fatal_error_exit;
    ***************
    *** 430,435 ****
    --- 430,440 ----
          clear_symtable();
      #endif
     
    +     if(fp_out != stdout)
    +         fclose( fp_out);
    +     if(fp_err != stderr)
    +         fclose( fp_err);
    +
          if (mcpp_debug & MEMORY)
              print_heap();
          if (errors > 0 && option_flags.no_source_line == FALSE) {
    diff -N -r -c mcpp-2.7/src/support.c mcpp-2.7-patched/src/support.c
    *** mcpp-2.7/src/support.c    Tue Mar 11 14:50:02 2008
    --- mcpp-2.7-patched/src/support.c    Fri Apr 18 11:11:57 2008
    ***************
    *** 1585,1591 ****
          if (file->fp) {                         /* Source file included */
              free( file->filename);              /* Free filename        */
              free( file->src_dir);               /* Free src_dir         */
    !         fclose( file->fp);                  /* Close finished file  */
              /* Do not free file->real_fname and file->full_fname        */
              cur_fullname = infile->full_fname;
              cur_fname = infile->real_fname;     /* Restore current fname*/
    --- 1585,1592 ----
          if (file->fp) {                         /* Source file included */
              free( file->filename);              /* Free filename        */
              free( file->src_dir);               /* Free src_dir         */
    !         if(file->fp != stdin)
    !             fclose( file->fp);              /* Close finished file  */
              /* Do not free file->real_fname and file->full_fname        */
              cur_fullname = infile->full_fname;
              cur_fname = infile->real_fname;     /* Restore current fname*/
    diff -N -r -c mcpp-2.7/src/system.c mcpp-2.7-patched/src/system.c
    *** mcpp-2.7/src/system.c    Tue Mar 18 10:05:57 2008
    --- mcpp-2.7-patched/src/system.c    Fri Apr 18 11:11:31 2008
    ***************
    *** 3349,3355 ****
               * The state will be restored by get_line() on end of the included.
               */
              file->pos = ftell( file->fp);
    !         fclose( file->fp);
              /* In case of failure, re-open the includer */
              if ((fp = fopen( fullname, "r")) == NULL) {
                  file->fp = fopen( cur_fullname, "r");
    --- 3349,3356 ----
               * The state will be restored by get_line() on end of the included.
               */
              file->pos = ftell( file->fp);
    !         if(file->fp != stdin)
    !             fclose( file->fp);
              /* In case of failure, re-open the includer */
              if ((fp = fopen( fullname, "r")) == NULL) {
                  file->fp = fopen( cur_fullname, "r");

    Thanks!

    Regards,
    Benoit.

     
    • Kiyoshi Matsui

      Kiyoshi Matsui - 2008-04-20

      Thanks for the patch!
      I took it in SVN revision 98.

       
    • Benoit Foucher

      Benoit Foucher - 2008-04-25

      Thanks for including the patch!

      However, I think there's a small issue with my patch: the input file doesn't get closed. I incorrectly assumed that it would get closed by get_ch() from support.c when the parsing is done. I've attached below a small patch to fix this.

      iff -r -c mcpp-2.7-patched/src/main.c mcpp-2.7-patched2/src/main.c
      *** mcpp-2.7-patched/src/main.c    Fri Apr 25 15:01:35 2008
      --- mcpp-2.7-patched2/src/main.c    Fri Apr 25 15:05:40 2008
      ***************
      *** 430,435 ****
      --- 430,437 ----
            clear_symtable();
        #endif
       
      +     if(fp_in != stdin)
      +         fclose( fp_in);
            if(fp_out != stdout)
                fclose( fp_out);
            if(fp_err != stderr)
      diff -r -c mcpp-2.7-patched/src/support.c mcpp-2.7-patched2/src/support.c
      *** mcpp-2.7-patched/src/support.c    Fri Apr 25 15:01:35 2008
      --- mcpp-2.7-patched2/src/support.c    Fri Apr 25 15:02:39 2008
      ***************
      *** 1585,1592 ****
            if (file->fp) {                         /* Source file included */
                free( file->filename);              /* Free filename        */
                free( file->src_dir);               /* Free src_dir         */
      !         if(file->fp != stdin)
      !             fclose( file->fp);              /* Close finished file  */
                /* Do not free file->real_fname and file->full_fname        */
                cur_fullname = infile->full_fname;
                cur_fname = infile->real_fname;     /* Restore current fname*/
      --- 1585,1591 ----
            if (file->fp) {                         /* Source file included */
                free( file->filename);              /* Free filename        */
                free( file->src_dir);               /* Free src_dir         */
      !         fclose( file->fp);                  /* Close finished file  */
                /* Do not free file->real_fname and file->full_fname        */
                cur_fullname = infile->full_fname;
                cur_fname = infile->real_fname;     /* Restore current fname*/

       
    • Kiyoshi Matsui

      Kiyoshi Matsui - 2008-05-02

      Thanks.  It was a carelessness of me to fail to find the problem.
      I took the patch, and committed SVN revision 99.

       

Log in to post a comment.