stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject svn commit: r451079 - in /incubator/stdcxx/trunk/util: cmdopt.cpp cmdopt.h display.cpp display.h exec.cpp exec.h output.cpp output.h runall.cpp target.h util.cpp util.h
Date Fri, 29 Sep 2006 01:11:14 GMT
Author: sebor
Date: Thu Sep 28 18:11:13 2006
New Revision: 451079

URL: http://svn.apache.org/viewvc?view=rev&rev=451079
Log:
2006-09-28  Martin Sebor  <sebor@roguewave.com>

	* exec.cpp (wait_for_child): Added SIGQUIT to the array of signals
	to send to child.

2006-09-28  Andrew Black  <ablack@roguewave.com>

	* target.h: Add new header.
	(target_opts): Define.
	(rw_rlimit, ProcessStatus, target_status): Move from display.h.
	(rw_timeval, RLIM_INFINITY, RLIM_SAVED_CUR, RLIM_SAVED_MAX): Move from
	cmdopt.h.
	* cmdopt.h (rw_timeval, RLIM_INFINITY, RLIM_SAVED_CUR, RLIM_SAVED_MAX):
	Move to target.h.
	(timeout, compat, verbose, exe_opts, in_root, child_limits): Remove
	global declarations.
	(target_name): Move from global scope to runall.cpp local scope.
	(eval_options): Alter declaration to take storage structure, handle.
	(get_target): Declare, document accessor function defined in runall.cpp.
	* cmdopt.cpp (timeout, compat, verbose, exe_opts, in_root, target_name,
	child_limits): Remove global definitions.
	(usage_text): Remove -q and -v switch descriptions (they were unused).
	(parse_limit_opts): Alter definition to take storage structure, use
	storage structure.
	(eval_options): Alter definition to take storage structure, handle,
	update documentation, store parsed values in provided structure/handle,
	remove -q, -v switches.
	* display.h (rw_rlimit, ProcessStatus, target_status): Move to target.h.
	(short_st_name): Make immutable.
	(print_target): Alter declaration to take target_opts rather than
	target_status.
	* display.cpp (print_target_plain): Alter definition to match
	print_target.
	(print_status_plain): Alter usage to match changes to target_status
	structure.
	(short_st_name): Make immutable.
	(print_target): Alter definition to match declaration.
	* exec.h (exec_attrs): Remove.
	(target.h): Include.
	(exec_file): Alter declaration to accept target_opts in addition to
	target_status.
	* exec.cpp (target.h): Include instead of display.h.
	(open_input): Alter definition to take data_dir, update documentation.
	[!_WIN32 && !_WIN64] (alarm_timeout): Clean documentation slightly.
	[!_WIN32 && !_WIN64] (wait_for_child): Alter definition to take timeout,
	target_status, store results directly in struct.
	[!_WIN32 && !_WIN64] (LIMIT, limit_process): Alter definition to take
	target_opts, update documentation, check for valid pointer to limit
	structure rather than invalid values.
	[!_WIN32 && !_WIN64 && _XOPEN_UNIX] (calculate_usage): Store calculated
	times in static local vartiables, and store references to these
	variables in target_status struct.
	[!_WIN32 && !_WIN64] (exec_file): Alter to match prototype, altered
	function usage to match definitions.
	[_WIN32 || _WIN64] (kill_child_process): New helper function to simplify
	child process kill code.
	[_WIN32 || _WIN64] (exec_file): Alter to match prototype, altered
	functions to match definitions, use new helper function, some cleaning,
	process execution results.
	* output.h (parse_output): Alter declaration to take target_opts in
	addition to target_status.
	* output.cpp (check_test): Retrieve target_name via get_target.
	(check_example): Alter definition to take data_dir, update
	documentation.
	(parse_output): Alter definition to match prototype, use target_opts
	in place of removed globals.
	* runall.cpp (target.h): Included.
	(check_target_ok): Alter definition to take target (char*) in addition
	to target_status, retrieve target_name via get_target.
	(process_results): Remove, functionality rolled into exec_file.
	(target_name): moved to file local scope from global scope.
	(get_target): Declare accessor function for target_name, defined in
	cmdopt.h.
	(run_target): Alter definition to take target_opts structure rather
	than argv array.
	(main): Create local target_opts structure to fill in eval_opts and
	use in target_template, free any rlimit structures allocated in
	parse_limit_opts.
	* util.h (reference_name): Alter declaration to take data_dir, update
	documentation.
	* util.cpp (warn, terminate): Retrieve target_name via get_target.
	(reference_name): Retrieve target_name via get_target, use data_dir
	rather than (removed) in_root global.

Added:
    incubator/stdcxx/trunk/util/target.h   (with props)
Modified:
    incubator/stdcxx/trunk/util/cmdopt.cpp
    incubator/stdcxx/trunk/util/cmdopt.h
    incubator/stdcxx/trunk/util/display.cpp
    incubator/stdcxx/trunk/util/display.h
    incubator/stdcxx/trunk/util/exec.cpp
    incubator/stdcxx/trunk/util/exec.h
    incubator/stdcxx/trunk/util/output.cpp
    incubator/stdcxx/trunk/util/output.h
    incubator/stdcxx/trunk/util/runall.cpp
    incubator/stdcxx/trunk/util/util.cpp
    incubator/stdcxx/trunk/util/util.h

Modified: incubator/stdcxx/trunk/util/cmdopt.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/cmdopt.cpp?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/cmdopt.cpp (original)
+++ incubator/stdcxx/trunk/util/cmdopt.cpp Thu Sep 28 18:11:13 2006
@@ -47,18 +47,12 @@
 #endif   /* _WIN{32,64} */
 
 #include "exec.h"
+#include "target.h"
 #include "util.h"
 
 #include "cmdopt.h"
 
-int timeout = 10; /**< Child process timeout.  Default 10. */
-int compat = 0; /**< Test compatability mode switch.  Defaults to 0 (off). */
-unsigned verbose = 0;
-const char* exe_opts = ""; /**< Global command line switches for child 
-                                processes. */
-const char* in_root = ""; /**< Root directory for input/reference files. */
 const char* exe_name; /**< Alias for process argv [0]. */
-const char* target_name;
 #if !defined (_WIN32) && !defined (_WIN64)
 const char escape_code = '\\';
 const char default_path_sep = '/';
@@ -71,17 +65,6 @@
 const size_t exe_suffix_len = 4; /* strlen(".exe") == 4 */
 #endif
 
