Update to latest master of remake.
authorKim Nguyễn <kn@lri.fr>
Sun, 8 Dec 2013 10:31:26 +0000 (11:31 +0100)
committerKim Nguyễn <kn@lri.fr>
Sun, 8 Dec 2013 10:31:26 +0000 (11:31 +0100)
Add a workaround to silence the linker warning when building remake in the configure script.

configure.in
remake.cpp

index 478a416..5bcb4c0 100644 (file)
@@ -228,16 +228,24 @@ AC_PROG_CXX()
 AC_SUBST([REMAKE], [./remake$EXE])
 if test ! -x  "$REMAKE" -o "$REMAKE" -ot remake.cpp; then
 AC_MSG_NOTICE([creating $REMAKE])
 AC_SUBST([REMAKE], [./remake$EXE])
 if test ! -x  "$REMAKE" -o "$REMAKE" -ot remake.cpp; then
 AC_MSG_NOTICE([creating $REMAKE])
+REMAKE_LOG=build_remake.log
 case $(uname -s) in
 MINGW*)
 case $(uname -s) in
 MINGW*)
-        $CXX -Wall -O2 -o remake.exe remake.cpp -lws2_32
-        if test $? != 0; then AC_MSG_FAILURE([failed]); fi
+        $CXX -Wall -O2 -o remake.exe remake.cpp -lws2_32 > "$REMAKE_LOG" 2>&1
+        if test $? != 0; then
+          cat "$REMAKE_LOG"; rm -f "$REMAKE_LOG";
+          AC_MSG_FAILURE([failed]);
+       fi
         ;;
 *)
         ;;
 *)
-        $CXX -Wall -O2 -o remake remake.cpp
-        if test $? != 0; then AC_MSG_FAILURE([failed]); fi
+        $CXX -Wall -O2 -o remake remake.cpp > "$REMAKE_LOG" 2>&1
+        if test $? != 0; then
+          cat "$REMAKE_LOG"; rm -f "$REMAKE_LOG";
+          AC_MSG_FAILURE([failed]);
+       fi
         ;;
 esac
         ;;
 esac
+rm -f "$REMAKE_LOG";
 else
 AC_MSG_NOTICE([$REMAKE exists, not rebuilding])
 fi
 else
 AC_MSG_NOTICE([$REMAKE exists, not rebuilding])
 fi
index 30440a8..de68c4d 100644 (file)
@@ -343,7 +343,7 @@ https://github.com/apenwarr/redo for an implementation and some comprehensive do
 \section sec-licensing Licensing
 
 @author Guillaume Melquiond
 \section sec-licensing Licensing
 
 @author Guillaume Melquiond
-@version 0.9
+@version 0.10
 @date 2012-2013
 @copyright
 This program is free software: you can redistribute it and/or modify
 @date 2012-2013
 @copyright
 This program is free software: you can redistribute it and/or modify
@@ -373,8 +373,8 @@ When building a target, the following sequence of events happens:
 
 - #start calls #find_rule (and #find_generic_rule) to get the rule.
 - It then creates a pseudo-client if the rule has static dependencies, or
 
 - #start calls #find_rule (and #find_generic_rule) to get the rule.
 - It then creates a pseudo-client if the rule has static dependencies, or
-  calls #run_script otherwise. In both cases, a new job is created and its
-  targets are put into #job_targets.
+  calls #run_script otherwise. In both cases, a new job is created; the
+  rule and the variables are stored into #jobs.
 - #run_script creates a shell process and stores it in #job_pids. It
   increases #running_jobs.
 - The child process possibly calls <b>remake</b> with a list of targets.
 - #run_script creates a shell process and stores it in #job_pids. It
   increases #running_jobs.
 - The child process possibly calls <b>remake</b> with a list of targets.
@@ -392,7 +392,7 @@ When building a target, the following sequence of events happens:
 - When a child process ends, #server_loop calls #finalize_job, which
   removes the process from #job_pids, decreases #running_jobs, and calls
   #complete_job.
 - When a child process ends, #server_loop calls #finalize_job, which
   removes the process from #job_pids, decreases #running_jobs, and calls
   #complete_job.
