diff --git a/common.h b/common.h index 8a10a7efb..e0d5c27e3 100644 --- a/common.h +++ b/common.h @@ -338,7 +338,7 @@ template class null_terminated_array_t { CharType_t **array; - + /* No assignment or copying */ void operator=(null_terminated_array_t rhs); null_terminated_array_t(const null_terminated_array_t &); @@ -369,7 +369,7 @@ public: null_terminated_array_t(const string_list_t &argv) : array(make_null_terminated_array(argv)) { } - + ~null_terminated_array_t() { this->free(); @@ -385,7 +385,7 @@ public: { return array; } - + void clear() { this->free(); @@ -455,34 +455,32 @@ public: template class scoped_push { - T &ref; + T * const ref; T saved_value; bool restored; public: - scoped_push(T &r): - ref(r), restored(false) + scoped_push(T *r): ref(r), saved_value(*r), restored(false) { - saved_value = ref; } - scoped_push(T &r, T new_value): - ref(r), restored(false) + scoped_push(T *r, const T &new_value) : ref(r), saved_value(*r), restored(false) { - saved_value = ref; - ref = new_value; + *r = new_value; } ~scoped_push() { - if (!restored) - restore(); + restore(); } void restore() { - ref = saved_value; - restored = true; + if (!restored) + { + std::swap(*ref, saved_value); + restored = true; + } } }; diff --git a/exec.cpp b/exec.cpp index 77c890bf0..7a8d92a63 100644 --- a/exec.cpp +++ b/exec.cpp @@ -1176,7 +1176,7 @@ void exec(parser_t &parser, job_t *j) io_buffer->out_buffer_append(res.c_str(), res.size()); skip_fork = true; } - + /* PCA for some reason, fish forks a lot, even for basic builtins like echo just to write out their buffers. I'm certain a lot of this is unnecessary, but I am not sure exactly when. If j->io is NULL, then it means there's no pipes or anything, so we can certainly just write out our data. Beyond that, we may be able to do the same if io_get returns 0 for STDOUT_FILENO and STDERR_FILENO. */ if (! skip_fork && stdout_io.get() == NULL && stderr_io.get() == NULL) diff --git a/fallback.h b/fallback.h index 82cef85db..9d52498e2 100644 --- a/fallback.h +++ b/fallback.h @@ -350,9 +350,9 @@ size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz); BSD del_curterm seems to do a double-free. We redefine it as a no-op */ #ifdef HAVE_BROKEN_DEL_CURTERM - #define fish_del_curterm(X) OK +#define fish_del_curterm(X) OK #else - #define fish_del_curterm(X) del_curterm(X) +#define fish_del_curterm(X) del_curterm(X) #endif #ifndef HAVE_LRAND48_R diff --git a/parser.cpp b/parser.cpp index 82c108a6d..e0a79ea7b 100644 --- a/parser.cpp +++ b/parser.cpp @@ -746,8 +746,8 @@ int parser_t::eval_args(const wchar_t *line, std::vector &args) eval_args may be called while evaulating another command, so we save the previous tokenizer and restore it on exit */ - scoped_push tokenizer_push(current_tokenizer, &tok); - scoped_push tokenizer_pos_push(current_tokenizer_pos, 0); + scoped_push tokenizer_push(¤t_tokenizer, &tok); + scoped_push tokenizer_pos_push(¤t_tokenizer_pos, 0); error_code=0; @@ -1556,8 +1556,9 @@ void parser_t::parse_job_argument_list(process_t *p, new_io.reset(new_io_file); } } - - if (new_io.get() != NULL) { + + if (new_io.get() != NULL) + { j->io.push_back(new_io); } @@ -1648,7 +1649,7 @@ int parser_t::parse_job(process_t *p, bool allow_bogus_command = false; // If we are an elseif that will not be executed, or an AND or OR that will have been short circuited, don't complain about non-existent commands block_t *prev_block = current_block; - scoped_push tokenizer_pos_push(current_tokenizer_pos, tok_get_pos(tok)); + scoped_push tokenizer_pos_push(¤t_tokenizer_pos, tok_get_pos(tok)); while (args.empty()) { @@ -2410,7 +2411,7 @@ void parser_t::eval_job(tokenizer_t *tok) int was_builtin = 0; if (j->first_process->type==INTERNAL_BUILTIN && !j->first_process->next) was_builtin = 1; - scoped_push tokenizer_pos_push(current_tokenizer_pos, job_begin_pos); + scoped_push tokenizer_pos_push(¤t_tokenizer_pos, job_begin_pos); exec(*this, j); /* Only external commands require a new fishd barrier */ @@ -2552,9 +2553,9 @@ int parser_t::eval(const wcstring &cmdStr, const io_chain_t &io, enum block_type block_t *start_current_block = current_block; /* Record the current chain so we can put it back later */ - scoped_push block_io_push(block_io, io); + scoped_push block_io_push(&block_io, io); - scoped_push > forbidden_function_push(forbidden_function); + scoped_push forbidden_function_push(&forbidden_function); if (block_type == SUBST) { @@ -2591,7 +2592,8 @@ int parser_t::eval(const wcstring &cmdStr, const io_chain_t &io, enum block_type this->push_block(new scope_block_t(block_type)); - scoped_push tokenizer_push(current_tokenizer, new tokenizer_t(cmd, 0)); + tokenizer_t local_tokenizer(cmd, 0); + scoped_push tokenizer_push(¤t_tokenizer, &local_tokenizer); error_code = 0; @@ -2641,7 +2643,7 @@ int parser_t::eval(const wcstring &cmdStr, const io_chain_t &io, enum block_type this->print_errors_stderr(); - delete current_tokenizer; + tokenizer_push.restore(); while (forbidden_function.size() > forbid_count) parser_t::allow_function(); @@ -2819,8 +2821,8 @@ int parser_t::test_args(const wchar_t * buff, wcstring *out, const wchar_t *pre CHECK(buff, 1); tokenizer_t tok(buff, 0); - scoped_push tokenizer_push(current_tokenizer, &tok); - scoped_push tokenizer_pos_push(current_tokenizer_pos); + scoped_push tokenizer_push(¤t_tokenizer, &tok); + scoped_push tokenizer_pos_push(¤t_tokenizer_pos); for (; do_loop && tok_has_next(&tok); tok_next(&tok)) { @@ -2946,8 +2948,8 @@ int parser_t::test(const wchar_t *buff, int *block_level, wcstring *out, const w tokenizer_t tok(buff, 0); - scoped_push tokenizer_push(current_tokenizer, &tok); - scoped_push tokenizer_pos_push(current_tokenizer_pos); + scoped_push tokenizer_push(¤t_tokenizer, &tok); + scoped_push tokenizer_pos_push(¤t_tokenizer_pos); for (;; tok_next(&tok)) { diff --git a/reader.cpp b/reader.cpp index da3675239..824d8a270 100644 --- a/reader.cpp +++ b/reader.cpp @@ -1592,7 +1592,7 @@ static bool handle_completions(const std::vector &comp) */ switch (comp.size()) { - /* No suitable completions found, flash screen and return */ + /* No suitable completions found, flash screen and return */ case 0: { reader_flash();