1 /*
2     Copyright 2007 Rene Rivera
3     Distributed under the Boost Software License, Version 1.0.
4     (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
5 */
6 
7 #include "jam.h"
8 #include "output.h"
9 
10 #include <stdio.h>
11 #include <stdarg.h>
12 
13 
14 #define bjam_out (stdout)
15 #define bjam_err (stderr)
16 
out_(char const * data,FILE * const io)17 static void out_( char const * data, FILE * const io )
18 {
19     while ( *data )
20     {
21         size_t const len = strcspn( data, "\r" );
22         data += fwrite( data, 1, len, io );
23         if ( *data == '\r' ) ++data;
24     }
25 }
26 
27 
out_flush()28 void out_flush()
29 {
30     fflush( bjam_out );
31     if ( globs.out ) fflush( globs.out );
32 }
err_flush()33 void err_flush()
34 {
35     fflush( bjam_err );
36     if ( globs.out ) fflush( globs.out );
37 }
out_puts(char const * const s)38 void out_puts(char const * const s)
39 {
40     fputs( s, bjam_out );
41     if ( globs.out ) fputs( s, globs.out );
42 }
err_puts(char const * const s)43 void err_puts(char const * const s)
44 {
45     fputs( s, bjam_err );
46     if ( globs.out ) fputs( s, globs.out );
47 }
out_putc(const char c)48 void out_putc(const char c)
49 {
50     fputc( c, bjam_out );
51     if ( globs.out ) fputc( c, globs.out );
52 }
err_putc(const char c)53 void err_putc(const char c)
54 {
55     fputc( c, bjam_err );
56     if ( globs.out ) fputc( c, globs.out );
57 }
out_data(char const * const s)58 void out_data(char const * const s)
59 {
60     out_( s, bjam_out );
61     if ( globs.out ) out_( s, globs.out );
62 }
err_data(char const * const s)63 void err_data(char const * const s)
64 {
65     out_( s, bjam_err );
66     if ( globs.out ) out_( s, globs.out );
67 }
out_printf(char const * const f,...)68 void out_printf(char const * const f, ...)
69 {
70     {
71         va_list args;
72         va_start( args, f );
73         vfprintf( bjam_out, f, args );
74         va_end( args );
75     }
76     if ( globs.out )
77     {
78         va_list args;
79         va_start( args, f );
80         vfprintf( globs.out, f, args );
81         va_end( args );
82     }
83 }
err_printf(char const * const f,...)84 void err_printf(char const * const f, ...)
85 {
86     {
87         va_list args;
88         va_start( args, f );
89         vfprintf( bjam_err, f, args );
90         va_end( args );
91     }
92     if ( globs.out )
93     {
94         va_list args;
95         va_start( args, f );
96         vfprintf( globs.out, f, args );
97         va_end( args );
98     }
99 }
100 
101 
out_action(char const * const action,char const * const target,char const * const command,char const * const out_d,char const * const err_d,int const exit_reason)102 void out_action
103 (
104     char const * const action,
105     char const * const target,
106     char const * const command,
107     char const * const out_d,
108     char const * const err_d,
109     int const exit_reason
110 )
111 {
112     /* Print out the action + target line, if the action is quiet the action
113      * should be null.
114      */
115     if ( action )
116         out_printf( "%s %s\n", action, target );
117 
118     /* Print out the command executed if given -d+2. */
119     if ( DEBUG_EXEC )
120     {
121         out_puts( command );
122         out_putc( '\n' );
123     }
124 
125     /* Print out the command output, if requested, or if the program failed, but
126      * only output for non-quiet actions.
127      */
128     if ( action || exit_reason != EXIT_OK )
129     {
130         if ( out_d &&
131            ( ( globs.pipe_action & 1 /* STDOUT_FILENO */ ) ||
132              ( globs.pipe_action == 0 ) ) )
133             out_data( out_d );
134         if ( err_d && ( globs.pipe_action & 2 /* STDERR_FILENO */ ) )
135             err_data( err_d );
136     }
137 }
138 
139 
outf_int(int const value)140 OBJECT * outf_int( int const value )
141 {
142     char buffer[ 50 ];
143     sprintf( buffer, "%i", value );
144     return object_new( buffer );
145 }
146 
147 
outf_double(double const value)148 OBJECT * outf_double( double const value )
149 {
150     char buffer[ 50 ];
151     sprintf( buffer, "%f", value );
152     return object_new( buffer );
153 }
154 
155 
outf_time(timestamp const * const time)156 OBJECT * outf_time( timestamp const * const time )
157 {
158     return object_new( timestamp_str( time ) );
159 }
160