stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject svn commit: r463535 - in /incubator/stdcxx/trunk: etc/config/makefile.common etc/config/makefile.rules util/cmdopt.cpp util/display.cpp util/output.cpp util/runall.cpp util/target.h
Date Fri, 13 Oct 2006 00:49:35 GMT
Author: sebor
Date: Thu Oct 12 17:49:34 2006
New Revision: 463535

URL: http://svn.apache.org/viewvc?view=rev&rev=463535
Log:
2006-10-12  Andrew Black  <ablack@roguewave.com>

	* makefile.rules (%.o: %(AS_EXT), %.o: %.cpp, %: %.o, %: %.cpp): Add
	$(TEEOPTS) to compile/link line so that output is routed to log files.
	* makefile.common (TEEOPTS): Always tee output to $@.log.
	* target.h (target_opts): Add c_warn and l_warn fields.
	(target_status): Split warn field into c_warn, l_warn, t_warn.
	* output.cpp (check_test): Count warnings, store in status->t_warn.
	(check_compat_test): Expand tail horizon, capture warnings into
	status->t_warn.
	* display.cpp (print_header_plain): Add WARN column, rename WALL
	column to REAL.
	(print_status_plain): Print the total number of warnings in the WARN
	column.
	* runall.cpp (count_warnings): Add static method to count the number
	of warnings in a .log file.
	(check_target_ok): Always calculate object file name, call
	count_warnings for object and executable.
	* cmdopt.cpp (usage_text): Document new --warn switch.
	(parse_warn_opts): Define new helper function to parse --warn switch.
	(eval_options): Used here in parsing and to initialize default c_warn
	and l_warn values. 

Modified:
    incubator/stdcxx/trunk/etc/config/makefile.common
    incubator/stdcxx/trunk/etc/config/makefile.rules
    incubator/stdcxx/trunk/util/cmdopt.cpp
    incubator/stdcxx/trunk/util/display.cpp
    incubator/stdcxx/trunk/util/output.cpp
    incubator/stdcxx/trunk/util/runall.cpp
    incubator/stdcxx/trunk/util/target.h

Modified: incubator/stdcxx/trunk/etc/config/makefile.common
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/etc/config/makefile.common?view=diff&rev=463535&r1=463534&r2=463535
==============================================================================
--- incubator/stdcxx/trunk/etc/config/makefile.common (original)
+++ incubator/stdcxx/trunk/etc/config/makefile.common Thu Oct 12 17:49:34 2006
@@ -143,8 +143,10 @@
 
 # if LOGFILE is being created, tee command output into it
 # IMPORTANT: $(TEEOPTS) must be last on the command line
-ifneq ($(LOGFILE),/dev/null)
-  TEEOPTS = 2>&1 | tee -a $(LOGFILE)
+ifeq ($(LOGFILE),/dev/null)
+  TEEOPTS = 2>&1 | tee $@.log
+else
+  TEEOPTS = 2>&1 | tee $@.log | tee -a $(LOGFILE)
 endif
 
 # determine the name of the results file against which to compute regressions

Modified: incubator/stdcxx/trunk/etc/config/makefile.rules
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/etc/config/makefile.rules?view=diff&rev=463535&r1=463534&r2=463535
==============================================================================
--- incubator/stdcxx/trunk/etc/config/makefile.rules (original)
+++ incubator/stdcxx/trunk/etc/config/makefile.rules Thu Oct 12 17:49:34 2006
@@ -60,16 +60,16 @@
     ifneq ($(AS_EXT),".")
 
 %.o: %$(AS_EXT)
-	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
+	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< $(TEEOPTS)
 
     endif   # ifneq ($(AS_EXT),".")
   endif   # ifneq ($(AS_EXT),)
 
 %.o: %.cpp
-	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
+	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< $(TEEOPTS)
 
 %: %.o
