Write some initial code to allow for output redirection

--HG--
extra : convert_revision : svn%3Aeff31bef-be4a-0410-a8fe-e47997df2690/trunk%40116
issue20
tibs 2009-02-16 21:45:34 +00:00
rodzic 84a69a90d4
commit 2f658aa0a3
6 zmienionych plików z 532 dodań i 3 usunięć

Wyświetl plik

@ -102,6 +102,7 @@ SRCS = \
l2audio.c \
misc.c \
nalunit.c \
printing.c \
ps.c \
pes.c \
pidint.c \
@ -128,6 +129,7 @@ OBJS = \
ps.o \
pes.o \
pidint.o \
printing.o \
reverse.o \
ts.o \
tswrite.o \
@ -161,6 +163,7 @@ PROG_OBJS = \
TS2PS_OBJS = $(OBJDIR)/ts2ps.o
TEST_PES_OBJS = $(OBJDIR)/test_pes.o
TEST_PRINTING_OBJS = $(OBJDIR)/test_printing.o
TEST_OBJS = \
$(OBJDIR)/test_nal_unit_list.o \
@ -197,6 +200,7 @@ TS2PS_PROG = $(BINDIR)/ts2ps
# Is test_pes still useful?
TEST_PES_PROG = $(BINDIR)/test_pes
TEST_PRINTING_PROG = $(BINDIR)/test_printing
# And then the testing programs (which we only build if we are
# running the tests)
@ -283,6 +287,9 @@ $(BINDIR)/pcapreport: $(OBJDIR)/pcapreport.o $(LIB)
$(BINDIR)/test_pes: $(OBJDIR)/test_pes.o $(LIB)
$(CC) $< -o $(BINDIR)/test_pes $(LDFLAGS) $(LIBOPTS)
$(BINDIR)/test_printing: $(OBJDIR)/test_printing.o $(LIB)
$(CC) $< -o $(BINDIR)/test_printing $(LDFLAGS) $(LIBOPTS)
$(BINDIR)/test_nal_unit_list: $(OBJDIR)/test_nal_unit_list.o $(LIB)
$(CC) $< -o $(BINDIR)/test_nal_unit_list $(LDFLAGS) $(LIBOPTS)
$(BINDIR)/test_es_unit_list: $(OBJDIR)/test_es_unit_list.o $(LIB)
@ -305,13 +312,14 @@ REVERSE_H = reverse_fns.h reverse_defns.h
FILTER_H = filter_fns.h filter_defns.h $(REVERSE_H)
AUDIO_H = adts_fns.h l2audio_fns.h ac3_fns.h audio_fns.h audio_defns.h adts_defns.h
# Everyone depends upon the basic configuration file
$(LIB)($(OBJS)) $(TEST_OBJS) $(PROG_OBJS): compat.h
# Everyone depends upon the basic configuration file, and I assert they all
# want (or may want) printing...
$(LIB)($(OBJS)) $(TEST_OBJS) $(PROG_OBJS): compat.h printing_fns.h
# Which library modules depend on which header files is complex, so
# lets just be simple
$(LIB)($(OBJS)): $(ACCESSUNIT_H) $(NALUNIT_H) $(TS_H) $(ES_H) $(PES_H) \
misc_fns.h $(PS_H) $(H262_H) $(TSWRITE_H) $(AVS_H) \
misc_fns.h printing_fns.h $(PS_H) $(H262_H) $(TSWRITE_H) $(AVS_H) \
$(REVERSE_H) $(FILTER_H) $(AUDIO_H)
$(OBJDIR)/es2ts.o: es2ts.c $(ES_H) $(TS_H) misc_fns.h version.h
@ -359,6 +367,8 @@ $(OBJDIR)/pcapreport.o: pcapreport.c pcap.h version.h misc_fns.h
$(OBJDIR)/test_pes.o: test_pes.c $(TS_H) $(PS_H) $(ES_H) misc_fns.h $(PES_H) version.h
$(CC) -c $< -o $@ $(CFLAGS)
$(OBJDIR)/test_printing.o: test_printing.c $(TS_H) $(PS_H) $(ES_H) version.h
$(CC) -c $< -o $@ $(CFLAGS)
$(OBJDIR)/test_ps.o: test_ps.c $(PS_H) misc_fns.h version.h
$(CC) -c $< -o $@ $(CFLAGS)
$(OBJDIR)/test_nal_unit_list.o: test_nal_unit_list.c $(NALUNIT_H) version.h
@ -386,6 +396,7 @@ objclean:
-rm -f $(TEST_PROGS)
-rm -f $(TS2PS_OBJS) $(TS2PS_PROG)
-rm -f $(TEST_PES_OBJS) $(TEST_PES_PROG)
-rm -f $(TEST_PRINTING_OBJS) $(TEST_PRINTING_PROG)
-rm -f ES_test3.ts es_test3.ts
-rm -f ES_test2.264 es_test3.264
-rm -f es_test_a.ts es_test_a.264
@ -406,6 +417,10 @@ distclean: clean
TESTDATAFILE = /data/video/CVBt_hp_trail.264
# Only build test_printing if explicitly asked to do so
.PHONY: test_printing
test_printing: $(BINDIR)/test_printing
# Only build test_pes if explicitly asked to do so
.PHONY: test_pes
test_pes: $(BINDIR)/test_pes

