<commit_before>/* bzflag
 * Copyright (c) 1993 - 2008 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <stdio.h>
#include <stdarg.h>
#include <sstream>
#include "plugin_utils.h"
#include "base64.h"

std::string base64_encode(const std::string &text)
{
  // convert to base64
  std::string dest;

  base64::encode(text.begin(), text.end(), std::back_inserter(dest));

  return dest;
}

std::string base64_decode(const std::string &text)
{
  // convert back to binary
  std::string dest;

  base64::decode(text.begin(), text.end(),std::back_inserter(dest));
  return dest;
}

const char* bzu_GetTeamName(bz_eTeamType team)
{
  switch (team) {

  case eRedTeam:
    return "Red";

  case eGreenTeam:
    return "Green";

  case eBlueTeam:
    return "Blue";

  case ePurpleTeam:
    return "Purple";

  case eRogueTeam:
    return "Rogue";

  case eObservers:
    return "Observer";

  case eRabbitTeam:
    return "Rabbit";

  case eHunterTeam:
    return "Hunter";

  default:
    break;
  }

  return "Unknown";
}

std::string printTime(bz_Time *ts, const char* _timezone)
{
  std::string time;
  appendTime(time,ts,_timezone);
  return time;
}

//Date: Mon, 23 Jun 2008 17:50:22 GMT

void appendTime(std::string & text, bz_Time *ts, const char* _timezone)
{
  switch(ts->dayofweek) {
  case 1:
    text += "Mon";
    break;
  case 2:
    text += "Tue";
    break;
  case 3:
    text += "Wed";
    break;
  case 4:
    text += "Thu";
    break;
  case 5:
    text += "Fri";
    break;
  case 6:
    text += "Sat";
    break;
  case 0:
    text += "Sun";
    break;
  }

  text += format(", %d ",ts->day);

  switch(ts->month) {
  case 0:
    text += "Jan";
    break;
  case 1:
    text += "Feb";
    break;
  case 2:
    text += "Mar";
    break;
  case 3:
    text += "Apr";
    break;
  case 4:
    text += "May";
    break;
  case 5:
    text += "Jun";
    break;
  case 6:
    text += "Jul";
    break;
  case 7:
    text += "Aug";
    break;
  case 8:
    text += "Sep";
    break;
  case 9:
    text += "Oct";
    break;
  case 10:
    text += "Nov";
    break;
  case 11:
    text += "Dec";
    break;
  }

  text += format(" %d %d:%d:%d ",ts->year,ts->hour,ts->minute,ts->second);
  if (_timezone)
    text += _timezone;
  else
    text += "GMT";
}

std::string no_whitespace(const std::string &s)
{
  const int sourcesize = (int)s.size();

  int count = 0, i = 0, j = 0;
  for (i = 0; i < sourcesize; i++)
    if (!isWhitespace(s[i]))
      count++;

  // create result string of correct size
  std::string result(count, ' ');

  for (i = 0, j = 0; i < sourcesize; i++)
    if (!isWhitespace(s[i]))
      result[j++] = s[i];

  return result;
}

const std::string& tolower(const std::string& s, std::string& dest)
{
  for (std::string::const_iterator i=s.begin(), end=s.end(); i!=end; ++i)
    dest += ::tolower(*i);

  return dest;
}

const std::string& toupper(const std::string& s, std::string& dest)
{
  for (std::string::const_iterator i=s.begin(), end=s.end(); i!=end; ++i)
    dest += ::toupper(*i);

  return dest;
}

const std::string& tolower(const char* s, std::string& dest)
{
  if (!s)
    return dest;

  for (size_t i =0,end = strlen(s); i < end; i++)
    dest += ::tolower(s[i]);

  return dest;
}

const std::string& toupper(const char* s, std::string& dest)
{
  if (!s)
    return dest;

  for (size_t i =0,end = strlen(s); i < end; i++)
    dest += ::toupper(s[i]);

  return dest;
}

const std::string& makelower(std::string& s)
{
  for (std::string::iterator i=s.begin(), end=s.end(); i!=end; ++i)
    *i = ::tolower(*i);

  return s;
}

const std::string& makeupper(std::string& s)
{
  for (std::string::iterator i=s.begin(), end=s.end(); i!=end; ++i)
    *i = ::toupper(*i);

  return s;
}

std::string format(const char* fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  char temp[2048];
  vsprintf(temp,fmt, args);
  std::string result = temp;
  va_end(args);
  return result;
}

std::vector<std::string> tokenize(const std::string& in, const std::string &delims,
				  const int maxTokens, const bool useQuotes, size_t offset)
{
  std::vector<std::string> tokens;
  int numTokens = 0;
  bool inQuote = false;

  std::ostringstream currentToken;

  std::string::size_type pos = in.find_first_not_of(delims,offset);
  int currentChar  = (pos == std::string::npos) ? -1 : in[pos];
  bool enoughTokens = (maxTokens && (numTokens >= (maxTokens-1)));

  while (pos != std::string::npos && !enoughTokens) {

    // get next token
    bool tokenDone = false;
    bool foundSlash = false;

    currentChar = (pos < in.size()) ? in[pos] : -1;
    while ((currentChar != -1) && !tokenDone) {

      tokenDone = false;

      if (delims.find(currentChar) != std::string::npos && !inQuote) { // currentChar is a delim
	pos ++;
	break; // breaks out of while loop
      }

      if (!useQuotes) {
	currentToken << char(currentChar);
      } else {

	switch (currentChar) {
	case '\\' : // found a backslash
	  if (foundSlash) {
	    currentToken << char(currentChar);
	    foundSlash = false;
	  } else {
	    foundSlash = true;
	  }
	  break;
	case '\"' : // found a quote
	  if (foundSlash) { // found \"
	    currentToken << char(currentChar);
	    foundSlash = false;
	  } else { // found unescaped "
	    if (inQuote) { // exiting a quote
	      // finish off current token
	      tokenDone = true;
	      inQuote = false;
	      //slurp off one additional delimeter if possible
	      if (pos+1 < in.size() &&
		  delims.find(in[pos+1]) != std::string::npos) {
		pos++;
	      }

	    } else { // entering a quote
	      // finish off current token
	      tokenDone = true;
	      inQuote = true;
	    }
	  }
	  break;
	default:
	  if (foundSlash) { // don't care about slashes except for above cases
	    currentToken << '\\';
	    foundSlash = false;
	  }
	  currentToken << char(currentChar);
	  break;
	}
      }

      pos++;
      currentChar = (pos < in.size()) ? in[pos] : -1;
    } // end of getting a Token

    if (currentToken.str().size() > 0) { // if the token is something add to list
      tokens.push_back(currentToken.str());
      currentToken.str("");
      numTokens ++;
    }

    enoughTokens = (maxTokens && (numTokens >= (maxTokens-1)));
    if (enoughTokens)
      break;
    else
      pos = in.find_first_not_of(delims,pos);

  } // end of getting all tokens -- either EOL or max tokens reached

  if (enoughTokens && pos != std::string::npos) {
    std::string lastToken = in.substr(pos);
    if (lastToken.size() > 0)
      tokens.push_back(lastToken);
  }

  return tokens;
}

std::string replace_all(const std::string& in, const std::string& replaceMe, const std::string& withMe)
{
  std::string result;
  std::string::size_type beginPos = 0;
  std::string::size_type endPos = 0;
  std::ostringstream tempStream;

  endPos = in.find(replaceMe);
  if (endPos == std::string::npos)
    return in; // can't find anything to replace
  if (replaceMe.empty()) return in; // can't replace nothing with something -- can do reverse

  while (endPos != std::string::npos) {
    // push the  part up to
    tempStream << in.substr(beginPos,endPos-beginPos);
    tempStream << withMe;
    beginPos = endPos + replaceMe.size();
    endPos = in.find(replaceMe,beginPos);
  }
  tempStream << in.substr(beginPos);
  return tempStream.str();
}

std::string url_encode(const std::string &text)
{
  char hex[5];
  std::string destination;
  for (int i=0;  i < (int) text.size(); i++) {
    char c = text[i];
    if (isAlphanumeric(c)) {
      destination+=c;
    } else if (isWhitespace(c)) {
      destination+='+';
    } else {
      destination+='%';
      sprintf(hex, "%-2.2X", c);
      destination.append(hex);
    }
  }
  return destination;
}

std::string url_decode(const std::string &text)
{
  std::string destination;

  std::string::const_iterator itr = text.begin();
  while (itr != text.end()) {
    if (*itr != '%' && *itr != '+')
      destination += *itr++;
    else if (*itr == '+')
      destination += " ";
    else
    {
      char hex[5] = "0x00";

      itr++;;
      if (itr == text.end())
	return destination;

      hex[2] = *itr;

      itr++;;
      if (itr == text.end())
	return destination;

      hex[3] = *itr;

      unsigned int val = 0;
      sscanf(hex,"%x",&val);
      if (val != 0)
	destination += (char)val;
      itr++;
    }
  }
  return destination;
}

size_t find_first_substr(const std::string &findin, const std::string findwhat, size_t offset)
{
  if (findwhat.size()) {
    for (size_t f = offset; f < findin.size(); f++) {
      if (findin[f] == findwhat[0]) {
	size_t start = f;
	for (size_t w = 1; w < findwhat.size(); w++) {
	  if (f+w > findin.size())
	    return std::string::npos;
	  if (findin[f+w] != findwhat[w]) {
	    f+=w;
	    w = findwhat.size();
	  }
	}
	if (start == f)
	  return f;
      }
    }
  }
  return std::string::npos;
}

void trimLeadingWhitespace(std::string &text)
{
  for(size_t s = 0; s < text.size(); s++) {
    if (!isWhitespace(text[s])) {
      if (s)
	text.erase(text.begin()+s-1);
      return;
    }
  }
}

std::string trimLeadingWhitespace(const std::string &text)
{
  std::string s = text;
  trimLeadingWhitespace(s);
  return s;
}

std::vector<std::string> perms;

const std::vector<std::string> bzu_standardPerms (void)
{
  if (perms.empty()){
    perms.push_back("actionMessage");
    perms.push_back("adminMessageReceive");
    perms.push_back("adminMessageSend");
    perms.push_back("antiban");
    perms.push_back("antikick");
    perms.push_back("antikill");
    perms.push_back("antipoll");
    perms.push_back("antipollban");
    perms.push_back("antipollkick");
    perms.push_back("antipollkill");
    perms.push_back("ban");
    perms.push_back("banlist");
    perms.push_back("countdown");
    perms.push_back("date");
    perms.push_back("endGame");
    perms.push_back("flagHistory");
    perms.push_back("flagMaster");
    perms.push_back("flagMod");
    perms.push_back("hideAdmin");
    perms.push_back("idleStats");
    perms.push_back("info");
    perms.push_back("jitter_warn");
    perms.push_back("kick");
    perms.push_back("kill");
    perms.push_back("lagStats");
    perms.push_back("lagwarn");
    perms.push_back("listPlugins");
    perms.push_back("listPerms");
    perms.push_back("masterBan");
    perms.push_back("modCount");
    perms.push_back("mute");
    perms.push_back("packetlosswarn");
    perms.push_back("playerList");
    perms.push_back("poll");
    perms.push_back("pollBan");
    perms.push_back("pollKick");
    perms.push_back("pollKill");
    perms.push_back("pollSet");
    perms.push_back("pollFlagReset");
    perms.push_back("privateMessage");
    perms.push_back("record");
    perms.push_back("rejoin");
    perms.push_back("removePerms");
    perms.push_back("replay");
    perms.push_back("say");
    perms.push_back("sendHelp");
    perms.push_back("setAll");
    perms.push_back("setPerms");
    perms.push_back("setVar");
    perms.push_back("showOthers");
    perms.push_back("shortBan");
    perms.push_back("shutdownServer");
    perms.push_back("spawn");
    perms.push_back("superKill");
    perms.push_back("talk");
    perms.push_back("unban");
    perms.push_back("unmute");
    perms.push_back("veto");
    perms.push_back("viewReports");
    perms.push_back("vote");
  }
  return perms;
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>Increment the character pointer when "+" is seen. Fix whitespace. Remove duplicate semicolons.<commit_after>/* bzflag
 * Copyright (c) 1993 - 2008 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <stdio.h>
#include <stdarg.h>
#include <sstream>
#include "plugin_utils.h"
#include "base64.h"

std::string base64_encode(const std::string &text)
{
  // convert to base64
  std::string dest;

  base64::encode(text.begin(), text.end(), std::back_inserter(dest));

  return dest;
}

std::string base64_decode(const std::string &text)
{
  // convert back to binary
  std::string dest;

  base64::decode(text.begin(), text.end(),std::back_inserter(dest));
  return dest;
}

const char* bzu_GetTeamName(bz_eTeamType team)
{
  switch (team) {

  case eRedTeam:
    return "Red";

  case eGreenTeam:
    return "Green";

  case eBlueTeam:
    return "Blue";

  case ePurpleTeam:
    return "Purple";

  case eRogueTeam:
    return "Rogue";

  case eObservers:
    return "Observer";

  case eRabbitTeam:
    return "Rabbit";

  case eHunterTeam:
    return "Hunter";

  default:
    break;
  }

  return "Unknown";
}

std::string printTime(bz_Time *ts, const char* _timezone)
{
  std::string time;
  appendTime(time,ts,_timezone);
  return time;
}

//Date: Mon, 23 Jun 2008 17:50:22 GMT

void appendTime(std::string & text, bz_Time *ts, const char* _timezone)
{
  switch(ts->dayofweek) {
  case 1:
    text += "Mon";
    break;
  case 2:
    text += "Tue";
    break;
  case 3:
    text += "Wed";
    break;
  case 4:
    text += "Thu";
    break;
  case 5:
    text += "Fri";
    break;
  case 6:
    text += "Sat";
    break;
  case 0:
    text += "Sun";
    break;
  }

  text += format(", %d ",ts->day);

  switch(ts->month) {
  case 0:
    text += "Jan";
    break;
  case 1:
    text += "Feb";
    break;
  case 2:
    text += "Mar";
    break;
  case 3:
    text += "Apr";
    break;
  case 4:
    text += "May";
    break;
  case 5:
    text += "Jun";
    break;
  case 6:
    text += "Jul";
    break;
  case 7:
    text += "Aug";
    break;
  case 8:
    text += "Sep";
    break;
  case 9:
    text += "Oct";
    break;
  case 10:
    text += "Nov";
    break;
  case 11:
    text += "Dec";
    break;
  }

  text += format(" %d %d:%d:%d ",ts->year,ts->hour,ts->minute,ts->second);
  if (_timezone)
    text += _timezone;
  else
    text += "GMT";
}

std::string no_whitespace(const std::string &s)
{
  const int sourcesize = (int)s.size();

  int count = 0, i = 0, j = 0;
  for (i = 0; i < sourcesize; i++)
    if (!isWhitespace(s[i]))
      count++;

  // create result string of correct size
  std::string result(count, ' ');

  for (i = 0, j = 0; i < sourcesize; i++)
    if (!isWhitespace(s[i]))
      result[j++] = s[i];

  return result;
}

const std::string& tolower(const std::string& s, std::string& dest)
{
  for (std::string::const_iterator i=s.begin(), end=s.end(); i!=end; ++i)
    dest += ::tolower(*i);

  return dest;
}

const std::string& toupper(const std::string& s, std::string& dest)
{
  for (std::string::const_iterator i=s.begin(), end=s.end(); i!=end; ++i)
    dest += ::toupper(*i);

  return dest;
}

const std::string& tolower(const char* s, std::string& dest)
{
  if (!s)
    return dest;

  for (size_t i =0,end = strlen(s); i < end; i++)
    dest += ::tolower(s[i]);

  return dest;
}

const std::string& toupper(const char* s, std::string& dest)
{
  if (!s)
    return dest;

  for (size_t i =0,end = strlen(s); i < end; i++)
    dest += ::toupper(s[i]);

  return dest;
}

const std::string& makelower(std::string& s)
{
  for (std::string::iterator i=s.begin(), end=s.end(); i!=end; ++i)
    *i = ::tolower(*i);

  return s;
}

const std::string& makeupper(std::string& s)
{
  for (std::string::iterator i=s.begin(), end=s.end(); i!=end; ++i)
    *i = ::toupper(*i);

  return s;
}

std::string format(const char* fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  char temp[2048];
  vsprintf(temp,fmt, args);
  std::string result = temp;
  va_end(args);
  return result;
}

std::vector<std::string> tokenize(const std::string& in, const std::string &delims,
				  const int maxTokens, const bool useQuotes, size_t offset)
{
  std::vector<std::string> tokens;
  int numTokens = 0;
  bool inQuote = false;

  std::ostringstream currentToken;

  std::string::size_type pos = in.find_first_not_of(delims,offset);
  int currentChar  = (pos == std::string::npos) ? -1 : in[pos];
  bool enoughTokens = (maxTokens && (numTokens >= (maxTokens-1)));

  while (pos != std::string::npos && !enoughTokens) {

    // get next token
    bool tokenDone = false;
    bool foundSlash = false;

    currentChar = (pos < in.size()) ? in[pos] : -1;
    while ((currentChar != -1) && !tokenDone) {

      tokenDone = false;

      if (delims.find(currentChar) != std::string::npos && !inQuote) { // currentChar is a delim
	pos ++;
	break; // breaks out of while loop
      }

      if (!useQuotes) {
	currentToken << char(currentChar);
      } else {

	switch (currentChar) {
	case '\\' : // found a backslash
	  if (foundSlash) {
	    currentToken << char(currentChar);
	    foundSlash = false;
	  } else {
	    foundSlash = true;
	  }
	  break;
	case '\"' : // found a quote
	  if (foundSlash) { // found \"
	    currentToken << char(currentChar);
	    foundSlash = false;
	  } else { // found unescaped "
	    if (inQuote) { // exiting a quote
	      // finish off current token
	      tokenDone = true;
	      inQuote = false;
	      //slurp off one additional delimeter if possible
	      if (pos+1 < in.size() &&
		  delims.find(in[pos+1]) != std::string::npos) {
		pos++;
	      }

	    } else { // entering a quote
	      // finish off current token
	      tokenDone = true;
	      inQuote = true;
	    }
	  }
	  break;
	default:
	  if (foundSlash) { // don't care about slashes except for above cases
	    currentToken << '\\';
	    foundSlash = false;
	  }
	  currentToken << char(currentChar);
	  break;
	}
      }

      pos++;
      currentChar = (pos < in.size()) ? in[pos] : -1;
    } // end of getting a Token

    if (currentToken.str().size() > 0) { // if the token is something add to list
      tokens.push_back(currentToken.str());
      currentToken.str("");
      numTokens ++;
    }

    enoughTokens = (maxTokens && (numTokens >= (maxTokens-1)));
    if (enoughTokens)
      break;
    else
      pos = in.find_first_not_of(delims,pos);

  } // end of getting all tokens -- either EOL or max tokens reached

  if (enoughTokens && pos != std::string::npos) {
    std::string lastToken = in.substr(pos);
    if (lastToken.size() > 0)
      tokens.push_back(lastToken);
  }

  return tokens;
}

std::string replace_all(const std::string& in, const std::string& replaceMe, const std::string& withMe)
{
  std::string result;
  std::string::size_type beginPos = 0;
  std::string::size_type endPos = 0;
  std::ostringstream tempStream;

  endPos = in.find(replaceMe);
  if (endPos == std::string::npos)
    return in; // can't find anything to replace
  if (replaceMe.empty()) return in; // can't replace nothing with something -- can do reverse

  while (endPos != std::string::npos) {
    // push the  part up to
    tempStream << in.substr(beginPos,endPos-beginPos);
    tempStream << withMe;
    beginPos = endPos + replaceMe.size();
    endPos = in.find(replaceMe,beginPos);
  }
  tempStream << in.substr(beginPos);
  return tempStream.str();
}

std::string url_encode(const std::string &text)
{
  char hex[5];
  std::string destination;
  for (int i=0;  i < (int) text.size(); i++) {
    char c = text[i];
    if (isAlphanumeric(c)) {
      destination+=c;
    } else if (isWhitespace(c)) {
      destination+='+';
    } else {
      destination+='%';
      sprintf(hex, "%-2.2X", c);
      destination.append(hex);
    }
  }
  return destination;
}

std::string url_decode(const std::string &text)
{
  std::string destination;

  std::string::const_iterator itr = text.begin();
  while (itr != text.end()) {
    if (*itr != '%' && *itr != '+')
      destination += *itr++;
    else if (*itr == '+') {
      destination += " ";
      itr++;
    }
    else {
      char hex[5] = "0x00";

      itr++;
      if (itr == text.end())
	return destination;

      hex[2] = *itr;

      itr++;
      if (itr == text.end())
	return destination;

      hex[3] = *itr;

      unsigned int val = 0;
      sscanf(hex,"%x",&val);
      if (val != 0)
	destination += (char)val;
      itr++;
    }
  }
  return destination;
}

size_t find_first_substr(const std::string &findin, const std::string findwhat, size_t offset)
{
  if (findwhat.size()) {
    for (size_t f = offset; f < findin.size(); f++) {
      if (findin[f] == findwhat[0]) {
	size_t start = f;
	for (size_t w = 1; w < findwhat.size(); w++) {
	  if (f+w > findin.size())
	    return std::string::npos;
	  if (findin[f+w] != findwhat[w]) {
	    f+=w;
	    w = findwhat.size();
	  }
	}
	if (start == f)
	  return f;
      }
    }
  }
  return std::string::npos;
}

void trimLeadingWhitespace(std::string &text)
{
  for(size_t s = 0; s < text.size(); s++) {
    if (!isWhitespace(text[s])) {
      if (s)
	text.erase(text.begin()+s-1);
      return;
    }
  }
}

std::string trimLeadingWhitespace(const std::string &text)
{
  std::string s = text;
  trimLeadingWhitespace(s);
  return s;
}

std::vector<std::string> perms;

const std::vector<std::string> bzu_standardPerms (void)
{
  if (perms.empty()){
    perms.push_back("actionMessage");
    perms.push_back("adminMessageReceive");
    perms.push_back("adminMessageSend");
    perms.push_back("antiban");
    perms.push_back("antikick");
    perms.push_back("antikill");
    perms.push_back("antipoll");
    perms.push_back("antipollban");
    perms.push_back("antipollkick");
    perms.push_back("antipollkill");
    perms.push_back("ban");
    perms.push_back("banlist");
    perms.push_back("countdown");
    perms.push_back("date");
    perms.push_back("endGame");
    perms.push_back("flagHistory");
    perms.push_back("flagMaster");
    perms.push_back("flagMod");
    perms.push_back("hideAdmin");
    perms.push_back("idleStats");
    perms.push_back("info");
    perms.push_back("jitter_warn");
    perms.push_back("kick");
    perms.push_back("kill");
    perms.push_back("lagStats");
    perms.push_back("lagwarn");
    perms.push_back("listPlugins");
    perms.push_back("listPerms");
    perms.push_back("masterBan");
    perms.push_back("modCount");
    perms.push_back("mute");
    perms.push_back("packetlosswarn");
    perms.push_back("playerList");
    perms.push_back("poll");
    perms.push_back("pollBan");
    perms.push_back("pollKick");
    perms.push_back("pollKill");
    perms.push_back("pollSet");
    perms.push_back("pollFlagReset");
    perms.push_back("privateMessage");
    perms.push_back("record");
    perms.push_back("rejoin");
    perms.push_back("removePerms");
    perms.push_back("replay");
    perms.push_back("say");
    perms.push_back("sendHelp");
    perms.push_back("setAll");
    perms.push_back("setPerms");
    perms.push_back("setVar");
    perms.push_back("showOthers");
    perms.push_back("shortBan");
    perms.push_back("shutdownServer");
    perms.push_back("spawn");
    perms.push_back("superKill");
    perms.push_back("talk");
    perms.push_back("unban");
    perms.push_back("unmute");
    perms.push_back("veto");
    perms.push_back("viewReports");
    perms.push_back("vote");
  }
  return perms;
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/******************************************************************************\
* File:          vcs.cpp
* Purpose:       Implementation of wxExVCS class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/config.h>
#include <wx/extension/vcs.h>
#include <wx/extension/configdlg.h>
#include <wx/extension/defs.h>
#include <wx/extension/frame.h>
#include <wx/extension/log.h>
#include <wx/extension/stcdlg.h>
#include <wx/extension/util.h>

wxExVCS* wxExVCS::m_Self = NULL;
#if wxUSE_GUI
wxExSTCEntryDialog* wxExVCS::m_STCEntryDialog = NULL;
#endif

wxExVCS::wxExVCS()
  : m_Command(VCS_NO_COMMAND)
  , m_FullPath(wxEmptyString)
{
  Initialize();
}

wxExVCS::wxExVCS(int command_id, const wxString& fullpath)
  : m_Command(GetType(command_id))
  , m_FullPath(fullpath)
{
  Initialize();
}

wxExVCS::wxExVCS(wxExCommand type, const wxString& fullpath)
  : m_Command(type)
  , m_FullPath(fullpath)
{
  Initialize();
}

#if wxUSE_GUI
int wxExVCS::ConfigDialog(
  wxWindow* parent,
  const wxString& title) const
{
  std::vector<wxExConfigItem> v;

  std::map<long, const wxString> choices;
  choices.insert(std::make_pair(VCS_NONE, _("None")));
  choices.insert(std::make_pair(VCS_GIT, "GIT"));
  choices.insert(std::make_pair(VCS_SVN, "SVN"));
  v.push_back(wxExConfigItem("VCS", choices));

  v.push_back(wxExConfigItem("GIT", CONFIG_FILEPICKERCTRL));
  v.push_back(wxExConfigItem("SVN", CONFIG_FILEPICKERCTRL));
  v.push_back(wxExConfigItem(_("Comparator"), CONFIG_FILEPICKERCTRL));

  return wxExConfigDialog(parent, v, title).ShowModal();
}
#endif

bool wxExVCS::DirExists(const wxFileName& filename) const
{
  switch (GetVCS())
  {
    case VCS_GIT:
      {
      // The .git dir only exists in the root, so check all components.
      wxFileName root(filename.GetPath());

      while (root.DirExists() && root.GetDirCount() > 0)
      {
        wxFileName path(root);
        path.AppendDir(".git");

        if (path.DirExists())
        {
          return true;
        }

        root.RemoveLastDir();
      }
      }
      break;

    case VCS_NONE: break; // prevent wxFAIL

    case VCS_SVN:
      {
      // these cannot be combined, as AppendDir is a void (2.9.1).
      wxFileName path(filename);
      path.AppendDir(".svn");
      return path.DirExists();
      }
      break;

    default: wxFAIL;
  }

  return false;
}

long wxExVCS::Execute()
{
  wxASSERT(m_Command != VCS_NO_COMMAND);

  wxString cwd;
  wxString file;

  if (m_FullPath.empty())
  {
    cwd = wxGetCwd();
    wxSetWorkingDirectory(wxExConfigFirstOf(_("Base folder")));

    if (m_Command == VCS_ADD)
    {
      file = " " + wxExConfigFirstOf(_("Path"));
    }
  }
  else
  {
    if (GetVCS() == VCS_GIT)
    {
      cwd = wxGetCwd();
      wxSetWorkingDirectory(wxFileName(m_FullPath).GetPath());
      file = " \"" + wxFileName(m_FullPath).GetFullName() + "\"";
    }
    else
    {
      file = " \"" + m_FullPath + "\"";
    }
  }

  wxString comment;

  if (m_Command == VCS_COMMIT)
  {
    comment =
      " -m \"" + wxExConfigFirstOf(_("Revision comment")) + "\"";
  }

  wxString subcommand;

  if (UseSubcommand())
  {
    subcommand = wxConfigBase::Get()->Read(_("Subcommand"));

    if (!subcommand.empty())
    {
      subcommand = " " + subcommand;
    }
  }

  wxString flags;

  if (UseFlags())
  {
    flags = wxConfigBase::Get()->Read(_("Flags"));

    if (!flags.empty())
    {
      flags = " " + flags;
    }
  }

  m_CommandWithFlags = m_CommandString + flags;

  wxString vcs_bin;

  switch (GetVCS())
  {
    case VCS_GIT: vcs_bin = wxConfigBase::Get()->Read("GIT", "git"); break;
    case VCS_SVN: vcs_bin = wxConfigBase::Get()->Read("SVN", "svn"); break;
    default: wxFAIL;
  }

  if (vcs_bin.empty())
  {
    wxLogError(GetVCSName() + " " + _("path is empty"));
    return -1;
  }

  const wxString commandline =
    vcs_bin + " " + m_CommandString + subcommand + flags + comment + file;

#if wxUSE_STATUSBAR
  wxExFrame::StatusText(commandline);
#endif

  wxArrayString output;
  wxArrayString errors;
  long retValue;

  if ((retValue = wxExecute(
    commandline,
    output,
    errors)) == -1)
  {
    // See also process, same log is shown.
    wxLogError(_("Cannot execute") + ": " + commandline);
  }
  else
  {
    wxExLog::Get()->Log(commandline);
  }

  if (!cwd.empty())
  {
    wxSetWorkingDirectory(cwd);
  }

  m_Output.clear();

  // First output the errors.
  for (
    size_t i = 0;
    i < errors.GetCount();
    i++)
  {
    m_Output += errors[i] + "\n";
  }

  // Then the normal output, will be empty if there are errors.
  for (
    size_t j = 0;
    j < output.GetCount();
    j++)
  {
    m_Output += output[j] + "\n";
  }

  return retValue;
}

#if wxUSE_GUI
wxStandardID wxExVCS::ExecuteDialog(wxWindow* parent)
{
  if (ShowDialog(parent) == wxID_CANCEL)
  {
    return wxID_CANCEL;
  }

  if (UseFlags())
  {
    wxConfigBase::Get()->Write(m_FlagsKey,
      wxConfigBase::Get()->Read(_("Flags")));
  }

  const auto retValue = Execute();

  return (retValue != -1 ? wxID_OK: wxID_CANCEL);
}
#endif

wxExVCS* wxExVCS::Get(bool createOnDemand)
{
  if (m_Self == NULL && createOnDemand)
  {
    m_Self = new wxExVCS;

    // Add default VCS.
    if (!wxConfigBase::Get()->Exists("VCS"))
    {
      // TODO: Add SVN only if svn bin exists on linux.
      wxConfigBase::Get()->Write("VCS", (long)VCS_SVN);
    }
  }

  return m_Self;
}

wxExVCS::wxExCommand wxExVCS::GetType(int command_id) const
{
  if (command_id > ID_VCS_LOWEST && command_id < ID_VCS_HIGHEST)
  {
    return (wxExCommand)(command_id - ID_VCS_LOWEST);
  }
  else if (command_id > ID_EDIT_VCS_LOWEST && command_id < ID_EDIT_VCS_HIGHEST)
  {
    return (wxExCommand)(command_id - ID_EDIT_VCS_LOWEST);
  }
  else
  {
    wxFAIL;
    return VCS_NO_COMMAND;
  }
}

long wxExVCS::GetVCS() const
{
  return wxConfigBase::Get()->ReadLong("VCS", VCS_SVN);
}

const wxString wxExVCS::GetVCSName() const
{
  wxString text;

  switch (GetVCS())
  {
    case VCS_GIT: text = "GIT"; break;
    case VCS_SVN: text = "SVN"; break;
    default: wxFAIL;
  }

  return text;
}

void wxExVCS::Initialize()
{
  if (Use() && m_Command != VCS_NO_COMMAND)
  {
    switch (GetVCS())
    {
      case VCS_GIT:
        switch (m_Command)
        {
          case VCS_ADD:      m_CommandString = "add"; break;
          case VCS_BLAME:    m_CommandString = "blame"; break;
          case VCS_CAT:      break;
          case VCS_COMMIT:   m_CommandString = "commit"; break;
          case VCS_DIFF:     m_CommandString = "diff"; break;
          case VCS_HELP:     m_CommandString = "help"; break;
          case VCS_INFO:     break;
          case VCS_LOG:      m_CommandString = "log"; break;
          case VCS_LS:       break;
          case VCS_PROPLIST: break;
          case VCS_PROPSET:  break;
          case VCS_PUSH:     m_CommandString = "push"; break;
          case VCS_REVERT:   m_CommandString = "revert"; break;
          case VCS_SHOW:     m_CommandString = "show"; break;
          case VCS_STAT:     m_CommandString = "status"; break;
          case VCS_UPDATE:   m_CommandString = "update"; break;
          default:
            wxFAIL;
            break;
        }
        break;

      case VCS_SVN:
        switch (m_Command)
        {
          case VCS_ADD:      m_CommandString = "add"; break;
          case VCS_BLAME:    m_CommandString = "blame"; break;
          case VCS_CAT:      m_CommandString = "cat"; break;
          case VCS_COMMIT:   m_CommandString = "commit"; break;
          case VCS_DIFF:     m_CommandString = "diff"; break;
          case VCS_HELP:     m_CommandString = "help"; break;
          case VCS_INFO:     m_CommandString = "info"; break;
          case VCS_LOG:      m_CommandString = "log"; break;
          case VCS_LS:       m_CommandString = "ls"; break;
          case VCS_PROPLIST: m_CommandString = "proplist"; break;
          case VCS_PROPSET:  m_CommandString = "propset"; break;
          case VCS_PUSH:     break;
          case VCS_REVERT:   m_CommandString = "revert"; break;
          case VCS_SHOW:     break;
          case VCS_STAT:     m_CommandString = "stat"; break;
          case VCS_UPDATE:   m_CommandString = "update"; break;
          default:
            wxFAIL;
            break;
        }
        break;

      default: wxFAIL;
    }

    m_Caption = GetVCSName() + " " + m_CommandString;

    // Currently no flags, as no command was executed.
    m_CommandWithFlags = m_CommandString;

    // Use general key.
    m_FlagsKey = wxString::Format("cvsflags/name%d", m_Command);
  }

  m_Output.clear();
}

#if wxUSE_GUI
wxStandardID wxExVCS::Request(wxWindow* parent)
{
  wxStandardID retValue;

  if ((retValue = ExecuteDialog(parent)) == wxID_OK)
  {
    ShowOutput(parent);
  }

  return retValue;
}
#endif

wxExVCS* wxExVCS::Set(wxExVCS* vcs)
{
  wxExVCS* old = m_Self;
  m_Self = vcs;
  return old;
}

#if wxUSE_GUI
int wxExVCS::ShowDialog(wxWindow* parent)
{
  std::vector<wxExConfigItem> v;

  if (m_Command == VCS_COMMIT)
  {
    v.push_back(wxExConfigItem(
      _("Revision comment"),
      CONFIG_COMBOBOX,
      wxEmptyString,
      true)); // required
  }

  if (m_FullPath.empty() && m_Command != VCS_HELP)
  {
    v.push_back(wxExConfigItem(
      _("Base folder"),
      CONFIG_COMBOBOXDIR,
      wxEmptyString,
      true,
      1000));

    if (m_Command == VCS_ADD)
    {
      v.push_back(wxExConfigItem(
        _("Path"),
        CONFIG_COMBOBOX,
        wxEmptyString,
        true)); // required
    }
  }

  if (UseFlags())
  {
    wxConfigBase::Get()->Write(
      _("Flags"),
      wxConfigBase::Get()->Read(m_FlagsKey));

    v.push_back(wxExConfigItem(_("Flags")));
  }

  if (UseSubcommand())
  {
    v.push_back(wxExConfigItem(_("Subcommand")));
  }

  return wxExConfigDialog(parent,
    v,
    m_Caption).ShowModal();
}
#endif

#if wxUSE_GUI
void wxExVCS::ShowOutput(wxWindow* parent) const
{
  wxString caption = m_Caption;

  if (m_Command != VCS_HELP)
  {
    caption += " " + (!m_FullPath.empty() ?
      wxFileName(m_FullPath).GetFullName():
      wxExConfigFirstOf(_("Base folder")));
  }

  // Create a dialog for contents.
  if (m_STCEntryDialog == NULL)
  {
    m_STCEntryDialog = new wxExSTCEntryDialog(
      parent,
      caption,
      m_Output,
      wxEmptyString,
      wxOK,
      wxID_ANY,
      wxDefaultPosition,
      wxSize(350, 50));
  }
  else
  {
    m_STCEntryDialog->SetText(m_Output);
    m_STCEntryDialog->SetTitle(caption);
  }

  // Add a lexer if we specified a path, asked for cat or blame
  // and there is a lexer.
  if (
    !m_FullPath.empty() &&
    (m_Command == VCS_CAT || m_Command == VCS_BLAME))
  {
    const wxExFileName fn(m_FullPath);

    if (fn.GetLexer().IsOk())
    {
      m_STCEntryDialog->SetLexer(fn.GetLexer().GetScintillaLexer());
    }
  }
  else
  {
    m_STCEntryDialog->SetLexer(wxEmptyString);
  }

  m_STCEntryDialog->Show();
}
#endif

bool wxExVCS::Use() const
{
  return GetVCS() != VCS_NONE;
}

bool wxExVCS::UseFlags() const
{
  return m_Command != VCS_UPDATE && m_Command != VCS_HELP;
}

bool wxExVCS::UseSubcommand() const
{
  return m_Command == VCS_HELP;
}
<commit_msg>added diff lexer for VCS_DIFF<commit_after>/******************************************************************************\
* File:          vcs.cpp
* Purpose:       Implementation of wxExVCS class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/config.h>
#include <wx/extension/vcs.h>
#include <wx/extension/configdlg.h>
#include <wx/extension/defs.h>
#include <wx/extension/frame.h>
#include <wx/extension/log.h>
#include <wx/extension/stcdlg.h>
#include <wx/extension/util.h>

wxExVCS* wxExVCS::m_Self = NULL;
#if wxUSE_GUI
wxExSTCEntryDialog* wxExVCS::m_STCEntryDialog = NULL;
#endif

wxExVCS::wxExVCS()
  : m_Command(VCS_NO_COMMAND)
  , m_FullPath(wxEmptyString)
{
  Initialize();
}

wxExVCS::wxExVCS(int command_id, const wxString& fullpath)
  : m_Command(GetType(command_id))
  , m_FullPath(fullpath)
{
  Initialize();
}

wxExVCS::wxExVCS(wxExCommand type, const wxString& fullpath)
  : m_Command(type)
  , m_FullPath(fullpath)
{
  Initialize();
}

#if wxUSE_GUI
int wxExVCS::ConfigDialog(
  wxWindow* parent,
  const wxString& title) const
{
  std::vector<wxExConfigItem> v;

  std::map<long, const wxString> choices;
  choices.insert(std::make_pair(VCS_NONE, _("None")));
  choices.insert(std::make_pair(VCS_GIT, "GIT"));
  choices.insert(std::make_pair(VCS_SVN, "SVN"));
  v.push_back(wxExConfigItem("VCS", choices));

  v.push_back(wxExConfigItem("GIT", CONFIG_FILEPICKERCTRL));
  v.push_back(wxExConfigItem("SVN", CONFIG_FILEPICKERCTRL));
  v.push_back(wxExConfigItem(_("Comparator"), CONFIG_FILEPICKERCTRL));

  return wxExConfigDialog(parent, v, title).ShowModal();
}
#endif

bool wxExVCS::DirExists(const wxFileName& filename) const
{
  switch (GetVCS())
  {
    case VCS_GIT:
      {
      // The .git dir only exists in the root, so check all components.
      wxFileName root(filename.GetPath());

      while (root.DirExists() && root.GetDirCount() > 0)
      {
        wxFileName path(root);
        path.AppendDir(".git");

        if (path.DirExists())
        {
          return true;
        }

        root.RemoveLastDir();
      }
      }
      break;

    case VCS_NONE: break; // prevent wxFAIL

    case VCS_SVN:
      {
      // these cannot be combined, as AppendDir is a void (2.9.1).
      wxFileName path(filename);
      path.AppendDir(".svn");
      return path.DirExists();
      }
      break;

    default: wxFAIL;
  }

  return false;
}

long wxExVCS::Execute()
{
  wxASSERT(m_Command != VCS_NO_COMMAND);

  wxString cwd;
  wxString file;

  if (m_FullPath.empty())
  {
    cwd = wxGetCwd();
    wxSetWorkingDirectory(wxExConfigFirstOf(_("Base folder")));

    if (m_Command == VCS_ADD)
    {
      file = " " + wxExConfigFirstOf(_("Path"));
    }
  }
  else
  {
    if (GetVCS() == VCS_GIT)
    {
      cwd = wxGetCwd();
      wxSetWorkingDirectory(wxFileName(m_FullPath).GetPath());
      file = " \"" + wxFileName(m_FullPath).GetFullName() + "\"";
    }
    else
    {
      file = " \"" + m_FullPath + "\"";
    }
  }

  wxString comment;

  if (m_Command == VCS_COMMIT)
  {
    comment =
      " -m \"" + wxExConfigFirstOf(_("Revision comment")) + "\"";
  }

  wxString subcommand;

  if (UseSubcommand())
  {
    subcommand = wxConfigBase::Get()->Read(_("Subcommand"));

    if (!subcommand.empty())
    {
      subcommand = " " + subcommand;
    }
  }

  wxString flags;

  if (UseFlags())
  {
    flags = wxConfigBase::Get()->Read(_("Flags"));

    if (!flags.empty())
    {
      flags = " " + flags;
    }
  }

  m_CommandWithFlags = m_CommandString + flags;

  wxString vcs_bin;

  switch (GetVCS())
  {
    case VCS_GIT: vcs_bin = wxConfigBase::Get()->Read("GIT", "git"); break;
    case VCS_SVN: vcs_bin = wxConfigBase::Get()->Read("SVN", "svn"); break;
    default: wxFAIL;
  }

  if (vcs_bin.empty())
  {
    wxLogError(GetVCSName() + " " + _("path is empty"));
    return -1;
  }

  const wxString commandline =
    vcs_bin + " " + m_CommandString + subcommand + flags + comment + file;

#if wxUSE_STATUSBAR
  wxExFrame::StatusText(commandline);
#endif

  wxArrayString output;
  wxArrayString errors;
  long retValue;

  if ((retValue = wxExecute(
    commandline,
    output,
    errors)) == -1)
  {
    // See also process, same log is shown.
    wxLogError(_("Cannot execute") + ": " + commandline);
  }
  else
  {
    wxExLog::Get()->Log(commandline);
  }

  if (!cwd.empty())
  {
    wxSetWorkingDirectory(cwd);
  }

  m_Output.clear();

  // First output the errors.
  for (
    size_t i = 0;
    i < errors.GetCount();
    i++)
  {
    m_Output += errors[i] + "\n";
  }

  // Then the normal output, will be empty if there are errors.
  for (
    size_t j = 0;
    j < output.GetCount();
    j++)
  {
    m_Output += output[j] + "\n";
  }

  return retValue;
}

#if wxUSE_GUI
wxStandardID wxExVCS::ExecuteDialog(wxWindow* parent)
{
  if (ShowDialog(parent) == wxID_CANCEL)
  {
    return wxID_CANCEL;
  }

  if (UseFlags())
  {
    wxConfigBase::Get()->Write(m_FlagsKey,
      wxConfigBase::Get()->Read(_("Flags")));
  }

  const auto retValue = Execute();

  return (retValue != -1 ? wxID_OK: wxID_CANCEL);
}
#endif

wxExVCS* wxExVCS::Get(bool createOnDemand)
{
  if (m_Self == NULL && createOnDemand)
  {
    m_Self = new wxExVCS;

    // Add default VCS.
    if (!wxConfigBase::Get()->Exists("VCS"))
    {
      // TODO: Add SVN only if svn bin exists on linux.
      wxConfigBase::Get()->Write("VCS", (long)VCS_SVN);
    }
  }

  return m_Self;
}

wxExVCS::wxExCommand wxExVCS::GetType(int command_id) const
{
  if (command_id > ID_VCS_LOWEST && command_id < ID_VCS_HIGHEST)
  {
    return (wxExCommand)(command_id - ID_VCS_LOWEST);
  }
  else if (command_id > ID_EDIT_VCS_LOWEST && command_id < ID_EDIT_VCS_HIGHEST)
  {
    return (wxExCommand)(command_id - ID_EDIT_VCS_LOWEST);
  }
  else
  {
    wxFAIL;
    return VCS_NO_COMMAND;
  }
}

long wxExVCS::GetVCS() const
{
  return wxConfigBase::Get()->ReadLong("VCS", VCS_SVN);
}

const wxString wxExVCS::GetVCSName() const
{
  wxString text;

  switch (GetVCS())
  {
    case VCS_GIT: text = "GIT"; break;
    case VCS_SVN: text = "SVN"; break;
    default: wxFAIL;
  }

  return text;
}

void wxExVCS::Initialize()
{
  if (Use() && m_Command != VCS_NO_COMMAND)
  {
    switch (GetVCS())
    {
      case VCS_GIT:
        switch (m_Command)
        {
          case VCS_ADD:      m_CommandString = "add"; break;
          case VCS_BLAME:    m_CommandString = "blame"; break;
          case VCS_CAT:      break;
          case VCS_COMMIT:   m_CommandString = "commit"; break;
          case VCS_DIFF:     m_CommandString = "diff"; break;
          case VCS_HELP:     m_CommandString = "help"; break;
          case VCS_INFO:     break;
          case VCS_LOG:      m_CommandString = "log"; break;
          case VCS_LS:       break;
          case VCS_PROPLIST: break;
          case VCS_PROPSET:  break;
          case VCS_PUSH:     m_CommandString = "push"; break;
          case VCS_REVERT:   m_CommandString = "revert"; break;
          case VCS_SHOW:     m_CommandString = "show"; break;
          case VCS_STAT:     m_CommandString = "status"; break;
          case VCS_UPDATE:   m_CommandString = "update"; break;
          default:
            wxFAIL;
            break;
        }
        break;

      case VCS_SVN:
        switch (m_Command)
        {
          case VCS_ADD:      m_CommandString = "add"; break;
          case VCS_BLAME:    m_CommandString = "blame"; break;
          case VCS_CAT:      m_CommandString = "cat"; break;
          case VCS_COMMIT:   m_CommandString = "commit"; break;
          case VCS_DIFF:     m_CommandString = "diff"; break;
          case VCS_HELP:     m_CommandString = "help"; break;
          case VCS_INFO:     m_CommandString = "info"; break;
          case VCS_LOG:      m_CommandString = "log"; break;
          case VCS_LS:       m_CommandString = "ls"; break;
          case VCS_PROPLIST: m_CommandString = "proplist"; break;
          case VCS_PROPSET:  m_CommandString = "propset"; break;
          case VCS_PUSH:     break;
          case VCS_REVERT:   m_CommandString = "revert"; break;
          case VCS_SHOW:     break;
          case VCS_STAT:     m_CommandString = "stat"; break;
          case VCS_UPDATE:   m_CommandString = "update"; break;
          default:
            wxFAIL;
            break;
        }
        break;

      default: wxFAIL;
    }

    m_Caption = GetVCSName() + " " + m_CommandString;

    // Currently no flags, as no command was executed.
    m_CommandWithFlags = m_CommandString;

    // Use general key.
    m_FlagsKey = wxString::Format("cvsflags/name%d", m_Command);
  }

  m_Output.clear();
}

#if wxUSE_GUI
wxStandardID wxExVCS::Request(wxWindow* parent)
{
  wxStandardID retValue;

  if ((retValue = ExecuteDialog(parent)) == wxID_OK)
  {
    ShowOutput(parent);
  }

  return retValue;
}
#endif

wxExVCS* wxExVCS::Set(wxExVCS* vcs)
{
  wxExVCS* old = m_Self;
  m_Self = vcs;
  return old;
}

#if wxUSE_GUI
int wxExVCS::ShowDialog(wxWindow* parent)
{
  std::vector<wxExConfigItem> v;

  if (m_Command == VCS_COMMIT)
  {
    v.push_back(wxExConfigItem(
      _("Revision comment"),
      CONFIG_COMBOBOX,
      wxEmptyString,
      true)); // required
  }

  if (m_FullPath.empty() && m_Command != VCS_HELP)
  {
    v.push_back(wxExConfigItem(
      _("Base folder"),
      CONFIG_COMBOBOXDIR,
      wxEmptyString,
      true,
      1000));

    if (m_Command == VCS_ADD)
    {
      v.push_back(wxExConfigItem(
        _("Path"),
        CONFIG_COMBOBOX,
        wxEmptyString,
        true)); // required
    }
  }

  if (UseFlags())
  {
    wxConfigBase::Get()->Write(
      _("Flags"),
      wxConfigBase::Get()->Read(m_FlagsKey));

    v.push_back(wxExConfigItem(_("Flags")));
  }

  if (UseSubcommand())
  {
    v.push_back(wxExConfigItem(_("Subcommand")));
  }

  return wxExConfigDialog(parent,
    v,
    m_Caption).ShowModal();
}
#endif

#if wxUSE_GUI
void wxExVCS::ShowOutput(wxWindow* parent) const
{
  wxString caption = m_Caption;

  if (m_Command != VCS_HELP)
  {
    caption += " " + (!m_FullPath.empty() ?
      wxFileName(m_FullPath).GetFullName():
      wxExConfigFirstOf(_("Base folder")));
  }

  // Create a dialog for contents.
  if (m_STCEntryDialog == NULL)
  {
    m_STCEntryDialog = new wxExSTCEntryDialog(
      parent,
      caption,
      m_Output,
      wxEmptyString,
      wxOK,
      wxID_ANY,
      wxDefaultPosition,
      wxSize(350, 50));
  }
  else
  {
    m_STCEntryDialog->SetText(m_Output);
    m_STCEntryDialog->SetTitle(caption);
  }

  // Add a lexer when appropriate.
  if (
    !m_FullPath.empty() &&
    (m_Command == VCS_CAT || m_Command == VCS_BLAME))
  {
    const wxExFileName fn(m_FullPath);

    if (fn.GetLexer().IsOk())
    {
      m_STCEntryDialog->SetLexer(fn.GetLexer().GetScintillaLexer());
    }
  }
  else if (m_Command == VCS_DIFF)
  {
    m_STCEntryDialog->SetLexer("diff");
  }
  else
  {
    m_STCEntryDialog->SetLexer(wxEmptyString);
  }

  m_STCEntryDialog->Show();
}
#endif

bool wxExVCS::Use() const
{
  return GetVCS() != VCS_NONE;
}

bool wxExVCS::UseFlags() const
{
  return m_Command != VCS_UPDATE && m_Command != VCS_HELP;
}

bool wxExVCS::UseSubcommand() const
{
  return m_Command == VCS_HELP;
}
<|endoftext|>


<commit_before><commit_msg>It executes right but it doesnt make sens, need to investigate<commit_after><|endoftext|>


<commit_before>
/**
  Copyright(c) 2015 - 2017 Denis Blank <denis.blank at outlook dot com>

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files(the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions :

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
**/

#ifndef TEST_CONTINUABLE_HPP__
#define TEST_CONTINUABLE_HPP__

#include <cassert>

#include <gtest/gtest.h>

#include <functional>

#include <continuable/continuable-base.hpp>
#include <continuable/continuable-testing.hpp>
#include <continuable/continuable.hpp>

using cti::detail::traits::identity;

inline auto to_hint(identity<> /*hint*/) {
  return identity<void>{};
}
template <typename... Args>
auto to_hint(identity<Args...> hint) {
  return hint;
}

template <typename... Args>
auto supplier_of(Args&&... args) {
  return [values = std::make_tuple(std::forward<Args>(args)...)](
      auto&& promise) mutable {
    cti::detail::traits::unpack(std::move(values), [&](auto&&... passed) {
      promise.set_value(std::forward<decltype(passed)>(passed)...);
    });
  };
}

template <typename Arg>
auto exception_supplier_of(Arg&& arg) {
  return [arg = std::forward<Arg>(arg)](auto&& promise) mutable {
    promise.set_exception(std::move(arg));
  };
}

template <typename Provider>
class continuation_provider : public ::testing::Test, public Provider {
public:
  template <typename T>
  auto invoke(T&& type) {
    return this->make(identity<>{}, identity<void>{},
                      [type = std::forward<T>(type)](auto&& promise) mutable {
                        promise.set_value();
                      });
  }

  template <typename... Args>
  auto supply(Args&&... args) {
    identity<std::decay_t<Args>...> arg_types;
    auto hint_types = to_hint(arg_types);

    return this->make(arg_types, hint_types,
                      supplier_of(std::forward<Args>(args)...));
  }

  template <typename Arg>
  auto supply_exception(Arg&& arg) {
    identity<> arg_types;
    auto hint_types = to_hint(arg_types);

    return this->make(arg_types, hint_types,
                      exception_supplier_of(std::forward<Arg>(arg)));
  }
};

inline auto empty_caller() {
  return [](auto&& promise) { promise.set_value(); };
}

inline auto empty_continuable() {
  return cti::make_continuable<void>(empty_caller());
}

struct provide_copyable {
  template <typename... Args, typename... Hint, typename T>
  auto make(identity<Args...>, identity<Hint...>, T&& callback) {
    return cti::make_continuable<Hint...>(std::forward<T>(callback));
  }
};

struct provide_unique {
  template <typename... Args, typename... Hint, typename T>
  auto make(identity<Args...>, identity<Hint...>, T&& callback) {
    return cti::make_continuable<Hint...>([
      callback = std::forward<T>(callback), guard = std::make_unique<int>(0)
    ](auto&&... args) mutable {
      (void)(*guard);
      return std::move(callback)(std::forward<decltype(args)>(args)...);
    });
  }
};

template <template <typename...> class Erasure>
struct provide_erasure {
  template <typename... Args, typename... Hint, typename T>
  Erasure<Args...> make(identity<Args...>, identity<Hint...>, T&& callback) {
    return cti::make_continuable<Hint...>(std::forward<T>(callback));
  }
};

template <typename Provider>
struct provide_continuation_and_left {
  Provider provider_;

  template <typename... Args, typename... Hint, typename T>
  auto make(identity<Args...> args, identity<Hint...> hint, T&& callback) {
    return empty_continuable() &&
           provider_.make(args, hint, std::forward<T>(callback));
  }
};

template <typename Provider>
struct provide_continuation_and_right {
  Provider provider_;

  template <typename... Args, typename... Hint, typename T>
  auto make(identity<Args...> args, identity<Hint...> hint, T&& callback) {
    return provider_.make(args, hint, std::forward<T>(callback)) &&
           empty_continuable();
  }
};

template <typename Provider>
struct provide_continuation_seq_right {
  Provider provider_;

  template <typename... Args, typename... Hint, typename T>
  auto make(identity<Args...> args, identity<Hint...> hint, T&& callback) {
    return provider_.make(args, hint, std::forward<T>(callback)) >>
           empty_continuable();
  }
};

// clang-format off
// Feel free to uncomment more tests, however this will increase the
// build time significantly.
using single_types = ::testing::Types<
#if UNIT_TEST_STEP == 0
  provide_copyable
  // provide_erasure<cti::continuable>,
  // provide_erasure<cti::unique_continuable>
#elif UNIT_TEST_STEP == 1
  // Some instantiations out commented for compilation speed reasons
  // provide_continuation_and_left<provide_copyable>,
  provide_continuation_and_left<provide_unique>
  // provide_continuation_and_left<provide_erasure<cti::continuable>>,
  // provide_continuation_and_left<provide_erasure<cti::unique_continuable>>,
  // provide_continuation_and_right<provide_copyable>,
  // provide_continuation_and_right<provide_unique>,
  // provide_continuation_and_left<provide_erasure<cti::continuable>>
#elif UNIT_TEST_STEP == 2
  provide_continuation_and_left<provide_erasure<cti::unique_continuable>>
#elif UNIT_TEST_STEP == 3
  provide_unique
#elif UNIT_TEST_STEP == 4
//#define NO_ERASURE_TESTS
//#define NO_FUTURE_TESTS
//  provide_erasure<cxx_continuable>,
//  provide_erasure<cxx_unique_continuable>
  provide_continuation_seq_right<provide_unique>
#endif
>;
// clang-format on

struct tag1 {};
struct tag2 {};
struct tag3 {};

template <typename Provider>
struct single_dimension_tests : continuation_provider<Provider> {};

TYPED_TEST_CASE(single_dimension_tests, single_types);

template <typename T>
auto make_step(T* me, unsigned& current, unsigned step) {
  return me->invoke([=]() mutable {
    ASSERT_EQ(step, current);
    ++current;
  });
}

#endif // TEST_CONTINUABLE_HPP__
<commit_msg>Attempt to fix the travis gcc build<commit_after>
/**
  Copyright(c) 2015 - 2017 Denis Blank <denis.blank at outlook dot com>

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files(the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions :

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
**/

#ifndef TEST_CONTINUABLE_HPP__
#define TEST_CONTINUABLE_HPP__

#include <cassert>

#include <gtest/gtest.h>

#include <functional>

#include <continuable/continuable-base.hpp>
#include <continuable/continuable-testing.hpp>
#include <continuable/continuable.hpp>

using cti::detail::traits::identity;

inline auto to_hint(identity<> /*hint*/) {
  return identity<void>{};
}
template <typename... Args>
auto to_hint(identity<Args...> hint) {
  return hint;
}

template <typename... Args>
auto supplier_of(Args&&... args) {
  return [values = std::make_tuple(std::forward<Args>(args)...)](
      auto&& promise) mutable {
    cti::detail::traits::unpack(std::move(values), [&](auto&&... passed) {
      promise.set_value(std::forward<decltype(passed)>(passed)...);
    });
  };
}

template <typename Arg>
auto exception_supplier_of(Arg&& arg) {
  return [arg = std::forward<Arg>(arg)](auto&& promise) mutable {
    promise.set_exception(std::move(arg));
  };
}

template <typename Provider>
class continuation_provider : public ::testing::Test, public Provider {
public:
  template <typename T>
  auto invoke(T&& type) {
    return this->make(identity<>{}, identity<void>{},
                      [type = std::forward<T>(type)](auto&& promise) mutable {
                        promise.set_value();
                      });
  }

  template <typename... Args>
  auto supply(Args&&... args) {
    identity<std::decay_t<Args>...> arg_types;
    auto hint_types = to_hint(arg_types);

    return this->make(arg_types, hint_types,
                      supplier_of(std::forward<Args>(args)...));
  }

  template <typename Arg>
  auto supply_exception(Arg&& arg) {
    identity<> arg_types;
    auto hint_types = to_hint(arg_types);

    return this->make(arg_types, hint_types,
                      exception_supplier_of(std::forward<Arg>(arg)));
  }
};

inline auto empty_caller() {
  return [](auto&& promise) { promise.set_value(); };
}

inline auto empty_continuable() {
  return cti::make_continuable<void>(empty_caller());
}

struct provide_copyable {
  template <typename... Args, typename... Hint, typename T>
  auto make(identity<Args...>, identity<Hint...>, T&& callback) {
    return cti::make_continuable<Hint...>(std::forward<T>(callback));
  }
};

struct provide_unique {
  template <typename... Args, typename... Hint, typename T>
  auto make(identity<Args...>, identity<Hint...>, T&& callback) {
    return cti::make_continuable<Hint...>([
      callback = std::forward<T>(callback), guard = std::make_unique<int>(0)
    ](auto&&... args) mutable {
      (void)(*guard);
      return std::move(callback)(std::forward<decltype(args)>(args)...);
    });
  }
};

template <template <typename...> class Erasure>
struct provide_erasure {
  template <typename... Args, typename... Hint, typename T>
  Erasure<Args...> make(identity<Args...>, identity<Hint...>, T&& callback) {
    return cti::make_continuable<Hint...>(std::forward<T>(callback));
  }
};

template <typename Provider>
struct provide_continuation_and_left {
  Provider provider_;

  template <typename... Args, typename... Hint, typename T>
  auto make(identity<Args...> args, identity<Hint...> hint, T&& callback) {
    return empty_continuable() &&
           provider_.make(args, hint, std::forward<T>(callback));
  }
};

template <typename Provider>
struct provide_continuation_and_right {
  Provider provider_;

  template <typename... Args, typename... Hint, typename T>
  auto make(identity<Args...> args, identity<Hint...> hint, T&& callback) {
    return provider_.make(args, hint, std::forward<T>(callback)) &&
           empty_continuable();
  }
};

template <typename Provider>
struct provide_continuation_seq_right {
  Provider provider_;

  template <typename... Args, typename... Hint, typename T>
  auto make(identity<Args...> args, identity<Hint...> hint, T&& callback) {
    return provider_.make(args, hint, std::forward<T>(callback)) >>
           empty_continuable();
  }
};

// clang-format off
// Feel free to uncomment more tests, however this will increase the
// build time significantly.
using single_types = ::testing::Types<
#if UNIT_TEST_STEP == 0
  provide_copyable
  // provide_erasure<cti::continuable>,
  // provide_erasure<cti::unique_continuable>
#elif UNIT_TEST_STEP == 1
  // Some instantiations out commented for compilation speed reasons
  // provide_continuation_and_left<provide_copyable>,
  provide_continuation_and_left<provide_unique>
  // provide_continuation_and_left<provide_erasure<cti::continuable>>,
  // provide_continuation_and_left<provide_erasure<cti::unique_continuable>>,
  // provide_continuation_and_right<provide_copyable>,
  // provide_continuation_and_right<provide_unique>,
  // provide_continuation_and_left<provide_erasure<cti::continuable>>
#elif UNIT_TEST_STEP == 2
  provide_continuation_and_right<provide_unique>
#elif UNIT_TEST_STEP == 3
  provide_unique
#elif UNIT_TEST_STEP == 4
//#define NO_ERASURE_TESTS
//#define NO_FUTURE_TESTS
//  provide_erasure<cxx_continuable>,
//  provide_erasure<cxx_unique_continuable>
  provide_continuation_seq_right<provide_unique>
#endif
>;
// clang-format on

struct tag1 {};
struct tag2 {};
struct tag3 {};

template <typename Provider>
struct single_dimension_tests : continuation_provider<Provider> {};

TYPED_TEST_CASE(single_dimension_tests, single_types);

template <typename T>
auto make_step(T* me, unsigned& current, unsigned step) {
  return me->invoke([=]() mutable {
    ASSERT_EQ(step, current);
    ++current;
  });
}

#endif // TEST_CONTINUABLE_HPP__
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ Includes -----------------------------------
#include <limits>
#include <utility>

// Local Includes -----------------------------------
#include "libmesh/elem.h"
#include "libmesh/topology_map.h"
#include "libmesh/mesh_base.h"
#include "libmesh/node.h"
#include "libmesh/parallel.h"

namespace libMesh
{

//--------------------------------------------------------------------------
void TopologyMap::init(MeshBase& mesh)
{
  // This function must be run on all processors at once
  // for non-serial meshes
  if (!mesh.is_serial())
    libmesh_parallel_only(mesh.comm());

  START_LOG("init()", "TopologyMap");

  // Clear the old map
  _map.clear();

  this->fill(mesh);

  STOP_LOG("init()", "TopologyMap");
}

void TopologyMap::add_node(const Node& mid_node,
                           const std::vector<std::pair<dof_id_type, dof_id_type> >& bracketing_nodes)
{
  const dof_id_type mid_node_id = mid_node.id();

  libmesh_assert_not_equal_to(mid_node_id, DofObject::invalid_id);

  for (unsigned int i=0; i != bracketing_nodes.size(); ++i)
    {
      const dof_id_type id1 = bracketing_nodes[i].first;
      const dof_id_type id2 = bracketing_nodes[i].second;
      const dof_id_type lower_id = std::min(id1, id2);
      const dof_id_type upper_id = std::max(id1, id2);

      // We should never be inserting inconsistent data
#ifndef NDEBUG
      map_type::iterator it =
        _map.find(std::make_pair(lower_id, upper_id));

      if (it != _map.end())
        libmesh_assert_equal_to (it->second, mid_node_id);
#endif

      this->_map.insert(std::make_pair(std::make_pair(lower_id, upper_id),
                                       mid_node_id));

    }
}

dof_id_type TopologyMap::find(const std::vector<std::pair<dof_id_type, dof_id_type> >& bracketing_nodes) const
{
  dof_id_type new_node_id = DofObject::invalid_id;

  for (unsigned int i = 0; i != bracketing_nodes.size(); ++i)
    {
      const dof_id_type lower_id = std::min(bracketing_nodes[i].first,
                                            bracketing_nodes[i].second);
      const dof_id_type upper_id = std::max(bracketing_nodes[i].first,
                                            bracketing_nodes[i].second);

      const dof_id_type possible_new_node_id =
        this->find(lower_id, upper_id);

      if (possible_new_node_id != DofObject::invalid_id)
        {
          // If we found a node already, but we're still here, it's to
          // debug map consistency: we'd better always find the same
          // node
          if (new_node_id != DofObject::invalid_id)
            libmesh_assert_equal_to (new_node_id, possible_new_node_id);

          new_node_id = possible_new_node_id;
        }

      // If we're not debugging map consistency then we can quit as
      // soon as we find a node
#ifdef NDEBUG
      if (new_node_id != DofObject::invalid_id)
        break;
#endif
    }
  return new_node_id;
}

dof_id_type TopologyMap::find(dof_id_type bracket_node1,
                              dof_id_type bracket_node2) const
{
  const dof_id_type lower_id = std::min(bracket_node1, bracket_node2);
  const dof_id_type upper_id = std::max(bracket_node1, bracket_node2);

  map_type::const_iterator it =
    _map.find(std::make_pair(lower_id, upper_id));

  if (it == _map.end())
    return DofObject::invalid_id;

  libmesh_assert_not_equal_to (it->second, DofObject::invalid_id);

  return it->second;
}

void TopologyMap::fill(const MeshBase& mesh)
{
  // Populate the nodes map
  MeshBase::const_element_iterator
    it = mesh.elements_begin(),
    end = mesh.elements_end();
  for (; it != end; ++it)
    {
      const Elem* elem = *it;

      // We only need to add nodes which might be added during mesh
      // refinement; this means they need to be child nodes.
      if (!elem->has_children())
        continue;

      for (unsigned int c = 0; c != elem->n_children(); ++c)
        {
          if (elem->child(c)->is_remote())
            continue;

          for (unsigned int n = 0; n != elem->n_nodes_in_child(c); ++n)
            {
              const std::vector<std::pair<dof_id_type, dof_id_type> >
                bracketing_nodes = elem->bracketing_nodes(c,n);

              this->add_node(*elem->child(c)->get_node(n),
                             bracketing_nodes);
            }
        }
    }
}

} // namespace libMesh
<commit_msg>fix for --disable-amr<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ Includes -----------------------------------
#include <limits>
#include <utility>

// Local Includes -----------------------------------
#include "libmesh/elem.h"
#include "libmesh/topology_map.h"
#include "libmesh/mesh_base.h"
#include "libmesh/node.h"
#include "libmesh/parallel.h"

namespace libMesh
{

//--------------------------------------------------------------------------
void TopologyMap::init(MeshBase& mesh)
{
  // This function must be run on all processors at once
  // for non-serial meshes
  if (!mesh.is_serial())
    libmesh_parallel_only(mesh.comm());

  START_LOG("init()", "TopologyMap");

  // Clear the old map
  _map.clear();

  this->fill(mesh);

  STOP_LOG("init()", "TopologyMap");
}

void TopologyMap::add_node(const Node& mid_node,
                           const std::vector<std::pair<dof_id_type, dof_id_type> >& bracketing_nodes)
{
  const dof_id_type mid_node_id = mid_node.id();

  libmesh_assert_not_equal_to(mid_node_id, DofObject::invalid_id);

  for (unsigned int i=0; i != bracketing_nodes.size(); ++i)
    {
      const dof_id_type id1 = bracketing_nodes[i].first;
      const dof_id_type id2 = bracketing_nodes[i].second;
      const dof_id_type lower_id = std::min(id1, id2);
      const dof_id_type upper_id = std::max(id1, id2);

      // We should never be inserting inconsistent data
#ifndef NDEBUG
      map_type::iterator it =
        _map.find(std::make_pair(lower_id, upper_id));

      if (it != _map.end())
        libmesh_assert_equal_to (it->second, mid_node_id);
#endif

      this->_map.insert(std::make_pair(std::make_pair(lower_id, upper_id),
                                       mid_node_id));

    }
}

dof_id_type TopologyMap::find(const std::vector<std::pair<dof_id_type, dof_id_type> >& bracketing_nodes) const
{
  dof_id_type new_node_id = DofObject::invalid_id;

  for (unsigned int i = 0; i != bracketing_nodes.size(); ++i)
    {
      const dof_id_type lower_id = std::min(bracketing_nodes[i].first,
                                            bracketing_nodes[i].second);
      const dof_id_type upper_id = std::max(bracketing_nodes[i].first,
                                            bracketing_nodes[i].second);

      const dof_id_type possible_new_node_id =
        this->find(lower_id, upper_id);

      if (possible_new_node_id != DofObject::invalid_id)
        {
          // If we found a node already, but we're still here, it's to
          // debug map consistency: we'd better always find the same
          // node
          if (new_node_id != DofObject::invalid_id)
            libmesh_assert_equal_to (new_node_id, possible_new_node_id);

          new_node_id = possible_new_node_id;
        }

      // If we're not debugging map consistency then we can quit as
      // soon as we find a node
#ifdef NDEBUG
      if (new_node_id != DofObject::invalid_id)
        break;
#endif
    }
  return new_node_id;
}

dof_id_type TopologyMap::find(dof_id_type bracket_node1,
                              dof_id_type bracket_node2) const
{
  const dof_id_type lower_id = std::min(bracket_node1, bracket_node2);
  const dof_id_type upper_id = std::max(bracket_node1, bracket_node2);

  map_type::const_iterator it =
    _map.find(std::make_pair(lower_id, upper_id));

  if (it == _map.end())
    return DofObject::invalid_id;

  libmesh_assert_not_equal_to (it->second, DofObject::invalid_id);

  return it->second;
}

#ifdef LIBMESH_ENABLE_AMR

void TopologyMap::fill(const MeshBase& mesh)
{
  // Populate the nodes map
  MeshBase::const_element_iterator
    it = mesh.elements_begin(),
    end = mesh.elements_end();
  for (; it != end; ++it)
    {
      const Elem* elem = *it;

      // We only need to add nodes which might be added during mesh
      // refinement; this means they need to be child nodes.
      if (!elem->has_children())
        continue;

      for (unsigned int c = 0; c != elem->n_children(); ++c)
        {
          if (elem->child(c)->is_remote())
            continue;

          for (unsigned int n = 0; n != elem->n_nodes_in_child(c); ++n)
            {
              const std::vector<std::pair<dof_id_type, dof_id_type> >
                bracketing_nodes = elem->bracketing_nodes(c,n);

              this->add_node(*elem->child(c)->get_node(n),
                             bracketing_nodes);
            }
        }
    }
}

#else

// no-op without AMR
void TopologyMap::fill(const MeshBase&) {}

#endif

} // namespace libMesh
<|endoftext|>


<commit_before>// Filename: geomVertexArrayData_ext.I
// Created by:  rdb (05Sep13)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University.  All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license.  You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

#include "geomVertexArrayData_ext.h"

struct InternalBufferData {
  CPT(GeomVertexArrayDataHandle) _handle;
  Py_ssize_t _num_rows;
  Py_ssize_t _stride;
  string _format;
};

#if PY_VERSION_HEX >= 0x02060000
////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayData::__getbuffer__
//       Access: Published
//  Description: This is used to implement the buffer protocol, in
//               order to allow efficient access to the array data
//               through a Python multiview object.
////////////////////////////////////////////////////////////////////
int Extension<GeomVertexArrayData>::
__getbuffer__(PyObject *self, Py_buffer *view, int flags) {

  PT(GeomVertexArrayDataHandle) handle = _this->modify_handle();
  CPT(GeomVertexArrayFormat) format = handle->get_array_format();

  int row_size;
  bool pad_fmt;

  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
    // The consumer is fine with having a stride value.
    row_size = format->get_total_bytes();
    pad_fmt = false;
  } else {
    // The consumer expects a contiguous buffer.  Give the
    // stride as row size, and pad the format with extra bytes.
    row_size = format->get_stride();
    pad_fmt = true;
  }

  InternalBufferData *data = new InternalBufferData;
  data->_handle = handle;
  data->_num_rows = handle->get_num_rows();
  data->_stride = format->get_stride();
  data->_format = format->get_format_string(pad_fmt);

  view->internal = (void*) data;

  if (self != NULL) {
    Py_INCREF(self);
  }
  view->obj = self;
  view->buf = (void*) handle->get_write_pointer();
  view->len = row_size * handle->get_num_rows();
  view->readonly = 0;
  view->itemsize = row_size;
  view->format = NULL;
  if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
    view->format = (char*) data->_format.c_str();
  }
  view->ndim = 1;
  view->shape = NULL;
  if ((flags & PyBUF_ND) == PyBUF_ND) {
    view->shape = &data->_num_rows;
  }
  view->strides = NULL;
  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
    view->strides = &data->_stride;
  }
  view->suboffsets = NULL;

  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayData::__getbuffer__
//       Access: Published
//  Description: This is the const version of __getbuffer__, which
//               does not support writing.
////////////////////////////////////////////////////////////////////
int Extension<GeomVertexArrayData>::
__getbuffer__(PyObject *self, Py_buffer *view, int flags) const {

  if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
      PyErr_SetString(PyExc_BufferError,
                      "Object is not writable.");
      return -1;
  }

  CPT(GeomVertexArrayDataHandle) handle = _this->get_handle();
  CPT(GeomVertexArrayFormat) format = handle->get_array_format();

  int row_size;
  bool pad_fmt;

  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
    // The consumer is fine with having a stride value.
    row_size = format->get_total_bytes();
    pad_fmt = false;
  } else {
    // The consumer expects a contiguous buffer.  Give the
    // stride as row size, and pad the format with extra bytes.
    row_size = format->get_stride();
    pad_fmt = true;
  }

  InternalBufferData *data = new InternalBufferData;
  data->_handle = handle;
  data->_num_rows = handle->get_num_rows();
  data->_stride = format->get_stride();
  data->_format = format->get_format_string(pad_fmt);

  view->internal = (void*) data;

  if (self != NULL) {
    Py_INCREF(self);
  }
  view->obj = self;
  view->buf = (void*) handle->get_read_pointer(true);
  view->len = row_size * handle->get_num_rows();
  view->readonly = 1;
  view->itemsize = row_size;
  view->format = NULL;
  if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
    view->format = (char*) data->_format.c_str();
  }
  view->ndim = 1;
  view->shape = NULL;
  if ((flags & PyBUF_ND) == PyBUF_ND) {
    view->shape = &data->_num_rows;
  }
  view->strides = NULL;
  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
    view->strides = &data->_stride;
  }
  view->suboffsets = NULL;

  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayData::__releasebuffer__
//       Access: Published
//  Description: Releases the buffer allocated by __getbuffer__.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayData>::
__releasebuffer__(PyObject *self, Py_buffer *view) const {
  // Note: PyBuffer_Release automatically decrements view->obj.

  InternalBufferData *data;
  data = (InternalBufferData *) view->internal;
  if (data == NULL) {
    return;
  }
  delete data;
  view->internal = NULL;
}

#endif  // PY_VERSION_HEX >= 0x02060000

////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayDataHandle::copy_data_from
//       Access: Published
//  Description: Copies all data from the given buffer object.
//               The array is rescaled as necessary.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayDataHandle>::
copy_data_from(PyObject *buffer) {

#if PY_VERSION_HEX < 0x02060000
  PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6");

#else
  if (!PyObject_CheckBuffer(buffer)) {
    PyErr_SetString(PyExc_TypeError, "buffer object expected");
    return;
  }

  Py_buffer view;
  if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) {
    PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected");
    return;
  }

  _this->copy_data_from((const unsigned char *) view.buf, view.len);

  PyBuffer_Release(&view);
#endif
}

////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayDataHandle::copy_subdata_from
//       Access: Public
//  Description: Copies the entire data array from the buffer
//               into a portion of the data array of this object.
//               If to_size is not the size of the given buffer,
//               the size of this dat array is adjusted accordingly.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayDataHandle>::
copy_subdata_from(size_t to_start, size_t to_size, PyObject *buffer) {

#if PY_VERSION_HEX < 0x02060000
  PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6");

#else
  if (!PyObject_CheckBuffer(buffer)) {
    PyErr_SetString(PyExc_TypeError, "buffer object expected");
    return;
  }

  Py_buffer view;
  if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) {
    PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected");
    return;
  }

  _this->copy_subdata_from(to_start, to_size,
                           (const unsigned char *) view.buf,
                           0, (size_t) view.len);

  PyBuffer_Release(&view);
#endif
}

////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayDataHandle::copy_subdata_from
//       Access: Public
//  Description: Copies a portion of the data array from the buffer
//               into a portion of the data array of this object.
//               If to_size != from_size, the size of this data
//               array is adjusted accordingly.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayDataHandle>::
copy_subdata_from(size_t to_start, size_t to_size,
                  PyObject *buffer,
                  size_t from_start, size_t from_size) {

#if PY_VERSION_HEX < 0x02060000
  PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6");

#else
  if (!PyObject_CheckBuffer(buffer)) {
    PyErr_SetString(PyExc_TypeError, "buffer object expected");
    return;
  }

  Py_buffer view;
  if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) {
    PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected");
    return;
  }

  size_t from_buffer_orig_size = (size_t) view.len;
  from_start = min(from_start, from_buffer_orig_size);
  from_size = min(from_size, from_buffer_orig_size - from_start);

  _this->copy_subdata_from(to_start, to_size,
                           (const unsigned char *) view.buf,
                           from_start, from_size);

  PyBuffer_Release(&view);
#endif
}

<commit_msg>Add HAVE_PYTHON guards<commit_after>// Filename: geomVertexArrayData_ext.I
// Created by:  rdb (05Sep13)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University.  All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license.  You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

#include "geomVertexArrayData_ext.h"

#ifdef HAVE_PYTHON

struct InternalBufferData {
  CPT(GeomVertexArrayDataHandle) _handle;
  Py_ssize_t _num_rows;
  Py_ssize_t _stride;
  string _format;
};

#if PY_VERSION_HEX >= 0x02060000
////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayData::__getbuffer__
//       Access: Published
//  Description: This is used to implement the buffer protocol, in
//               order to allow efficient access to the array data
//               through a Python multiview object.
////////////////////////////////////////////////////////////////////
int Extension<GeomVertexArrayData>::
__getbuffer__(PyObject *self, Py_buffer *view, int flags) {

  PT(GeomVertexArrayDataHandle) handle = _this->modify_handle();
  CPT(GeomVertexArrayFormat) format = handle->get_array_format();

  int row_size;
  bool pad_fmt;

  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
    // The consumer is fine with having a stride value.
    row_size = format->get_total_bytes();
    pad_fmt = false;
  } else {
    // The consumer expects a contiguous buffer.  Give the
    // stride as row size, and pad the format with extra bytes.
    row_size = format->get_stride();
    pad_fmt = true;
  }

  InternalBufferData *data = new InternalBufferData;
  data->_handle = handle;
  data->_num_rows = handle->get_num_rows();
  data->_stride = format->get_stride();
  data->_format = format->get_format_string(pad_fmt);

  view->internal = (void*) data;

  if (self != NULL) {
    Py_INCREF(self);
  }
  view->obj = self;
  view->buf = (void*) handle->get_write_pointer();
  view->len = row_size * handle->get_num_rows();
  view->readonly = 0;
  view->itemsize = row_size;
  view->format = NULL;
  if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
    view->format = (char*) data->_format.c_str();
  }
  view->ndim = 1;
  view->shape = NULL;
  if ((flags & PyBUF_ND) == PyBUF_ND) {
    view->shape = &data->_num_rows;
  }
  view->strides = NULL;
  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
    view->strides = &data->_stride;
  }
  view->suboffsets = NULL;

  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayData::__getbuffer__
//       Access: Published
//  Description: This is the const version of __getbuffer__, which
//               does not support writing.
////////////////////////////////////////////////////////////////////
int Extension<GeomVertexArrayData>::
__getbuffer__(PyObject *self, Py_buffer *view, int flags) const {

  if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
      PyErr_SetString(PyExc_BufferError,
                      "Object is not writable.");
      return -1;
  }

  CPT(GeomVertexArrayDataHandle) handle = _this->get_handle();
  CPT(GeomVertexArrayFormat) format = handle->get_array_format();

  int row_size;
  bool pad_fmt;

  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
    // The consumer is fine with having a stride value.
    row_size = format->get_total_bytes();
    pad_fmt = false;
  } else {
    // The consumer expects a contiguous buffer.  Give the
    // stride as row size, and pad the format with extra bytes.
    row_size = format->get_stride();
    pad_fmt = true;
  }

  InternalBufferData *data = new InternalBufferData;
  data->_handle = handle;
  data->_num_rows = handle->get_num_rows();
  data->_stride = format->get_stride();
  data->_format = format->get_format_string(pad_fmt);

  view->internal = (void*) data;

  if (self != NULL) {
    Py_INCREF(self);
  }
  view->obj = self;
  view->buf = (void*) handle->get_read_pointer(true);
  view->len = row_size * handle->get_num_rows();
  view->readonly = 1;
  view->itemsize = row_size;
  view->format = NULL;
  if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
    view->format = (char*) data->_format.c_str();
  }
  view->ndim = 1;
  view->shape = NULL;
  if ((flags & PyBUF_ND) == PyBUF_ND) {
    view->shape = &data->_num_rows;
  }
  view->strides = NULL;
  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
    view->strides = &data->_stride;
  }
  view->suboffsets = NULL;

  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayData::__releasebuffer__
//       Access: Published
//  Description: Releases the buffer allocated by __getbuffer__.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayData>::
__releasebuffer__(PyObject *self, Py_buffer *view) const {
  // Note: PyBuffer_Release automatically decrements view->obj.

  InternalBufferData *data;
  data = (InternalBufferData *) view->internal;
  if (data == NULL) {
    return;
  }
  delete data;
  view->internal = NULL;
}

#endif  // PY_VERSION_HEX >= 0x02060000

////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayDataHandle::copy_data_from
//       Access: Published
//  Description: Copies all data from the given buffer object.
//               The array is rescaled as necessary.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayDataHandle>::
copy_data_from(PyObject *buffer) {

#if PY_VERSION_HEX < 0x02060000
  PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6");

#else
  if (!PyObject_CheckBuffer(buffer)) {
    PyErr_SetString(PyExc_TypeError, "buffer object expected");
    return;
  }

  Py_buffer view;
  if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) {
    PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected");
    return;
  }

  _this->copy_data_from((const unsigned char *) view.buf, view.len);

  PyBuffer_Release(&view);
#endif
}

////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayDataHandle::copy_subdata_from
//       Access: Public
//  Description: Copies the entire data array from the buffer
//               into a portion of the data array of this object.
//               If to_size is not the size of the given buffer,
//               the size of this dat array is adjusted accordingly.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayDataHandle>::
copy_subdata_from(size_t to_start, size_t to_size, PyObject *buffer) {

#if PY_VERSION_HEX < 0x02060000
  PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6");

#else
  if (!PyObject_CheckBuffer(buffer)) {
    PyErr_SetString(PyExc_TypeError, "buffer object expected");
    return;
  }

  Py_buffer view;
  if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) {
    PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected");
    return;
  }

  _this->copy_subdata_from(to_start, to_size,
                           (const unsigned char *) view.buf,
                           0, (size_t) view.len);

  PyBuffer_Release(&view);
#endif
}

////////////////////////////////////////////////////////////////////
//     Function: GeomVertexArrayDataHandle::copy_subdata_from
//       Access: Public
//  Description: Copies a portion of the data array from the buffer
//               into a portion of the data array of this object.
//               If to_size != from_size, the size of this data
//               array is adjusted accordingly.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayDataHandle>::
copy_subdata_from(size_t to_start, size_t to_size,
                  PyObject *buffer,
                  size_t from_start, size_t from_size) {

#if PY_VERSION_HEX < 0x02060000
  PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6");

#else
  if (!PyObject_CheckBuffer(buffer)) {
    PyErr_SetString(PyExc_TypeError, "buffer object expected");
    return;
  }

  Py_buffer view;
  if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) {
    PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected");
    return;
  }

  size_t from_buffer_orig_size = (size_t) view.len;
  from_start = min(from_start, from_buffer_orig_size);
  from_size = min(from_size, from_buffer_orig_size - from_start);

  _this->copy_subdata_from(to_start, to_size,
                           (const unsigned char *) view.buf,
                           from_start, from_size);

  PyBuffer_Release(&view);
#endif
}

#endif  // HAVE_PYTHON
<|endoftext|>