-	$(LD) $< -o $@ $(LDFLAGS) $(LDLIBS)
+	$(LD) $< -o $@ $(LDFLAGS) $(LDLIBS) $(TEEOPTS)
 
 # disable compilation and linking in the same step
 # %: %.cpp
@@ -78,7 +78,7 @@
 
 # compile and link in one step to eliminate the space overhead of .o files
 %: %.cpp
-	$(CXX) $< -o $@ $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(LDLIBS)
+	$(CXX) $< -o $@ $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(LDLIBS) $(TEEOPTS)
 
 endif   # eq ($(NO_DOT_O),)
 

Modified: incubator/stdcxx/trunk/util/cmdopt.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/cmdopt.cpp?view=diff&rev=463535&r1=463534&r2=463535
==============================================================================
--- incubator/stdcxx/trunk/util/cmdopt.cpp (original)
+++ incubator/stdcxx/trunk/util/cmdopt.cpp Thu Oct 12 17:49:34 2006
@@ -89,6 +89,7 @@
     "    --signal=sig Send itself the specified signal.\n"
     "    --ignore=sig Ignore the specified signal.\n"
     "    --ulimit=lim Set child process usage limits (see below).\n"
+    "    --warn=alias Set compiler log warning pattern (see below).\n"
     "\n"
     "  All short (single dash) options must be specified seperately.\n"
     "  If a short option takes a value, it may either be provided like\n"
@@ -121,6 +122,22 @@
     "  Note: Some operating systems lack support for some or all of the\n"
     "  ulimit modes.  If a system is unable to limit a given property, a\n"
     "  warning message will be produced.\n"
+    "\n"
+    "  --warn set the string used to parse compile and link logs.  Rather\n"
+    "  than specifying a search string, an alias code is provided,\n"
+    "  coresponding to the output of a compiler and linker.  Alias codes\n"
+    "  are case sensitive.\n"
+    "\n"
+    "  --warn modes:\n"
+    "    acc     HP aCC\n"
+    "    cxx     Compaq C++\n"
+    "    eccp    EDG eccp\n"
+    "    gcc     GNU gcc\n"
+    "    icc     Intel icc for Linux\n"
+    "    mipspro SGI MIPSpro\n"
+    "    sunpro  Sun C++\n"
+    "    vacpp   IBM VisualAge C++\n"
+    "    xlc     IBM XLC++\n"
 };
 
 #if !defined (_WIN32) && !defined (_WIN64)
@@ -365,6 +382,51 @@
     return 0;
 }
 
+/**
+   Helper function to parse a warning value string
+
+   @param opts ulimit value string to pares
+   @see child_limits
+*/
+static bool
+parse_warn_opts (const char* arg, struct target_opts* defaults)
+{
+    static const struct {
+        const char* name;
+        const char* pat;
+    } warn_set [] = {
+        { "acc", "Warning " },
+/*
+        { "cds", "UNKNOWN"},
+        { "como", "UNKNOWN"},
+*/
+        { "cxx", "Warning:"},
+        { "eccp", "warning:"},
+        { "gcc", "warning:"},
+        { "icc", "warning #"},
+        { "mipspro", "CC: WARNING"},
+        { "sunpro", "Warning:"},
+        { "vacpp", ": (W) "},
+        { "xlc", ": (W) "}, /* xlc and vacpp are synonyms. */
+        { 0, 0 }
+    };
+
+    assert (0 != arg);
+    assert (0 != defaults);
+
+    for (size_t i = 0; warn_set [i].name; ++i) {
+        if (0 == strcmp (warn_set [i].name, arg)) {
+
+            /* Set both compiler and linker warning string. */
+            defaults->c_warn = warn_set [i].pat;
+            defaults->l_warn = warn_set [i].pat;
+
+            return 0;
+        }
+    }
+
+    return 1;
+}
 
 /**
     Helper function to produce 'Bad argument' error message.
@@ -423,11 +485,41 @@
     const char opt_signal[]   = "--signal";
     const char opt_sleep[]    = "--sleep";
     const char opt_ulimit[]   = "--ulimit";
+    const char opt_warn[]     = "--warn";
 
     int i;
 
     assert (0 != argv);
 
+    /* The chain of preprocesor logic below initializes the defaults->c_warn 
+       and defaults->l_warn values.
+    */
+#ifdef __GNUG__
+    parse_warn_opts ("Gcc", defaults);
+#elif defined (__HP_aCC)
+    parse_warn_opts ("Acc", defaults);
+#elif defined (__IBMCPP__)
+    parse_warn_opts ("Xlc", defaults);
+#elif defined (__SUNPRO_CC)
+    parse_warn_opts ("Sunpro", defaults);
+#elif defined (SNI)
+    parse_warn_opts ("Cds", defaults);
+#elif defined (__APOGEE__) /* EDG variant that doesn't define __EDG__. */
+    parse_warn_opts ("Como", defaults);
+
+/* The following are EDG variants, that define __EDG__ */
+#elif defined (__DECCXX)
+    parse_warn_opts ("Cxx", defaults);
+#elif defined (_SGI_COMPILER_VERSION)
+    parse_warn_opts ("Mipspro", defaults);
+#elif defined (__INTEL_COMPILER)
+    parse_warn_opts ("Icc", defaults);
+
+/* So we need to check for __EDG__ after we check for them. */
+#elif defined (__EDG__)
+    parse_warn_opts ("Eccp", defaults);
+#endif
+
     if (1 == argc || '-' != argv [1][0])
         return 1;
 