-struct limit_set child_limits = {
-    { RLIM_SAVED_CUR, RLIM_SAVED_MAX },
-    { RLIM_SAVED_CUR, RLIM_SAVED_MAX },
-    { RLIM_SAVED_CUR, RLIM_SAVED_MAX },
-    { RLIM_SAVED_CUR, RLIM_SAVED_MAX },
-    { RLIM_SAVED_CUR, RLIM_SAVED_MAX },
-    { RLIM_SAVED_CUR, RLIM_SAVED_MAX },
-    { RLIM_SAVED_CUR, RLIM_SAVED_MAX },
-    { RLIM_SAVED_CUR, RLIM_SAVED_MAX }
-};
-
 static const char
 usage_text[] = {
     "Usage: %s [OPTIONS] [targets]\n"
@@ -95,8 +78,6 @@
     "    -h, -?       Display usage information and exit.\n"
     "    -t seconds   Set timeout before killing target (default is 10\n"
     "                 seconds).\n"
-    "    -q           Set verbosity level to 0 (default).\n"
-    "    -v           Increase verbosity of output.\n"
     "    -x opts      Specify command line options to pass to targets.\n"
     "    --           Terminate option processing and treat all arguments\n"
     "                 that follow as targets.\n"
@@ -259,10 +240,10 @@
    @see child_limits
 */
 static bool
-parse_limit_opts (const char* opts)
+parse_limit_opts (const char* opts, struct target_opts* defaults)
 {
     static const struct {
-        rw_rlimit* limit;
+        rw_rlimit** limit;
         const char* name;
         const char* caps;
         const char* mixd;
@@ -270,49 +251,49 @@
     } limits[] = {
         {
 #ifdef RLIMIT_CORE
-            &child_limits.core,
+            &defaults->core,
 #else
             0,
 #endif   // RLIMIT_CORE
             "core", "CORE", "Core", 4 },
         {
 #ifdef RLIMIT_CPU
-            &child_limits.cpu,
+            &defaults->cpu,
 #else
             0,
 #endif   // RLIMIT_CPU
             "cpu", "CPU", "Cpu", 3 },
         {
 #ifdef RLIMIT_DATA
-            &child_limits.data,
+            &defaults->data,
 #else
             0,
 #endif   // RLIMIT_DATA
             "data", "DATA", "Data", 4 },
         {
 #ifdef RLIMIT_FSIZE
-            &child_limits.fsize,
+            &defaults->fsize,
 #else
             0,
 #endif   // RLIMIT_FSIZE
             "fsize", "FSIZE", "Fsize", 5 },
         {
 #ifdef RLIMIT_NOFILE
-            &child_limits.nofile,
+            &defaults->nofile,
 #else
             0,
 #endif   // RLIMIT_NOFILE
             "nofile", "NOFILE", "Nofile", 6 },
         {
 #ifdef RLIMIT_STACK
-            &child_limits.stack,
+            &defaults->stack,
 #else
             0,
 #endif   // RLIMIT_STACK
             "stack", "STACK", "Stack", 5 },
         {
 #ifdef RLIMIT_AS
-            &child_limits.as,
+            &defaults->as,
 #else
             0,
 #endif   // RLIMIT_AS    
@@ -355,11 +336,17 @@
                     break;
 
                 if (limits [i].limit) {
+                    if (!*limits [i].limit) {
+                        (*limits [i].limit) = 
+                            (rw_rlimit*)RW_MALLOC (sizeof (rw_rlimit));
+                        (*limits [i].limit)->rlim_cur = RLIM_SAVED_CUR;
+                        (*limits [i].limit)->rlim_max = RLIM_SAVED_MAX;
+                    }
                     if (soft)
-                        limits [i].limit->rlim_cur = lim;
+                        (*limits [i].limit)->rlim_cur = lim;
 
                     if (hard)
-                        limits [i].limit->rlim_max = lim;
+                        (*limits [i].limit)->rlim_max = lim;
                 } else
                     warn ("Unable to process %s limit: Not supported\n", 
                           limits [i].name);
@@ -423,16 +410,15 @@
 /**
    Parses command line arguments for switches and options.
 
-   @param argc number of command line arguments
-   @param argv command line arguments
+   @param argc number of command line arguments.
+   @param argv command line arguments.
+   @param defaults target_status structure containing default values.
+   @param exe_opts handle to default child process arguments string
    @return number of command line arguments parsed.
-   @see timeout
-   @see compat
-   @see in_root
-   @see exe_opts
 */
 int 
-eval_options (int argc, char **argv)
+eval_options (int argc, char **argv, struct target_opts* defaults, 
+              const char** exe_opts)
 {
     const char opt_timeout[]  = "-t";
     const char opt_data_dir[] = "-d";
@@ -476,7 +462,7 @@
             if (optarg) {
                 if (!isdigit (*optarg))
                     bad_value (optname, optarg);
-                timeout = strtol (optarg, &end, 10);
+                defaults->timeout = strtol (optarg, &end, 10);
                 if (*end || errno)
                     bad_value (optname, optarg);
             }
@@ -487,23 +473,16 @@
 
         case 'd':
             optname = opt_data_dir;
-            in_root = get_short_val (argv, &i);
-            if (!in_root)
+            defaults->data_dir = get_short_val (argv, &i);
+            if (!defaults->data_dir)
                 missing_value (optname);
             break;
         case 'x':
             optname  = opt_t_flags;
-            exe_opts = get_short_val (argv, &i);
-            if (!exe_opts)
+            *exe_opts = get_short_val (argv, &i);
+            if (!*exe_opts)
                 missing_value (optname);
             break;
-        case 'v':
-            ++verbose;
-            break;
-        case 'q':
-            verbose = 0;
-            break;
-
         case '-':
         {
             const size_t arglen = strlen (argv [i]);
@@ -514,12 +493,12 @@
 
             if (   sizeof opt_compat - 1 == arglen
                 && !memcmp (opt_compat, argv [i], sizeof opt_compat)) {
-                compat  = 1;
+                defaults->compat = 1;
                 break;
             }
             else if (   sizeof opt_nocompat - 1 == arglen
                      && !memcmp (opt_nocompat, argv [i], sizeof opt_nocompat)) {
-                compat  = 0;
+                defaults->compat = 0;
                 break;
             }
             else if (   sizeof opt_exit - 1 <= arglen
@@ -587,7 +566,7 @@
                 optname = opt_ulimit;
                 optarg  = get_long_val (argv, &i, sizeof opt_ulimit - 1);
                 if (optarg && *optarg) {
-                    if (!parse_limit_opts (optarg)) {
+                    if (!parse_limit_opts (optarg, defaults)) {
                         break;
                     }
                 }

Modified: incubator/stdcxx/trunk/util/cmdopt.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/cmdopt.h?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/cmdopt.h (original)
+++ incubator/stdcxx/trunk/util/cmdopt.h Thu Sep 28 18:11:13 2006
@@ -27,76 +27,33 @@
 #ifndef RW_PARSE_OPTS_H
 #define RW_PARSE_OPTS_H
 
-#if !defined (_WIN32) && !defined (_WIN64)
-#  include <unistd.h> /* For _XOPEN_UNIX */
-#endif
-
-extern int timeout;
-extern int compat;
-extern unsigned verbose; /**< Verbose output mode switch.  Defaults to 0 */
-extern const char* exe_opts;
-extern const char* in_root;
+#include "target.h" /* For struct target_opts */
+
 extern const char* exe_name;
-extern const char* target_name; /**< Alias for current target name. */
 extern const char escape_code; /**< Escape character used in paths. */
 extern const char default_path_sep; /**< Primary path seperator */
 extern const char suffix_sep; /**< File suffix seperator. */
 extern const size_t exe_suffix_len; /**< Length of executable suffix. */
 
-#ifdef _XOPEN_UNIX
-#  include <sys/resource.h> /* for struct rlimit */
-/**
-   Abstraction typedef for struct rlimit using real struct
-*/
-typedef struct rlimit rw_rlimit;
-#else
-/**
-   Placeholder rlim_t for use in rw_rlimit
-*/
-typedef unsigned long rw_rlim_t;
-/**
-   Placeholder struct rlimit to use if _XOPEN_UNIX isn't defined
-*/
-struct rw_rlimit {
-    rw_rlim_t rlim_cur;
-    rw_rlim_t rlim_max;
-};
-/**
-   Abstraction typedef for struct rlimit using placeholder struct
-*/
-typedef struct rw_rlimit rw_rlimit;
-#endif
-
-#ifndef RLIM_INFINITY
-#  define RLIM_INFINITY -1
-#endif /* RLIM_INFINITY */
-
-#ifndef RLIM_SAVED_CUR
-#  define RLIM_SAVED_CUR RLIM_INFINITY
-#endif   /* RLIM_SAVED_CUR */
-
-#ifndef RLIM_SAVED_MAX
-#  define RLIM_SAVED_MAX RLIM_INFINITY
-#endif   /* RLIM_SAVED_MAX */
-
-extern struct limit_set {
-    rw_rlimit core;
-    rw_rlimit cpu;
-    rw_rlimit data;
-    rw_rlimit fsize;
-    rw_rlimit nofile;
-    rw_rlimit stack;
-    rw_rlimit mem;
-    rw_rlimit as;
-} child_limits; /**< Container holding child process limits. */
-
 void 
 show_usage (int status);
 
 int 
-eval_options (int argc, char** argv);
+eval_options (int argc, char** argv, struct target_opts* defaults, 
+              const char** exe_opts);
 
 char**
 split_opt_string (const char* opts);
+
+/**
+   Accessor method for current execution target.
+
+   This function is defined in runall.cpp (not cmdopt.cpp).
+
+   This value is a pointer into argv[0] of the current target.
+
+   @returns (Base) name of current execution target.
+*/
+const char* get_target ();
 
 #endif   // RW_PARSE_OPTS_H

Modified: incubator/stdcxx/trunk/util/display.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/display.cpp?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/display.cpp (original)
+++ incubator/stdcxx/trunk/util/display.cpp Thu Sep 28 18:11:13 2006
@@ -41,8 +41,9 @@
           "SYS");
 }
 
-void print_target_plain (const struct target_status*)
+void print_target_plain (const struct target_opts*)
 {
+    const char* const target_name = get_target ();
     printf ("%-25.25s ", target_name);
     fflush (stdout);
 }
@@ -53,14 +54,15 @@
     assert (0 != status);
     assert (ST_OK <= status->status && ST_LAST > status->status);
 
-    valid_timing = status->run && ST_NOT_KILLED != status->status;
+    valid_timing = status->user && status->sys  && 
+        ST_NOT_KILLED != status->status;
 
     if (status->status) /* if status is set, print it */
         printf ("%6s", short_st_name [status->status]);
+    else if (status->signaled) /* if exit signal is non-zero, print it */
+        printf ("%6s", get_signame (status->exit));
     else if (status->exit) /* if exit code is non-zero, print it */
         printf ("%6d", status->exit);
-    else if (status->signal) /* if exit signal is non-zero, print it */
-        printf ("%6s", get_signame (status->signal));
     else 
         printf ("     0");
 
@@ -74,9 +76,9 @@
 
     /* Print timings, if available */
     if (valid_timing)
-        printf (" %3ld.%03ld %3ld.%03ld\n", status->user.tv_sec,
-                status->user.tv_usec/1000, status->sys.tv_sec,
-                status->sys.tv_usec/1000);
+        printf (" %3ld.%03ld %3ld.%03ld\n", status->user->tv_sec,
+                status->user->tv_usec/1000, status->sys->tv_sec,
+                status->sys->tv_usec/1000);
     else {
         puts ("");
     }
@@ -85,7 +87,7 @@
 
 void print_footer_plain () {}
 
-const char* short_st_name [ST_LAST] = {
+const char* const short_st_name [ST_LAST] = {
     "OK", /*ST_OK*/
     "COMP", /*ST_COMPILE*/
     "LINK", /*ST_LINK*/
@@ -105,6 +107,6 @@
 
 
 void (*print_header) () = print_header_plain;
-void (*print_target) (const struct target_status*) = print_target_plain;
+void (*print_target) (const struct target_opts*) = print_target_plain;
 void (*print_status) (const struct target_status* status)  = print_status_plain;
 void (*print_footer) () = print_footer_plain;

Modified: incubator/stdcxx/trunk/util/display.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/display.h?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/display.h (original)
+++ incubator/stdcxx/trunk/util/display.h Thu Sep 28 18:11:13 2006
@@ -27,37 +27,7 @@
 #ifndef RW_DISPLAY_H
 #define RW_DISPLAY_H
 
-#if !defined (_WIN32) && !defined (_WIN64)
-#  include <unistd.h> /* for _XOPEN_UNIX */
-#endif
-
-#ifdef _XOPEN_UNIX
-#  include <sys/time.h> /* for struct timeval */
-/**
-   Abstraction typedef for struct timeval using real struct
-*/
-typedef struct timeval rw_timeval;
-#else
-/**
-   Placeholder time_t for use in rw_timeval
-*/
-typedef long rw_time_t;
-/**
-   Placeholder suseconds_t for use in rw_timeval
-*/
-typedef long rw_suseconds_t;
-/**
-   Placeholder struct timeval to use if _XOPEN_UNIX isn't defined
-*/
-struct rw_timeval {
-    rw_time_t tv_sec;
-    rw_suseconds_t tv_usec;
-};
-/**
-   Abstraction typedef for struct timeval using placeholder struct
-*/
-typedef struct rw_timeval rw_timeval;
-#endif
+#include "target.h" /* For target_opts */
 
 /**
    Output format mode enumeration.
@@ -73,47 +43,9 @@
 };
 
 /**
-   Status codes to denote result of analysis.
-*/
-enum ProcessStatus {
-    ST_OK = 0, /**< Default (OK) status */
-    ST_COMPILE, /**< Target failed to compile */
-    ST_LINK, /**< Target failed to link */
-    ST_EXIST, /**< Target doesn't exist? */
-    ST_EXECUTE_FLAG, /**< Target lacks X flag */
-    ST_EXECUTE, /**< Target failed to execute? */
-    ST_NO_OUTPUT, /**< Target produced no output */
-    ST_NO_REF, /**< No reference file found */
-    ST_BAD_REF, /**< Invalid reference file found */
-    ST_BAD_OUTPUT, /**< Incorrect output found */
-    ST_FORMAT, /**< Incorrectly formatted (test) output found */
-    ST_OVERFLOW, /**< Assertion counter overflow */
-    ST_SYSTEM_ERROR, /**< System error during file system operation */
-    ST_KILLED, /**< Target killed by exec utility */
-    ST_NOT_KILLED, /** Target not killed by exec utility */
-    ST_LAST /**< Array terminator */
-};
-
-/**
    ProcessStatus enum lookup table for 'short' (6 character) strings.
 */
-extern const char* short_st_name [ST_LAST];
-
-/**
-   Structure encapsulating the results extracted from a run.
-*/
-struct target_status {
-    char** argv; /**< Target argv array. */
-    int exit; /**< exit code for process. */
-    int signal; /**< Termination signal for process. */
-    int run; /**< Flag indicating if the process executed. */
-    enum ProcessStatus status; /**< Textual process status. */
-    rw_timeval user; /**< Elapsed user time spent in execution. */
-    rw_timeval sys; /**< Elapsed system time spent in execution. */
-    unsigned warn; /**< Number of (test) warnings. */
-    unsigned assert; /**< Number of (test) assertions. */
-    unsigned failed; /**< Number of failed (test) assertions. */
-};
+extern const char* const short_st_name [ST_LAST];
 
 /**
    Sets the output functions referenced.
@@ -140,7 +72,7 @@
 
    @see target_name
 */
-extern void (*print_target) (const struct target_status* status);
+extern void (*print_target) (const struct target_opts* options);
 
 /**
    Updates the display of a (non-final) status indicator

Modified: incubator/stdcxx/trunk/util/exec.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/exec.cpp?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/exec.cpp (original)
+++ incubator/stdcxx/trunk/util/exec.cpp Thu Sep 28 18:11:13 2006
@@ -51,7 +51,7 @@
 #include <sys/types.h>
 
 #include "cmdopt.h"
-#include "display.h" /* for struct target_status */
+#include "target.h" /* For struct target_opts */
 #include "util.h"
 
 #include "exec.h"
@@ -63,7 +63,6 @@
    Value is 1 when alarm has been triggered and hasn't been handled
 
    @see handle_alrm
-   @see open_input
 */
 static int alarm_timeout;
 
@@ -404,19 +403,20 @@
    @see handle_alrm
    @see alarm_timeout
 */
-static struct exec_attrs
-wait_for_child (pid_t child_pid)
+static void
+wait_for_child (pid_t child_pid, int timeout, struct target_status* result)
 {
+    /* note that processes with no controlling terminal ignore
+       the SIGINT and SIGQUIT signals
+    */
     static const int signals [] = {
-        SIGHUP, SIGINT, SIGTERM, SIGKILL, SIGKILL
+        SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGKILL, SIGKILL
     };
 
     static const unsigned sigcount = sizeof (signals) / sizeof (int);
 
     struct sigaction act;
 
-    struct exec_attrs state = {-1, 0};
-
     unsigned siginx = 0;
 
     int stopped = 0;
@@ -426,6 +426,9 @@
 #else
     int waitopts = WUNTRACED;
 #endif
+
+    int status;
+
     assert (1 < child_pid);
 
     /* Clear timeout */
@@ -448,14 +451,27 @@
         alarm (timeout);
 
     while (1) {
-        const pid_t wait_pid = waitpid (child_pid, &state.status, waitopts);
+        const pid_t wait_pid = waitpid (child_pid, &status, waitopts);
         if (child_pid == wait_pid) {
-            if (WIFEXITED (state.status) || WIFSIGNALED (state.status))
+            if (WIFEXITED (status)) {
+                result->exit = WEXITSTATUS (status);
+                switch (result->exit) {
+                case 126:
+                    result->status = ST_EXIST;
+                    break;
+                case 127:
+                    result->status = ST_EXECUTE;
+                    break;
+                }
+                break; /*we've got an exit state, so let's bail*/
+            } else if (WIFSIGNALED (status)) {
+                result->exit = WTERMSIG (status);
+                result->signaled = 1;
                 break; /*we've got an exit state, so let's bail*/
-            else if (WIFSTOPPED (state.status))
-                stopped = state.status;
+            } else if (WIFSTOPPED (status))
+                stopped = status;
 #ifdef WIFCONTINUED /*Perhaps we should guard WIFSTOPPED with this guard also */
-            else if (WIFCONTINUED (state.status))
+            else if (WIFCONTINUED (status))
                 stopped = 0;
 #endif
             else
@@ -469,7 +485,8 @@
                        recieving signals.  Therefore, we'll record this
                        and break out of the loop.
                     */
-                    state.status = stopped;
+                    result->exit = WTERMSIG (stopped);
+                    result->signaled = 1;
                     break;
                 }
 
@@ -502,7 +519,7 @@
                 }
 
                 /* Record the signal used*/
-                state.killed = signals [siginx];
+                /* result->killed = signals [siginx];*/
 
                 ++siginx;
 
@@ -512,8 +529,7 @@
                        Therefore, we'll set error flags and break out of 
                        the loop.
                     */
-                    state.status = -1;
-                    state.killed = -1;
+                    result->status = ST_NOT_KILLED;
                     break;
                 }
 
@@ -560,40 +576,38 @@
         ++siginx;
         sleep(1);
     }
-
-    return state;
 }
 
 /**
    Opens an input file, based on exec_name
 
-   Takes an executable name, and tries to open an input file based on this 
-   name and the value of the in_root global variable.  If a file is found in 
-   neither of two locattions derived from these variables, this method tries
-   to fall back on /dev/null.
+   Takes a data directory and an executable name, and tries to open an input 
+   file based on these variables.  If a file is found in neither of two 
+   locattions derived from these variables, this method tries to fall back on 
+   /dev/null.
 
    Source file locations:
-     - [in_root]/manual/in/[exec_name].in
-     - [in_root]/tutorial/in/[exec_name].in
+     - [data_dir]/manual/in/[exec_name].in
+     - [data_dir]/tutorial/in/[exec_name].in
      - /dev/null
 
+   @param data_dir the path of the reference data directory
    @param exec_name the name of executable being run
    @returns the file descriptor of the opened file
-   @see in_root
 */
 static int
-open_input (const char* exec_name)
+open_input (const char* data_dir, const char* exec_name)
 {
     int intermit = -1;
 
     assert (0 != exec_name);
-    assert (0 != in_root);
+    assert (0 != data_dir);
 
-    if (strlen (in_root)) {
+    if (strlen (data_dir)) {
         char* tmp_name;
 
-        /* Try in_root/manual/in/exec_name.in */
-        tmp_name = reference_name ("manual", "in");
+        /* Try data_dir/manual/in/exec_name.in */
+        tmp_name = reference_name (data_dir, "manual", "in");
         intermit = open (tmp_name, O_RDONLY);
     
         /* If we opened the file, return the descriptor */
@@ -607,9 +621,9 @@
             terminate (1, "open (%s) failed: %s\n", tmp_name, 
                        strerror (errno));
 
-        /* Try in_root/tutorial/in/exec_name.in */
+        /* Try data_dir/tutorial/in/exec_name.in */
         free (tmp_name);
-        tmp_name = reference_name ("tutorial", "in");
+        tmp_name = reference_name (data_dir, "tutorial", "in");
         intermit = open (tmp_name, O_RDONLY);
 
         /* If we opened the file, return the descriptor */
@@ -673,21 +687,23 @@
     Utility macro to generate an rlimit tuple.
     
     @parm val 'short' resource name (no leading RLIMIT_).
-    @param idx limit structure name in child_limits global
+    @param idx rw_rlimit pointer in the target_opts structure
     @see limit_process
-    @see child_limits
+    @see target_opts
 */
 #undef LIMIT
-#define LIMIT(val, idx)   { RLIMIT_ ## val, &child_limits.idx, #val }
+#define LIMIT(val, idx)   { RLIMIT_ ## val, options->idx, #val }
 
 /**
    Set process resource limits, based on the child_limits global.
 
-   This method uses the LIMIT macro to build an internal array of limits
-   to try setting.  If setrlimit fails
+   This method uses the LIMIT macro to build an internal array of limits to 
+   try setting.  If setrlimit fails, we print a warning message (into the 
+   output file) and move on.
+   @param options structure containing limits to set.
 */
 static void
-limit_process ()
+limit_process (const struct target_opts* options)
 {
     static const struct {
         int resource;
@@ -719,13 +735,12 @@
     };
 
     for (size_t i = 0; limits [i].limit; ++i) {
-        rw_rlimit local;
+        struct rlimit local;
 
-        if (   RLIM_SAVED_CUR == limits [i].limit->rlim_cur
-            && RLIM_SAVED_MAX == limits [i].limit->rlim_max )
+        if (!limits [i].limit)
             continue;
 
-        memcpy (&local, limits [i].limit, sizeof (struct rlimit));
+        memcpy (&local, limits [i].limit, sizeof local);
 
         if (setrlimit (limits [i].resource, &local)) {
             warn ("error setting process limits for %s (soft: %lu, hard: "
@@ -754,12 +769,15 @@
 #ifdef _XOPEN_UNIX
     static bool init = 0;
     static struct rusage history;
+    static rw_timeval user, sys;
     struct rusage now;
 
     assert (0 != result);
 
     if (!init) {
         memset (&history, 0, sizeof history);
+        memset (&user, 0, sizeof user);
+        memset (&sys, 0, sizeof sys);
         init = 1;
     }
 
@@ -769,23 +787,24 @@
     }
 
     /* time calculations */
-    result->user.tv_sec = now.ru_utime.tv_sec - history.ru_utime.tv_sec;
-    result->user.tv_usec = now.ru_utime.tv_usec - history.ru_utime.tv_usec;
-    result->sys.tv_sec = now.ru_stime.tv_sec - history.ru_stime.tv_sec;
-    result->sys.tv_usec = now.ru_stime.tv_usec - history.ru_stime.tv_usec;
+    user.tv_sec = now.ru_utime.tv_sec - history.ru_utime.tv_sec;
+    user.tv_usec = now.ru_utime.tv_usec - history.ru_utime.tv_usec;
+    sys.tv_sec = now.ru_stime.tv_sec - history.ru_stime.tv_sec;
+    sys.tv_usec = now.ru_stime.tv_usec - history.ru_stime.tv_usec;
 
     /* Adjust seconds/microseconds */
     if (now.ru_utime.tv_usec < history.ru_utime.tv_usec) {
-        --result->user.tv_sec;
-        result->user.tv_usec += 1000000;
+        --user.tv_sec;
+        user.tv_usec += 1000000;
     }
     if (now.ru_stime.tv_usec < history.ru_stime.tv_usec) {
-        --result->sys.tv_sec;
-        result->sys.tv_usec += 1000000;
+        --sys.tv_sec;
+        sys.tv_usec += 1000000;
     }
 
     /* Tag result as having run */
-    result->run = 1;
+    result->user = &user;
+    result->sys = &sys;
 
     /* Cache the values retrieved */
     memcpy (&history, &now, sizeof (struct rusage));
@@ -807,16 +826,16 @@
    @return structure describing how the child procees exited
    @see wait_for_child ()
 */
-struct exec_attrs 
-exec_file (struct target_status* result)
+void exec_file (const struct target_opts* options, struct target_status* result)
 {
     const pid_t child_pid = fork ();
 
-    assert (0 != result);
-    assert (0 != result->argv);
-    assert (0 != result->argv [0]);
+    assert (0 != options);
+    assert (0 != options->argv);
+    assert (0 != options->argv [0]);
 
     if (0 == child_pid) {   /* child */
+        const char* const target_name = get_target ();
         FILE* error_file;
 
         assert (0 != target_name);
@@ -844,13 +863,13 @@
 
         /* Redirect stdin */
         {
-            const int intermit = open_input (target_name);
+            const int intermit = open_input (options->data_dir, target_name);
             replace_file (intermit, 0, "stdin");
         }
 
         /* Redirect stdout */
         {
-            char* const tmp_name = output_name (result->argv [0]);
+            char* const tmp_name = output_name (options->argv [0]);
             int intermit;
 
             intermit = open (tmp_name, O_WRONLY | O_CREAT | O_TRUNC, 
@@ -871,28 +890,25 @@
                        strerror (errno));
 
 #ifdef _XOPEN_UNIX
-        limit_process ();
+        limit_process (options);
 #endif /* _XOPEN_UNIX */
 
-        execv (result->argv [0], result->argv);
+        execv (options->argv [0], options->argv);
 
         fprintf (error_file, "%s (%s): execv (\"%s\", ...) error: %s\n",
-                 exe_name, target_name, result->argv [0], strerror (errno));
+                 exe_name, target_name, options->argv [0], strerror (errno));
 
         exit (1);
     }
 
     if (-1 == child_pid) {
-        /* Fake a failue to execute status return structure */
-        struct exec_attrs state = {127, -1};
-        warn ("Unable to create child process for %s: %s\n", result->argv [0],
+        result->status = ST_EXECUTE;
+        warn ("Unable to create child process for %s: %s\n", options->argv [0],
               strerror (errno));
-        return state;
     } else {
         /* parent */
-        struct exec_attrs state = wait_for_child (child_pid);
+        wait_for_child (child_pid, options->timeout, result);
         calculate_usage (result);
-        return state;
     }
 }
 #else  /* _WIN{32,64} */
@@ -900,39 +916,39 @@
    Opens an input file, based on exec_name, using the child_sa security 
    setting.
 
-   Takes an executable name and security setting, and tries to open an input 
-   file based on these variables and the value of the in_root global variable.
+   Takes a data directory, an executable name and security setting, and tries 
+   to open an input file based on these variables.
    If a file is found in neither of two locations derived from these 
-   variables, or if in_root is a null string, it returns null.
+   variables, or if data_dir is a null string, it returns null.
    If a file system error occurs when opening a file, INVALID_HANDLE_VALUE
    is returned (and should be checked for).
 
    Source file locations:
-     - [in_root]/manual/in/[exec_name].in
-     - [in_root]/tutorial/in/[exec_name].in
+     - [data_dir]/manual/in/[exec_name].in
+     - [data_dir]/tutorial/in/[exec_name].in
 
+   @param data_dir the path of the reference data directory
    @param exec_name the name of executable being run
    @param child_sa pointer to a SECURITY_ATTRIBUTES    structure
    @returns the file descriptor of the opened file
-   @see in_root
 */
 static HANDLE
-open_input (const char* exec_name, SECURITY_ATTRIBUTES* child_sa)
+open_input (const char* data_dir, const char* exec_name, 
+            SECURITY_ATTRIBUTES* child_sa)
 {
-    const size_t root_len = strlen (in_root);
     HANDLE intermit;
     DWORD error;
     char* tmp_name;
 
     assert (0 != exec_name);
-    assert (0 != in_root);
+    assert (0 != data_dir);
     assert (0 != child_sa);
 
-    if (!root_len) 
+    if (!strlen (data_dir)) 
         return 0;
 
-    /* Try in_root\manual\in\exec_name.in */
-    tmp_name = reference_name ("manual", "in");
+    /* Try data_dir\manual\in\exec_name.in */
+    tmp_name = reference_name (data_dir, "manual", "in");
 
     intermit = CreateFile (tmp_name, GENERIC_READ, FILE_SHARE_READ, child_sa, 
         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
@@ -944,9 +960,9 @@
         return intermit;
     }
 
-    /* Try in_root\tutorial\in\exec_name.in */
+    /* Try data_dir\tutorial\in\exec_name.in */
     free (tmp_name);
-    tmp_name = reference_name ("tutorial", "in");
+    tmp_name = reference_name (data_dir, "tutorial", "in");
     intermit = CreateFile (tmp_name, GENERIC_READ, FILE_SHARE_READ, child_sa, 
         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
@@ -1033,6 +1049,65 @@
 }
 
 /**
+   Try killing the child process with what (limited) facilities we have at
+   our disposal.  Does not collect exit code or close child process handle.
+
+   @param process Process handle of process to kill.
+   @param result status structure to record system errors in.
+*/
+static void
+kill_child_process (PROCESS_INFORMATION child, struct target_status* result)
+{
+    OSVERSIONINFO OSVer;
+
+    OSVer.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+    if (0 == GetVersionEx (&OSVer)) {
+        result->status = ST_SYSTEM_ERROR;
+        warn_last_error ("Retrieving host version");
+        return;
+    }
+    /* Try to soft kill child process group if it didn't terminate, but only 
+       on NT */
+
+    if (VER_PLATFORM_WIN32_NT == OSVer.dwPlatformId) {
+
+        struct sig_event
+        {
+            DWORD       signal_;
+            const char* msg_;
+        }
+        sig_events [] = {
+            { CTRL_C_EVENT,     "Sending child process Control-C"     },
+            { CTRL_BREAK_EVENT, "Sending child process Control-Break" }
+        };
+
+        for (unsigned long i = 0;
+            i < sizeof (sig_events) / sizeof (*sig_events); ++i) {
+            DWORD wait_code;
+
+            if (0 == GenerateConsoleCtrlEvent (sig_events [i].signal_,
+                                               child.dwProcessId))
+                warn_last_error (sig_events [i].msg_);
+
+            wait_code = WaitForSingleObject (child.hProcess, 1000);
+            if (WAIT_TIMEOUT == wait_code)
+                continue;
+
+            if (WAIT_OBJECT_0 != wait_code) {
+                result->status = ST_SYSTEM_ERROR;
+                warn_last_error ("Waiting for child process");
+            }
+            return;
+        }
+    }
+    /* Then hard kill the child process */
+    if (0 == TerminateProcess (child.hProcess, 3))
+        warn_last_error ("Terminating child process");
+    else if (WAIT_FAILED == WaitForSingleObject (child.hProcess, 1000))
+        warn_last_error ("Waiting for child process");
+}
+
+/**
    Entry point to the child process (watchdog) subsystem.
 
    This method creates a process using the windows CreateProcess API call.
@@ -1049,31 +1124,21 @@
    @return structure describing how the child procees exited
    @see wait_for_child ()
 */
-struct exec_attrs 
-exec_file (struct target_status* result)
+void exec_file (const struct target_opts* options, struct target_status* result)
 {
     char* merged;
     PROCESS_INFORMATION child;
-    OSVERSIONINFO OSVer;
     STARTUPINFO context;
     SECURITY_ATTRIBUTES child_sa = /* SA for inheritable handle. */
           {sizeof (SECURITY_ATTRIBUTES), NULL, TRUE};
-    struct exec_attrs status;
-    const DWORD real_timeout = (timeout > 0) ? timeout * 1000 : INFINITE;
-    DWORD wait_code;
+    DWORD real_timeout, wait_code;
 
-    assert (0 != result);
-    assert (0 != result->argv);
-    assert (0 != result->argv [0]);
+    assert (0 != options);
+    assert (0 != options->argv);
+    assert (0 != options->argv [0]);
 
-    memset (&status, 0, sizeof status);
+    real_timeout = (options->timeout > 0) ? options->timeout * 1000 : INFINITE;
 
-    OSVer.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
-    if (0 == GetVersionEx (&OSVer)) {
-        status.status = -1;
-        status.error = warn_last_error ("Retrieving host version");
-        return status;
-    }
     /* Borrow our startup info */
     GetStartupInfo (&context);
     context.dwFlags = STARTF_USESTDHANDLES;
@@ -1081,31 +1146,32 @@
     /* Create I/O handles */
     {
         /* Output redirection */
-        char* const tmp_name = output_name (result->argv [0]);
+        char* const tmp_name = output_name (options->argv [0]);
 
         context.hStdOutput = CreateFile (tmp_name, GENERIC_WRITE, 
                 FILE_SHARE_WRITE, &child_sa, CREATE_ALWAYS, 
                 FILE_ATTRIBUTE_NORMAL, NULL);
         if (INVALID_HANDLE_VALUE == context.hStdOutput) { 
-            status.status = -1;
-            status.error = warn_last_error ("Opening child output stream");
-            return status;
+            result->status = ST_SYSTEM_ERROR;
+            warn_last_error ("Opening child output stream");
+            return;
         }
 
         context.hStdError = context.hStdOutput;
         free (tmp_name);
 
         /* Input redirection */
-        context.hStdInput = open_input (target_name, &child_sa);
+        context.hStdInput = open_input (options->data_dir, get_target (), 
+                                        &child_sa);
         if (INVALID_HANDLE_VALUE == context.hStdInput) { 
             CloseHandle (context.hStdOutput);
-            status.status = -1;
-            status.error = warn_last_error ("Opening child input stream");
-            return status;
+            result->status = ST_SYSTEM_ERROR;
+            warn_last_error ("Opening child input stream");
+            return;
         }
     }    
 
-    merged = merge_argv (result->argv);
+    merged = merge_argv (options->argv);
 
     /* set appropriate error mode (the child process inherits this
        error mode) to disable displaying the critical-error-handler
@@ -1113,11 +1179,11 @@
     UINT old_mode = SetErrorMode (SEM_FAILCRITICALERRORS
                                 | SEM_NOGPFAULTERRORBOX);
     /* Create the child process */
-    if (0 == CreateProcess (result->argv [0], merged, 0, 0, 1, 
+    if (0 == CreateProcess (options->argv [0], merged, 0, 0, 1, 
         CREATE_NEW_PROCESS_GROUP, 0, 0, &context, &child)) {
         /* record the status if we failed to create the process */
-        status.status = -1;
-        status.error = warn_last_error ("Creating child process");;
+        result->status = ST_SYSTEM_ERROR;
+        warn_last_error ("Creating child process");;
     }
 
     /* restore the previous error mode */
@@ -1134,87 +1200,41 @@
     free (merged);
 
     /* Return if we failed to create the child process */
-    if (-1 == status.status)
-        return status;
+    if (ST_SYSTEM_ERROR == result->status)
+        return;
 
     if (0 == CloseHandle (child.hThread))
         warn_last_error ("Closing child main thread handle");
 
     /* Wait for the child process to terminate */
     wait_code = WaitForSingleObject (child.hProcess, real_timeout);
-    if (WAIT_TIMEOUT != wait_code) {
-        if (WAIT_OBJECT_0 == wait_code) {
-            if (0 == GetExitCodeProcess (child.hProcess, &status.status)) {
-                warn_last_error ("Retrieving child process exit code");
-                status.status = -1;
-            }
-            status.error = 0;
-        }
-        else {
-            status.status = -1;
-            status.error = warn_last_error ("Waiting for child process");
-        }
-
-        if (0 == CloseHandle (child.hProcess))
-            warn_last_error ("Closing child process handle");
-        return status;
-    }
-
-    /* Try to soft kill child process group if it didn't terminate, but only 
-       on NT */
-    if (VER_PLATFORM_WIN32_NT == OSVer.dwPlatformId) {
-
-        struct sig_event
-        {
-            DWORD       signal_;
-            const char* msg_;
-        }
-        sig_events [] = {
-            { CTRL_C_EVENT,     "Sending child process Control-C"     },
-            { CTRL_BREAK_EVENT, "Sending child process Control-Break" }
-        };
 
-        for (unsigned long i = 0;
-            i < sizeof (sig_events) / sizeof (*sig_events); ++i) {
-
-            if (0 == GenerateConsoleCtrlEvent (sig_events [i].signal_,
-                                               child.dwProcessId))
-                warn_last_error (sig_events [i].msg_);
-
-            wait_code = WaitForSingleObject (child.hProcess, 1000);
-            if (WAIT_TIMEOUT == wait_code)
-                continue;
-
-            if (WAIT_OBJECT_0 == wait_code) {
-                if (0 == GetExitCodeProcess (child.hProcess, &status.status)) {
-                    warn_last_error ("Retrieving child process exit code");
-                    status.status = -1;
-                }
-                status.error = i + 1;
-            }
-            else {
-                status.status = -1;
-                status.error = warn_last_error ("Waiting for child process");
-            }
-
-            if (0 == CloseHandle (child.hProcess))
-                warn_last_error ("Closing child process handle");
-            return status;
-        }
-    }
-    /* Then hard kill the child process */
-    if (0 == TerminateProcess (child.hProcess, 3))
-        warn_last_error ("Terminating child process");
-    else if (WAIT_FAILED == WaitForSingleObject (child.hProcess, 1000))
+    switch (wait_code) {
+    case WAIT_OBJECT_0:
+        break;
+    case WAIT_TIMEOUT:
+        /* Child process didn't shut down, so note that we killed it. */
+        result->status = ST_KILLED;
+
+        kill_child_process (child, result);
+        break;
+    default:
+        result->status = ST_SYSTEM_ERROR;
         warn_last_error ("Waiting for child process");
+    }
 
-    if (0 == GetExitCodeProcess (child.hProcess, &status.status)) {
+    if (0 == GetExitCodeProcess (child.hProcess, (LPDWORD)&result->exit)) {
         warn_last_error ("Retrieving child process exit code");
-        status.status = -1;
+        result->status = ST_SYSTEM_ERROR;
     }
-    status.error = 3;
+
     if (0 == CloseHandle (child.hProcess))
         warn_last_error ("Closing child process handle");
-    return status;
+
+    if (STATUS_ACCESS_VIOLATION == result->exit) {
+        result->exit = SIGSEGV;
+        result->signaled = 1;
+    }
 }
+
 #endif  /* _WIN{32,64} */

Modified: incubator/stdcxx/trunk/util/exec.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/exec.h?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/exec.h (original)
+++ incubator/stdcxx/trunk/util/exec.h Thu Sep 28 18:11:13 2006
@@ -27,21 +27,12 @@
 #ifndef RW_EXEC_H
 #define RW_EXEC_H
 
-struct exec_attrs {
-#if !defined (_WIN32) && !defined (_WIN64)
-    int status;
-    int killed;
-#else
-    /* AKA DWORD */
-    unsigned long status;
-    unsigned long error;
-#endif  /* _WIN{32,64} */
-};
+#include "target.h" /* For struct target_opts */
 
 int get_signo (const char* signame);
 
 const char* get_signame (int signo);
 
-struct exec_attrs exec_file (struct target_status* result);
+void exec_file (const struct target_opts* options, struct target_status* result);
 
 #endif   // RW_EXEC_H

Modified: incubator/stdcxx/trunk/util/output.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/output.cpp?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/output.cpp (original)
+++ incubator/stdcxx/trunk/util/output.cpp Thu Sep 28 18:11:13 2006
@@ -63,6 +63,8 @@
     unsigned fsm = 0;
     char tok;
 
+    const char* const target_name = get_target ();
+
     assert (0 != target_name);
     assert (0 != data);
     assert (0 != status);
@@ -185,8 +187,8 @@
    reference file name is generated by the reference_name function.
 
    Reference file locations:
-     - [in_root]/manual/out/[target_name].out
-     - [in_root]/tutorial/out/[target_name].out
+     - [data_dir]/manual/out/[target_name].out
+     - [data_dir]/tutorial/out/[target_name].out
 
    @todo add logic to handle differing line endings (CR vs LF vs CRLF)
 
@@ -196,7 +198,8 @@
    @see reference_name
 */
 static void
-check_example (char* const out_name, FILE* fout, struct target_status* status)
+check_example (const char* const data_dir, char* const out_name, FILE* fout, 
+               struct target_status* status)
 {
     struct stat file_info;
     char* ref_name;
@@ -207,8 +210,8 @@
     assert (0 != fout);
     assert (0 != status);
 
-    /* Try in_root/manual/out/target_name.out */
-    ref_name = reference_name ("manual", "out");
+    /* Try data_dir/manual/out/target_name.out */
+    ref_name = reference_name (data_dir, "manual", "out");
 
     if (0 > stat (ref_name, &file_info)) {
         if (ENOENT != errno) {
@@ -220,9 +223,9 @@
         }
                         
         /* If that doesn't exist, try 
-           in_root/tutorial/out/target_name.out */
+           data_dir/tutorial/out/target_name.out */
         free (ref_name);
-        ref_name = reference_name ("tutorial", "out");
+        ref_name = reference_name (data_dir, "tutorial", "out");
 
         if (0 > stat (ref_name, &file_info)) {
             if (ENOENT != errno) {
@@ -256,14 +259,14 @@
             size_t nread [2];   /* bytes read from the output/ref file */
 
             /* First, read a block from the files into the buffer */
-            nread [0] = fread (buf [0], 1, sizeof buf [0], fout);
+            nread [0] = fread (buf [0], sizeof buf [0], 1, fout);
             if (ferror (fout)) {
                 warn ("Error reading %s: %s\n", out_name, strerror (errno));
                 match = 0;
                 break;
             }
 
-            nread [1] = fread (buf [1], 1, sizeof buf [1], fref);
+            nread [1] = fread (buf [1], sizeof buf [1], 1, fref);
             if (ferror (fref)) {
                 warn ("Error reading %s: %s\n", ref_name, strerror (errno));
                 match = 0;
@@ -306,14 +309,14 @@
    @param status status object to record results in.
 */
 void
-parse_output (struct target_status* status)
+parse_output (const struct target_opts* options, struct target_status* status)
 {
     char* out_name;
     FILE* data;
 
     assert (0 != status);
-    assert (0 != status->argv [0]);
-    out_name = output_name (status->argv [0]);
+    assert (0 != options->argv [0]);
+    out_name = output_name (options->argv [0]);
 
     data = fopen (out_name, "r");
 
@@ -323,17 +326,17 @@
         status->status = ST_NO_OUTPUT;
     }
     else {
-        if (!strlen (in_root)) {
+        if (!strlen (options->data_dir)) {
             /* If there is not an input directory, look at the assertion tags */
 
-            if (!compat)
+            if (!options->compat)
                 check_test (data, status);
             else
                 check_compat_test (data, status);
         }
         else {
             /* Otherwise, diff against the output file */
-            check_example (out_name, data, status);
+            check_example (options->data_dir, out_name, data, status);
         }
         fclose (data);
     }

Modified: incubator/stdcxx/trunk/util/output.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/output.h?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/output.h (original)
+++ incubator/stdcxx/trunk/util/output.h Thu Sep 28 18:11:13 2006
@@ -28,6 +28,6 @@
 #define OUTPUT_H
 
 void
-parse_output (struct target_status* status);
+parse_output (const struct target_opts* options, struct target_status* status);
 
 #endif   // OUTPUT_H

Modified: incubator/stdcxx/trunk/util/runall.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/runall.cpp?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/runall.cpp (original)
+++ incubator/stdcxx/trunk/util/runall.cpp Thu Sep 28 18:11:13 2006
@@ -45,6 +45,8 @@
 #include "output.h"
 #include "util.h"
 
+#include "target.h"
+
 #ifndef ENOENT
 #  define ENOENT 2
 #endif   // ENOENT
@@ -206,18 +208,17 @@
    @return 1 if valid target to run, 0 otherwise.
 */
 static int
-check_target_ok (struct target_status* status)
+check_target_ok (const char* target, struct target_status* status)
 {
     struct stat file_info;
     int exists = 1;
 
+    assert (0 != target);
     assert (0 != status);
-    assert (0 != status->argv);
-    assert (0 != status->argv[0]);
 
-    if (0 > stat (status->argv [0], &file_info)) {
+    if (0 > stat (target, &file_info)) {
         if (ENOENT != errno) {
-            warn ("Error stating %s: %s\n", status->argv [0], strerror (errno));
+            warn ("Error stating %s: %s\n", target, strerror (errno));
             status->status = ST_SYSTEM_ERROR;
             return 0;
         }
@@ -228,12 +229,12 @@
         /* This is roughly equivlent to the -x bash operator.
            It checks if the file can be run, /not/ if we can run it
         */
-        const size_t path_len = strlen (status->argv [0]);
+        const size_t path_len = strlen (target);
         char* tmp_name;
 
 #if 0 /* Disable .o target check as unused */
         /* If target is a .o file, check if it exists */
-        if ('.' == status->argv [0] [path_len-1] && 'o' == status->argv [0] [path_len]) {
+        if ('.' == target [path_len-1] && 'o' == target [path_len]) {
             if (!exists)
                 status->status = ST_COMPILE;
             return 0;
@@ -249,18 +250,19 @@
 #if !defined (_WIN32) && !defined (_WIN64)
         /* Otherwise, check for the .o file on non-windows systems */
         tmp_name = (char*)RW_MALLOC (path_len + 3);
-        memcpy (tmp_name, status->argv [0], path_len + 1);
+        memcpy (tmp_name, target, path_len + 1);
         strcat (tmp_name,".o");
 #else
         /* Or the target\target.obj file on windows systems*/
         {
+            const char* const target_name = get_target ();
             size_t target_len = strlen (target_name);
             size_t tmp_len = path_len + target_len - 2;
                 /* - 2 comes from removing 4 characters (extra .exe) and 
                    adding 2 characters (\ directory seperator and trailing 
                    null) */
             tmp_name = (char*)RW_MALLOC (tmp_len);
-            memcpy (tmp_name, status->argv [0], path_len - 4);
+            memcpy (tmp_name, target, path_len - 4);
             tmp_name [path_len - 4] = default_path_sep;
             memcpy (tmp_name + path_len - 3, target_name, target_len);
             tmp_name [tmp_len - 4] = 'o';
@@ -289,69 +291,6 @@
 }
 
 /**
-   Post target execution result analysis.
-
-   This method examines the content of result, dispatching the processing
-   to pares_output () if target had a return code of 0.
-   Otherwise, this method determines why target terminated, based on the
-   return code and fills the result structure with these results.
-
-   @param target the path to the executable that was run
-   @param result the return code data from running the target
-   @param status status object to record results in.
-   @see parse_output ()
-*/
-static void
-process_results (const struct exec_attrs* result, 
-                 struct target_status* status)
-{
-    assert (0 != result);
-    assert (0 != status);
-
-    if (0 == result->status) {
-        parse_output (status);
-    } 
-#if !defined (_WIN32) && !defined (_WIN64)
-    else if (WIFEXITED (result->status)) {
-        const int retcode = WEXITSTATUS (result->status);
-        switch (retcode) {
-        case 126:
-            status->status = ST_EXIST;
-            break;
-        case 127:
-            status->status = ST_EXECUTE;
-            break;
-        default:
-            status->exit = retcode;
-        }
-    }
-    else if (WIFSIGNALED (result->status)) {
-        status->signal = WTERMSIG (result->status);
-    }
-    else if (WIFSTOPPED (result->status)) {
-        status->signal = WSTOPSIG (result->status);
-    }
-    else if (-1 == result->status && -1 == result->killed) {
-        status->status = ST_NOT_KILLED;
-    }
-    else {
-        warn ("Unknown result status: %d, %d\n", result->status, 
-              result->killed);
-        status->status = ST_SYSTEM_ERROR;
-    }
-#else
-    else if (-1 == result->status)
-        status->status = ST_SYSTEM_ERROR;
-    else if (result->error)
-        status->status = ST_KILLED;
-    else if (STATUS_ACCESS_VIOLATION == result->status)
-        status->signal = SIGSEGV;
-    else
-        status->exit = result->status;
-#endif   /* _WIN{32,64} */
-}
-
-/**
    (Re)implementation of the POSIX basename function.
 
    This is a simplistic (re)implementation of the basename function
@@ -382,6 +321,13 @@
     return mark;
 }
 
+static const char* target_name;
+
+const char* get_target ()
+{
+    return target_name;
+}
+
 /**
    High level method to run target, using childargv as arguments.
 
@@ -396,33 +342,37 @@
    @see process_results
 */
 static void
-run_target (char* target, char** argv)
+run_target (char* target, const struct target_opts *target_template)
 {
+    struct target_opts options;
     struct target_status results;
 
     assert (0 != target);
-    assert (0 != argv);
+    assert (0 != target_template);
+    assert (0 != target_template->argv);
 
+    memcpy (&options, target_template, sizeof options);
     memset (&results, 0, sizeof results);
 
-    results.argv = merge_argv (target, argv);
+    options.argv = merge_argv (target, options.argv);
 
-    assert (0 != results.argv);
-    assert (0 != results.argv [0]);
+    assert (0 != options.argv);
+    assert (0 != options.argv [0]);
 
-    target_name = rw_basename (results.argv [0]);
+    target_name = rw_basename (options.argv [0]);
 
-    print_target (&results);
+    print_target (&options);
 
-    if (check_target_ok (&results)) {
-        struct exec_attrs status = exec_file (&results);
-        process_results (&status, &results);
+    if (check_target_ok (options.argv [0], &results)) {
+        exec_file (&options, &results);
+        if (0 == results.exit && 0 == results.signaled)
+            parse_output (&options, &results);
     }
 
     print_status (&results);
 
-    free (results.argv [0]);
-    free (results.argv);
+    free (options.argv [0]);
+    free (options.argv);
 }
 
 /**
@@ -439,10 +389,18 @@
 int
 main (int argc, char *argv [])
 {
+    struct target_opts target_template;
+    const char* exe_opts = "";
+
     exe_name = argv [0];
+    memset (&target_template, 0, sizeof target_template);
+
+    target_template.timeout = 10;
+    target_template.data_dir = "";
 
     if (1 < argc && '-' == argv [1][0]) {
-        const int nopts = eval_options (argc, argv);
+        const int nopts =
+            eval_options (argc, argv, &target_template, &exe_opts);
 
         if (0 > nopts)
             return 1;
@@ -457,22 +415,30 @@
 
     if (0 < argc) {
         int i;
-        char** childargv = split_opt_string (exe_opts);
+        target_template.argv = split_opt_string (exe_opts);
 
-        assert (0 != childargv);
+        assert (0 != target_template.argv);
 
         print_header ();
 
         for (i = 0; i < argc; ++i) {
-            run_target (argv [i], childargv);
+            run_target (argv [i], &target_template);
         }
 
         print_footer ();
 
-        if (childargv [0])
-            free (childargv [0]);
-        free (childargv);
+        if (target_template.argv [0])
+            free (target_template.argv [0]);
+        free (target_template.argv);
     }
+
+    free (target_template.core);
+    free (target_template.cpu);
+    free (target_template.data);
+    free (target_template.fsize);
+    free (target_template.nofile);
+    free (target_template.stack);
+    free (target_template.as);
 
     return 0;
 }

Added: incubator/stdcxx/trunk/util/target.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/target.h?view=auto&rev=451079
==============================================================================
--- incubator/stdcxx/trunk/util/target.h (added)
+++ incubator/stdcxx/trunk/util/target.h Thu Sep 28 18:11:13 2006
@@ -0,0 +1,148 @@
+/************************************************************************
+ *
+ * cmdopt.h - Interface declaration for the option parsing subsystem
+ *
+ * $Id$
+ *
+ ************************************************************************
+ *
+ * Licensed to the Apache Software  Foundation (ASF) under one or more
+ * contributor  license agreements.  See  the NOTICE  file distributed
+ * with  this  work  for  additional information  regarding  copyright
+ * ownership.   The ASF  licenses this  file to  you under  the Apache
+ * License, Version  2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the  License is distributed on an  "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
+ * implied.   See  the License  for  the  specific language  governing
+ * permissions and limitations under the License.
+ * 
+ **************************************************************************/
+
+#ifndef RW_TARGET_H
+#define RW_TARGET_H
+
+#if !defined (_WIN32) && !defined (_WIN64)
+#  include <unistd.h> /* For _XOPEN_UNIX */
+#endif
+
+#ifdef _XOPEN_UNIX
+#  include <sys/resource.h> /* for struct rlimit */
+#  include <sys/time.h> /* for struct timeval */
+/**
+   Abstraction typedef for struct rlimit using real struct
+*/
+typedef struct rlimit rw_rlimit;
+/**
+   Abstraction typedef for struct timeval using real struct
+*/
+typedef struct timeval rw_timeval;
+#else
+/**
+   Placeholder rlim_t for use in rw_rlimit
+*/
+typedef unsigned long rw_rlim_t;
+/**
+   Placeholder struct rlimit to use if _XOPEN_UNIX isn't defined
+*/
+struct rw_rlimit {
+    rw_rlim_t rlim_cur;
+    rw_rlim_t rlim_max;
+};
+/**
+   Abstraction typedef for struct rlimit using placeholder struct
+*/
+typedef struct rw_rlimit rw_rlimit;
+/**
+   Placeholder time_t for use in rw_timeval
+*/
+typedef long rw_time_t;
+/**
+   Placeholder suseconds_t for use in rw_timeval
+*/
+typedef long rw_suseconds_t;
+/**
+   Placeholder struct timeval to use if _XOPEN_UNIX isn't defined
+*/
+struct rw_timeval {
+    rw_time_t tv_sec;
+    rw_suseconds_t tv_usec;
+};
+/**
+   Abstraction typedef for struct timeval using placeholder struct
+*/
+typedef struct rw_timeval rw_timeval;
+#endif
+
+#ifndef RLIM_INFINITY
+#  define RLIM_INFINITY -1
+#endif /* RLIM_INFINITY */
+
+#ifndef RLIM_SAVED_CUR
+#  define RLIM_SAVED_CUR RLIM_INFINITY
+#endif   /* RLIM_SAVED_CUR */
+
+#ifndef RLIM_SAVED_MAX
+#  define RLIM_SAVED_MAX RLIM_INFINITY
+#endif   /* RLIM_SAVED_MAX */
+
+/**
+   Structure encapsulating the options involved in executing a run.
+*/
+struct target_opts {
+    char** argv; /**< Target argv array. */
+    unsigned timeout; /**< Allowed time for process execution. */
+    const char* data_dir; /**< Root dir for reference input/output files. */
+    int compat; /**< Test suite compatability mode switch. */
+    rw_rlimit* core;
+    rw_rlimit* cpu;
+    rw_rlimit* data;
+    rw_rlimit* fsize;
+    rw_rlimit* nofile;
+    rw_rlimit* stack;
+    rw_rlimit* as;
+};
+
+/**
+   Status codes to denote result of analysis.
+*/
+enum ProcessStatus {
+    ST_OK = 0, /**< Default (OK) status */
+    ST_COMPILE, /**< Target failed to compile */
+    ST_LINK, /**< Target failed to link */
+    ST_EXIST, /**< Target doesn't exist? */
+    ST_EXECUTE_FLAG, /**< Target lacks X flag */
+    ST_EXECUTE, /**< Target failed to execute? */
+    ST_NO_OUTPUT, /**< Target produced no output */
+    ST_NO_REF, /**< No reference file found */
+    ST_BAD_REF, /**< Invalid reference file found */
+    ST_BAD_OUTPUT, /**< Incorrect output found */
+    ST_FORMAT, /**< Incorrectly formatted (test) output found */
+    ST_OVERFLOW, /**< Assertion counter overflow */
+    ST_SYSTEM_ERROR, /**< System error during file system operation */
+    ST_KILLED, /**< Target killed by exec utility */
+    ST_NOT_KILLED, /** Target not killed by exec utility */
+    ST_LAST /**< Array terminator */
+};
+
+/**
+   Structure encapsulating the results extracted from a run.
+*/
+struct target_status {
+    int exit; /**< exit/signal code for process. */
+    int signaled; /**< 1 if exit is a signal number, 0 denoting exit code 
+                     otherwise */
+    enum ProcessStatus status; /**< Textual process status. */
+    const rw_timeval* user; /**< Elapsed user time spent in execution. */
+    const rw_timeval* sys; /**< Elapsed system time spent in execution. */
+    unsigned warn; /**< Number of (test) warnings. */
+    unsigned assert; /**< Number of (test) assertions. */
+    unsigned failed; /**< Number of failed (test) assertions. */
+};
+
+#endif   /* RW_TARGET_H */

Propchange: incubator/stdcxx/trunk/util/target.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/stdcxx/trunk/util/target.h
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: incubator/stdcxx/trunk/util/util.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/util.cpp?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/util.cpp (original)
+++ incubator/stdcxx/trunk/util/util.cpp Thu Sep 28 18:11:13 2006
@@ -35,6 +35,7 @@
 void
 warn (const char* const format, ...)
 {
+    const char* const target_name = get_target ();
     va_list args;
 
     assert (0 != format);
@@ -58,6 +59,7 @@
 void
 terminate (const int state, const char* const format, ...)
 {
+    const char* const target_name = get_target ();
     va_list args;
 
     assert (0 != format);
@@ -128,30 +130,31 @@
 }
 
 char*
-reference_name (const char* dir, const char* mode)
+reference_name (const char* data_dir, const char* subdir, const char* mode)
 {
     size_t root_len, cmp_len, dir_len, mode_len, net_len;
     char* ref_name;
     char* tail;
+    const char* const target_name = get_target ();
 
-    assert (0 != in_root);
+    assert (0 != data_dir);
     assert (0 != target_name);
-    assert (0 != dir);
+    assert (0 != subdir);
     assert (0 != mode);
 
-    root_len = strlen (in_root);
+    root_len = strlen (data_dir);
     cmp_len = strlen (target_name) - exe_suffix_len;
-    dir_len = strlen (dir);
+    dir_len = strlen (subdir);
     mode_len = strlen (mode);
     net_len = root_len + cmp_len + dir_len + mode_len * 2 + 5;
     /* 5 comes from 3 path seperator characters, the suffix seperator 
        character, and the trailing null */
     tail = ref_name = (char*)RW_MALLOC (net_len);
 
-    memcpy (tail, in_root, root_len);
+    memcpy (tail, data_dir, root_len);
     tail += root_len;
     *tail++ = default_path_sep;
-    memcpy (tail , dir, dir_len);
+    memcpy (tail , subdir, dir_len);
     tail += dir_len;
     *tail++ = default_path_sep;
     memcpy (tail , mode, mode_len);

Modified: incubator/stdcxx/trunk/util/util.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/util.h?view=diff&rev=451079&r1=451078&r2=451079
==============================================================================
--- incubator/stdcxx/trunk/util/util.h (original)
+++ incubator/stdcxx/trunk/util/util.h Thu Sep 28 18:11:13 2006
@@ -53,15 +53,17 @@
                        const char* const file, const unsigned line);
 
 /**
-   Generates the name of a reference (input/output) file, based on dir and mode.
+   Generates the name of a reference (input/output) file.
 
    This function allocates memory which is to be freed by the caller.
 
-   @param dir example subdirectory to reference
+   @param data_dir location of example data directory
+   @param subdir example subdirectory to reference
    @param mode type of file to generate name for (should be 'in' or 'out')
-   @return translation of 'in_root/dir/mode/target_name.mode'
+   @return translation of 'data_dir/subdir/mode/target_name.mode'
 */
-char* reference_name (const char* dir, const char* mode);
+char* reference_name (const char* data_dir, const char* subdir, 
+                      const char* mode);
 
 /**
    Generates the name of the output file for the executable target.



Mime
View raw message