Revision: 75797
          http://sourceforge.net/p/brlcad/code/75797
Author:   starseeker
Date:     2020-05-14 12:57:10 +0000 (Thu, 14 May 2020)
Log Message:
-----------
Back down to single threaded execution

Modified Paths:
--------------
    brlcad/trunk/regress/repository/repocheck.cpp

Modified: brlcad/trunk/regress/repository/repocheck.cpp
===================================================================
--- brlcad/trunk/regress/repository/repocheck.cpp       2020-05-14 12:11:48 UTC 
(rev 75796)
+++ brlcad/trunk/regress/repository/repocheck.cpp       2020-05-14 12:57:10 UTC 
(rev 75797)
@@ -39,12 +39,10 @@
  *
  */
 
-#include <cstring>
 #include <cstdio>
 #include <algorithm>
 #include <locale>
 #include <fstream>
-#include <sstream>
 #include <iomanip>
 #include <iostream>
 #include <regex>
@@ -52,237 +50,13 @@
 #include <map>
 #include <sstream>
 #include <string>
-#include <thread>
 #define MAX_LINES_CHECK 500
 #define EXPECTED_PLATFORM_SYMBOLS 206
 
-class repo_state_t {
+class repo_log_t {
     public:
-
-       // Thread state and result info
-       std::string cfile;
-       int ret = 0;
-       int inc_cnt = 0;
-       int src_cnt = 0;
-       int bld_cnt = 0;
-
-       // Initialize the regex info once per thread
-       repo_state_t() {
-           int cnt = 0;
-           const char *rf;
-           inc_regex = std::regex("#[[:space:]]*include.*");
-
-           /* bio.h regex */
-           {
-               bio_regex = 
std::regex("#[[:space:]]*include[[:space:]]*\"bio.h\".*");
-               const char *bio_redundant_filter_strs[] {
-                   "stdio.h",
-                   "windows.h",
-                   "io.h",
-                   "unistd.h",
-                   "fcntl.h",
-                   NULL
-               };
-               cnt = 0;
-               rf = bio_redundant_filter_strs[cnt];
-               while (rf) {
-                   std::string rrf = std::string(".*<") + std::string(rf) + 
std::string(">.*");
-                   bio_redundant_filters[std::string(rf)] = std::regex(rrf);
-                   cnt++;
-                   rf = bio_redundant_filter_strs[cnt];
-               }
-           }
-
-
-           /* bnetwork.h regex */
-           {
-               bnetwork_regex = 
std::regex("#[[:space:]]*include[[:space:]]*\"bnetwork.h\".*");
-               const char *bnetwork_redundant_filter_strs[] {
-                   "winsock2.h",
-                   "netinet/in.h",
-                   "netinet/tcp.h",
-                   "arpa/inet.h",
-                   NULL
-               };
-               cnt = 0;
-               rf = bnetwork_redundant_filter_strs[cnt];
-               while (rf) {
-                   std::string rrf = std::string(".*<") + std::string(rf) + 
std::string(">.*");
-                   bnetwork_redundant_filters[std::string(rf)] = 
std::regex(rrf);
-                   cnt++;
-                   rf = bnetwork_redundant_filter_strs[cnt];
-               }
-           }
-
-           /* common.h regex */
-           {
-               common_regex = 
std::regex("#[[:space:]]*include[[:space:]]*\"common.h\".*");
-               const char *common_exempt_filter_strs[] {
-                   ".*/bio.h",
-                   ".*/bnetwork.h",
-                   ".*/config_win.h",
-                   ".*/csg_parser.c",
-                   ".*/csg_scanner.h",
-                   ".*/obj_grammar.c",
-                   ".*/obj_grammar.cpp",
-                   ".*/obj_libgcv_grammar.cpp",
-                   ".*/obj_obj-g_grammar.cpp",
-                   ".*/obj_parser.h",
-                   ".*/obj_rules.cpp",
-                   ".*/obj_rules.l",
-                   ".*/obj_scanner.h",
-                   ".*/obj_util.h",
-                   ".*/optionparser.h",
-                   ".*/pinttypes.h",
-                   ".*/points_scan.c",
-                   ".*/pstdint.h",
-                   ".*/schema.h",
-                   ".*/script.c",
-                   ".*/ttcp.c",
-                   ".*/uce-dirent.h",
-                   NULL
-               };
-               cnt = 0;
-               rf = common_exempt_filter_strs[cnt];
-               while (rf) {
-                   common_exempt_filters.push_back(std::regex(rf));
-                   cnt++;
-                   rf = common_exempt_filter_strs[cnt];
-               }
-
-           }
-
-           /* API usage check regex */
-           {
-               const char *api_file_exemption_strs[] {
-                   ".*/CONFIG_CONTROL_DESIGN.*",
-                   ".*/bu/log[.]h$",
-                   ".*/bu/path[.]h$",
-                   ".*/bu/str[.]h$",
-                   ".*/cursor[.]c$",
-                   ".*/ttcp[.]c$",
-                   ".*/misc/CMake/compat/.*",
-                   NULL
-               };
-               cnt = 0;
-               rf = api_file_exemption_strs[cnt];
-               while (rf) {
-                   api_file_filters.push_back(std::regex(rf));
-                   cnt++;
-                   rf = api_file_exemption_strs[cnt];
-               }
-
-               const char *api_func_strs[] {
-                   "abort",
-                   "dirname",
-                   "fgets",
-                   "getopt",
-                   "qsort",
-                   "remove",
-                   "rmdir",
-                   "strcasecmp",
-                   "strcat",
-                   "strcmp",
-                   "strcpy",
-                   "strdup",
-                   "stricmp",
-                   "strlcat",
-                   "strlcpy",
-                   "strncasecmp",
-                   "strncat",
-                   "strncmp",
-                   "strncpy",
-                   "unlink",
-                   NULL
-               };
-               cnt = 0;
-               rf = api_func_strs[cnt];
-               while (rf) {
-                   std::string rrf = std::string(".*[^a-zA-Z0-9_:]") + 
std::string(rf) + std::string("[(].*");
-                   api_func_filters[std::string(rf)] = std::regex(rrf);
-                   cnt++;
-                   rf = api_func_strs[cnt];
-               }
-
-               
api_exemptions[std::string("abort")].push_back(std::regex(".*/bomb[.]c$"));
-               
api_exemptions[std::string("dirname")].push_back(std::regex(".*/tests/dirname[.]c$"));
-               
api_exemptions[std::string("remove")].push_back(std::regex(".*/file[.]c$"));
-               
api_exemptions[std::string("strcasecmp")].push_back(std::regex(".*/str[.]c$"));
-               
api_exemptions[std::string("strcmp")].push_back(std::regex(".*/str[.]c$"));
-               
api_exemptions[std::string("strdup")].push_back(std::regex(".*/str[.]c$"));
-               
api_exemptions[std::string("strlcat")].push_back(std::regex(".*/str[.]c$"));
-               
api_exemptions[std::string("strlcpy")].push_back(std::regex(".*/str[.]c$"));
-               
api_exemptions[std::string("strncasecmp")].push_back(std::regex(".*/str[.]c$"));
-               
api_exemptions[std::string("strncat")].push_back(std::regex(".*/str[.]c$"));
-               
api_exemptions[std::string("strncmp")].push_back(std::regex(".*/str[.]c$"));
-               
api_exemptions[std::string("strncpy")].push_back(std::regex(".*/rt/db4[.]h$"));
-               
api_exemptions[std::string("strncpy")].push_back(std::regex(".*/str[.]c$"));
-               
api_exemptions[std::string("strncpy")].push_back(std::regex(".*/vls[.]c$"));
-               
api_exemptions[std::string("strncpy")].push_back(std::regex(".*/wfobj/obj_util[.]cpp$"));
-           }
-
-           /* Platform symbol usage check regex */
-           {
-               const char *platform_strs[] {
-                   "AIX",
-                   "APPLE",
-                   "CYGWIN",
-                   "DARWIN",
-                   "FREEBSD",
-                   "HAIKU",
-                   "HPUX",
-                   "LINUX",
-                   "MINGW",
-                   "MSDOS",
-                   "QNX",
-                   "SGI",
-                   "SOLARIS",
-                   "SUN",
-                   "SUNOS",
-                   "SVR4",
-                   "SYSV",
-                   "ULTRIX",
-                   "UNIX",
-                   "VMS",
-                   "WIN16",
-                   "WIN32",
-                   "WIN64",
-                   "WINE",
-                   "WINNT",
-                   NULL
-               };
-               cnt = 0;
-               rf = platform_strs[cnt];
-               while (rf) {
-                   std::string p_upper(rf);
-                   std::string p_lower = p_upper;
-                   std::transform(p_lower.begin(), p_lower.end(), 
p_lower.begin(), [](unsigned char c){ return std::tolower(c); });
-                   std::string rrf = 
std::string("^[[:space:]#]*(if|IF).*[[:space:](]_*(") + p_lower + 
std::string("|") + p_upper + std::string(")_*([[:space:]]|[)]|$).*$");
-                   platform_checks[std::string(rf)] = std::regex(rrf);
-                   cnt++;
-                   rf = platform_strs[cnt];
-               }
-
-               const char *platform_exemption_strs[] {
-                   ".*/pstdint[.]h$",
-                   ".*/pinttypes[.]h$",
-                   ".*/uce-dirent[.]h$",
-                   NULL
-               };
-               cnt = 0;
-               rf = platform_exemption_strs[cnt];
-               while (rf) {
-                   platform_file_filters.push_back(std::regex(rf));
-                   cnt++;
-                   rf = platform_exemption_strs[cnt];
-               }
-           }
-       }
-
-       // Root of input source dir - used to trim the source dir prefix off of 
file paths
        std::string path_root;
 
-       // Output logs
        std::vector<std::string> api_log;
        std::vector<std::string> bio_log;
        std::vector<std::string> bnet_log;
@@ -290,68 +64,73 @@
        std::vector<std::string> symbol_inc_log;
        std::vector<std::string> symbol_src_log;
        std::vector<std::string> symbol_bld_log;
+};
 
-       /* Standard regex patterns uses in searches */
+bool
+bio_redundant_check(repo_log_t &l, std::vector<std::string> &srcs)
+{
+    bool ret = false;
+    std::regex bio_regex("#[[:space:]]*include[[:space:]]*\"bio.h\".*");
+    std::regex inc_regex("#[[:space:]]*include.*");
+    const char *redundant_filters[] {
+       ".*<stdio.h>.*",
+       ".*<windows.h>.*",
+       ".*<io.h>.*",
+       ".*<unistd.h>.*",
+       ".*<fcntl.h>.*",
+       NULL
+    };
 
-       std::regex inc_regex;
+    std::map<std::string, std::regex> filters;
+    int cnt = 0;
+    const char *rf = redundant_filters[cnt];
+    while (rf) {
+       filters[std::string(rf)] = std::regex(rf);
+       cnt++;
+       rf = redundant_filters[cnt];
+    }
 
-       /* bio.h */
-       std::regex bio_regex;
-       std::map<std::string, std::regex> bio_redundant_filters;
 
-       /* bnetwork.h */
-       std::regex bnetwork_regex;
-       std::map<std::string, std::regex> bnetwork_redundant_filters;
+    for (size_t i = 0; i < srcs.size(); i++) {
+       std::string sline;
 
-       /* common.h */
-       std::regex common_regex;
-       std::vector<std::regex> common_exempt_filters;
+       std::map<std::string, std::set<int>> match_line_nums;
 
-       /* api usage */
-       std::vector<std::regex> api_file_filters;
-       std::map<std::string, std::vector<std::regex>> api_exemptions;
-       std::map<std::string, std::regex> api_func_filters;
-
-       /* platform symbols */
-       std::map<std::string, std::regex> platform_checks;
-       std::vector<std::regex> platform_file_filters;
-
-};
-
-int
-bio_redundant_check(repo_state_t &l, std::string &tfile, std::stringstream &fs)
-{
-    bool have_bio = false;
-    int lcnt = 0;
-    int ret = 0;
-    std::map<std::string, std::set<int>> match_line_nums;
-    std::string sline;
-
-    while (std::getline(fs, sline) && lcnt < MAX_LINES_CHECK) {
-       lcnt++;
-       if (std::regex_match(sline, l.bio_regex)) {
-           have_bio = true;
+       std::ifstream fs;
+       fs.open(srcs[i]);
+       if (!fs.is_open()) {
+           std::cerr << "Unable to open " << srcs[i] << " for reading, 
skipping\n";
            continue;
        }
 
-       std::map<std::string, std::regex>::iterator f_it;
-       for (f_it = l.bio_redundant_filters.begin(); f_it != 
l.bio_redundant_filters.end(); f_it++) {
-           if (std::regex_match(sline, f_it->second)) {
-               match_line_nums[f_it->first].insert(lcnt);
+       int lcnt = 0;
+       bool have_bio = false;
+       while (std::getline(fs, sline) && lcnt < MAX_LINES_CHECK) {
+           lcnt++;
+           if (std::regex_match(sline, bio_regex)) {
+               have_bio = true;
                continue;
            }
+
+           std::map<std::string, std::regex>::iterator f_it;
+           for (f_it = filters.begin(); f_it != filters.end(); f_it++) {
+               if (std::regex_match(sline, f_it->second)) {
+                   match_line_nums[f_it->first].insert(lcnt);
+                   continue;
+               }
+           }
        }
-    }
 
-    if (have_bio) {
-       std::map<std::string, std::set<int>>::iterator m_it;
-       for (m_it = match_line_nums.begin(); m_it != match_line_nums.end(); 
m_it++) {
-           if (m_it->second.size()) {
-               std::set<int>::iterator l_it;
-               ret = 1;
-               for (l_it = m_it->second.begin(); l_it != m_it->second.end(); 
l_it++) {
-                   std::string lstr = tfile.substr(l.path_root.length()+1) + 
std::string(" uses bio.h, but includes header ") + m_it->first + std::string(" 
on line ") + std::to_string(*l_it) + std::string("\n");
-                   l.bio_log.push_back(lstr);
+       if (have_bio) {
+           std::map<std::string, std::set<int>>::iterator m_it;
+           for (m_it = match_line_nums.begin(); m_it != match_line_nums.end(); 
m_it++) {
+               if (m_it->second.size()) {
+                   std::set<int>::iterator l_it;
+                   ret = true;
+                   for (l_it = m_it->second.begin(); l_it != 
m_it->second.end(); l_it++) {
+                       std::string lstr = 
srcs[i].substr(l.path_root.length()+1) + std::string(" has bio.h, but also 
matches regex ") + m_it->first + std::string(" on line ") + 
std::to_string(lcnt) + std::string("\n");
+                       l.bio_log.push_back(lstr);
+                   }
                }
            }
        }
@@ -360,40 +139,70 @@
     return ret;
 }
 
-int
-bnetwork_redundant_check(repo_state_t &l, std::string &tfile, 
std::stringstream &fs)
+bool
+bnetwork_redundant_check(repo_log_t &l, std::vector<std::string> &srcs)
 {
-    bool have_bnetwork = false;
-    int lcnt = 0;
-    int ret = 0;
-    std::map<std::string, std::set<int>> match_line_nums;
-    std::string sline;
+    bool ret = false;
+    std::regex 
bnetwork_regex("#[[:space:]]*include[[:space:]]*\"bnetwork.h\".*");
+    std::regex inc_regex("#[[:space:]]*include.*");
+    const char *redundant_filters[] {
+       ".*<winsock2.h>.*",
+       ".*<netinet/in.h>.*",
+       ".*<netinet/tcp.h>.*",
+       ".*<arpa/inet.h>.*",
+       NULL
+    };
 
-    while (std::getline(fs, sline) && lcnt < MAX_LINES_CHECK) {
-       lcnt++;
-       if (std::regex_match(sline, l.bnetwork_regex)) {
-           have_bnetwork = true;
+    std::map<std::string, std::regex> filters;
+    int cnt = 0;
+    const char *rf = redundant_filters[cnt];
+    while (rf) {
+       filters[std::string(rf)] = std::regex(rf);
+       cnt++;
+       rf = redundant_filters[cnt];
+    }
+
+
+    for (size_t i = 0; i < srcs.size(); i++) {
+       std::string sline;
+
+       std::map<std::string, std::set<int>> match_line_nums;
+
+       std::ifstream fs;
+       fs.open(srcs[i]);
+       if (!fs.is_open()) {
+           std::cerr << "Unable to open " << srcs[i] << " for reading, 
skipping\n";
            continue;
        }
 
-       std::map<std::string, std::regex>::iterator f_it;
-       for (f_it = l.bnetwork_redundant_filters.begin(); f_it != 
l.bnetwork_redundant_filters.end(); f_it++) {
-           if (std::regex_match(sline, f_it->second)) {
-               match_line_nums[f_it->first].insert(lcnt);
+       int lcnt = 0;
+       bool have_bnetwork = false;
+       while (std::getline(fs, sline) && lcnt < MAX_LINES_CHECK) {
+           lcnt++;
+           if (std::regex_match(sline, bnetwork_regex)) {
+               have_bnetwork = true;
                continue;
            }
+
+           std::map<std::string, std::regex>::iterator f_it;
+           for (f_it = filters.begin(); f_it != filters.end(); f_it++) {
+               if (std::regex_match(sline, f_it->second)) {
+                   match_line_nums[f_it->first].insert(lcnt);
+                   continue;
+               }
+           }
        }
-    }
 
-    if (have_bnetwork) {
-       std::map<std::string, std::set<int>>::iterator m_it;
-       for (m_it = match_line_nums.begin(); m_it != match_line_nums.end(); 
m_it++) {
-           if (m_it->second.size()) {
-               std::set<int>::iterator l_it;
-               ret = 1;
-               for (l_it = m_it->second.begin(); l_it != m_it->second.end(); 
l_it++) {
-                   std::string lstr = tfile.substr(l.path_root.length()+1) + 
std::string(" uses bnetwork.h, but also includes header ") + m_it->first + 
std::string(" on line ") + std::to_string(*l_it) + std::string("\n");
-                   l.bnet_log.push_back(lstr);
+       if (have_bnetwork) {
+           std::map<std::string, std::set<int>>::iterator m_it;
+           for (m_it = match_line_nums.begin(); m_it != match_line_nums.end(); 
m_it++) {
+               if (m_it->second.size()) {
+                   std::set<int>::iterator l_it;
+                   ret = true;
+                   for (l_it = m_it->second.begin(); l_it != 
m_it->second.end(); l_it++) {
+                       std::string lstr = 
srcs[i].substr(l.path_root.length()+1) + std::string(" has bnetwork.h, but also 
matches regex ") + m_it->first + std::string(" on line ") + 
std::to_string(lcnt) + std::string("\n");
+                       l.bnet_log.push_back(lstr);
+                   }
                }
            }
        }
@@ -404,102 +213,226 @@
 
 
 
-int
-common_include_first(repo_state_t &l, std::string &tfile, std::stringstream 
&fs)
+bool
+common_include_first(repo_log_t &l, std::vector<std::string> &srcs)
 {
-    int ret = 0;
+    bool ret = false;
+    std::regex inc_regex("#[[:space:]]*include.*");
+    std::regex common_regex("#[[:space:]]*include[[:space:]]*\"common.h\".*");
+    const char *exempt_filters[] {
+       ".*/bio.h",
+       ".*/bnetwork.h",
+       ".*/config_win.h",
+       ".*/csg_parser.c",
+       ".*/csg_scanner.h",
+       ".*/obj_grammar.c",
+       ".*/obj_grammar.cpp",
+       ".*/obj_libgcv_grammar.cpp",
+       ".*/obj_obj-g_grammar.cpp",
+       ".*/obj_parser.h",
+       ".*/obj_rules.cpp",
+       ".*/obj_rules.l",
+       ".*/obj_scanner.h",
+       ".*/obj_util.h",
+       ".*/optionparser.h",
+       ".*/pinttypes.h",
+       ".*/points_scan.c",
+       ".*/pstdint.h",
+       ".*/schema.h",
+       ".*/script.c",
+       ".*/ttcp.c",
+       ".*/uce-dirent.h",
+       NULL
+    };
 
-    bool skip = false;
-    for (size_t j = 0; j < l.common_exempt_filters.size(); j++) {
-       if (std::regex_match(tfile, l.common_exempt_filters[j])) {
-           skip = true;
-           break;
-       }
+    std::vector<std::regex> filters;
+    int cnt = 0;
+    const char *rf = exempt_filters[cnt];
+    while (rf) {
+       filters.push_back(std::regex(rf));
+       cnt++;
+       rf = exempt_filters[cnt];
     }
-    if (skip) {
-       return ret;
-    }
 
-    int lcnt = 0;
-    int first_inc_line = -1;
-    bool have_inc = false;
-    std::string sline;
-    while (std::getline(fs, sline) && lcnt < MAX_LINES_CHECK) {
-       lcnt++;
-       if (std::regex_match(sline, l.common_regex)) {
-           if (have_inc) {
-               std::string lstr = tfile.substr(l.path_root.length()+1) + 
std::string(" includes common.h on line ") + std::to_string(lcnt) + 
std::string(" but a prior #include statement was found at line ") + 
std::to_string(first_inc_line) + std::string("\n");
-               l.common_log.push_back(lstr);
-               ret = 1;
+    for (size_t i = 0; i < srcs.size(); i++) {
+       bool skip = false;
+       for (size_t j = 0; j < filters.size(); j++) {
+           if (std::regex_match(srcs[i], filters[j])) {
+               skip = true;
+               break;
            }
-           break;
        }
-       if (!have_inc && std::regex_match(sline, l.inc_regex)) {
-           have_inc = true;
-           first_inc_line = lcnt;
+       if (skip) {
+           continue;
        }
+
+       std::ifstream fs;
+       fs.open(srcs[i]);
+       if (!fs.is_open()) {
+           std::cerr << "Unable to open " << srcs[i] << " for reading, 
skipping\n";
+           continue;
+       }
+
+       int lcnt = 0;
+       int first_inc_line = -1;
+       bool have_inc = false;
+       std::string sline;
+       while (std::getline(fs, sline) && lcnt < MAX_LINES_CHECK) {
+           lcnt++;
+           if (std::regex_match(sline, common_regex)) {
+               if (have_inc) {
+                   std::string lstr = srcs[i].substr(l.path_root.length()+1) + 
std::string(" includes common.h on line ") + std::to_string(lcnt) + 
std::string(" but a prior #include statement was found at line ") + 
std::to_string(first_inc_line) + std::string("\n");
+                   l.common_log.push_back(lstr);
+                   ret = true;
+               }
+               break;
+           }
+           if (!have_inc && std::regex_match(sline, inc_regex)) {
+               have_inc = true;
+               first_inc_line = lcnt;
+           }
+       }
     }
 
+
     return ret;
 }
 
-int
-api_usage(repo_state_t &l, std::string &tfile, std::stringstream &fs)
+bool
+api_usage(repo_log_t &l, std::vector<std::string> &srcs)
 {
-    int ret = 0;
+    bool ret = false;
+    std::map<std::string, std::vector<std::regex>> exemptions;
+    exemptions[std::string("abort")].push_back(std::regex(".*/bomb[.]c$"));
+    
exemptions[std::string("dirname")].push_back(std::regex(".*/tests/dirname[.]c$"));
+    exemptions[std::string("remove")].push_back(std::regex(".*/file[.]c$"));
+    exemptions[std::string("strcasecmp")].push_back(std::regex(".*/str[.]c$"));
+    exemptions[std::string("strcmp")].push_back(std::regex(".*/str[.]c$"));
+    exemptions[std::string("strdup")].push_back(std::regex(".*/str[.]c$"));
+    exemptions[std::string("strlcat")].push_back(std::regex(".*/str[.]c$"));
+    exemptions[std::string("strlcpy")].push_back(std::regex(".*/str[.]c$"));
+    
exemptions[std::string("strncasecmp")].push_back(std::regex(".*/str[.]c$"));
+    exemptions[std::string("strncat")].push_back(std::regex(".*/str[.]c$"));
+    exemptions[std::string("strncmp")].push_back(std::regex(".*/str[.]c$"));
+    exemptions[std::string("strncpy")].push_back(std::regex(".*/rt/db4[.]h$"));
+    exemptions[std::string("strncpy")].push_back(std::regex(".*/str[.]c$"));
+    exemptions[std::string("strncpy")].push_back(std::regex(".*/vls[.]c$"));
+    
exemptions[std::string("strncpy")].push_back(std::regex(".*/wfobj/obj_util[.]cpp$"));
 
-    bool skip = false;
-    for (size_t j = 0; j < l.api_file_filters.size(); j++) {
-       if (std::regex_match(tfile, l.api_file_filters[j])) {
-           skip = true;
-           break;
-       }
+    const char *file_exemptions[] {
+       ".*/CONFIG_CONTROL_DESIGN.*",
+       ".*/bu/log[.]h$",
+       ".*/bu/path[.]h$",
+       ".*/bu/str[.]h$",
+       ".*/cursor[.]c$",
+       ".*/ttcp[.]c$",
+       ".*/misc/CMake/compat/.*",
+       NULL
+    };
+
+    const char *funcs[] {
+       "abort",
+       "dirname",
+       "fgets",
+       "getopt",
+       "qsort",
+       "remove",
+       "rmdir",
+       "strcasecmp",
+       "strcat",
+       "strcmp",
+       "strcpy",
+       "strdup",
+       "stricmp",
+       "strlcat",
+       "strlcpy",
+       "strncasecmp",
+       "strncat",
+       "strncmp",
+       "strncpy",
+       "unlink",
+       NULL
+    };
+
+    std::vector<std::regex> file_filters;
+    int cnt = 0;
+    const char *rf = file_exemptions[cnt];
+    while (rf) {
+       file_filters.push_back(std::regex(rf));
+       cnt++;
+       rf = file_exemptions[cnt];
     }
-    if (skip) {
-       return ret;
+
+    std::map<std::string, std::regex> func_filters;
+    cnt = 0;
+    rf = funcs[cnt];
+    while (rf) {
+       std::string rrf = std::string(".*[^a-zA-Z0-9_:]") + std::string(rf) + 
std::string("[(].*");
+       func_filters[std::string(rf)] = std::regex(rrf);
+       cnt++;
+       rf = funcs[cnt];
     }
 
-    std::map<std::string, std::set<int>> instances;
 
-    int lcnt = 0;
-    std::string sline;
-    while (std::getline(fs, sline)) {
-       lcnt++;
-       std::map<std::string, std::regex>::iterator ff_it;
-       for (ff_it = l.api_func_filters.begin(); ff_it != 
l.api_func_filters.end(); ff_it++) {
-           std::string p_lower = ff_it->first;
-           std::transform(p_lower.begin(), p_lower.end(), p_lower.begin(), 
[](unsigned char c){ return std::tolower(c); });
-           if (!std::strstr(sline.c_str(), ff_it->first.c_str()) && 
!std::strstr(sline.c_str(), p_lower.c_str())) {
-               // Only try the full regex if strstr says there is a chance
-               continue;
+    for (size_t i = 0; i < srcs.size(); i++) {
+       bool skip = false;
+       for (size_t j = 0; j < file_filters.size(); j++) {
+           if (std::regex_match(srcs[i], file_filters[j])) {
+               skip = true;
+               break;
            }
-           if (std::regex_match(sline, ff_it->second)) {
-               // If we have a it, make sure it's not an exemption
-               bool exempt = false;
-               if (l.api_exemptions.find(ff_it->first) != 
l.api_exemptions.end()) {
-                   std::vector<std::regex>::iterator e_it;
-                   for (e_it = l.api_exemptions[ff_it->first].begin(); e_it != 
l.api_exemptions[ff_it->first].end(); e_it++) {
-                       if (std::regex_match(tfile, *e_it)) {
-                           exempt = true;
-                           break;
+       }
+       if (skip) {
+           continue;
+       }
+
+       std::ifstream fs;
+       fs.open(srcs[i]);
+       if (!fs.is_open()) {
+           std::cerr << "Unable to open " << srcs[i] << " for reading, 
skipping\n";
+           continue;
+       }
+
+       std::map<std::string, std::set<int>> instances;
+
+       int lcnt = 0;
+       std::string sline;
+       while (std::getline(fs, sline)) {
+           lcnt++;
+           std::map<std::string, std::regex>::iterator ff_it;
+           for (ff_it = func_filters.begin(); ff_it != func_filters.end(); 
ff_it++) {
+               if (!std::strstr(sline.c_str(), ff_it->first.c_str())) {
+                   // Only try the full regex if strstr says there is a chance
+                   continue;
+               }
+               if (std::regex_match(sline, ff_it->second)) {
+                   // If we have a it, make sure it's not an exemption
+                   bool exempt = false;
+                   if (exemptions.find(ff_it->first) != exemptions.end()) {
+                       std::vector<std::regex>::iterator e_it;
+                       for (e_it = exemptions[ff_it->first].begin(); e_it != 
exemptions[ff_it->first].end(); e_it++) {
+                           if (std::regex_match(srcs[i], *e_it)) {
+                               exempt = true;
+                               break;
+                           }
                        }
                    }
+                   if (!exempt) {
+                       instances[ff_it->first].insert(lcnt);
+                       ret = true;
+                   }
                }
-               if (!exempt) {
-                   instances[ff_it->first].insert(lcnt);
-                   ret = 1;
-               }
            }
        }
-    }
 
-    std::map<std::string, std::set<int>>::iterator i_it;
+       std::map<std::string, std::set<int>>::iterator i_it;
 
-    for (i_it = instances.begin(); i_it != instances.end(); i_it++) {
-       std::set<int>::iterator num_it;
-       for (num_it = i_it->second.begin(); num_it != i_it->second.end(); 
num_it++) {
-           std::string lstr = tfile.substr(l.path_root.length()+1) + 
std::string(" matches ") + i_it->first + std::string(" on line ") + 
std::to_string(*num_it) + std::string("\n");
+       for (i_it = instances.begin(); i_it != instances.end(); i_it++) {
+           std::set<int>::iterator num_it;
+           for (num_it = i_it->second.begin(); num_it != i_it->second.end(); 
num_it++) {
+           std::string lstr = srcs[i].substr(l.path_root.length()+1) + 
std::string(" matches ") + i_it->first + std::string(" on line ") + 
std::to_string(*num_it) + std::string("\n");
            l.api_log.push_back(lstr);
+           }
        }
     }
 
@@ -516,41 +449,109 @@
 
 
 int
-platform_symbols(repo_state_t &l, std::vector<std::string> &log, std::string 
&tfile, std::stringstream &fs)
+platform_symbols(repo_log_t &l, std::vector<std::string> &log, 
std::vector<std::string> &srcs)
 {
-    std::map<std::string, std::vector<platform_entry>> instances;
-    bool skip = false;
-    for (size_t j = 0; j < l.platform_file_filters.size(); j++) {
-       if (std::regex_match(tfile, l.platform_file_filters[j])) {
-           skip = true;
-           break;
-       }
+
+    const char *platforms[] {
+       "AIX",
+       "APPLE",
+       "CYGWIN",
+       "DARWIN",
+       "FREEBSD",
+       "HAIKU",
+       "HPUX",
+       "LINUX",
+       "MINGW",
+       "MSDOS",
+       "QNX",
+       "SGI",
+       "SOLARIS",
+       "SUN",
+       "SUNOS",
+       "SVR4",
+       "SYSV",
+       "ULTRIX",
+       "UNIX",
+       "VMS",
+       "WIN16",
+       "WIN32",
+       "WIN64",
+       "WINE",
+       "WINNT",
+       NULL
+    };
+    std::map<std::pair<std::string, std::string>, std::regex> platform_checks;
+    int cnt = 0;
+    const char *rf = platforms[cnt];
+    while (rf) {
+       cnt++;
+       std::string p_upper(rf);
+       std::string p_lower = p_upper;
+       std::transform(p_lower.begin(), p_lower.end(), p_lower.begin(), 
[](unsigned char c){ return std::tolower(c); });
+       std::string pregex_str = 
std::string("^[[:space:]#]*(if|IF).*[[:space:](]_*(") + p_lower + 
std::string("|") + p_upper + std::string(")_*([[:space:]]|[)]|$).*$");
+       platform_checks[std::make_pair(p_lower, p_upper)] = 
std::regex(pregex_str);
+       rf = platforms[cnt];
     }
-    if (skip) {
-       return 0;
+
+    const char *file_exemptions[] {
+       ".*/pstdint[.]h$",
+       ".*/pinttypes[.]h$",
+       ".*/uce-dirent[.]h$",
+       NULL
+    };
+
+    std::vector<std::regex> file_filters;
+    cnt = 0;
+    rf = file_exemptions[cnt];
+    while (rf) {
+       file_filters.push_back(std::regex(rf));
+       cnt++;
+       rf = file_exemptions[cnt];
     }
 
-    int lcnt = 0;
-    std::string sline;
-    while (std::getline(fs, sline)) {
-       lcnt++;
 
-       std::map<std::string, std::regex>::iterator  p_it;
-       for (p_it = l.platform_checks.begin(); p_it != l.platform_checks.end(); 
p_it++) {
-           std::string p_lower = p_it->first;
-           std::transform(p_lower.begin(), p_lower.end(), p_lower.begin(), 
[](unsigned char c){ return std::tolower(c); });
-           if (!std::strstr(sline.c_str(), p_it->first.c_str()) && 
!std::strstr(sline.c_str(), p_lower.c_str())) {
-               // Only try the full regex if strstr says there is a chance
-               continue;
+    std::map<std::string, std::vector<platform_entry>> instances;
+    for (size_t i = 0; i < srcs.size(); i++) {
+       bool skip = false;
+       for (size_t j = 0; j < file_filters.size(); j++) {
+           if (std::regex_match(srcs[i], file_filters[j])) {
+               skip = true;
+               break;
            }
-           if (std::regex_match(sline, p_it->second)) {
-               //std::cout << "match on line: " << sline << "\n";
-               platform_entry pe;
-               pe.symbol = p_it->first;
-               pe.file = tfile.substr(l.path_root.length()+1);
-               pe.line_num = lcnt;
-               pe.line = sline;
-               instances[p_it->first].push_back(pe);
+       }
+       if (skip) {
+           continue;
+       }
+
+       std::ifstream fs;
+       fs.open(srcs[i]);
+       if (!fs.is_open()) {
+           std::cerr << "Unable to open " << srcs[i] << " for reading, 
skipping\n";
+           continue;
+       }
+
+       //std::cout << "Reading " << srcs[i] << "\n";
+
+       int lcnt = 0;
+       std::string sline;
+       while (std::getline(fs, sline)) {
+           lcnt++;
+
+           std::map<std::pair<std::string, std::string>, std::regex>::iterator 
 p_it;
+           for (p_it = platform_checks.begin(); p_it != platform_checks.end(); 
p_it++) {
+               if (!std::strstr(sline.c_str(), p_it->first.first.c_str()) && 
!std::strstr(sline.c_str(), p_it->first.second.c_str())) {
+                   // Only try the full regex if strstr says there is a chance
+                   continue;
+               }
+               if (std::regex_match(sline, p_it->second)) {
+                   //std::cout << "match on line: " << sline << "\n";
+                   platform_entry pe;
+                   pe.symbol = p_it->first.second;
+                   pe.file = srcs[i].substr(l.path_root.length()+1);
+                   pe.line_num = lcnt;
+                   pe.line = sline;
+                   instances[p_it->first.second].push_back(pe);
+               }
            }
        }
     }
@@ -569,79 +570,6 @@
     return match_cnt;
 }
 
-
-void
-process_inc_file(repo_state_t &r_t)
-{
-    std::ifstream fs;
-    fs.open(r_t.cfile);
-    if (!fs.is_open()) {
-       return;
-    }
-
-    std::stringstream fss;
-    fss << fs.rdbuf();
-    fs.close();
-
-    fss.clear();
-    fss.seekg(0, std::ios::beg);
-    r_t.ret += bio_redundant_check(r_t, r_t.cfile, fss);
-    fss.clear();
-    fss.seekg(0, std::ios::beg);
-    r_t.ret += bnetwork_redundant_check(r_t, r_t.cfile, fss);
-    fss.clear();
-    fss.seekg(0, std::ios::beg);
-    r_t.inc_cnt += platform_symbols(r_t, r_t.symbol_inc_log, r_t.cfile, fss);
-}
-
-void
-process_src_file(repo_state_t &r_t)
-{
-    std::ifstream fs;
-    fs.open(r_t.cfile);
-    if (!fs.is_open()) {
-       return;
-    }
-
-    std::stringstream fss;
-    fss << fs.rdbuf();
-    fs.close();
-
-    fss.clear();
-    fss.seekg(0, std::ios::beg);
-    r_t.ret += bio_redundant_check(r_t, r_t.cfile, fss);
-    fss.clear();
-    fss.seekg(0, std::ios::beg);
-    r_t.ret += bnetwork_redundant_check(r_t, r_t.cfile, fss);
-    fss.clear();
-    fss.seekg(0, std::ios::beg);
-    r_t.ret += common_include_first(r_t, r_t.cfile, fss);
-    fss.clear();
-    fss.seekg(0, std::ios::beg);
-    r_t.ret += api_usage(r_t, r_t.cfile, fss);
-    fss.clear();
-    fss.seekg(0, std::ios::beg);
-    r_t.src_cnt += platform_symbols(r_t, r_t.symbol_src_log, r_t.cfile, fss);
-}
-
-void
-process_bld_file(repo_state_t &r_t)
-{
-    std::ifstream fs;
-    fs.open(r_t.cfile);
-    if (!fs.is_open()) {
-       return;
-    }
-
-    std::stringstream fss;
-    fss << fs.rdbuf();
-    fs.close();
-
-    fss.clear();
-    fss.seekg(0, std::ios::beg);
-    r_t.bld_cnt += platform_symbols(r_t, r_t.symbol_bld_log, r_t.cfile, fss);
-}
-
 int
 main(int argc, const char *argv[])
 {
@@ -650,6 +578,9 @@
        return -1;
     }
 
+    repo_log_t repo_log;
+    repo_log.path_root = std::string(argv[2]);
+
     std::string sfile;
     std::ifstream src_file_stream;
     src_file_stream.open(argv[1]);
@@ -694,7 +625,7 @@
     std::regex hdrfile_regex(".*/include/.*");
     std::vector<std::string> src_files;
     std::vector<std::string> inc_files;
-    std::vector<std::string> bld_files;
+    std::vector<std::string> build_files;
 
     while (std::getline(src_file_stream, sfile)) {
        bool reject = false;
@@ -717,7 +648,7 @@
            continue;
        }
        if (std::regex_match(sfile, buildfile_regex)) {
-           bld_files.push_back(sfile);
+           build_files.push_back(sfile);
            continue;
        }
     }
@@ -724,150 +655,81 @@
 
     int ret = 0;
 
-
-    // Regex testing is CPU intensive - go parallel for main checks
-    size_t fcnt = 0;
-    unsigned int hwc = std::thread::hardware_concurrency();
-    if (!hwc) {
-       hwc = 10;
+    if (bio_redundant_check(repo_log, src_files)) {
+       ret = -1;
     }
-    std::vector<repo_state_t> repo_states;
-    for (unsigned int i = 0; i < hwc; i++) {
-       repo_state_t repo_state;
-       repo_state.path_root = std::string(argv[2]);
-       repo_states.push_back(repo_state);
-    }
 
-    fcnt = 0;
-    while (fcnt < inc_files.size()) {
-        int athreads = 0;
-        std::vector<std::thread> t;
-        for (unsigned int i = 0; i < hwc; i++) {
-            if (fcnt + i < inc_files.size()) {
-                repo_states[i].cfile = inc_files[fcnt+i];
-                t.push_back(std::thread(process_inc_file, 
std::ref(repo_states[i])));
-                athreads++;
-            }
-        }
-        for (int i = 0; i < athreads; i++) {
-            t[i].join();
-        }
-        fcnt += athreads;
+    if (bnetwork_redundant_check(repo_log, src_files)) {
+       ret = -1;
     }
 
-    fcnt = 0;
-    while (fcnt < src_files.size()) {
-        int athreads = 0;
-        std::vector<std::thread> t;
-        for (unsigned int i = 0; i < hwc; i++) {
-            if (fcnt + i < src_files.size()) {
-                repo_states[i].cfile = src_files[fcnt+i];
-                t.push_back(std::thread(process_src_file, 
std::ref(repo_states[i])));
-                athreads++;
-            }
-        }
-        for (int i = 0; i < athreads; i++) {
-            t[i].join();
-        }
-        fcnt += athreads;
+    if (common_include_first(repo_log, src_files)) {
+       ret = -1;
     }
 
-    fcnt = 0;
-    while (fcnt < bld_files.size()) {
-        int athreads = 0;
-        std::vector<std::thread> t;
-        for (unsigned int i = 0; i < hwc; i++) {
-            if (fcnt + i < bld_files.size()) {
-                repo_states[i].cfile = bld_files[fcnt+i];
-                t.push_back(std::thread(process_bld_file, 
std::ref(repo_states[i])));
-                athreads++;
-            }
-        }
-        for (int i = 0; i < athreads; i++) {
-            t[i].join();
-        }
-        fcnt += athreads;
+    if (api_usage(repo_log, src_files)) {
+       ret = -1;
     }
 
-    repo_state_t repo_state;
-
-    // Consolidate
-    for (unsigned int i = 0; i < hwc; i++) {
-       repo_state_t &rs = repo_states[i];
-       repo_state.ret += rs.ret;
-       repo_state.inc_cnt += rs.inc_cnt;
-       repo_state.src_cnt += rs.src_cnt;
-       repo_state.bld_cnt += rs.bld_cnt;
-    
-       repo_state.api_log.insert(repo_state.api_log.end(), rs.api_log.begin(), 
rs.api_log.end());
-       repo_state.bio_log.insert(repo_state.bio_log.end(), rs.bio_log.begin(), 
rs.bio_log.end());
-       repo_state.bnet_log.insert(repo_state.bnet_log.end(), 
rs.bnet_log.begin(), rs.bnet_log.end());
-       repo_state.common_log.insert(repo_state.common_log.end(), 
rs.common_log.begin(), rs.common_log.end());
-       repo_state.symbol_inc_log.insert(repo_state.symbol_inc_log.end(), 
rs.symbol_inc_log.begin(), rs.symbol_inc_log.end());
-       repo_state.symbol_src_log.insert(repo_state.symbol_src_log.end(), 
rs.symbol_src_log.begin(), rs.symbol_src_log.end());
-       repo_state.symbol_bld_log.insert(repo_state.symbol_bld_log.end(), 
rs.symbol_bld_log.begin(), rs.symbol_bld_log.end());
-    }
-
-    int psym_cnt = repo_state.inc_cnt + repo_state.src_cnt + 
repo_state.bld_cnt;
-    int expected_psym_cnt = EXPECTED_PLATFORM_SYMBOLS ;
+    int h_cnt = platform_symbols(repo_log, repo_log.symbol_inc_log, inc_files);
+    int s_cnt = platform_symbols(repo_log, repo_log.symbol_src_log, src_files);
+    int b_cnt = platform_symbols(repo_log, repo_log.symbol_bld_log, 
build_files);
+    int psym_cnt = h_cnt + s_cnt + b_cnt;
+    int expected_psym_cnt = EXPECTED_PLATFORM_SYMBOLS;
     if (psym_cnt > expected_psym_cnt) {
-       ret += 1;
+       std::cout << "FAILURE: expected " << expected_psym_cnt << " platform 
symbols, found " << psym_cnt << "\n";
+       ret = -1;
     }
 
-    if (ret) {
-       std::sort(repo_state.api_log.begin(), repo_state.api_log.end());
-       std::sort(repo_state.bio_log.begin(), repo_state.bio_log.end());
-       std::sort(repo_state.bnet_log.begin(), repo_state.bnet_log.end());
-       std::sort(repo_state.common_log.begin(), repo_state.common_log.end());
-       std::sort(repo_state.symbol_inc_log.begin(), 
repo_state.symbol_inc_log.end());
-       std::sort(repo_state.symbol_src_log.begin(), 
repo_state.symbol_src_log.end());
-       std::sort(repo_state.symbol_bld_log.begin(), 
repo_state.symbol_bld_log.end());
+    if (ret == -1) {
+       std::sort(repo_log.api_log.begin(), repo_log.api_log.end());
+       std::sort(repo_log.bio_log.begin(), repo_log.bio_log.end());
+       std::sort(repo_log.bnet_log.begin(), repo_log.bnet_log.end());
+       std::sort(repo_log.common_log.begin(), repo_log.common_log.end());
+       std::sort(repo_log.symbol_inc_log.begin(), 
repo_log.symbol_inc_log.end());
+       std::sort(repo_log.symbol_src_log.begin(), 
repo_log.symbol_src_log.end());
+       std::sort(repo_log.symbol_bld_log.begin(), 
repo_log.symbol_bld_log.end());
 
-       if (repo_state.api_log.size()) {
-           std::cout << "\nFound " << repo_state.api_log.size() << " instances 
of unguarded API usage:\n";
-           for (size_t i = 0; i < repo_state.api_log.size(); i++) {
-               std::cout << repo_state.api_log[i];
+       if (repo_log.api_log.size()) {
+           std::cout << "\nFound " << repo_log.api_log.size() << " instances 
of unguarded API usage:\n";
+           for (size_t i = 0; i < repo_log.api_log.size(); i++) {
+               std::cout << repo_log.api_log[i];
            }
        }
-       if (repo_state.bio_log.size()) {
-           std::cout << "\nFound " << repo_state.bio_log.size() << " instances 
of redundant header inclusions in files using bio.h:\n";
-           for (size_t i = 0; i < repo_state.bio_log.size(); i++) {
-               std::cout << repo_state.bio_log[i];
+       if (repo_log.bio_log.size()) {
+           std::cout << "\nFound " << repo_log.bio_log.size() << " instances 
of redundant header inclusions in files using bio.h:\n";
+           for (size_t i = 0; i < repo_log.bio_log.size(); i++) {
+               std::cout << repo_log.bio_log[i];
            }
        }
-       if (repo_state.bnet_log.size()) {
-           std::cout << "\nFound " << repo_state.bnet_log.size() << " 
instances of redundant header inclusions in files using bnetwork.h:\n";
-           for (size_t i = 0; i < repo_state.bnet_log.size(); i++) {
-               std::cout << repo_state.bnet_log[i];
+       if (repo_log.bnet_log.size()) {
+           std::cout << "\nFound " << repo_log.bnet_log.size() << " instances 
of redundant header inclusions in files using bnetwork.h:\n";
+           for (size_t i = 0; i < repo_log.bnet_log.size(); i++) {
+               std::cout << repo_log.bnet_log[i];
            }
        }
-       if (repo_state.common_log.size()) {
-           std::cout << "\nFound " << repo_state.common_log.size() << " 
instances of files using common.h with out-of-order inclusions:\n";
-           for (size_t i = 0; i < repo_state.common_log.size(); i++) {
-               std::cout << repo_state.common_log[i];
+       if (repo_log.common_log.size()) {
+           std::cout << "\nFound " << repo_log.common_log.size() << " 
instances of files using common.h with out-of-order inclusions:\n";
+           for (size_t i = 0; i < repo_log.common_log.size(); i++) {
+               std::cout << repo_log.common_log[i];
            }
        }
-
-       if (psym_cnt > expected_psym_cnt) {
-           std::cout << "\n\nFAILURE: expected " << expected_psym_cnt << " 
platform symbols, found " << psym_cnt << ":\n";
-       }
-
-       if (repo_state.symbol_inc_log.size()) {
-           std::cout << "\nFound " << repo_state.symbol_inc_log.size() << " 
instances of platform symbol usage in header files:\n";
-           for (size_t i = 0; i < repo_state.symbol_inc_log.size(); i++) {
-               std::cout << repo_state.symbol_inc_log[i];
+       if (repo_log.symbol_inc_log.size()) {
+           std::cout << "\nFound " << repo_log.symbol_inc_log.size() << " 
instances of platform symbol usage in header files:\n";
+           for (size_t i = 0; i < repo_log.symbol_inc_log.size(); i++) {
+               std::cout << repo_log.symbol_inc_log[i];
            }
        }
-       if (repo_state.symbol_src_log.size()) {
-           std::cout << "\nFound " << repo_state.symbol_src_log.size() << " 
instances of platform symbol usage in source files:\n";
-           for (size_t i = 0; i < repo_state.symbol_src_log.size(); i++) {
-               std::cout << repo_state.symbol_src_log[i];
+       if (repo_log.symbol_src_log.size()) {
+           std::cout << "\nFound " << repo_log.symbol_src_log.size() << " 
instances of platform symbol usage in source files:\n";
+           for (size_t i = 0; i < repo_log.symbol_src_log.size(); i++) {
+               std::cout << repo_log.symbol_src_log[i];
            }
        }
-       if (repo_state.symbol_bld_log.size()) {
-           std::cout << "\nFound " << repo_state.symbol_bld_log.size() << " 
instances of platform symbol usage in build files:\n";
-           for (size_t i = 0; i < repo_state.symbol_bld_log.size(); i++) {
-               std::cout << repo_state.symbol_bld_log[i];
+       if (repo_log.symbol_bld_log.size()) {
+           std::cout << "\nFound " << repo_log.symbol_bld_log.size() << " 
instances of platform symbol usage in build files:\n";
+           for (size_t i = 0; i < repo_log.symbol_bld_log.size(); i++) {
+               std::cout << repo_log.symbol_bld_log[i];
            }
        }
     }

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to