@@ -559,6 +651,16 @@
                 optarg  = get_long_val (argv, &i, sizeof opt_ulimit - 1);
                 if (optarg && *optarg) {
                     if (!parse_limit_opts (optarg, defaults)) {
+                        break;
+                    }
+                }
+            }
+            else if (   sizeof opt_warn - 1 <= arglen
+                     && !memcmp (opt_warn, argv [i], sizeof opt_warn - 1)) {
+                optname = opt_warn;
+                optarg  = get_long_val (argv, &i, sizeof opt_warn - 1);
+                if (optarg && *optarg) {
+                    if (!parse_warn_opts (optarg, defaults)) {
                         break;
                     }
                 }

Modified: incubator/stdcxx/trunk/util/display.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/display.cpp?view=diff&rev=463535&r1=463534&r2=463535
==============================================================================
--- incubator/stdcxx/trunk/util/display.cpp (original)
+++ incubator/stdcxx/trunk/util/display.cpp Thu Oct 12 17:49:34 2006
@@ -40,8 +40,8 @@
 */
 static void print_header_plain ()
 {
-    puts ("NAME                      STATUS ASSERTS FAILED PERCNT    USER     "
-          "SYS    WALL");
+    puts ("NAME                      STATUS WARN ASSERTS FAILED PERCNT    "
+          "USER     SYS    REAL");
 }
 
 /**
@@ -75,6 +75,8 @@
         printf ("%6d", status->exit);
     else 
         printf ("     0");
+
+    printf (" %4u", status->c_warn + status->l_warn + status->t_warn);
 
     /* Print assetions, if any registered */
     if (status->assert) {

Modified: incubator/stdcxx/trunk/util/output.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/output.cpp?view=diff&rev=463535&r1=463534&r2=463535
==============================================================================
--- incubator/stdcxx/trunk/util/output.cpp (original)
+++ incubator/stdcxx/trunk/util/output.cpp Thu Oct 12 17:49:34 2006
@@ -109,7 +109,13 @@
                     return;
                 }
             }
-            /* else if (1 < r_lvl) warning*/
+            else if (1 < r_lvl) {
+                status->t_warn += r_active;
+                if (status->t_warn < r_active) {
+                    status->t_warn = (unsigned int)-1;
+                    return;
+                }
+            }
             fmt_ok = 1;
         }
     }
@@ -138,7 +144,7 @@
     assert (0 != data);
     assert (0 != status);
 
