// Copyright 2015 Google Inc. All rights reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build ignore

#include "func.h"

#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

#include <algorithm>
#include <iterator>
#include <memory>
#include <unordered_map>

#include "eval.h"
#include "fileutil.h"
#include "find.h"
#include "log.h"
#include "parser.h"
#include "stats.h"
#include "stmt.h"
#include "strutil.h"
#include "symtab.h"
#include "var.h"

namespace {

// TODO: This code is very similar to
// NinjaGenerator::TranslateCommand. Factor them out.
void StripShellComment(string* cmd) {
  if (cmd->find('#') == string::npos)
    return;

  string res;
  bool prev_backslash = false;
  // Set space as an initial value so the leading comment will be
  // stripped out.
  char prev_char = ' ';
  char quote = 0;
  bool done = false;
  const char* in = cmd->c_str();
  for (; *in && !done; in++) {
    switch (*in) {
      case '#':
        if (quote == 0 && isspace(prev_char)) {
          while (in[1] && *in != '\n')
            in++;
          break;
        }
#if defined(__has_cpp_attribute) && __has_cpp_attribute(clang::fallthrough)
        [[clang::fallthrough]];
#endif

      case '\'':
      case '"':
      case '`':
        if (quote) {
          if (quote == *in)
            quote = 0;
        } else if (!prev_backslash) {
          quote = *in;
        }
        res += *in;
        break;

      case '\\':
        res += '\\';
        break;

      default:
        res += *in;
    }

    if (*in == '\\') {
      prev_backslash = !prev_backslash;
    } else {
      prev_backslash = false;
    }

    prev_char = *in;
  }
  cmd->swap(res);
}

void PatsubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& pat_str = args[0]->Eval(ev);
  const string&& repl = args[1]->Eval(ev);
  const string&& str = args[2]->Eval(ev);
  WordWriter ww(s);
  Pattern pat(pat_str);
  for (StringPiece tok : WordScanner(str)) {
    ww.MaybeAddWhitespace();
    pat.AppendSubst(tok, repl, s);
  }
}

void StripFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& str = args[0]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(str)) {
    ww.Write(tok);
  }
}

void SubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& pat = args[0]->Eval(ev);
  const string&& repl = args[1]->Eval(ev);
  const string&& str = args[2]->Eval(ev);
  if (pat.empty()) {
    *s += str;
    *s += repl;
    return;
  }
  size_t index = 0;
  while (index < str.size()) {
    size_t found = str.find(pat, index);
    if (found == string::npos)
      break;
    AppendString(StringPiece(str).substr(index, found - index), s);
    AppendString(repl, s);
    index = found + pat.size();
  }
  AppendString(StringPiece(str).substr(index), s);
}

void FindstringFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& find = args[0]->Eval(ev);
  const string&& in = args[1]->Eval(ev);
  if (in.find(find) != string::npos)
    AppendString(find, s);
}

void FilterFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& pat_buf = args[0]->Eval(ev);
  const string&& text = args[1]->Eval(ev);
  vector<Pattern> pats;
  for (StringPiece pat : WordScanner(pat_buf)) {
    pats.push_back(Pattern(pat));
  }
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(text)) {
    for (const Pattern& pat : pats) {
      if (pat.Match(tok)) {
        ww.Write(tok);
        break;
      }
    }
  }
}

void FilterOutFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& pat_buf = args[0]->Eval(ev);
  const string&& text = args[1]->Eval(ev);
  vector<Pattern> pats;
  for (StringPiece pat : WordScanner(pat_buf)) {
    pats.push_back(Pattern(pat));
  }
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(text)) {
    bool matched = false;
    for (const Pattern& pat : pats) {
      if (pat.Match(tok)) {
        matched = true;
        break;
      }
    }
    if (!matched)
      ww.Write(tok);
  }
}

void SortFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  string list;
  args[0]->Eval(ev, &list);
  COLLECT_STATS("func sort time");
  // TODO(hamaji): Probably we could use a faster string-specific sort
  // algorithm.
  vector<StringPiece> toks;
  WordScanner(list).Split(&toks);
  stable_sort(toks.begin(), toks.end());
  WordWriter ww(s);
  StringPiece prev;
  for (StringPiece tok : toks) {
    if (prev != tok) {
      ww.Write(tok);
      prev = tok;
    }
  }
}

