Remake
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 <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  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_list
variable_map
 
typedef std::map< std::string,
status_t
status_map
 
typedef std::list< assign_tassign_list
 
typedef std::list< rule_trule_list
 
typedef std::map< std::string,
ref_ptr< rule_t > > 
rule_map
 
typedef std::map< int,
string_list
job_targets_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,
  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
}
 
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)
 
void init_working_dir ()
 
static std::string normalize_abs (std::string const &s)
 
static std::string normalize (std::string const &s)
 
static void normalize_list (string_list &l)
 
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)
 
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 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 rule_t find_generic_rule (std::string const &target)
 
static rule_t find_rule (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)
 
static std::string prepare_script (rule_t const &rule)
 
static bool run_script (int job_id, rule_t const &rule)
 
static bool 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 ()
 
void accept_client ()
 
void finalize_job (pid_t pid, bool res)
 
void server_loop ()
 
void server_mode (std::string const &remakefile, string_list const &targets)
 
void client_mode (char *socket_name, string_list const &targets)
 
void usage (int exit_status)
 
int main (int argc, char *argv[])
 

Variables

static variable_map variables
 
static dependency_map dependencies
 
static status_map status
 
static rule_list generic_rules
 
static rule_map specific_rules
 
static job_targets_map job_targets
 
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 volatile sig_atomic_t got_SIGCHLD = 0
 
log debug
 

Macro Definition Documentation

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

Definition at line 719 of file remake.cpp.

Referenced by accept_client(), get_status(), load_dependencies(), load_rule(), load_rules(), and main().

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

Typedef Documentation

typedef std::list<assign_t> assign_list

Definition at line 498 of file remake.cpp.

typedef std::list<client_t> client_list

Definition at line 544 of file remake.cpp.

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

Definition at line 460 of file remake.cpp.

typedef std::map<int, string_list> job_targets_map

Definition at line 516 of file remake.cpp.

typedef std::map<pid_t, int> pid_job_map

Definition at line 518 of file remake.cpp.

typedef std::list<rule_t> rule_list

Definition at line 512 of file remake.cpp.

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

Definition at line 514 of file remake.cpp.

typedef int socket_t

Definition at line 406 of file remake.cpp.

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

Definition at line 486 of file remake.cpp.

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

Definition at line 414 of file remake.cpp.

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

Definition at line 416 of file remake.cpp.

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

Definition at line 462 of file remake.cpp.

Enumeration Type Documentation

anonymous enum
Enumerator
INVALID_SOCKET 

Definition at line 407 of file remake.cpp.

407 { INVALID_SOCKET = -1 };
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.

Remade 

Target was successfully rebuilt.

Failed 

Build failed for target.

Definition at line 467 of file remake.cpp.

468 {
469  Uptodate, ///< Target is up-to-date.
470  Todo, ///< Target is missing or obsolete.
471  Recheck, ///< Target has an obsolete dependency.
472  Running, ///< Target is being rebuilt.
473  Remade, ///< Target was successfully rebuilt.
474  Failed ///< Build failed for target.
475 };

Function Documentation

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 738 of file remake.cpp.

739 {
740  std::string const &s = se.input;
741  char const *quoted_char = ",: '";
742  char const *escaped_char = "\"\\$!";
743  bool need_quotes = false;
744  char *buf = NULL;
745  size_t len = s.length(), last = 0, j = 0;
746  for (size_t i = 0; i < len; ++i)
747  {
748  if (strchr(escaped_char, s[i]))
749  {
750  need_quotes = true;
751  if (!buf) buf = new char[len * 2];
752  memcpy(&buf[j], &s[last], i - last);
753  j += i - last;
754  buf[j++] = '\\';
755  buf[j++] = s[i];
756  last = i + 1;
757  }
758  if (!need_quotes && strchr(quoted_char, s[i]))
759  need_quotes = true;
760  }
761  if (!need_quotes) return out << s;
762  out << '"';
763  if (!buf) return out << s << '"';
764  out.write(buf, j);
765  out.write(&s[last], len - last);
766  delete[] buf;
767  return out << '"';
768 }
static void sigchld_handler ( int  )
static

Definition at line 665 of file remake.cpp.

Referenced by create_server().

666 {
667  got_SIGCHLD = 1;
668 }
static void sigint_handler ( int  )
static

Definition at line 670 of file remake.cpp.

Referenced by create_server().

671 {
672  // Child processes will receive the signal too, so just prevent
673  // new jobs from starting and wait for the running jobs to fail.
674  keep_going = false;
675 }

Variable Documentation

bool build_failure
static

Whether the request of an original client failed.

Definition at line 634 of file remake.cpp.

Referenced by complete_request(), and server_mode().

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 585 of file remake.cpp.

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

log debug

Definition at line 705 of file remake.cpp.

Referenced by log_auto_close::~log_auto_close().

dependency_map dependencies
static

Map from targets to their known dependencies.

Definition at line 554 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().

bool echo_scripts = false
static

Whether script commands are echoed.

Definition at line 656 of file remake.cpp.

Referenced by main(), and run_script().

std::string first_target
static

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

Definition at line 646 of file remake.cpp.

Referenced by load_rule(), and server_mode().

rule_list generic_rules
static

Set of generic rules loaded from Remakefile.

Definition at line 564 of file remake.cpp.

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

volatile sig_atomic_t got_SIGCHLD = 0
static

Definition at line 663 of file remake.cpp.

Referenced by server_loop(), and sigchld_handler().

int job_counter = 0
static

Global counter used to produce increasing job numbers.

See Also
job_targets

Definition at line 624 of file remake.cpp.

Referenced by start().

pid_job_map job_pids
static

Map from jobs to shell pids.

Definition at line 579 of file remake.cpp.

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

job_targets_map job_targets
static

Map from jobs to targets being built.

Definition at line 574 of file remake.cpp.

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

bool keep_going = false
static

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

Definition at line 597 of file remake.cpp.

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

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 591 of file remake.cpp.

Referenced by has_free_slots(), and main().

time_t now = time(NULL)
static

Definition at line 658 of file remake.cpp.

Referenced by update_status().

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 610 of file remake.cpp.

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

bool show_targets = true
static

Whether a short message should be displayed for each target.

Definition at line 651 of file remake.cpp.

Referenced by main(), and run_script().

socket_t socket_fd
static

Socket on which the server listens for client request.

Definition at line 629 of file remake.cpp.

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

char* socket_name
static

Name of the server socket in the file system.

Definition at line 640 of file remake.cpp.

Referenced by create_server(), and server_mode().

rule_map specific_rules
static

Map from targets to specific rules loaded from Remakefile.

Definition at line 569 of file remake.cpp.

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

status_map status
static

Map from targets to their build status.

Definition at line 559 of file remake.cpp.

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

variable_map variables
static

Map from variable names to their content.

Definition at line 549 of file remake.cpp.

Referenced by load_rules(), server_mode(), and variable_generator::variable_generator().

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 618 of file remake.cpp.

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

std::string working_dir
static

Definition at line 660 of file remake.cpp.

Referenced by init_working_dir(), normalize(), and normalize_abs().