-    fseek (data, -64, SEEK_END); /* Seek near the end of the file */
+    fseek (data, -80, SEEK_END); /* Seek near the end of the file */
 
     for (tok = fgetc (data); fsm < 4 && !feof (data); tok = fgetc (data)) {
         switch (tok) {
@@ -160,13 +166,13 @@
             fsm = 0;
         }
     }
-
-    if (!feof (data)) { /* leading "## A" eaten above */
-        read = fscanf (data, "ssertions = %u\n## FailedAssertions = %u",
-                        &status->assert, &status->failed);
+    if (!feof (data)) { /* leading "## W" eaten above */
+        read = fscanf (data, "arnings = %u\n## Assertions = %u\n"
+                       "## FailedAssertions = %u",
+                       &status->t_warn, &status->assert, &status->failed);
     }
 
-    if (2 != read) {
+    if (3 != read) {
         status->status = ST_FORMAT;
     }
 }

Modified: incubator/stdcxx/trunk/util/runall.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/runall.cpp?view=diff&rev=463535&r1=463534&r2=463535
==============================================================================
--- incubator/stdcxx/trunk/util/runall.cpp (original)
+++ incubator/stdcxx/trunk/util/runall.cpp Thu Oct 12 17:49:34 2006
@@ -28,6 +28,7 @@
 #include <errno.h>      /* for errno */
 #include <stdlib.h>     /* for exit(), free() */
 #include <string.h>     /* for memcpy(), ... */
+#include <stdio.h>      /* for FILE, fopen(), ... */
 
 #include <ctype.h>      /* for isspace */
 #include <sys/types.h>
@@ -193,11 +194,82 @@
 }
 
 /**
+   Arbitrary constant controling static read buffer size.
+
+   @see count_warnings
+*/
+#define READ_BUF_LEN 64
+
+/**
+   Compiler/linker output parser.
+
+   This method tries to open the compiler/linker log file, based on the name
+   of a the target file that was generated by the compiler/linker.
+   Upon opening the file, it tries to count the number of warnings present.
+
+   @param target name of target to parse the log for
+   @param counter pointer to the counter to count warnings in.
+   @param match string to match when detecting a warning.
+*/
+static
+void count_warnings (const char* const target, unsigned* counter, 
+                     const char* const match)
+{
+    size_t path_len;
+    char* tmp_name;
+    FILE* data;
+
+    assert (0 != target);
+    assert (0 != counter);
+
+    if (0 == match)
+        return; /* Don't have a match string, so don't tally warnings */
+
+    path_len = strlen (target);
+    tmp_name = (char*)RW_MALLOC (path_len + 5);
+    memcpy (tmp_name, target, path_len + 1);
+    strcat (tmp_name,".log");
+
+    data = fopen (tmp_name, "r");
+    if (data) {
+        size_t pos = 0, limit = strlen (match);
+        while (!feof (data)) {
+            char buf [READ_BUF_LEN];
+            size_t nread;   /* bytes read */
+
+            /* First, read a block from the file into the buffer */
+            nread = fread (buf, 1, sizeof buf, data);
+            if (ferror (data)) {
+                warn ("Error reading %s: %s\n", tmp_name, strerror (errno));
+                break;
+            }
+
+            /* Then, look for the search string within it. */
+            for (size_t i = 0; i < nread; ++i) {
+                if (buf [i] != match [pos])
+                    pos = 0;
+                else if (++pos == limit) {
+                    pos = 0;
+                    ++*counter;
+                }
+            }
+        }
+
+        fclose (data);
+    }
+    else if (ENOENT != errno)
+        warn ("Error opening %s: %s\n", tmp_name, strerror (errno));
+
+    free (tmp_name);
+}
+
+/**
    Preflight check to ensure that target is something that should be run.
 
    This method checks to see if target exists and is theoretically executable.
    If a problem is detected, the condition is recorded in the status structure
-   and 0 is returned.
+   and 0 is returned.  This method also attempts to determine the number of 
+   compile and link warnings that occurred, using count_warnings.
 
    A special case is the situation where the target name ends in .o, 
    indicating that the target only needed to compile, and doesn't need to
@@ -212,31 +284,63 @@
 {
     struct stat file_info;
     int exists = 1;
+    size_t path_len;
+    char* tmp_name;
 
     assert (0 != target);
     assert (0 != status);
 
+    path_len = strlen (target);
+
+#ifndef _WIN32
+    /* Otherwise, check for the .o file on non-windows systems */
+    tmp_name = (char*)RW_MALLOC (path_len + 3);
+    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, 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';
+        tmp_name [tmp_len - 3] = 'b';
+        tmp_name [tmp_len - 2] = 'j';
+        tmp_name [tmp_len - 2] = '\0';
+    }
+#endif   /* _WIN32 */
+
+    count_warnings (target, &status->l_warn, "warning:");
+    count_warnings (tmp_name, &status->c_warn, "warning:");
+
     if (0 > stat (target, &file_info)) {
         if (ENOENT != errno) {
             warn ("Error stating %s: %s\n", target, strerror (errno));
             status->status = ST_SYSTEM_ERROR;
+            free (tmp_name);
             return 0;
         }
         file_info.st_mode = 0; /* force mode on non-existant file to 0 */
         exists = 0; /* note that it doesn't exist */
     }