static int GetNumericValueForFunc(const string& buf) {
  StringPiece s = TrimLeftSpace(buf);
  char* end;
  long n = strtol(s.data(), &end, 10);
  if (n < 0 || n == LONG_MAX || s.data() + s.size() != end) {
    return -1;
  }
  return n;
}

void WordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& n_str = args[0]->Eval(ev);
  int n = GetNumericValueForFunc(n_str);
  if (n < 0) {
    ev->Error(
        StringPrintf("*** non-numeric first argument to `word' function: '%s'.",
                     n_str.c_str()));
  }
  if (n == 0) {
    ev->Error("*** first argument to `word' function must be greater than 0.");
  }

  const string&& text = args[1]->Eval(ev);
  for (StringPiece tok : WordScanner(text)) {
    n--;
    if (n == 0) {
      AppendString(tok, s);
      break;
    }
  }
}

void WordlistFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& s_str = args[0]->Eval(ev);
  int si = GetNumericValueForFunc(s_str);
  if (si < 0) {
    ev->Error(StringPrintf(
        "*** non-numeric first argument to `wordlist' function: '%s'.",
        s_str.c_str()));
  }
  if (si == 0) {
    ev->Error(
        StringPrintf("*** invalid first argument to `wordlist' function: %s`",
                     s_str.c_str()));
  }

  const string&& e_str = args[1]->Eval(ev);
  int ei = GetNumericValueForFunc(e_str);
  if (ei < 0) {
    ev->Error(StringPrintf(
        "*** non-numeric second argument to `wordlist' function: '%s'.",
        e_str.c_str()));
  }

  const string&& text = args[2]->Eval(ev);
  int i = 0;
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(text)) {
    i++;
    if (si <= i && i <= ei) {
      ww.Write(tok);
    }
  }
}

void WordsFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& text = args[0]->Eval(ev);
  WordScanner ws(text);
  int n = 0;
  for (auto iter = ws.begin(); iter != ws.end(); ++iter)
    n++;
  char buf[32];
  sprintf(buf, "%d", n);
  *s += buf;
}

void FirstwordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& text = args[0]->Eval(ev);
  for (StringPiece tok : WordScanner(text)) {
    AppendString(tok, s);
    return;
  }
}

void LastwordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& text = args[0]->Eval(ev);
  StringPiece last;
  for (StringPiece tok : WordScanner(text)) {
    last = tok;
  }
  AppendString(last, s);
}

void JoinFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& list1 = args[0]->Eval(ev);
  const string&& list2 = args[1]->Eval(ev);
  WordScanner ws1(list1);
  WordScanner ws2(list2);
  WordWriter ww(s);
  WordScanner::Iterator iter1, iter2;
  for (iter1 = ws1.begin(), iter2 = ws2.begin();
       iter1 != ws1.end() && iter2 != ws2.end(); ++iter1, ++iter2) {
    ww.Write(*iter1);
    // Use |AppendString| not to append extra ' '.
    AppendString(*iter2, s);
  }
  for (; iter1 != ws1.end(); ++iter1)
    ww.Write(*iter1);
  for (; iter2 != ws2.end(); ++iter2)
    ww.Write(*iter2);
}

void WildcardFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& pat = args[0]->Eval(ev);
  COLLECT_STATS("func wildcard time");
  // Note GNU make does not delay the execution of $(wildcard) so we
  // do not need to check avoid_io here.
  WordWriter ww(s);
  vector<string>* files;
  for (StringPiece tok : WordScanner(pat)) {
    ScopedTerminator st(tok);
    Glob(tok.data(), &files);
    for (const string& file : *files) {
      ww.Write(file);
    }
  }
}

void DirFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& text = args[0]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(text)) {
    ww.Write(Dirname(tok));
    s->push_back('/');
  }
}

void NotdirFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& text = args[0]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(text)) {
    if (tok == "/") {
      ww.Write(StringPiece(""));
    } else {
      ww.Write(Basename(tok));
    }
  }
}

void SuffixFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& text = args[0]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(text)) {
    StringPiece suf = GetExt(tok);
    if (!suf.empty())
      ww.Write(suf);
  }
}

void BasenameFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& text = args[0]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(text)) {
    ww.Write(StripExt(tok));
  }
}

void AddsuffixFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& suf = args[0]->Eval(ev);
  const string&& text = args[1]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(text)) {
    ww.Write(tok);
    *s += suf;
  }
}

void AddprefixFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& pre = args[0]->Eval(ev);
  const string&& text = args[1]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(text)) {
    ww.Write(pre);
    AppendString(tok, s);
  }
}

void RealpathFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& text = args[0]->Eval(ev);
  if (ev->avoid_io()) {
    *s += "$(";
    string kati_binary;
    GetExecutablePath(&kati_binary);
    *s += kati_binary;
    *s += " --realpath ";
    *s += text;
    *s += " 2> /dev/null)";
    return;
  }

  WordWriter ww(s);
  for (StringPiece tok : WordScanner(text)) {
    ScopedTerminator st(tok);
    char buf[PATH_MAX];
    if (realpath(tok.data(), buf))
      ww.Write(buf);
  }
}

void AbspathFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& text = args[0]->Eval(ev);
  WordWriter ww(s);
  string buf;
  for (StringPiece tok : WordScanner(text)) {
    AbsPath(tok, &buf);
    ww.Write(buf);
  }
}

void IfFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& cond = args[0]->Eval(ev);
  if (cond.empty()) {
    if (args.size() > 2)
      args[2]->Eval(ev, s);
  } else {
    args[1]->Eval(ev, s);
  }
}

void AndFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  string cond;
  for (Value* a : args) {
    cond = a->Eval(ev);
    if (cond.empty())
      return;
  }
  if (!cond.empty()) {
    *s += cond;
  }
}

void OrFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  for (Value* a : args) {
    const string&& cond = a->Eval(ev);
    if (!cond.empty()) {
      *s += cond;
      return;
    }
  }
}

void ValueFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& var_name = args[0]->Eval(ev);
  Var* var = ev->LookupVar(Intern(var_name));
  AppendString(var->String().as_string(), s);
}

void EvalFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  // TODO: eval leaks everything... for now.
  // const string text = args[0]->Eval(ev);
  ev->CheckStack();
  string* text = new string;
  args[0]->Eval(ev, text);
  if (ev->avoid_io()) {
    KATI_WARN_LOC(ev->loc(),
                  "*warning*: $(eval) in a recipe is not recommended: %s",
                  text->c_str());
  }
  vector<Stmt*> stmts;
  Parse(*text, ev->loc(), &stmts);
  for (Stmt* stmt : stmts) {
    LOG("%s", stmt->DebugString().c_str());
    stmt->Eval(ev);
    // delete stmt;
  }
}

//#define TEST_FIND_EMULATOR

// A hack for Android build. We need to evaluate things like $((3+4))
// when we emit ninja file, because the result of such expressions
// will be passed to other make functions.
// TODO: Maybe we should introduce a helper binary which evaluate
// make expressions at ninja-time.
static bool HasNoIoInShellScript(const string& cmd) {
  if (cmd.empty())
    return true;
  if (HasPrefix(cmd, "echo $((") && cmd[cmd.size() - 1] == ')')
    return true;
  return false;
}