-- #complete_job removes the job from #job_targets and calls #update_status
+- #complete_job removes the job from #jobs and calls #update_status
   to change the status of the targets. It also removes the target files in
   case of failure.
 */
   to change the status of the targets. It also removes the target files in
   case of failure.
 */
@@ -668,7 +668,7 @@ static int waiting_jobs = 0;
 
 /**
  * Global counter used to produce increasing job numbers.
 
 /**
  * Global counter used to produce increasing job numbers.
- * @see job_targets
+ * @see jobs
  */
 static int job_counter = 0;
 
  */
 static int job_counter = 0;
 
@@ -720,15 +720,14 @@ static std::string working_dir;
 static std::string prefix_dir;
 
 /**
 static std::string prefix_dir;
 
 /**
- * Whether target-specific variables are propagated to prerequisites.
+ * Whether the prefix directory is different from #working_dir.
  */
  */
-static bool propagate_vars = false;
-
+static bool changed_prefix_dir;
 
 /**
 
 /**
- * Whether to print that we changed working directory (to be nice with emacs)
+ * Whether target-specific variables are propagated to prerequisites.
  */
  */
-static bool print_change_working_dir = false;
+static bool propagate_vars = false;
 
 #ifndef WINDOWS
 static volatile sig_atomic_t got_SIGCHLD = 0;
 
 #ifndef WINDOWS
 static volatile sig_atomic_t got_SIGCHLD = 0;
@@ -871,28 +870,22 @@ static void init_working_dir()
  */
 static void init_prefix_dir()
 {
  */
 static void init_prefix_dir()
 {
-       std::string old_prefix_dir = prefix_dir;
        for (;;)
        {
                struct stat s;
                if (stat((prefix_dir + "/Remakefile").c_str(), &s) == 0)
                {
        for (;;)
        {
                struct stat s;
                if (stat((prefix_dir + "/Remakefile").c_str(), &s) == 0)
                {
-                       if (0 == chdir(prefix_dir.c_str()))
+                       if (!changed_prefix_dir) return;
+                       if (chdir(prefix_dir.c_str()))
                        {
                        {
-                               if (old_prefix_dir != prefix_dir)
-                               {
-                                       std::cout << "remake: Entering directory `"
-                                                 << prefix_dir << "'"
-                                                 << std::endl;
-                                       print_change_working_dir = true;
-                               }
-                               return;
+                               perror("Failed to change working directory");
+                               exit(EXIT_FAILURE);
                        }
                        }
-                       else
+                       if (show_targets)
                        {
                        {
-                               std::cerr << "Cannot change working directory to '" << prefix_dir << "'";
-                               exit(EXIT_FAILURE);
+                               std::cout << "remake: Entering directory `" << prefix_dir << '\'' << std::endl;
                        }
                        }
+                       return;
                }
                size_t pos = prefix_dir.find_last_of('/');
                if (pos == std::string::npos)
                }
                size_t pos = prefix_dir.find_last_of('/');
                if (pos == std::string::npos)
@@ -901,6 +894,7 @@ static void init_prefix_dir()
                        exit(EXIT_FAILURE);
                }
                prefix_dir.erase(pos);
                        exit(EXIT_FAILURE);
                }
                prefix_dir.erase(pos);
+               changed_prefix_dir = true;
        }
 }
 
        }
 }
 
@@ -1097,44 +1091,44 @@ static int expect_token(std::istream &in, int mask)
 /**
  * Read a (possibly quoted) word.
  */
 /**
  * Read a (possibly quoted) word.
  */