+
     if (0 == (file_info.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
         /* 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 (target);
-        char* tmp_name;
 
 #if 0 /* Disable .o target check as unused */
         /* If target is a .o file, check if it exists */
         if ('.' == target [path_len-1] && 'o' == target [path_len]) {
             if (!exists)
                 status->status = ST_COMPILE;
+            free (tmp_name);
             return 0;
         }
 #endif
@@ -244,34 +348,10 @@
         /* If the target exists, it doesn't have valid permissions */
         if (exists) {
             status->status = ST_EXECUTE_FLAG;
+            free (tmp_name);
             return 0;
         }
 
-#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, 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, 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';
-            tmp_name [tmp_len - 3] = 'b';
-            tmp_name [tmp_len - 2] = 'j';
-            tmp_name [tmp_len - 2] = '\0';
-        }
-#endif   /* _WIN{32,64} */
-
         if (0 > stat (tmp_name, &file_info)) {
             if (ENOENT != errno) {
                 warn ("Error stating %s: %s\n", tmp_name, strerror (errno));
@@ -287,6 +367,7 @@
         free (tmp_name);
         return 0;
     }
+    free (tmp_name);
     return 1;
 }
 

Modified: incubator/stdcxx/trunk/util/target.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/target.h?view=diff&rev=463535&r1=463534&r2=463535
==============================================================================
--- incubator/stdcxx/trunk/util/target.h (original)
+++ incubator/stdcxx/trunk/util/target.h Thu Oct 12 17:49:34 2006
@@ -98,6 +98,8 @@
     char** argv; /**< Target argv array. */
     unsigned timeout; /**< Allowed time for process execution. */
     const char* data_dir; /**< Root dir for reference input/output files. */
+    const char* c_warn; /**< Warning flag string when compiling. */
+    const char* l_warn; /**< Warning flag string when linking. */
     int compat; /**< Test suite compatability mode switch. */
     rw_rlimit* core;
     rw_rlimit* cpu;
@@ -141,7 +143,9 @@
     const rw_timeval* user; /**< Elapsed user time spent in execution. */
     const rw_timeval* sys; /**< Elapsed system time spent in execution. */
     const rw_timeval* wall; /**< Wall clock time spent in execution. */
-    unsigned warn; /**< Number of (test) warnings. */
+    unsigned c_warn; /**< Number of compile warnings. */
+    unsigned l_warn; /**< Number of link warnings. */
+    unsigned t_warn; /**< Number of (test) warnings. */
     unsigned assert; /**< Number of (test) assertions. */
     unsigned failed; /**< Number of failed (test) assertions. */
 };



Mime
View raw message