static void ShellFuncImpl(const string& shell,
                          const string& shellflag,
                          const string& cmd,
                          const Loc& loc,
                          string* s,
                          FindCommand** fc) {
  LOG("ShellFunc: %s", cmd.c_str());

#ifdef TEST_FIND_EMULATOR
  bool need_check = false;
  string out2;
#endif
  if (FindEmulator::Get()) {
    *fc = new FindCommand();
    if ((*fc)->Parse(cmd)) {
#ifdef TEST_FIND_EMULATOR
      if (FindEmulator::Get()->HandleFind(cmd, **fc, loc, &out2)) {
        need_check = true;
      }
#else
      if (FindEmulator::Get()->HandleFind(cmd, **fc, loc, s)) {
        return;
      }
#endif
    }
    delete *fc;
    *fc = NULL;
  }

  COLLECT_STATS_WITH_SLOW_REPORT("func shell time", cmd.c_str());
  RunCommand(shell, shellflag, cmd, RedirectStderr::NONE, s);
  FormatForCommandSubstitution(s);

#ifdef TEST_FIND_EMULATOR
  if (need_check) {
    if (*s != out2) {
      ERROR("FindEmulator is broken: %s\n%s\nvs\n%s", cmd.c_str(), s->c_str(),
            out2.c_str());
    }
  }
#endif
}

static vector<CommandResult*> g_command_results;

bool ShouldStoreCommandResult(StringPiece cmd) {
  // We really just want to ignore this one, or remove BUILD_DATETIME from
  // Android completely
  if (cmd == "date +%s")
    return false;

  Pattern pat(g_flags.ignore_dirty_pattern);
  Pattern nopat(g_flags.no_ignore_dirty_pattern);
  for (StringPiece tok : WordScanner(cmd)) {
    if (pat.Match(tok) && !nopat.Match(tok)) {
      return false;
    }
  }

  return true;
}

void ShellFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  string cmd = args[0]->Eval(ev);
  if (ev->avoid_io() && !HasNoIoInShellScript(cmd)) {
    if (ev->eval_depth() > 1) {
      ERROR_LOC(ev->loc(),
                "kati doesn't support passing results of $(shell) "
                "to other make constructs: %s",
                cmd.c_str());
    }
    StripShellComment(&cmd);
    *s += "$(";
    *s += cmd;
    *s += ")";
    return;
  }

  const string&& shell = ev->GetShell();
  const string&& shellflag = ev->GetShellFlag();

  string out;
  FindCommand* fc = NULL;
  ShellFuncImpl(shell, shellflag, cmd, ev->loc(), &out, &fc);
  if (ShouldStoreCommandResult(cmd)) {
    CommandResult* cr = new CommandResult();
    cr->op = (fc == NULL) ? CommandOp::SHELL : CommandOp::FIND,
    cr->shell = shell;
    cr->shellflag = shellflag;
    cr->cmd = cmd;
    cr->find.reset(fc);
    cr->result = out;
    g_command_results.push_back(cr);
  }
  *s += out;
}

void CallFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  static const Symbol tmpvar_names[] = {
      Intern("0"), Intern("1"), Intern("2"), Intern("3"), Intern("4"),
      Intern("5"), Intern("6"), Intern("7"), Intern("8"), Intern("9")};

  ev->CheckStack();
  const string&& func_name_buf = args[0]->Eval(ev);
  Symbol func_sym = Intern(TrimSpace(func_name_buf));
  Var* func = ev->LookupVar(func_sym);
  func->Used(ev, func_sym);
  if (!func->IsDefined()) {
    KATI_WARN_LOC(ev->loc(), "*warning*: undefined user function: %s",
                  func_sym.c_str());
  }
  vector<unique_ptr<SimpleVar>> av;
  for (size_t i = 1; i < args.size(); i++) {
    unique_ptr<SimpleVar> s(
        new SimpleVar(args[i]->Eval(ev), VarOrigin::AUTOMATIC));
    av.push_back(move(s));
  }
  vector<unique_ptr<ScopedGlobalVar>> sv;
  for (size_t i = 1;; i++) {
    string s;
    Symbol tmpvar_name_sym;
    if (i < sizeof(tmpvar_names) / sizeof(tmpvar_names[0])) {
      tmpvar_name_sym = tmpvar_names[i];
    } else {
      s = StringPrintf("%d", i);
      tmpvar_name_sym = Intern(s);
    }
    if (i < args.size()) {
      sv.emplace_back(new ScopedGlobalVar(tmpvar_name_sym, av[i - 1].get()));
    } else {
      // We need to blank further automatic vars
      Var* v = ev->LookupVar(tmpvar_name_sym);
      if (!v->IsDefined())
        break;
      if (v->Origin() != VarOrigin::AUTOMATIC)
        break;

      av.emplace_back(new SimpleVar("", VarOrigin::AUTOMATIC));
      sv.emplace_back(new ScopedGlobalVar(tmpvar_name_sym, av[i - 1].get()));
    }
  }

  ev->DecrementEvalDepth();
  func->Eval(ev, s);
  ev->IncrementEvalDepth();
}

void ForeachFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& varname = args[0]->Eval(ev);
  const string&& list = args[1]->Eval(ev);
  ev->DecrementEvalDepth();
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(list)) {
    unique_ptr<SimpleVar> v(
        new SimpleVar(tok.as_string(), VarOrigin::AUTOMATIC));
    ScopedGlobalVar sv(Intern(varname), v.get());
    ww.MaybeAddWhitespace();
    args[2]->Eval(ev, s);
  }
  ev->IncrementEvalDepth();
}

void OriginFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& var_name = args[0]->Eval(ev);
  Var* var = ev->LookupVar(Intern(var_name));
  *s += GetOriginStr(var->Origin());
}

void FlavorFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  const string&& var_name = args[0]->Eval(ev);
  Var* var = ev->LookupVar(Intern(var_name));
  *s += var->Flavor();
}

void InfoFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  const string&& a = args[0]->Eval(ev);
  if (ev->avoid_io()) {
    ev->add_delayed_output_command(
        StringPrintf("echo -e \"%s\"", EchoEscape(a).c_str()));
    return;
  }
  printf("%s\n", a.c_str());
  fflush(stdout);
}

void WarningFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  const string&& a = args[0]->Eval(ev);
  if (ev->avoid_io()) {
    ev->add_delayed_output_command(StringPrintf(
        "echo -e \"%s:%d: %s\" 2>&1", LOCF(ev->loc()), EchoEscape(a).c_str()));
    return;
  }
  WARN_LOC(ev->loc(), "%s", a.c_str());
}

void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  const string&& a = args[0]->Eval(ev);
  if (ev->avoid_io()) {
    ev->add_delayed_output_command(
        StringPrintf("echo -e \"%s:%d: *** %s.\" 2>&1 && false",
                     LOCF(ev->loc()), EchoEscape(a).c_str()));
    return;
  }
  ev->Error(StringPrintf("*** %s.", a.c_str()));
}

static void FileReadFunc(Evaluator* ev, const string& filename, string* s) {
  int fd = open(filename.c_str(), O_RDONLY);
  if (fd < 0) {
    if (errno == ENOENT) {
      if (ShouldStoreCommandResult(filename)) {
        CommandResult* cr = new CommandResult();
        cr->op = CommandOp::READ_MISSING;
        cr->cmd = filename;
        g_command_results.push_back(cr);
      }
      return;
    } else {
      ev->Error("*** open failed.");
    }
  }

  struct stat st;
  if (fstat(fd, &st) < 0) {
    ev->Error("*** fstat failed.");
  }

  size_t len = st.st_size;
  string out;
  out.resize(len);
  ssize_t r = HANDLE_EINTR(read(fd, &out[0], len));
  if (r != static_cast<ssize_t>(len)) {
    ev->Error("*** read failed.");
  }

  if (close(fd) < 0) {
    ev->Error("*** close failed.");
  }

  if (out.back() == '\n') {
    out.pop_back();
  }

  if (ShouldStoreCommandResult(filename)) {
    CommandResult* cr = new CommandResult();
    cr->op = CommandOp::READ;
    cr->cmd = filename;
    g_command_results.push_back(cr);
  }
  *s += out;
}

static void FileWriteFunc(Evaluator* ev,
                          const string& filename,
                          bool append,
                          string text) {
  FILE* f = fopen(filename.c_str(), append ? "ab" : "wb");
  if (f == NULL) {
    ev->Error("*** fopen failed.");
  }

  if (fwrite(&text[0], text.size(), 1, f) != 1) {
    ev->Error("*** fwrite failed.");
  }

  if (fclose(f) != 0) {
    ev->Error("*** fclose failed.");
  }

  if (ShouldStoreCommandResult(filename)) {
    CommandResult* cr = new CommandResult();
    cr->op = CommandOp::WRITE;
    cr->cmd = filename;
    cr->result = text;
    g_command_results.push_back(cr);
  }
}

void FileFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  if (ev->avoid_io()) {
    ev->Error("*** $(file ...) is not supported in rules.");
  }

  string arg = args[0]->Eval(ev);
  StringPiece filename = TrimSpace(arg);

  if (filename.size() <= 1) {
    ev->Error("*** Missing filename");
  }

  if (filename[0] == '<') {
    filename = TrimLeftSpace(filename.substr(1));
    if (!filename.size()) {
      ev->Error("*** Missing filename");
    }
    if (args.size() > 1) {
      ev->Error("*** invalid argument");
    }

    FileReadFunc(ev, filename.as_string(), s);
  } else if (filename[0] == '>') {
    bool append = false;
    if (filename[1] == '>') {
      append = true;
      filename = filename.substr(2);
    } else {
      filename = filename.substr(1);
    }
    filename = TrimLeftSpace(filename);
    if (!filename.size()) {
      ev->Error("*** Missing filename");
    }

    string text;
    if (args.size() > 1) {
      text = args[1]->Eval(ev);
      if (text.size() == 0 || text.back() != '\n') {
        text.push_back('\n');
      }
    }

    FileWriteFunc(ev, filename.as_string(), append, text);
  } else {
    ev->Error(StringPrintf("*** Invalid file operation: %s.  Stop.",
                           filename.as_string().c_str()));
  }
}

void DeprecatedVarFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  string vars_str = args[0]->Eval(ev);
  string msg;

  if (args.size() == 2) {
    msg = ". " + args[1]->Eval(ev);
  }

  if (ev->avoid_io()) {
    ev->Error("*** $(KATI_deprecated_var ...) is not supported in rules.");
  }

  for (StringPiece var : WordScanner(vars_str)) {
    Symbol sym = Intern(var);
    Var* v = ev->PeekVar(sym);
    if (!v->IsDefined()) {
      v = new SimpleVar(VarOrigin::FILE);
      sym.SetGlobalVar(v, false, nullptr);
    }

    if (v->Deprecated()) {
      ev->Error(
          StringPrintf("*** Cannot call KATI_deprecated_var on already "
                       "deprecated variable: %s.",
                       sym.c_str()));
    } else if (v->Obsolete()) {
      ev->Error(
          StringPrintf("*** Cannot call KATI_deprecated_var on already "
                       "obsolete variable: %s.",
                       sym.c_str()));
    }

    v->SetDeprecated(msg);
  }
}

void ObsoleteVarFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  string vars_str = args[0]->Eval(ev);
  string msg;

  if (args.size() == 2) {
    msg = ". " + args[1]->Eval(ev);
  }

  if (ev->avoid_io()) {
    ev->Error("*** $(KATI_obsolete_var ...) is not supported in rules.");
  }

  for (StringPiece var : WordScanner(vars_str)) {
    Symbol sym = Intern(var);
    Var* v = ev->PeekVar(sym);
    if (!v->IsDefined()) {
      v = new SimpleVar(VarOrigin::FILE);
      sym.SetGlobalVar(v, false, nullptr);
    }

    if (v->Deprecated()) {
      ev->Error(
          StringPrintf("*** Cannot call KATI_obsolete_var on already "
                       "deprecated variable: %s.",
                       sym.c_str()));
    } else if (v->Obsolete()) {
      ev->Error(StringPrintf(
          "*** Cannot call KATI_obsolete_var on already obsolete variable: %s.",
          sym.c_str()));
    }

    v->SetObsolete(msg);
  }
}

void DeprecateExportFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  string msg = ". " + args[0]->Eval(ev);

  if (ev->avoid_io()) {
    ev->Error("*** $(KATI_deprecate_export) is not supported in rules.");
  }

  if (ev->ExportObsolete()) {
    ev->Error("*** Export is already obsolete.");
  } else if (ev->ExportDeprecated()) {
    ev->Error("*** Export is already deprecated.");
  }

  ev->SetExportDeprecated(msg);
}

void ObsoleteExportFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  string msg = ". " + args[0]->Eval(ev);

  if (ev->avoid_io()) {
    ev->Error("*** $(KATI_obsolete_export) is not supported in rules.");
  }

  if (ev->ExportObsolete()) {
    ev->Error("*** Export is already obsolete.");
  }

  ev->SetExportObsolete(msg);
}

FuncInfo g_func_infos[] = {
    {"patsubst", &PatsubstFunc, 3, 3, false, false},
    {"strip", &StripFunc, 1, 1, false, false},
    {"subst", &SubstFunc, 3, 3, false, false},
    {"findstring", &FindstringFunc, 2, 2, false, false},
    {"filter", &FilterFunc, 2, 2, false, false},
    {"filter-out", &FilterOutFunc, 2, 2, false, false},
    {"sort", &SortFunc, 1, 1, false, false},
    {"word", &WordFunc, 2, 2, false, false},
    {"wordlist", &WordlistFunc, 3, 3, false, false},
    {"words", &WordsFunc, 1, 1, false, false},
    {"firstword", &FirstwordFunc, 1, 1, false, false},
    {"lastword", &LastwordFunc, 1, 1, false, false},

    {"join", &JoinFunc, 2, 2, false, false},
    {"wildcard", &WildcardFunc, 1, 1, false, false},
    {"dir", &DirFunc, 1, 1, false, false},
    {"notdir", &NotdirFunc, 1, 1, false, false},
    {"suffix", &SuffixFunc, 1, 1, false, false},
    {"basename", &BasenameFunc, 1, 1, false, false},
    {"addsuffix", &AddsuffixFunc, 2, 2, false, false},
    {"addprefix", &AddprefixFunc, 2, 2, false, false},
    {"realpath", &RealpathFunc, 1, 1, false, false},
    {"abspath", &AbspathFunc, 1, 1, false, false},

    {"if", &IfFunc, 3, 2, false, true},
    {"and", &AndFunc, 0, 0, true, false},
    {"or", &OrFunc, 0, 0, true, false},

    {"value", &ValueFunc, 1, 1, false, false},
    {"eval", &EvalFunc, 1, 1, false, false},
    {"shell", &ShellFunc, 1, 1, false, false},
    {"call", &CallFunc, 0, 0, false, false},
    {"foreach", &ForeachFunc, 3, 3, false, false},

    {"origin", &OriginFunc, 1, 1, false, false},
    {"flavor", &FlavorFunc, 1, 1, false, false},

    {"info", &InfoFunc, 1, 1, false, false},
    {"warning", &WarningFunc, 1, 1, false, false},
    {"error", &ErrorFunc, 1, 1, false, false},

    {"file", &FileFunc, 2, 1, false, false},

    /* Kati custom extension functions */
    {"KATI_deprecated_var", &DeprecatedVarFunc, 2, 1, false, false},
    {"KATI_obsolete_var", &ObsoleteVarFunc, 2, 1, false, false},
    {"KATI_deprecate_export", &DeprecateExportFunc, 1, 1, false, false},
    {"KATI_obsolete_export", &ObsoleteExportFunc, 1, 1, false, false},
};

unordered_map<StringPiece, FuncInfo*>* g_func_info_map;

}  // namespace

void InitFuncTable() {
  g_func_info_map = new unordered_map<StringPiece, FuncInfo*>;
  for (size_t i = 0; i < sizeof(g_func_infos) / sizeof(g_func_infos[0]); i++) {
    FuncInfo* fi = &g_func_infos[i];
    bool ok = g_func_info_map->emplace(fi->name, fi).second;
    CHECK(ok);
  }
}

void QuitFuncTable() {
  delete g_func_info_map;
}

FuncInfo* GetFuncInfo(StringPiece name) {
  auto found = g_func_info_map->find(name);
  if (found == g_func_info_map->end())
    return NULL;
  return found->second;
}

const vector<CommandResult*>& GetShellCommandResults() {
  return g_command_results;
}