Wyświetl plik

@ -107,6 +107,7 @@ LIB_OBJS = \
$(OBJDIR)\pcap.obj \
$(OBJDIR)\pes.obj \
$(OBJDIR)\pidint.obj \
$(OBJDIR)\printing.obj \
$(OBJDIR)\ps.obj \
$(OBJDIR)\reverse.obj \
$(OBJDIR)\ts.obj \

199
printing.c 100644
Wyświetl plik

@ -0,0 +1,199 @@
/*
* Support for printing out to stdout/stderr/elsewhere -- functions to use
* instead of printf, etc.
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the MPEG TS, PS and ES tools.
*
* The Initial Developer of the Original Code is Amino Communications Ltd.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Amino Communications Ltd, Swavesey, Cambridge UK
*
* ***** END LICENSE BLOCK *****
*/
#include <stdio.h>
#include <stdarg.h>
#include "compat.h"
#include "printing_fns.h"
// ============================================================
// Default printing functions
// ============================================================
static int print_message_to_stdout(const char *message)
{
return (fputs(message,stdout) == 0 ? 0:1);
}
static int print_message_to_stderr(const char *message)
{
return (fputs(message,stderr) == 0 ? 0:1);
}
static int fprint_message_to_stdout(const char *format, va_list arg_ptr)
{
return (vfprintf(stdout, format, arg_ptr) < 0 ? 1:0);
}
static int fprint_message_to_stderr(const char *format, va_list arg_ptr)
{
return (vfprintf(stderr, format, arg_ptr) < 0 ? 1:0);
}
// ============================================================
// Print redirection
// ============================================================
static int (*print_message_fn) (const char *message) = print_message_to_stdout;
static int (*print_error_fn) (const char *message) = print_message_to_stdout;
static int (*fprint_message_fn) (const char *format, va_list arg_ptr) = fprint_message_to_stdout;
static int (*fprint_error_fn) (const char *format, va_list arg_ptr) = fprint_message_to_stdout;
// ============================================================
// Functions for printing
// ============================================================
/*
* Prints the given string, as a normal message.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int print_msg(const char *text)
{
return print_message_fn(text);
}
/*
* Prints the given string, as an error message.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int print_err(const char *text)
{
return print_error_fn(text);
}
/*
* Prints the given format text, as a normal message.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int fprint_msg(const char *format, ...)
{
int retval;
va_list va_arg;
va_start(va_arg, format);
retval = fprint_message_fn(format, va_arg);
va_end(va_arg);
return retval;
}
/*
* Prints the given formatted text, as an error message.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int fprint_err(const char *format, ...)
{
int retval;
va_list va_arg;
va_start(va_arg, format);
retval = fprint_error_fn(format, va_arg);
va_end(va_arg);
return retval;
}
// ============================================================
// Choosing what the printing functions do
// ============================================================
/*
* Calling this causes errors to go to stderr, and all other output
* to go to stdout. This is the "traditional" mechanism used by
* Unices.
*/
extern void redirect_output_traditional(void)
{
print_message_fn = &print_message_to_stdout;
print_error_fn = &print_message_to_stderr;
fprint_message_fn = &fprint_message_to_stdout;
fprint_error_fn = &fprint_message_to_stderr;
}
/*
* Calling this causes all output to go to stdout. This is simpler,
* and is likely to be more use to most users.
*
* This is the default state.
*/
extern void redirect_output_stdout(void)
{
print_message_fn = &print_message_to_stdout;
print_error_fn = &print_message_to_stdout;
fprint_message_fn = &fprint_message_to_stdout;
fprint_error_fn = &fprint_message_to_stdout;
}
/*
* This allows the user to specify a set of functions to use for
* formatted printing and non-formatted printing of errors and
* other messages.
*
* It is up to the caller to ensure that all of the functions
* make sense. All four functions must be specified.
*
* * `new_print_message_fn` takes a string and prints it out to the "normal"
* output stream.
* * `new_print_error_fn` takes a string and prints it out to the error output
* stream.
* * `new_fprint_message_fn` takes a printf-style format string and the
* appropriate arguments, and writes the result out to the "normal" output.
* * `new_fprint_error_fn` takes a printf-style format string and the
* appropriate arguments, and writes the result out to the "error" output.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int redirect_output( int (*new_print_message_fn) (const char *message),
int (*new_print_error_fn) (const char *message),
int (*new_fprint_message_fn) (const char *format, va_list arg_ptr),
int (*new_fprint_error_fn) (const char *format, va_list arg_ptr)
)
{
if (new_print_message_fn == NULL || new_print_error_fn == NULL ||
new_fprint_message_fn == NULL || new_fprint_error_fn == NULL)
return 1;
print_message_fn = new_print_message_fn;
print_error_fn = new_print_error_fn;
fprint_message_fn = new_fprint_message_fn;
fprint_error_fn = new_fprint_error_fn;
return 0;
}
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab:

43
printing_defns.h 100644
Wyświetl plik

@ -0,0 +1,43 @@
/*
* Support for printing out to stdout/stderr/elsewhere -- functions to use
* instead of printf, etc.
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the MPEG TS, PS and ES tools.
*
* The Initial Developer of the Original Code is Amino Communications Ltd.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Amino Communications Ltd, Swavesey, Cambridge UK
*
* ***** END LICENSE BLOCK *****
*/
#ifndef _printing_defns
#define _printing_defns
#include <stdio.h>
#include <stdarg.h>
#endif // _printing_defns
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab:

