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.
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.
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.
Thanks for the patch!
I took it in SVN revision 98.
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*/
Thanks. It was a carelessness of me to fail to find the problem.
I took the patch, and committed SVN revision 99.