-static std::string read_word(std::istream &in)
+static std::string read_word(std::istream &in, bool detect_equal = true)
 {
 {
-       int c = in.get();
+       int c = in.peek();
        std::string res;
        if (!in.good()) return res;
        std::string res;
        if (!in.good()) return res;
-       char const *separators = " \t\r\n:$(),=+\"";
+       char const *separators = " \t\r\n$(),:";
        bool quoted = c == '"';
        bool quoted = c == '"';
-       if (!quoted)
-       {
-               if (strchr(separators, c))
-               {
-                       in.putback(c);
-                       return res;
-               }
-               res += c;
-       }
+       if (quoted) in.ignore(1);
+       bool plus = false;
        while (true)
        {
        while (true)
        {
-               c = in.get();
+               c = in.peek();
                if (!in.good()) return res;
                if (quoted)
                {
                if (!in.good()) return res;
                if (quoted)
                {
+                       in.ignore(1);
                        if (c == '\\')
                                res += in.get();
                        else if (c == '"')
                        if (c == '\\')
                                res += in.get();
                        else if (c == '"')
-                               return res;
+                               quoted = false;
                        else
                                res += c;
                        else
                                res += c;
+                       continue;
                }
                }
-               else
+               if (detect_equal && c == '=')
                {
                {
-                       if (strchr(separators, c))
-                       {
-                               in.putback(c);
-                               return res;
-                       }
-                       res += c;
+                       if (plus) in.putback('+');
+                       return res;
+               }
+               if (plus)
+               {
+                       res += '+';
+                       plus = false;
                }
                }
+               if (strchr(separators, c)) return res;
+               in.ignore(1);
+               if (detect_equal && c == '+') plus = true;
+               else res += c;
        }
 }
 
        }
 }
 
@@ -1239,11 +1233,11 @@ input_status input_generator::next(std::string &res)
        switch (expect_token(in, Word | Dollarpar))
        {
        case Word:
        switch (expect_token(in, Word | Dollarpar))
        {
        case Word:
-               res = read_word(in);
+               res = read_word(in, false);
                return Success;
        case Dollarpar:
        {
                return Success;
        case Dollarpar:
        {
-               std::string name = read_word(in);
+               std::string name = read_word(in, false);
                if (name.empty()) return SyntaxError;
                if (expect_token(in, Rightpar))
                        nested = new variable_generator(name, local_variables);
                if (name.empty()) return SyntaxError;
                if (expect_token(in, Rightpar))
                        nested = new variable_generator(name, local_variables);
@@ -2042,21 +2036,23 @@ static bool still_need_rebuild(std::string const &target)
  */
 static void complete_job(int job_id, bool success)
 {
  */
 static void complete_job(int job_id, bool success)
 {
-       DEBUG_open << "Completing job " << job_id << "... ";
+       DEBUG << "Completing job " << job_id << '\n';
        job_map::iterator i = jobs.find(job_id);
        assert(i != jobs.end());
        string_list const &targets = i->second.rule.targets;
        if (success)
        {
        job_map::iterator i = jobs.find(job_id);
        assert(i != jobs.end());
        string_list const &targets = i->second.rule.targets;
        if (success)
        {
+               if (show_targets) std::cout << "Finished";
                for (string_list::const_iterator j = targets.begin(),
                     j_end = targets.end(); j != j_end; ++j)
                {
                        update_status(*j);
                for (string_list::const_iterator j = targets.begin(),
                     j_end = targets.end(); j != j_end; ++j)
                {
                        update_status(*j);
+                       if (show_targets) std::cout << ' ' << *j;
                }
                }
+               if (show_targets) std::cout << std::endl;
        }
        else
        {
        }
        else
        {
-               DEBUG_close << "failed\n";
                std::cerr << "Failed to build";
                for (string_list::const_iterator j = targets.begin(),
                     j_end = targets.end(); j != j_end; ++j)
                std::cerr << "Failed to build";
                for (string_list::const_iterator j = targets.begin(),
                     j_end = targets.end(); j != j_end; ++j)
@@ -2158,25 +2154,17 @@ static std::string prepare_script(job_t const &job)
  */
 static status_e run_script(int job_id, job_t const &job)
 {
  */
 static status_e run_script(int job_id, job_t const &job)
 {
-       if (show_targets)
-       {
-               std::cout << "Building";
-               for (string_list::const_iterator i = job.rule.targets.begin(),
-                    i_end = job.rule.targets.end(); i != i_end; ++i)
-               {
-                       std::cout << ' ' << *i;
-               }
-               std::cout << std::endl;
-       }
-
        ref_ptr<dependency_t> dep;
        dep->targets = job.rule.targets;
        dep->deps.insert(job.rule.deps.begin(), job.rule.deps.end());
        ref_ptr<dependency_t> dep;
        dep->targets = job.rule.targets;
        dep->deps.insert(job.rule.deps.begin(), job.rule.deps.end());
+       if (show_targets) std::cout << "Building";
        for (string_list::const_iterator i = job.rule.targets.begin(),
             i_end = job.rule.targets.end(); i != i_end; ++i)
        {
                dependencies[*i] = dep;
        for (string_list::const_iterator i = job.rule.targets.begin(),
             i_end = job.rule.targets.end(); i != i_end; ++i)
        {
                dependencies[*i] = dep;
+               if (show_targets) std::cout << ' ' << *i;
        }
        }
+       if (show_targets) std::cout << std::endl;
 
        std::string script = prepare_script(job);
 
 
        std::string script = prepare_script(job);
 
@@ -2560,28 +2548,7 @@ static void create_server()
        if (sigaction(SIGINT, &sa, NULL) == -1) goto error;
 
        // Prepare a named unix socket in temporary directory.
        if (sigaction(SIGINT, &sa, NULL) == -1) goto error;
 
        // Prepare a named unix socket in temporary directory.
-       struct stat tmpstat;
-       char * tmpdir;
-       if ((0 == stat(tmpdir = getenv("TMPDIR"), &tmpstat)
-            && (S_ISDIR(tmpstat.st_mode)))
-           || ((0 == stat(tmpdir = (char*)P_tmpdir, &tmpstat))
-               && (S_ISDIR(tmpstat.st_mode)))
-           || ((0 == stat(tmpdir = (char*)"/tmp", &tmpstat))
-               && (S_ISDIR(tmpstat.st_mode))));
-       else goto error;
-       std::stringstream tmpname;
-       long int rnd = now ^ getpid();
-       do
-       {
-               srandom(rnd);
-               rnd = random();
-               tmpname << tmpdir << "/rmk-";
-               tmpname.fill('0');
-               tmpname.width(8);
-               tmpname << rnd;
-       }
-       while (access (tmpname.str().c_str(), F_OK) == 0);
-       socket_name = strdup(tmpname.str().c_str());
+       socket_name = tempnam(NULL, "rmk-");
        if (!socket_name) goto error2;
        struct sockaddr_un socket_addr;
        size_t len = strlen(socket_name);
        if (!socket_name) goto error2;
        struct sockaddr_un socket_addr;
        size_t len = strlen(socket_name);
@@ -2834,9 +2801,10 @@ static void server_mode(std::string const &remakefile, string_list const &target
        free(socket_name);
 #endif
        save_dependencies();
        free(socket_name);
 #endif
        save_dependencies();
-       if (print_change_working_dir)
-               std::cout << "remake: Leaving directory `" << prefix_dir 
-                         << "'" <<std::endl;
+       if (show_targets && changed_prefix_dir)
+       {
+               std::cout << "remake: Leaving directory `" << prefix_dir << '\'' << std::endl;
+       }
        exit(build_failure ? EXIT_FAILURE : EXIT_SUCCESS);
 }
 
        exit(build_failure ? EXIT_FAILURE : EXIT_SUCCESS);
 }
 
@@ -2972,8 +2940,6 @@ static void usage(int exit_status)
  */
 int main(int argc, char *argv[])
 {
  */
 int main(int argc, char *argv[])
 {
-       init_working_dir();
-
        std::string remakefile;
        string_list targets;
        bool literal_targets = false;
        std::string remakefile;
        string_list targets;
        bool literal_targets = false;
@@ -3018,11 +2984,14 @@ int main(int argc, char *argv[])
                                continue;
                        }
                        new_target:
                                continue;
                        }
                        new_target:
-                       targets.push_back(normalize(arg, working_dir, working_dir));
+                       targets.push_back(arg);
                        DEBUG << "New target: " << arg << '\n';
                }
        }
 
                        DEBUG << "New target: " << arg << '\n';
                }
        }
 
+       init_working_dir();
+       normalize_list(targets, working_dir, working_dir);
+
        if (indirect_targets)
        {
                load_dependencies(std::cin);
        if (indirect_targets)
        {
                load_dependencies(std::cin);