110
printing_fns.h 100644
Wyświetl plik

@ -0,0 +1,110 @@
/*
* Support for printing out to stdout/stderr/elsewhere -- functions to use
* instead of printf, etc.
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the MPEG TS, PS and ES tools.
*
* The Initial Developer of the Original Code is Amino Communications Ltd.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Amino Communications Ltd, Swavesey, Cambridge UK
*
* ***** END LICENSE BLOCK *****
*/
#ifndef _printing_fns
#define _printing_fns
#include "printing_defns.h"
// ============================================================
// Functions for printing
// ============================================================
/*
* Prints the given string, as a normal message.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int print_msg(const char *text);
/*
* Prints the given string, as an error message.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int print_err(const char *text);
/*
* Prints the given format text, as a normal message.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int fprint_msg(const char *format, ...);
/*
* Prints the given formatted text, as an error message.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int fprint_err(const char *format, ...);
// ============================================================
// Choosing what the printing functions do
// ============================================================
/*
* Calling this causes errors to go to stderr, and all other output
* to go to stdout. This is the "traditional" mechanism used by
* Unices.
*/
extern void redirect_output_traditional(void);
/*
* Calling this causes all output to go to stdout. This is simpler,
* and is likely to be more use to most users.
*
* This is the default state.
*/
extern void redirect_output_stdout(void);
/*
* This allows the user to specify a set of functions to use for
* formatted printing and non-formatted printing of errors and
* other messages.
*
* It is up to the caller to ensure that all of the functions
* make sense. All four functions must be specified.
*
* * `new_print_message_fn` takes a string and prints it out to the "normal"
* output stream.
* * `new_print_error_fn` takes a string and prints it out to the error output
* stream.
* * `new_fprint_message_fn` takes a printf-style format string and the
* appropriate arguments, and writes the result out to the "normal" output.
* * `new_fprint_error_fn` takes a printf-style format string and the
* appropriate arguments, and writes the result out to the "error" output.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int redirect_output( int (*new_print_message_fn) (const char *message),
int (*new_print_error_fn) (const char *message),
int (*new_fprint_message_fn) (const char *format, va_list arg_ptr),
int (*new_fprint_error_fn) (const char *format, va_list arg_ptr)
);
#endif // _printing_fns
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab:

161
test_printing.c 100644
Wyświetl plik

@ -0,0 +1,161 @@
/*
* Test the print redirection facilities
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the MPEG TS, PS and ES tools.
*
* The Initial Developer of the Original Code is Amino Communications Ltd.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Amino Communications Ltd, Swavesey, Cambridge UK
*
* ***** END LICENSE BLOCK *****
*/
#include <stdio.h>
#include "printing_fns.h"
#include "version.h"
// Some example redirection routines
static int print_message_to_stdout(const char *message)
{
(void) printf("<<<MSG>>> %s",message);
return 0;
}
static int print_message_to_stderr(const char *message)
{
(void) printf("<<<ERR>>> %s",message);
return 0;
}
static int fprint_message_to_stdout(const char *format, va_list arg_ptr)
{
printf("<<<MSG>>> ");
return (vfprintf(stdout, format, arg_ptr) < 0 ? 1:0);
}
static int fprint_message_to_stderr(const char *format, va_list arg_ptr)
{
printf("<<<ERR>>> ");
return (vfprintf(stdout, format, arg_ptr) < 0 ? 1:0);
}
static void print_usage()
{
printf(
"Usage: test_printing\n"
"\n"
);
REPORT_VERSION("test_printing");
printf(
"\n"
" Test the print redirection facilities.\n"
);
}
int main(int argc, char **argv)
{
int err;
if (argc > 1)
{
print_usage();
return 1;
}
printf("A fairly crude set of tests, mainly to check that nothing falls over.\n");
printf("For each set of tests, you should see 4 messages, all very similar.\n");
printf("------------------------------------\n");
printf("Testing the default output functions\n");
printf("------------------------------------\n");
print_msg("1. Printing a normal message\n");
print_err("2. Printing an error message\n");
fprint_msg("3. Printing a formatted '%s'\n","message");
fprint_err("4. Printing a formatted '%s'\n","error");
printf("-------------------------------------------\n");
printf("Choosing 'traditional' output and repeating\n");
printf("-------------------------------------------\n");
redirect_output_traditional();
print_msg("1. Printing a normal message\n");
print_err("2. Printing an error message\n");
fprint_msg("3. Printing a formatted '%s'\n","message");
fprint_err("4. Printing a formatted '%s'\n","error");
printf("---------------------------------------------\n");
printf("Choosing 'all output to stdout' and repeating\n");
printf("---------------------------------------------\n");
redirect_output_stdout();
print_msg("1. Printing a normal message\n");
print_err("2. Printing an error message\n");
fprint_msg("3. Printing a formatted '%s'\n","message");
fprint_err("4. Printing a formatted '%s'\n","error");
printf("-----------------------------------------\n");
printf("Choosing 'custom functions' and repeating\n");
printf("-----------------------------------------\n");
err = redirect_output(print_message_to_stdout,
print_message_to_stderr,
fprint_message_to_stdout,
fprint_message_to_stderr);
if (err)
{
printf("Oops -- that went wrong: %d\n",err);
return 1;
}
print_msg("1. Printing a normal message\n");
print_err("2. Printing an error message\n");
fprint_msg("3. Printing a formatted '%s'\n","message");
fprint_err("4. Printing a formatted '%s'\n","error");
printf("---------------------------------------------\n");
printf("Trying to choose only *some* custom functions\n");
printf("---------------------------------------------\n");
err = redirect_output(print_message_to_stdout,
print_message_to_stderr,
NULL,
fprint_message_to_stderr);
if (err == 0)
{
printf("Oh dear, that appeared to work: %d\n",err);
printf("So what happens if we try our tests again?\n");
print_msg("1. Printing a normal message\n");
print_err("2. Printing an error message\n");
fprint_msg("3. Printing a formatted '%s'\n","message");
fprint_err("4. Printing a formatted '%s'\n","error");
return 1;
}
printf("Which failed - good\n");
printf("------------------------------------------------------------------\n");
printf("After that (expected) failure, all four messages should still work\n");
printf("------------------------------------------------------------------\n");
print_msg("1. Printing a normal message\n");
print_err("2. Printing an error message\n");
fprint_msg("3. Printing a formatted '%s'\n","message");
fprint_err("4. Printing a formatted '%s'\n","error");
return 0;
}
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab: