Remake
Classes | Macros | Typedefs | Enumerations | Functions | Variables
remake.cpp File Reference
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>

Go to the source code of this file.

Classes

struct  ref_ptr< T >
 
struct  ref_ptr< T >::content
 
struct  dependency_t
 
struct  status_t
 
struct  assign_t
 
struct  rule_t
 
struct  job_t
 
struct  client_t
 
struct  log
 
struct  log_auto_close
 
struct  escape_string
 
struct  generator
 
struct  variable_generator
 
struct  input_generator
 
struct  addprefix_generator
 
struct  addsuffix_generator
 

Macros

#define DEBUG   if (debug.active) debug()
 
#define DEBUG_open   log_auto_close auto_close; if (debug.active) debug(true)
 
#define DEBUG_close   if ((auto_close.still_open = false), debug.active) debug(false)
 

Typedefs

typedef int socket_t
 
typedef std::list< std::string > string_list
 
typedef std::set< std::string > string_set
 
typedef std::map< std::string, ref_ptr< dependency_t > > dependency_map
 
typedef std::map< std::string, string_listvariable_map
 
typedef std::map< std::string, status_tstatus_map
 
typedef std::map< std::string, assign_tassign_map
 
typedef std::list< rule_trule_list
 
typedef std::map< std::string, ref_ptr< rule_t > > rule_map
 
typedef std::map< int, job_tjob_map
 
typedef std::map< pid_t, int > pid_job_map
 
typedef std::list< client_tclient_list
 

Enumerations

enum  { INVALID_SOCKET = -1 }
 
enum  status_e {
  Uptodate, Todo, Recheck, Running,
  RunningRecheck, Remade, Failed
}
 
enum  {
  Unexpected = 0, Word = 1 << 1, Colon = 1 << 2, Equal = 1 << 3,
  Dollarpar = 1 << 4, Rightpar = 1 << 5, Comma = 1 << 6, Plusequal = 1 << 7,
  Pipe = 1 << 8
}
 
enum  input_status { Success, SyntaxError, Eof }
 

Functions

static void sigchld_handler (int)
 
static void sigint_handler (int)
 
static std::ostream & operator<< (std::ostream &out, escape_string const &se)
 
static void init_working_dir ()
 
static void init_prefix_dir ()
 
static std::string normalize_abs (std::string const &s, std::string const &p)
 
static std::string normalize (std::string const &s, std::string const &w, std::string const &p)
 
static void normalize_list (string_list &l, std::string const &w, std::string const &p)
 
static void skip_spaces (std::istream &in)
 
static void skip_empty (std::istream &in)
 
static bool skip_eol (std::istream &in, bool multi=false)
 
static int expect_token (std::istream &in, int mask)
 
static std::string read_word (std::istream &in, bool detect_equal=true)
 
static generatorget_function (input_generator const &, std::string const &)
 
static bool read_words (input_generator &in, string_list &res)
 
static bool read_words (std::istream &in, string_list &res)
 
static void load_dependencies (std::istream &in)
 
static void load_dependencies ()
 
static void save_dependencies ()
 
static void merge_rule (rule_t &dest, rule_t const &src)
 
static void register_transparent_rule (rule_t const &rule, string_list const &targets)
 
static void register_scripted_rule (rule_t const &rule)
 
static void load_rule (std::istream &in, std::string const &first)
 
static void load_rules (std::string const &remakefile)
 
static void substitute_pattern (std::string const &pat, string_list const &src, string_list &dst)
 
static void find_generic_rule (job_t &job, std::string const &target)
 
static void find_rule (job_t &job, std::string const &target)
 
static status_t const & get_status (std::string const &target)
 
static void update_status (std::string const &target)
 
static bool still_need_rebuild (std::string const &target)
 
static void complete_job (int job_id, bool success, bool started=true)
 
static std::string prepare_script (job_t const &job)
 
static status_e run_script (int job_id, job_t const &job)
 
static status_e start (std::string const &target, client_list::iterator &current)
 
static void complete_request (client_t &client, bool success)
 
static bool has_free_slots ()
 
static bool handle_clients ()
 
static void create_server ()
 
static void accept_client ()
 
static void finalize_job (pid_t pid, bool res)
 
static void server_loop ()
 
static void server_mode (std::string const &remakefile, string_list const &targets)
 
static void client_mode (char *socket_name, string_list const &targets)
 
static void usage (int exit_status)
 
int main (int argc, char *argv[])
 

Variables

char ** environ
 
static variable_map variables
 
static dependency_map dependencies
 
static status_map status
 
static rule_list generic_rules
 
static rule_map specific_rules
 
static job_map jobs
 
static pid_job_map job_pids
 
static client_list clients
 
static int max_active_jobs = 1
 
static bool keep_going = false
 
static int running_jobs = 0
 
static int waiting_jobs = 0
 
static int job_counter = 0
 
static socket_t socket_fd
 
static bool build_failure
 
static char * socket_name
 
static std::string first_target
 
static bool show_targets = true
 
static bool echo_scripts = false
 
static time_t now = time(NULL)
 
static std::string working_dir
 
static std::string prefix_dir
 
static bool changed_prefix_dir
 
static bool propagate_vars = false
 
static bool obsolete_targets = false
 
static volatile sig_atomic_t got_SIGCHLD = 0
 
static log debug
 

Macro Definition Documentation

◆ DEBUG

#define DEBUG   if (debug.active) debug()

◆ DEBUG_close

#define DEBUG_close   if ((auto_close.still_open = false), debug.active) debug(false)

◆ DEBUG_open

#define DEBUG_open   log_auto_close auto_close; if (debug.active) debug(true)

Typedef Documentation

◆ assign_map

typedef std::map<std::string, assign_t> assign_map

Definition at line 540 of file remake.cpp.

◆ client_list

typedef std::list<client_t> client_list

Definition at line 598 of file remake.cpp.

◆ dependency_map

typedef std::map<std::string, ref_ptr<dependency_t> > dependency_map

Definition at line 502 of file remake.cpp.

◆ job_map

typedef std::map<int, job_t> job_map

Definition at line 569 of file remake.cpp.

◆ pid_job_map

typedef std::map<pid_t, int> pid_job_map

Definition at line 571 of file remake.cpp.

◆ rule_list

typedef std::list<rule_t> rule_list

Definition at line 554 of file remake.cpp.

◆ rule_map

typedef std::map<std::string, ref_ptr<rule_t> > rule_map

Definition at line 556 of file remake.cpp.

◆ socket_t

typedef int socket_t

Definition at line 447 of file remake.cpp.

◆ status_map

typedef std::map<std::string, status_t> status_map

Definition at line 529 of file remake.cpp.

◆ string_list

typedef std::list<std::string> string_list

Definition at line 456 of file remake.cpp.

◆ string_set

typedef std::set<std::string> string_set

Definition at line 458 of file remake.cpp.

◆ variable_map

typedef std::map<std::string, string_list> variable_map

Definition at line 504 of file remake.cpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
INVALID_SOCKET 

Definition at line 448 of file remake.cpp.

448 { INVALID_SOCKET = -1 };

◆ status_e

enum status_e

Build status of a target.

Enumerator
Uptodate 

Target is up-to-date.

Todo 

Target is missing or obsolete.

Recheck 

Target has an obsolete dependency.

Running 

Target is being rebuilt.

RunningRecheck 

Static prerequisites are being rebuilt.

Remade 

Target was successfully rebuilt.

Failed 

Build failed for target.

Definition at line 509 of file remake.cpp.

510 {
511  Uptodate, ///< Target is up-to-date.
512  Todo, ///< Target is missing or obsolete.
513  Recheck, ///< Target has an obsolete dependency.
514  Running, ///< Target is being rebuilt.
515  RunningRecheck, ///< Static prerequisites are being rebuilt.
516  Remade, ///< Target was successfully rebuilt.
517  Failed ///< Build failed for target.
518 };
Target is being rebuilt.
Definition: remake.cpp:514
Target is up-to-date.
Definition: remake.cpp:511
Target is missing or obsolete.
Definition: remake.cpp:512
Build failed for target.
Definition: remake.cpp:517
Target has an obsolete dependency.
Definition: remake.cpp:513
Target was successfully rebuilt.
Definition: remake.cpp:516
Static prerequisites are being rebuilt.
Definition: remake.cpp:515

Function Documentation

◆ operator<<()

static std::ostream& operator<< ( std::ostream &  out,
escape_string const &  se 
)
static

Write the string in se to out if it does not contain any special characters, a quoted and escaped string otherwise.

Definition at line 819 of file remake.cpp.

820 {
821  std::string const &s = se.input;
822  char const *quoted_char = ",: '";
823  char const *escaped_char = "\"\\$!";
824  bool need_quotes = false;
825  char *buf = NULL;
826  size_t len = s.length(), last = 0, j = 0;
827  for (size_t i = 0; i < len; ++i)
828  {
829  if (strchr(escaped_char, s[i]))
830  {
831  need_quotes = true;
832  if (!buf) buf = new char[len * 2];
833  memcpy(&buf[j], &s[last], i - last);
834  j += i - last;
835  buf[j++] = '\\';
836  buf[j++] = s[i];
837  last = i + 1;
838  }
839  if (!need_quotes && strchr(quoted_char, s[i]))
840  need_quotes = true;
841  }
842  if (!need_quotes) return out << s;
843  out << '"';
844  if (!buf) return out << s << '"';
845  out.write(buf, j);
846  out.write(&s[last], len - last);
847  delete[] buf;
848  return out << '"';
849 }

◆ sigchld_handler()

static void sigchld_handler ( int  )
static

Definition at line 746 of file remake.cpp.

Referenced by create_server().

747 {
748  got_SIGCHLD = 1;
749 }
static volatile sig_atomic_t got_SIGCHLD
Definition: remake.cpp:744

◆ sigint_handler()

static void sigint_handler ( int  )
static

Definition at line 751 of file remake.cpp.

Referenced by create_server().

752 {
753  // Child processes will receive the signal too, so just prevent
754  // new jobs from starting and wait for the running jobs to fail.
755  keep_going = false;
756 }
static bool keep_going
Definition: remake.cpp:652

Variable Documentation

◆ build_failure

bool build_failure
static

Whether the request of an original client failed.

Definition at line 689 of file remake.cpp.

Referenced by complete_request(), and server_mode().

◆ changed_prefix_dir

bool changed_prefix_dir
static

Whether the prefix directory is different from working_dir.

Definition at line 731 of file remake.cpp.

Referenced by init_prefix_dir(), and server_mode().

◆ clients

client_list clients
static

List of clients waiting for a request to complete. New clients are put to front, so that the build process is depth-first.

Definition at line 640 of file remake.cpp.

Referenced by accept_client(), handle_clients(), server_loop(), server_mode(), and start().

◆ debug

log debug
static

Definition at line 786 of file remake.cpp.

Referenced by log_auto_close::~log_auto_close().

◆ dependencies

dependency_map dependencies
static

Map from targets to their known dependencies.

Definition at line 609 of file remake.cpp.

Referenced by accept_client(), get_status(), load_dependencies(), main(), register_scripted_rule(), register_transparent_rule(), run_script(), save_dependencies(), and still_need_rebuild().

◆ echo_scripts

bool echo_scripts = false
static

Whether script commands are echoed.

Definition at line 711 of file remake.cpp.

Referenced by main(), and run_script().

◆ environ

char** environ

Referenced by run_script().

◆ first_target

std::string first_target
static

Name of the first target of the first specific rule, used for default run.

Definition at line 701 of file remake.cpp.

Referenced by load_rule(), and server_mode().

◆ generic_rules

rule_list generic_rules
static

Set of generic rules loaded from Remakefile.

Definition at line 619 of file remake.cpp.

Referenced by find_generic_rule(), load_rule(), and server_mode().

◆ got_SIGCHLD

volatile sig_atomic_t got_SIGCHLD = 0
static

Definition at line 744 of file remake.cpp.

Referenced by server_loop(), and sigchld_handler().

◆ job_counter

int job_counter = 0
static

Global counter used to produce increasing job numbers.

See also
jobs

Definition at line 679 of file remake.cpp.

Referenced by start().

◆ job_pids

pid_job_map job_pids
static

Map from jobs to shell pids.

Definition at line 634 of file remake.cpp.

Referenced by finalize_job(), run_script(), and server_loop().

◆ jobs

job_map jobs
static

Map of jobs being built.

Definition at line 629 of file remake.cpp.

Referenced by accept_client(), complete_job(), complete_request(), and start().

◆ keep_going

bool keep_going = false
static

Whether to keep building targets in case of failure. Can be modified by the -k option.

Definition at line 652 of file remake.cpp.

Referenced by handle_clients(), main(), and sigint_handler().

◆ max_active_jobs

int max_active_jobs = 1
static

Maximum number of parallel jobs (non-positive if unbounded). Can be modified by the -j option.

Definition at line 646 of file remake.cpp.

Referenced by has_free_slots(), and main().

◆ now

time_t now = time(NULL)
static

Time at the start of the program.

Definition at line 716 of file remake.cpp.

Referenced by update_status().

◆ obsolete_targets

bool obsolete_targets = false
static

Whether targets are unconditionally obsolete.

Definition at line 741 of file remake.cpp.

Referenced by get_status(), and main().

◆ prefix_dir

std::string prefix_dir
static

Directory with respect to which targets are relative.

Definition at line 726 of file remake.cpp.

Referenced by init_prefix_dir(), init_working_dir(), main(), and server_mode().

◆ propagate_vars

bool propagate_vars = false
static

Whether target-specific variables are propagated to prerequisites.

Definition at line 736 of file remake.cpp.

Referenced by accept_client(), load_rules(), and start().

◆ running_jobs

int running_jobs = 0
static

Number of jobs currently running:

  • it increases when a process is created in run_script,
  • it decreases when a completion message is received in finalize_job.
Note
There might be some jobs running while clients is empty. Indeed, if a client requested two targets to be rebuilt, if they are running concurrently, if one of them fails, the client will get a failure notice and might terminate before the other target finishes.

Definition at line 665 of file remake.cpp.

Referenced by finalize_job(), handle_clients(), has_free_slots(), and run_script().

◆ show_targets

bool show_targets = true
static

Whether a short message should be displayed for each target.

Definition at line 706 of file remake.cpp.

Referenced by complete_job(), init_prefix_dir(), main(), run_script(), and server_mode().

◆ socket_fd

socket_t socket_fd
static

Socket on which the server listens for client request.

Definition at line 684 of file remake.cpp.

Referenced by accept_client(), client_mode(), create_server(), server_loop(), and server_mode().

◆ socket_name

char* socket_name
static

Name of the server socket in the file system.

Definition at line 695 of file remake.cpp.

Referenced by create_server(), and server_mode().

◆ specific_rules

rule_map specific_rules
static

Map from targets to specific rules loaded from Remakefile.

Definition at line 624 of file remake.cpp.

Referenced by find_rule(), register_scripted_rule(), register_transparent_rule(), and server_mode().

◆ status

status_map status
static

Map from targets to their build status.

Definition at line 614 of file remake.cpp.

Referenced by complete_job(), get_status(), handle_clients(), load_rule(), server_loop(), server_mode(), start(), still_need_rebuild(), and update_status().

◆ variables

variable_map variables
static

Map from variable names to their content. Initialized with the values passed on the command line.

Definition at line 604 of file remake.cpp.

Referenced by client_mode(), load_rules(), main(), server_mode(), start(), and variable_generator::variable_generator().

◆ waiting_jobs

int waiting_jobs = 0
static

Number of jobs currently waiting for a build request to finish:

  • it increases when a build request is received in accept_client (since the client is presumably waiting for the reply),
  • it decreases when a reply is sent in complete_request.

Definition at line 673 of file remake.cpp.

Referenced by accept_client(), complete_request(), handle_clients(), and has_free_slots().

◆ working_dir

std::string working_dir
static

Directory with respect to which command-line names are relative.

Definition at line 721 of file remake.cpp.

Referenced by init_working_dir(), and main().