<commit_before>// Copyright (c) 2016 IBM Corporation.

#include "string-extern.h"

#include "std/core.h"
#include "std/listdef.h"
#include "strutils.h"
#include <regex>

using namespace tosca;

StringTerm& AfterFirst(Context& ctx, StringTerm& string, StringTerm& sep)
{
    const tosca::string& ustring = string.Unbox();
    const tosca::string& usep = sep.Unbox();
    tosca::string::size_type idx = ustring.find(usep);

    StringTerm& result = newStringTerm(ctx, (idx == tosca::string::npos) ? "" : ustring.substr(idx + 1).c_str());
    string.Release();
    sep.Release();
    return result;
}

StringTerm& BeforeFirst(Context& ctx, StringTerm& string, StringTerm& sep)
{
    const tosca::string& ustring = string.Unbox();
    const tosca::string& usep = sep.Unbox();
    tosca::string::size_type idx = ustring.find(usep);

    StringTerm& result = newStringTerm(ctx, (idx == tosca::string::npos) ? ustring : ustring.substr(0, idx).c_str());
    string.Release();
    sep.Release();
    return result;
}

Bool& StringEqual(Context& ctx, StringTerm& str1, StringTerm& str2)
{
    const tosca::string& ustr1 = str1.Unbox();
    const tosca::string& ustr2 = str2.Unbox();
    Bool& result = ustr1 == ustr2 ? newTRUE(ctx) : newFALSE(ctx);
    str1.Release();
    str2.Release();
    return result;
}

StringTerm& Escape(Context& ctx, StringTerm& str)
{
    StringTerm& result = newStringTerm(ctx, makeEscaped(str.Unbox()));
    str.Release();
    return result;
}

DoubleTerm& Length(Context& ctx, StringTerm& str)
{
    DoubleTerm& result = newDoubleTerm(ctx, str.Unbox().size());
    str.Release();
    return result;
}

StringTerm& Mangle(Context& ctx, StringTerm& str)
{
    StringTerm& result = newStringTerm(ctx, makeMangle(str.Unbox()));
    str.Release();
    return result;
}

StringTerm& UpCase(Context& ctx, StringTerm& str)
{
    tosca::string upper(str.Unbox());
    for (tosca::string::iterator it= upper.begin(); it != upper.end(); ++it)
        *it = toupper(*it);
    str.Release();
    return newStringTerm(ctx, upper.c_str());
}

StringTerm& DownCase(Context& ctx, StringTerm& str)
{
    tosca::string lower(str.Unbox());
    for (tosca::string::iterator it= lower.begin(); it != lower.end(); ++it)
        *it = tolower(*it);
    str.Release();
    return newStringTerm(ctx, lower.c_str());
}

StringTerm& Replace(Context& ctx, StringTerm& str, StringTerm& oldStr, StringTerm& newStr)
{
    if (oldStr.Unbox().empty())
    {
        oldStr.Release();
        newStr.Release();
        return str;
    }

    tosca::string result(str.Unbox());
    const tosca::string& uoldStr = oldStr.Unbox();
    const tosca::string& unewStr = newStr.Unbox();

    size_t pos = 0;
    while ((pos = result.find(uoldStr, pos)) != tosca::string::npos)
    {
        result.replace(pos, uoldStr.length(), unewStr);
        pos += unewStr.length();
    }
    str.Release();
    oldStr.Release();
    newStr.Release();

    return newStringTerm(ctx, result.c_str());
}

Bool& Contains(Context& ctx, StringTerm& str1, StringTerm& str2)
{
    const tosca::string& ustr1 = str1.Unbox();
    const tosca::string& ustr2 = str2.Unbox();
    Bool& result = ustr1.find(ustr2) != tosca::string::npos ? newTRUE(ctx) : newFALSE(ctx);
    str1.Release();
    str2.Release();
    return result;
}

StringTerm& Substring(Context& ctx, StringTerm& str, DoubleTerm& from, DoubleTerm& to)
{
    const tosca::string& ustr = str.Unbox();
    tosca::string::size_type pos = static_cast<tosca::string::size_type>(from.Unbox());
    tosca::string::size_type end = static_cast<tosca::string::size_type>(to.Unbox());
    tosca::string::size_type count = end > pos ? end - pos : 0;
    StringTerm& result = newStringTerm(ctx, ustr.substr(pos, count).c_str());
    str.Release();
    from.Release();
    return result;
}

StringTerm& Substring2(Context& ctx, StringTerm& str, DoubleTerm& from)
{
    const tosca::string& ustr = str.Unbox();
    tosca::string::size_type pos = static_cast<tosca::string::size_type>(from.Unbox());
    StringTerm& result = newStringTerm(ctx, ustr.substr(pos).c_str());
    str.Release();
    from.Release();
    return result;
}

#ifdef STD_REGEX
Bool& MatchRegex(Context& ctx, StringTerm& pattern, StringTerm& str)
{
    std::regex regex(pattern.Unbox());
    Bool& result = std::regex_match(str.Unbox(), regex) ? newTRUE(ctx) : newFALSE(ctx);
    pattern.Release();
    str.Release();
    return result;
}
#endif

Bool& StartsWith(Context& ctx, StringTerm& str, StringTerm& prefix)
{
    const tosca::string& ustr = str.Unbox();
    const tosca::string& uprefix = prefix.Unbox();
    Bool& result = (!ustr.compare(0, uprefix.size(), uprefix)) ? newTRUE(ctx) : newFALSE(ctx);
    str.Release();
    prefix.Release();
    return result;
}

Bool& EndsWith(tosca::Context& ctx, tosca::StringTerm& str, tosca::StringTerm& suffix)
{
    const tosca::string& ustr = str.Unbox();
    const tosca::string& usuffix = suffix.Unbox();
    Bool& result = (ustr.size() >= usuffix.size()
                    && !ustr.compare(ustr.size() - usuffix.size(), usuffix.size(), usuffix)) ? newTRUE(ctx) : newFALSE(ctx);
    str.Release();
    suffix.Release();
    return result;
}

tosca::StringTerm& Trim(tosca::Context& ctx, tosca::StringTerm& str)
{
    const tosca::string& ustr = str.Unbox();
    if (ustr.empty())
        return str;

    tosca::string::size_type first = ustr.find_first_not_of(" \t\f\n\r\b");
    if (first == tosca::string::npos)
    {
        // All whitespace characters.
        str.Release();
        return newStringTerm(ctx, "");
    }

    size_t last = ustr.find_last_not_of(" \t\f\n\r\b");
    StringTerm& result = newStringTerm(ctx, ustr.substr(first, (last-first+1)).c_str());
    str.Release();
    return result;
}

List<tosca::StringTerm>& Split(tosca::Context& ctx, tosca::StringTerm& str, tosca::StringTerm& sep)
{
    const tosca::string& ustr = str.Unbox();
    if (ustr.empty())
    {
        str.Release();
        sep.Release();
        return newNil<tosca::StringTerm>(ctx);
    }

    const tosca::string& usep = sep.Unbox();
    List<tosca::StringTerm>* result = 0;
    List<tosca::StringTerm>* last = 0;

    tosca::string::size_type spos = 0;
    tosca::string::size_type pos = 0;
    int trailings = 0; // to discard empty trailing strings
    while ((pos = ustr.find(usep, spos)) != tosca::string::npos)
    {
    	tosca::string::size_type count = pos - spos;
    	if (count == 0)
    	{
    		trailings ++;
    		spos += usep.length();
    		continue;
    	}
    	for (; trailings > 0; trailings--)
    	{
    		List<tosca::StringTerm>& cons = dynamic_cast<List<tosca::StringTerm>&>(_CCons<tosca::StringTerm>::Make(ctx));
    		cons.SetSub(0, newStringTerm(ctx, ""));
    		if (last)
    			last->SetSub(1, cons);
    		last = &cons;

    		if (!result)
    			result = last;
    	}

    	List<tosca::StringTerm>& cons = dynamic_cast<List<tosca::StringTerm>&>(_CCons<tosca::StringTerm>::Make(ctx));
    	cons.SetSub(0, newStringTerm(ctx, ustr.substr(spos, count).c_str()));
    	if (last)
    		last->SetSub(1, cons);
    	last = &cons;

    	if (!result)
    		result = last;

        spos = pos + usep.length();
    }
    if (spos < ustr.length())
    {
    	List<tosca::StringTerm>& cons = dynamic_cast<List<tosca::StringTerm>&>(_CCons<tosca::StringTerm>::Make(ctx));
    	cons.SetSub(0, newStringTerm(ctx, ustr.substr(spos).c_str()));
    	if (last)
    		last->SetSub(1, cons);
    	last = &cons;

    	if (!result)
    		result = last;
    }

    if (last)
    {
        last->SetSub(1, newNil<tosca::StringTerm>(ctx));
        str.Release();
    }
    else
    {
        // sep was not found or only trailing empty strings. Just return the original string, even when empty
        result = &newCons(ctx, str, newNil<tosca::StringTerm>(ctx));
    }
    sep.Release();
    return *result;
}

tosca::StringTerm& Squash(tosca::Context& ctx, tosca::StringTerm& str)
{
    tosca::string squashed;
    bool wasspace = false;

    for (auto iter = str.Unbox().begin(); iter != str.Unbox().end(); iter++)
    {
        if (isspace(*iter))
        {
            if (!wasspace)
            {
                wasspace=true;
                squashed += ' ';
            }
        }
        else
        {
            squashed += *iter;
            wasspace = false;
        }
    }
    str.Release();
    return newStringTerm(ctx, squashed.c_str());
}

tosca::DoubleTerm& Index(tosca::Context& ctx, tosca::StringTerm& string, tosca::StringTerm& pattern)
{
    auto search = string.Unbox().find(pattern.Unbox());
    tosca::DoubleTerm& result = newDoubleTerm(ctx, search == tosca::string::npos ? -1 : search);
    string.Release();
    pattern.Release();
    return result;
}

<commit_msg>Attempt to eliminate leak #43<commit_after>// Copyright (c) 2016 IBM Corporation.

#include "string-extern.h"

#include "std/core.h"
#include "std/listdef.h"
#include "strutils.h"
#include <regex>

using namespace tosca;

StringTerm& AfterFirst(Context& ctx, StringTerm& string, StringTerm& sep)
{
    const tosca::string& ustring = string.Unbox();
    const tosca::string& usep = sep.Unbox();
    tosca::string::size_type idx = ustring.find(usep);

    StringTerm& result = newStringTerm(ctx, (idx == tosca::string::npos) ? "" : ustring.substr(idx + 1).c_str());
    string.Release();
    sep.Release();
    return result;
}

StringTerm& BeforeFirst(Context& ctx, StringTerm& string, StringTerm& sep)
{
    const tosca::string& ustring = string.Unbox();
    const tosca::string& usep = sep.Unbox();
    tosca::string::size_type idx = ustring.find(usep);

    StringTerm& result = newStringTerm(ctx, (idx == tosca::string::npos) ? ustring : ustring.substr(0, idx));
    string.Release();
    sep.Release();
    return result;
}

Bool& StringEqual(Context& ctx, StringTerm& str1, StringTerm& str2)
{
    const tosca::string& ustr1 = str1.Unbox();
    const tosca::string& ustr2 = str2.Unbox();
    Bool& result = ustr1 == ustr2 ? newTRUE(ctx) : newFALSE(ctx);
    str1.Release();
    str2.Release();
    return result;
}

StringTerm& Escape(Context& ctx, StringTerm& str)
{
    StringTerm& result = newStringTerm(ctx, makeEscaped(str.Unbox()));
    str.Release();
    return result;
}

DoubleTerm& Length(Context& ctx, StringTerm& str)
{
    DoubleTerm& result = newDoubleTerm(ctx, str.Unbox().size());
    str.Release();
    return result;
}

StringTerm& Mangle(Context& ctx, StringTerm& str)
{
    StringTerm& result = newStringTerm(ctx, makeMangle(str.Unbox()));
    str.Release();
    return result;
}

StringTerm& UpCase(Context& ctx, StringTerm& str)
{
    tosca::string upper(str.Unbox());
    for (tosca::string::iterator it= upper.begin(); it != upper.end(); ++it)
        *it = toupper(*it);
    str.Release();
    return newStringTerm(ctx, upper.c_str());
}

StringTerm& DownCase(Context& ctx, StringTerm& str)
{
    tosca::string lower(str.Unbox());
    for (tosca::string::iterator it= lower.begin(); it != lower.end(); ++it)
        *it = tolower(*it);
    str.Release();
    return newStringTerm(ctx, lower.c_str());
}

StringTerm& Replace(Context& ctx, StringTerm& str, StringTerm& oldStr, StringTerm& newStr)
{
    if (oldStr.Unbox().empty())
    {
        oldStr.Release();
        newStr.Release();
        return str;
    }

    tosca::string result(str.Unbox());
    const tosca::string& uoldStr = oldStr.Unbox();
    const tosca::string& unewStr = newStr.Unbox();

    size_t pos = 0;
    while ((pos = result.find(uoldStr, pos)) != tosca::string::npos)
    {
        result.replace(pos, uoldStr.length(), unewStr);
        pos += unewStr.length();
    }
    str.Release();
    oldStr.Release();
    newStr.Release();

    return newStringTerm(ctx, result.c_str());
}

Bool& Contains(Context& ctx, StringTerm& str1, StringTerm& str2)
{
    const tosca::string& ustr1 = str1.Unbox();
    const tosca::string& ustr2 = str2.Unbox();
    Bool& result = ustr1.find(ustr2) != tosca::string::npos ? newTRUE(ctx) : newFALSE(ctx);
    str1.Release();
    str2.Release();
    return result;
}

StringTerm& Substring(Context& ctx, StringTerm& str, DoubleTerm& from, DoubleTerm& to)
{
    const tosca::string& ustr = str.Unbox();
    tosca::string::size_type pos = static_cast<tosca::string::size_type>(from.Unbox());
    tosca::string::size_type end = static_cast<tosca::string::size_type>(to.Unbox());
    tosca::string::size_type count = end > pos ? end - pos : 0;
    StringTerm& result = newStringTerm(ctx, ustr.substr(pos, count).c_str());
    str.Release();
    from.Release();
    return result;
}

StringTerm& Substring2(Context& ctx, StringTerm& str, DoubleTerm& from)
{
    const tosca::string& ustr = str.Unbox();
    tosca::string::size_type pos = static_cast<tosca::string::size_type>(from.Unbox());
    StringTerm& result = newStringTerm(ctx, ustr.substr(pos).c_str());
    str.Release();
    from.Release();
    return result;
}

#ifdef STD_REGEX
Bool& MatchRegex(Context& ctx, StringTerm& pattern, StringTerm& str)
{
    std::regex regex(pattern.Unbox());
    Bool& result = std::regex_match(str.Unbox(), regex) ? newTRUE(ctx) : newFALSE(ctx);
    pattern.Release();
    str.Release();
    return result;
}
#endif

Bool& StartsWith(Context& ctx, StringTerm& str, StringTerm& prefix)
{
    const tosca::string& ustr = str.Unbox();
    const tosca::string& uprefix = prefix.Unbox();
    Bool& result = (!ustr.compare(0, uprefix.size(), uprefix)) ? newTRUE(ctx) : newFALSE(ctx);
    str.Release();
    prefix.Release();
    return result;
}

Bool& EndsWith(tosca::Context& ctx, tosca::StringTerm& str, tosca::StringTerm& suffix)
{
    const tosca::string& ustr = str.Unbox();
    const tosca::string& usuffix = suffix.Unbox();
    Bool& result = (ustr.size() >= usuffix.size()
                    && !ustr.compare(ustr.size() - usuffix.size(), usuffix.size(), usuffix)) ? newTRUE(ctx) : newFALSE(ctx);
    str.Release();
    suffix.Release();
    return result;
}

tosca::StringTerm& Trim(tosca::Context& ctx, tosca::StringTerm& str)
{
    const tosca::string& ustr = str.Unbox();
    if (ustr.empty())
        return str;

    tosca::string::size_type first = ustr.find_first_not_of(" \t\f\n\r\b");
    if (first == tosca::string::npos)
    {
        // All whitespace characters.
        str.Release();
        return newStringTerm(ctx, "");
    }

    size_t last = ustr.find_last_not_of(" \t\f\n\r\b");
    StringTerm& result = newStringTerm(ctx, ustr.substr(first, (last-first+1)).c_str());
    str.Release();
    return result;
}

List<tosca::StringTerm>& Split(tosca::Context& ctx, tosca::StringTerm& str, tosca::StringTerm& sep)
{
    const tosca::string& ustr = str.Unbox();
    if (ustr.empty())
    {
        str.Release();
        sep.Release();
        return newNil<tosca::StringTerm>(ctx);
    }

    const tosca::string& usep = sep.Unbox();
    List<tosca::StringTerm>* result = 0;
    List<tosca::StringTerm>* last = 0;

    tosca::string::size_type spos = 0;
    tosca::string::size_type pos = 0;
    int trailings = 0; // to discard empty trailing strings
    while ((pos = ustr.find(usep, spos)) != tosca::string::npos)
    {
    	tosca::string::size_type count = pos - spos;
    	if (count == 0)
    	{
    		trailings ++;
    		spos += usep.length();
    		continue;
    	}
    	for (; trailings > 0; trailings--)
    	{
    		List<tosca::StringTerm>& cons = dynamic_cast<List<tosca::StringTerm>&>(_CCons<tosca::StringTerm>::Make(ctx));
    		cons.SetSub(0, newStringTerm(ctx, ""));
    		if (last)
    			last->SetSub(1, cons);
    		last = &cons;

    		if (!result)
    			result = last;
    	}

    	List<tosca::StringTerm>& cons = dynamic_cast<List<tosca::StringTerm>&>(_CCons<tosca::StringTerm>::Make(ctx));
    	cons.SetSub(0, newStringTerm(ctx, ustr.substr(spos, count).c_str()));
    	if (last)
    		last->SetSub(1, cons);
    	last = &cons;

    	if (!result)
    		result = last;

        spos = pos + usep.length();
    }
    if (spos < ustr.length())
    {
    	List<tosca::StringTerm>& cons = dynamic_cast<List<tosca::StringTerm>&>(_CCons<tosca::StringTerm>::Make(ctx));
    	cons.SetSub(0, newStringTerm(ctx, ustr.substr(spos).c_str()));
    	if (last)
    		last->SetSub(1, cons);
    	last = &cons;

    	if (!result)
    		result = last;
    }

    if (last)
    {
        last->SetSub(1, newNil<tosca::StringTerm>(ctx));
        str.Release();
    }
    else
    {
        // sep was not found or only trailing empty strings. Just return the original string, even when empty
        result = &newCons(ctx, str, newNil<tosca::StringTerm>(ctx));
    }
    sep.Release();
    return *result;
}

tosca::StringTerm& Squash(tosca::Context& ctx, tosca::StringTerm& str)
{
    tosca::string squashed;
    bool wasspace = false;

    for (auto iter = str.Unbox().begin(); iter != str.Unbox().end(); iter++)
    {
        if (isspace(*iter))
        {
            if (!wasspace)
            {
                wasspace=true;
                squashed += ' ';
            }
        }
        else
        {
            squashed += *iter;
            wasspace = false;
        }
    }
    str.Release();
    return newStringTerm(ctx, squashed.c_str());
}

tosca::DoubleTerm& Index(tosca::Context& ctx, tosca::StringTerm& string, tosca::StringTerm& pattern)
{
    auto search = string.Unbox().find(pattern.Unbox());
    tosca::DoubleTerm& result = newDoubleTerm(ctx, search == tosca::string::npos ? -1 : search);
    string.Release();
    pattern.Release();
    return result;
}

<|endoftext|>


<commit_before>/* Copyright 2017 The TensorFlow Authors. 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.
==============================================================================*/

#include "tensorflow/compiler/xla/service/conditional_simplifier.h"

#include <string>
#include <utility>
#include <vector>

#include "tensorflow/compiler/xla/literal_util.h"
#include "tensorflow/compiler/xla/service/call_inliner.h"
#include "tensorflow/compiler/xla/service/hlo_computation.h"
#include "tensorflow/compiler/xla/service/hlo_instruction.h"
#include "tensorflow/compiler/xla/service/hlo_opcode.h"
#include "tensorflow/compiler/xla/status_macros.h"
#include "tensorflow/compiler/xla/types.h"
#include "tensorflow/compiler/xla/util.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/strcat.h"

namespace xla {

// Tries to replace a conditional with a call operation of the corresponding
// computation. If the given conditional has a constant predicate, tries to
// replace it with a call to its true/false computation as appropirate and then
// inline that computation.
//
// Returns true if it made a change to the graph.
static StatusOr<bool> TryRemoveConditional(HloInstruction* conditional) {
  CHECK_EQ(conditional->opcode(), HloOpcode::kConditional);
  // Do not remove conditionals that contain side-effecting instructions or
  // have control predecessors/successors in either true/false computation.
  if (!conditional->parent()->IsRemovable(conditional) ||
      conditional->HasSideEffect()) {
    VLOG(2) << "Not attempting to remove conditional as it is not removable or "
               "has side effect: "
            << conditional->ToShortString();
    return false;
  }

  if (conditional->operand(0)->opcode() != HloOpcode::kConstant) {
    VLOG(2) << "Not attempting to remove conditional as its predicate is not a "
               "compile-time constant: "
            << conditional->ToShortString();
    return false;
  }

  auto computation = conditional->parent();
  HloInstruction* call_op;
  if (conditional->operand(0)->literal().Get<bool>({})) {
    call_op = computation->AddInstruction(HloInstruction::CreateCall(
        conditional->shape(), {conditional->mutable_operand(1)},
        conditional->true_computation()));
  } else {
    call_op = computation->AddInstruction(HloInstruction::CreateCall(
        conditional->shape(), {conditional->mutable_operand(2)},
        conditional->false_computation()));
  }

  TF_RETURN_IF_ERROR(computation->ReplaceInstruction(conditional, call_op));
  TF_RETURN_IF_ERROR(CallInliner::Inline(call_op).status());

  return true;
}

StatusOr<bool> ConditionalSimplifier::Run(HloModule* module) {
  XLA_VLOG_LINES(
      3, "ConditionalSimplifier::Run(), before:\n" + module->ToString());
  bool changed = false;

  // Gather all the conditional ops in our module. We do this ahead of time so
  // we don't have to worry about mutating the lists of computations or
  // instructions as we iterate.
  std::vector<HloInstruction*> conditional_ops;
  for (auto* comp : module->computations()) {
    for (auto* instr : comp->instructions()) {
      if (instr->opcode() == HloOpcode::kConditional) {
        conditional_ops.push_back(instr);
      }
    }
  }

  for (HloInstruction* conditional_op : conditional_ops) {
    TF_ASSIGN_OR_RETURN(bool result, TryRemoveConditional(conditional_op));
    changed |= result;
  }

  XLA_VLOG_LINES(3,
                 "ConditionalSimplifier::Run(), after:\n" + module->ToString());
  return changed;
}

}  // namespace xla
<commit_msg>Teach the conditinal simplifier about sharding.<commit_after>/* Copyright 2017 The TensorFlow Authors. 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.
==============================================================================*/

#include "tensorflow/compiler/xla/service/conditional_simplifier.h"

#include <string>
#include <utility>
#include <vector>

#include "tensorflow/compiler/xla/literal_util.h"
#include "tensorflow/compiler/xla/service/call_inliner.h"
#include "tensorflow/compiler/xla/service/hlo_computation.h"
#include "tensorflow/compiler/xla/service/hlo_instruction.h"
#include "tensorflow/compiler/xla/service/hlo_opcode.h"
#include "tensorflow/compiler/xla/status_macros.h"
#include "tensorflow/compiler/xla/types.h"
#include "tensorflow/compiler/xla/util.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/strcat.h"

namespace xla {

// Tries to replace a conditional with a call operation of the corresponding
// computation. If the given conditional has a constant predicate, tries to
// replace it with a call to its true/false computation as appropirate and then
// inline that computation.
//
// Returns true if it made a change to the graph.
static StatusOr<bool> TryRemoveConditional(HloInstruction* conditional) {
  CHECK_EQ(conditional->opcode(), HloOpcode::kConditional);
  // Do not remove conditionals that contain side-effecting instructions or
  // have control predecessors/successors in either true/false computation.
  if (!conditional->parent()->IsRemovable(conditional) ||
      conditional->HasSideEffect()) {
    VLOG(2) << "Not attempting to remove conditional as it is not removable or "
               "has side effect: "
            << conditional->ToShortString();
    return false;
  }

  if (conditional->operand(0)->opcode() != HloOpcode::kConstant) {
    VLOG(2) << "Not attempting to remove conditional as its predicate is not a "
               "compile-time constant: "
            << conditional->ToShortString();
    return false;
  }

  auto computation = conditional->parent();
  HloInstruction* call_op;
  if (conditional->operand(0)->literal().Get<bool>({})) {
    call_op = computation->AddInstruction(HloInstruction::CreateCall(
        conditional->shape(), {conditional->mutable_operand(1)},
        conditional->true_computation()));
  } else {
    call_op = computation->AddInstruction(HloInstruction::CreateCall(
        conditional->shape(), {conditional->mutable_operand(2)},
        conditional->false_computation()));
  }
  conditional->SetupDerivedInstruction(call_op);
  TF_RETURN_IF_ERROR(computation->ReplaceInstruction(conditional, call_op));
  TF_RETURN_IF_ERROR(CallInliner::Inline(call_op).status());

  return true;
}

StatusOr<bool> ConditionalSimplifier::Run(HloModule* module) {
  XLA_VLOG_LINES(
      3, "ConditionalSimplifier::Run(), before:\n" + module->ToString());
  bool changed = false;

  // Gather all the conditional ops in our module. We do this ahead of time so
  // we don't have to worry about mutating the lists of computations or
  // instructions as we iterate.
  std::vector<HloInstruction*> conditional_ops;
  for (auto* comp : module->computations()) {
    for (auto* instr : comp->instructions()) {
      if (instr->opcode() == HloOpcode::kConditional) {
        conditional_ops.push_back(instr);
      }
    }
  }

  for (HloInstruction* conditional_op : conditional_ops) {
    TF_ASSIGN_OR_RETURN(bool result, TryRemoveConditional(conditional_op));
    changed |= result;
  }

  XLA_VLOG_LINES(3,
                 "ConditionalSimplifier::Run(), after:\n" + module->ToString());
  return changed;
}

}  // namespace xla
<|endoftext|>


<commit_before>// kmreadermainwin
// (c) 2002 Don Sanders <sanders@kde.org>
// License: GPL
//
// A toplevel KMainWindow derived class for displaying
// single messages or single message parts.
//
// Could be extended to include support for normal main window
// widgets like a toolbar.

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <qaccel.h>
#include <kapplication.h>
#include <klocale.h>
#include <kstdaccel.h>
#include <kwin.h>
#include <kaction.h>
#include <kiconloader.h>

#include "kmcommands.h"
#include "kmenubar.h"
#include "kpopupmenu.h"
#include "kmreaderwin.h"
#include "kmfolder.h"

#include "kmreadermainwin.h"
#include "kmreadermainwin.moc"

KMReaderMainWin::KMReaderMainWin( bool htmlOverride, char *name )
  : KMail::SecondaryWindow( name ), mMsg( 0 )
{
  KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon());
  mReaderWin = new KMReaderWin( this, this, actionCollection() );
  //mReaderWin->setShowCompleteMessage( true );
  mReaderWin->setAutoDelete( true );
  mReaderWin->setHtmlOverride( htmlOverride );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::KMReaderMainWin( char *name )
  : KMail::SecondaryWindow( name ), mMsg( 0 )
{
  mReaderWin = new KMReaderWin( this, this, actionCollection() );
  mReaderWin->setAutoDelete( true );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::KMReaderMainWin(KMMessagePart* aMsgPart,
    bool aHTML, const QString& aFileName, const QString& pname,
    const QTextCodec *codec, char *name )
  : KMail::SecondaryWindow( name ), mMsg( 0 )
{
  resize( 550, 600 );
  mReaderWin = new KMReaderWin( this, this, actionCollection() ); //new reader
  mReaderWin->setOverrideCodec( codec );
  mReaderWin->setMsgPart( aMsgPart, aHTML, aFileName, pname );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::~KMReaderMainWin()
{
  saveMainWindowSettings(KMKernel::config(), "Separate Reader Window");
}

void KMReaderMainWin::showMsg( const QTextCodec *codec, KMMessage *msg )
{
  mReaderWin->setOverrideCodec( codec );
  mReaderWin->setMsg( msg, true );
  setCaption( msg->subject() );
  mMsg = msg;
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotPrintMsg()
{
  KMCommand *command = new KMPrintCommand( this, mReaderWin->message(),
      mReaderWin->htmlOverride() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyToMsg()
{
  KMCommand *command = new KMReplyToCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyAuthorToMsg()
{
  KMCommand *command = new KMReplyAuthorCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyAllToMsg()
{
  KMCommand *command = new KMReplyToAllCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyListToMsg()
{
  KMCommand *command = new KMReplyListCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotForwardMsg()
{
   KMCommand *command = 0;
   if ( mReaderWin->message()->parent() ) {
    command = new KMForwardCommand( this, mReaderWin->message(),
        mReaderWin->message()->parent()->identity() );
   } else {
    command = new KMForwardCommand( this, mReaderWin->message() );
   }
   command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotForwardAttachedMsg()
{
   KMCommand *command = 0;
   if ( mReaderWin->message()->parent() ) {
     command = new KMForwardAttachedCommand( this, mReaderWin->message(),
        mReaderWin->message()->parent()->identity() );
   } else {
     command = new KMForwardAttachedCommand( this, mReaderWin->message() );
   }
   command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotRedirectMsg()
{
  KMCommand *command = new KMRedirectCommand( this, mReaderWin->message() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotBounceMsg()
{
  KMCommand *command = new KMBounceCommand( this, mReaderWin->message() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotConfigChanged()
{
  //readConfig();
}

void KMReaderMainWin::setupAccel()
{
  if (kmkernel->xmlGuiInstance())
    setInstance( kmkernel->xmlGuiInstance() );
  KStdAction::close( this, SLOT( close() ), actionCollection() );
  applyMainWindowSettings(KMKernel::config(), "Separate Reader Window");
  QAccel *accel = new QAccel(mReaderWin, "showMsg()");
  accel->connectItem(accel->insertItem(Key_Up),
                     mReaderWin, SLOT(slotScrollUp()));
  accel->connectItem(accel->insertItem(Key_Down),
                     mReaderWin, SLOT(slotScrollDown()));
  accel->connectItem(accel->insertItem(Key_Prior),
                     mReaderWin, SLOT(slotScrollPrior()));
  accel->connectItem(accel->insertItem(Key_Next),
                     mReaderWin, SLOT(slotScrollNext()));
  accel->connectItem(accel->insertItem(KStdAccel::shortcut(KStdAccel::Copy)),
                     mReaderWin, SLOT(slotCopySelectedText()));
  connect( mReaderWin, SIGNAL(popupMenu(KMMessage&,const KURL&,const QPoint&)),
	  this, SLOT(slotMsgPopup(KMMessage&,const KURL&,const QPoint&)));
  connect(mReaderWin, SIGNAL(urlClicked(const KURL&,int)),
	  mReaderWin, SLOT(slotUrlClicked()));

  mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"),
					"mail_forward", actionCollection(),
					"message_forward" );

  mForwardAction = new KAction( i18n("&Inline..."), "mail_forward",
				SHIFT+Key_F, this, SLOT(slotForwardMsg()),
				actionCollection(), "message_forward" );
  mForwardActionMenu->insert( mForwardAction );

  mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."),
				       "mail_forward", Key_F, this,
					SLOT(slotForwardAttachedMsg()), actionCollection(),
					"message_forward_as_attachment" );
  mForwardActionMenu->insert( mForwardAttachedAction );

  mRedirectAction = new KAction( i18n("Message->Forward->","&Redirect..."),
				 Key_E, this, SLOT(slotRedirectMsg()),
				 actionCollection(), "message_forward_redirect" );
  mForwardActionMenu->insert( mRedirectAction );

  mBounceAction = new KAction( i18n("&Bounce..."), 0, this,
			      SLOT(slotBounceMsg()), actionCollection(), "bounce" );

  mReplyActionMenu = new KActionMenu( i18n("Message->","&Reply"),
                                      "mail_reply", actionCollection(),
                                      "message_reply_menu" );
  connect( mReplyActionMenu, SIGNAL(activated()), this,
	   SLOT(slotReplyToMsg()) );

  mReplyAction = new KAction( i18n("&Reply..."), "mail_reply", Key_R, this,
			      SLOT(slotReplyToMsg()), actionCollection(), "reply" );
  mReplyActionMenu->insert( mReplyAction );

  mReplyAuthorAction = new KAction( i18n("Reply to A&uthor..."), "mail_reply",
                                    SHIFT+Key_A, this,
                                    SLOT(slotReplyAuthorToMsg()),
                                    actionCollection(), "reply_author" );
  mReplyActionMenu->insert( mReplyAuthorAction );

  mReplyAllAction = new KAction( i18n("Reply to &All..."), "mail_replyall",
				 Key_A, this, SLOT(slotReplyAllToMsg()),
				 actionCollection(), "reply_all" );
  mReplyActionMenu->insert( mReplyAllAction );

  mReplyListAction = new KAction( i18n("Reply to Mailing-&List..."),
				  "mail_replylist", Key_L, this,
				  SLOT(slotReplyListToMsg()), actionCollection(),
				  "reply_list" );
  mReplyActionMenu->insert( mReplyListAction );

  mPrintAction = KStdAction::print (this, SLOT(slotPrintMsg()), actionCollection());
  createGUI( "kmreadermainwin.rc" );
  menuBar()->hide();

}

void KMReaderMainWin::slotMsgPopup(KMMessage &aMsg, const KURL &aUrl, const QPoint& aPoint)
{
  KPopupMenu * menu = new KPopupMenu;
  mUrl = aUrl;
  mMsg = &aMsg;

  if (!aUrl.isEmpty()) {
    if (aUrl.protocol() == "mailto") {
      // popup on a mailto URL
      mReaderWin->mailToComposeAction()->plug( menu );
      if ( mMsg ) {
	mReaderWin->mailToReplyAction()->plug( menu );
	mReaderWin->mailToForwardAction()->plug( menu );
        menu->insertSeparator();
      }
      mReaderWin->addAddrBookAction()->plug( menu );
      mReaderWin->openAddrBookAction()->plug( menu );
      mReaderWin->copyAction()->plug( menu );
    } else {
      // popup on a not-mailto URL
      mReaderWin->urlOpenAction()->plug( menu );
      mReaderWin->urlSaveAsAction()->plug( menu );
      mReaderWin->copyURLAction()->plug( menu );
      mReaderWin->addBookmarksAction()->plug( menu );
    }
  } else {
    // popup somewhere else (i.e., not a URL) on the message

    if (!mMsg) // no message
    {
      delete menu;
      return;
    }

    mReplyAction->plug( menu );
    mReplyAllAction->plug( menu );
    mReplyAuthorAction->plug( menu );
    mReplyListAction->plug( menu );
    mForwardActionMenu->plug( menu );
    mBounceAction->plug( menu );

    menu->insertSeparator();

    QPopupMenu* copyMenu = new QPopupMenu(menu);
    KMMenuCommand::folderToPopupMenu( false, this, &mMenuToFolder, copyMenu );
    menu->insertItem( i18n("&Copy To" ), copyMenu );
    menu->insertSeparator();
    mReaderWin->toggleFixFontAction()->plug( menu );
    mReaderWin->viewSourceAction()->plug( menu );

    mPrintAction->plug( menu );
    menu->insertItem(  SmallIcon("filesaveas"), i18n( "Save &As..." ), mReaderWin, SLOT( slotSaveMsg() ) );
    menu->insertItem( i18n("Save Attachments..."), mReaderWin, SLOT(slotSaveAttachments()) );
  }
  menu->exec(aPoint, 0);
  delete menu;
}

void KMReaderMainWin::copySelectedToFolder( int menuId )
{
  if (!mMenuToFolder[menuId])
    return;

  KMCommand *command = new KMCopyCommand( mMenuToFolder[menuId], mMsg );
  command->start();
}
<commit_msg>Don't show the toolbar when the external message window is abused as an attachment viewer. Enable it when a message is set for the window. FixeÑ a crash with trying to forward a 0 mail.<commit_after>// kmreadermainwin
// (c) 2002 Don Sanders <sanders@kde.org>
// License: GPL
//
// A toplevel KMainWindow derived class for displaying
// single messages or single message parts.
//
// Could be extended to include support for normal main window
// widgets like a toolbar.

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <qaccel.h>
#include <kapplication.h>
#include <klocale.h>
#include <kstdaccel.h>
#include <kwin.h>
#include <kaction.h>
#include <kiconloader.h>

#include "kmcommands.h"
#include "kmenubar.h"
#include "kpopupmenu.h"
#include "kmreaderwin.h"
#include "kmfolder.h"

#include "kmreadermainwin.h"
#include "kmreadermainwin.moc"

KMReaderMainWin::KMReaderMainWin( bool htmlOverride, char *name )
  : KMail::SecondaryWindow( name ), mMsg( 0 )
{
  KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon());
  mReaderWin = new KMReaderWin( this, this, actionCollection() );
  //mReaderWin->setShowCompleteMessage( true );
  mReaderWin->setAutoDelete( true );
  mReaderWin->setHtmlOverride( htmlOverride );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::KMReaderMainWin( char *name )
  : KMail::SecondaryWindow( name ), mMsg( 0 )
{
  mReaderWin = new KMReaderWin( this, this, actionCollection() );
  mReaderWin->setAutoDelete( true );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::KMReaderMainWin(KMMessagePart* aMsgPart,
    bool aHTML, const QString& aFileName, const QString& pname,
    const QTextCodec *codec, char *name )
  : KMail::SecondaryWindow( name ), mMsg( 0 )
{
  resize( 550, 600 );
  mReaderWin = new KMReaderWin( this, this, actionCollection() ); //new reader
  mReaderWin->setOverrideCodec( codec );
  mReaderWin->setMsgPart( aMsgPart, aHTML, aFileName, pname );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::~KMReaderMainWin()
{
  saveMainWindowSettings(KMKernel::config(), "Separate Reader Window");
}

void KMReaderMainWin::showMsg( const QTextCodec *codec, KMMessage *msg )
{
  mReaderWin->setOverrideCodec( codec );
  mReaderWin->setMsg( msg, true );
  setCaption( msg->subject() );
  mMsg = msg;
  toolBar( "mainToolBar" )->show();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotPrintMsg()
{
  KMCommand *command = new KMPrintCommand( this, mReaderWin->message(),
      mReaderWin->htmlOverride() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyToMsg()
{
  KMCommand *command = new KMReplyToCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyAuthorToMsg()
{
  KMCommand *command = new KMReplyAuthorCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyAllToMsg()
{
  KMCommand *command = new KMReplyToAllCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyListToMsg()
{
  KMCommand *command = new KMReplyListCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotForwardMsg()
{
   KMCommand *command = 0;
   if ( mReaderWin->message()->parent() ) {
    command = new KMForwardCommand( this, mReaderWin->message(),
        mReaderWin->message()->parent()->identity() );
   } else {
    command = new KMForwardCommand( this, mReaderWin->message() );
   }
   command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotForwardAttachedMsg()
{
   KMCommand *command = 0;
   if ( mReaderWin->message()->parent() ) {
     command = new KMForwardAttachedCommand( this, mReaderWin->message(),
        mReaderWin->message()->parent()->identity() );
   } else {
     command = new KMForwardAttachedCommand( this, mReaderWin->message() );
   }
   command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotRedirectMsg()
{
  KMCommand *command = new KMRedirectCommand( this, mReaderWin->message() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotBounceMsg()
{
  KMCommand *command = new KMBounceCommand( this, mReaderWin->message() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotConfigChanged()
{
  //readConfig();
}

void KMReaderMainWin::setupAccel()
{
  if (kmkernel->xmlGuiInstance())
    setInstance( kmkernel->xmlGuiInstance() );
  KStdAction::close( this, SLOT( close() ), actionCollection() );
  applyMainWindowSettings(KMKernel::config(), "Separate Reader Window");
  QAccel *accel = new QAccel(mReaderWin, "showMsg()");
  accel->connectItem(accel->insertItem(Key_Up),
                     mReaderWin, SLOT(slotScrollUp()));
  accel->connectItem(accel->insertItem(Key_Down),
                     mReaderWin, SLOT(slotScrollDown()));
  accel->connectItem(accel->insertItem(Key_Prior),
                     mReaderWin, SLOT(slotScrollPrior()));
  accel->connectItem(accel->insertItem(Key_Next),
                     mReaderWin, SLOT(slotScrollNext()));
  accel->connectItem(accel->insertItem(KStdAccel::shortcut(KStdAccel::Copy)),
                     mReaderWin, SLOT(slotCopySelectedText()));
  connect( mReaderWin, SIGNAL(popupMenu(KMMessage&,const KURL&,const QPoint&)),
	  this, SLOT(slotMsgPopup(KMMessage&,const KURL&,const QPoint&)));
  connect(mReaderWin, SIGNAL(urlClicked(const KURL&,int)),
	  mReaderWin, SLOT(slotUrlClicked()));

  mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"),
					"mail_forward", actionCollection(),
					"message_forward" );

  mForwardAction = new KAction( i18n("&Inline..."), "mail_forward",
				SHIFT+Key_F, this, SLOT(slotForwardMsg()),
				actionCollection(), "message_forward" );
  mForwardActionMenu->insert( mForwardAction );

  mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."),
				       "mail_forward", Key_F, this,
					SLOT(slotForwardAttachedMsg()), actionCollection(),
					"message_forward_as_attachment" );
  mForwardActionMenu->insert( mForwardAttachedAction );

  mRedirectAction = new KAction( i18n("Message->Forward->","&Redirect..."),
				 Key_E, this, SLOT(slotRedirectMsg()),
				 actionCollection(), "message_forward_redirect" );
  mForwardActionMenu->insert( mRedirectAction );

  mBounceAction = new KAction( i18n("&Bounce..."), 0, this,
			      SLOT(slotBounceMsg()), actionCollection(), "bounce" );

  mReplyActionMenu = new KActionMenu( i18n("Message->","&Reply"),
                                      "mail_reply", actionCollection(),
                                      "message_reply_menu" );
  connect( mReplyActionMenu, SIGNAL(activated()), this,
	   SLOT(slotReplyToMsg()) );

  mReplyAction = new KAction( i18n("&Reply..."), "mail_reply", Key_R, this,
			      SLOT(slotReplyToMsg()), actionCollection(), "reply" );
  mReplyActionMenu->insert( mReplyAction );

  mReplyAuthorAction = new KAction( i18n("Reply to A&uthor..."), "mail_reply",
                                    SHIFT+Key_A, this,
                                    SLOT(slotReplyAuthorToMsg()),
                                    actionCollection(), "reply_author" );
  mReplyActionMenu->insert( mReplyAuthorAction );

  mReplyAllAction = new KAction( i18n("Reply to &All..."), "mail_replyall",
				 Key_A, this, SLOT(slotReplyAllToMsg()),
				 actionCollection(), "reply_all" );
  mReplyActionMenu->insert( mReplyAllAction );

  mReplyListAction = new KAction( i18n("Reply to Mailing-&List..."),
				  "mail_replylist", Key_L, this,
				  SLOT(slotReplyListToMsg()), actionCollection(),
				  "reply_list" );
  mReplyActionMenu->insert( mReplyListAction );

  mPrintAction = KStdAction::print (this, SLOT(slotPrintMsg()), actionCollection());
  createGUI( "kmreadermainwin.rc" );
  menuBar()->hide();
  toolBar( "mainToolBar" )->hide();
}

void KMReaderMainWin::slotMsgPopup(KMMessage &aMsg, const KURL &aUrl, const QPoint& aPoint)
{
  KPopupMenu * menu = new KPopupMenu;
  mUrl = aUrl;
  mMsg = &aMsg;

  if (!aUrl.isEmpty()) {
    if (aUrl.protocol() == "mailto") {
      // popup on a mailto URL
      mReaderWin->mailToComposeAction()->plug( menu );
      if ( mMsg ) {
	mReaderWin->mailToReplyAction()->plug( menu );
	mReaderWin->mailToForwardAction()->plug( menu );
        menu->insertSeparator();
      }
      mReaderWin->addAddrBookAction()->plug( menu );
      mReaderWin->openAddrBookAction()->plug( menu );
      mReaderWin->copyAction()->plug( menu );
    } else {
      // popup on a not-mailto URL
      mReaderWin->urlOpenAction()->plug( menu );
      mReaderWin->urlSaveAsAction()->plug( menu );
      mReaderWin->copyURLAction()->plug( menu );
      mReaderWin->addBookmarksAction()->plug( menu );
    }
  } else {
    // popup somewhere else (i.e., not a URL) on the message

    if (!mMsg) // no message
    {
      delete menu;
      return;
    }

    mReplyAction->plug( menu );
    mReplyAllAction->plug( menu );
    mReplyAuthorAction->plug( menu );
    mReplyListAction->plug( menu );
    mForwardActionMenu->plug( menu );
    mBounceAction->plug( menu );

    menu->insertSeparator();

    QPopupMenu* copyMenu = new QPopupMenu(menu);
    KMMenuCommand::folderToPopupMenu( false, this, &mMenuToFolder, copyMenu );
    menu->insertItem( i18n("&Copy To" ), copyMenu );
    menu->insertSeparator();
    mReaderWin->toggleFixFontAction()->plug( menu );
    mReaderWin->viewSourceAction()->plug( menu );

    mPrintAction->plug( menu );
    menu->insertItem(  SmallIcon("filesaveas"), i18n( "Save &As..." ), mReaderWin, SLOT( slotSaveMsg() ) );
    menu->insertItem( i18n("Save Attachments..."), mReaderWin, SLOT(slotSaveAttachments()) );
  }
  menu->exec(aPoint, 0);
  delete menu;
}

void KMReaderMainWin::copySelectedToFolder( int menuId )
{
  if (!mMenuToFolder[menuId])
    return;

  KMCommand *command = new KMCopyCommand( mMenuToFolder[menuId], mMsg );
  command->start();
}
<|endoftext|>


<commit_before>/***************************************************************************
                          knarticlewindow.cpp  -  description
                             -------------------

    copyright            : (C) 2000 by Christian Thurner
    email                : cthurner@freepage.de
 ***************************************************************************/

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

#include <kstdaction.h>
#include <klocale.h>
#include <kedittoolbar.h>
#include <kkeydialog.h>
#include <khtml_part.h>

#include "kngroup.h"
#include "knsavedarticle.h"
#include "knfetcharticle.h"
#include "knarticlewidget.h"
#include "knsavedarticlemanager.h"
#include "utilities.h"
#include "knglobals.h"
#include "knode.h"
#include "knarticlewindow.h"

KNArticleWindow::KNArticleWindow(KNArticle *art, KNArticleCollection *col, const char *name )
  : KMainWindow(0, name)
{
  if(art)
    setCaption(art->subject());
  //setIcon(UserIcon("posting"));

  artW=new KNArticleWidget(this);
  artW->setData(art, col);
  setCentralWidget(artW);
  connect(artW, SIGNAL(articleLoaded()), SLOT(slotArticleLoaded()));

  *actionCollection() += artW->actions();        // include the actions of the article widget

  // file menu
  KStdAction::close(this, SLOT(slotFileClose()),actionCollection());

  // article menu
  actPostReply = new KAction(i18n("Post &reply"),"reply", Key_R , this, SLOT(slotArtReply()),
                             actionCollection(), "article_postReply");
  actPostReply->setEnabled(false);
  actMailReply = new KAction(i18n("&Mail reply"),"mail_reply", Key_A , this, SLOT(slotArtRemail()),
                             actionCollection(), "article_mailReply");
  actMailReply->setEnabled(false);
  actForward = new KAction(i18n("&Forward"), "mail_forward", Key_F , this, SLOT(slotArtForward()),
                           actionCollection(), "article_forward");
  actForward->setEnabled(false);
  actCancel = new KAction(i18n("article","&Cancel"), 0 , this, SLOT(slotArtCancel()),
                          actionCollection(), "article_cancel");
  actCancel->setEnabled(false);
  actSupersede = new KAction(i18n("&Supersede"), 0 , this, SLOT(slotArtSupersede()),
                             actionCollection(), "article_supersede");
  actSupersede->setEnabled(false);

  // settings menu
  KStdAction::showToolbar(this, SLOT(slotToggleToolBar()), actionCollection());
  KStdAction::keyBindings(this, SLOT(slotConfKeys()), actionCollection());
  KStdAction::configureToolbars(this, SLOT(slotConfToolbar()), actionCollection());
  KStdAction::preferences(knGlobals.top, SLOT(slotSettings()), actionCollection());

  createGUI("knreaderui.rc");

  restoreWindowSize("reader", this, QSize(500,400));
}

KNArticleWindow::~KNArticleWindow()
{
  saveWindowSize("reader", size());
}

void KNArticleWindow::slotArticleLoaded()
{
  actPostReply->setEnabled(true);
  actMailReply->setEnabled(true);
  actForward->setEnabled(true);
  actCancel->setEnabled(true);
  actSupersede->setEnabled(true);
}

void KNArticleWindow::slotFileClose()
{
  close();
}

void KNArticleWindow::slotArtReply()
{
  knGlobals.sArtManager->reply(artW->article(),static_cast<KNGroup*>(artW->collection()));
}

void KNArticleWindow::slotArtRemail()
{
  knGlobals.sArtManager->reply(artW->article(), 0);
}

void KNArticleWindow::slotArtForward()
{
  knGlobals.sArtManager->forward(artW->article());
}

void KNArticleWindow::slotArtCancel()
{
  knGlobals.sArtManager->cancel(static_cast<KNFetchArticle*>(artW->article()),static_cast<KNGroup*>(artW->collection()));
}

void KNArticleWindow::slotArtSupersede()
{
  knGlobals.sArtManager->supersede(static_cast<KNFetchArticle*>(artW->article()),static_cast<KNGroup*>(artW->collection()));
}

void KNArticleWindow::slotToggleToolBar()
{
  if(toolBar("mainToolBar")->isVisible())
    toolBar("mainToolBar")->hide();
  else
    toolBar("mainToolBar")->show();
}

void KNArticleWindow::slotConfKeys()
{
  KKeyDialog::configureKeys(actionCollection(), xmlFile(), true, this);
}

void KNArticleWindow::slotConfToolbar()
{
  KEditToolbar *dlg = new KEditToolbar(guiFactory(),this);
  if (dlg->exec()) {
    //guiFactory()->removeClient(artW->part());
    createGUI("knreaderui.rc",false);
    //guiFactory()->addClient(artW->part());
    conserveMemory();
  }
  delete dlg;
}

//--------------------------------

#include "knarticlewindow.moc"
<commit_msg>-  actPostReply = new KAction(i18n("Post &reply"),"reply", Key_R , this, SLOT(slotArtReply()), +  actPostReply = new KAction(i18n("Post &reply"),"message_reply", Key_R , this, SLOT(slotArtReply()),<commit_after>/***************************************************************************
                          knarticlewindow.cpp  -  description
                             -------------------

    copyright            : (C) 2000 by Christian Thurner
    email                : cthurner@freepage.de
 ***************************************************************************/

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

#include <kstdaction.h>
#include <klocale.h>
#include <kedittoolbar.h>
#include <kkeydialog.h>
#include <khtml_part.h>

#include "kngroup.h"
#include "knsavedarticle.h"
#include "knfetcharticle.h"
#include "knarticlewidget.h"
#include "knsavedarticlemanager.h"
#include "utilities.h"
#include "knglobals.h"
#include "knode.h"
#include "knarticlewindow.h"

KNArticleWindow::KNArticleWindow(KNArticle *art, KNArticleCollection *col, const char *name )
  : KMainWindow(0, name)
{
  if(art)
    setCaption(art->subject());
  //setIcon(UserIcon("posting"));

  artW=new KNArticleWidget(this);
  artW->setData(art, col);
  setCentralWidget(artW);
  connect(artW, SIGNAL(articleLoaded()), SLOT(slotArticleLoaded()));

  *actionCollection() += artW->actions();        // include the actions of the article widget

  // file menu
  KStdAction::close(this, SLOT(slotFileClose()),actionCollection());

  // article menu
  actPostReply = new KAction(i18n("Post &reply"),"message_reply", Key_R , this, SLOT(slotArtReply()),
                             actionCollection(), "article_postReply");
  actPostReply->setEnabled(false);
  actMailReply = new KAction(i18n("&Mail reply"),"mail_reply", Key_A , this, SLOT(slotArtRemail()),
                             actionCollection(), "article_mailReply");
  actMailReply->setEnabled(false);
  actForward = new KAction(i18n("&Forward"), "mail_forward", Key_F , this, SLOT(slotArtForward()),
                           actionCollection(), "article_forward");
  actForward->setEnabled(false);
  actCancel = new KAction(i18n("article","&Cancel"), 0 , this, SLOT(slotArtCancel()),
                          actionCollection(), "article_cancel");
  actCancel->setEnabled(false);
  actSupersede = new KAction(i18n("&Supersede"), 0 , this, SLOT(slotArtSupersede()),
                             actionCollection(), "article_supersede");
  actSupersede->setEnabled(false);

  // settings menu
  KStdAction::showToolbar(this, SLOT(slotToggleToolBar()), actionCollection());
  KStdAction::keyBindings(this, SLOT(slotConfKeys()), actionCollection());
  KStdAction::configureToolbars(this, SLOT(slotConfToolbar()), actionCollection());
  KStdAction::preferences(knGlobals.top, SLOT(slotSettings()), actionCollection());

  createGUI("knreaderui.rc");

  restoreWindowSize("reader", this, QSize(500,400));
}

KNArticleWindow::~KNArticleWindow()
{
  saveWindowSize("reader", size());
}

void KNArticleWindow::slotArticleLoaded()
{
  actPostReply->setEnabled(true);
  actMailReply->setEnabled(true);
  actForward->setEnabled(true);
  actCancel->setEnabled(true);
  actSupersede->setEnabled(true);
}

void KNArticleWindow::slotFileClose()
{
  close();
}

void KNArticleWindow::slotArtReply()
{
  knGlobals.sArtManager->reply(artW->article(),static_cast<KNGroup*>(artW->collection()));
}

void KNArticleWindow::slotArtRemail()
{
  knGlobals.sArtManager->reply(artW->article(), 0);
}

void KNArticleWindow::slotArtForward()
{
  knGlobals.sArtManager->forward(artW->article());
}

void KNArticleWindow::slotArtCancel()
{
  knGlobals.sArtManager->cancel(static_cast<KNFetchArticle*>(artW->article()),static_cast<KNGroup*>(artW->collection()));
}

void KNArticleWindow::slotArtSupersede()
{
  knGlobals.sArtManager->supersede(static_cast<KNFetchArticle*>(artW->article()),static_cast<KNGroup*>(artW->collection()));
}

void KNArticleWindow::slotToggleToolBar()
{
  if(toolBar("mainToolBar")->isVisible())
    toolBar("mainToolBar")->hide();
  else
    toolBar("mainToolBar")->show();
}

void KNArticleWindow::slotConfKeys()
{
  KKeyDialog::configureKeys(actionCollection(), xmlFile(), true, this);
}

void KNArticleWindow::slotConfToolbar()
{
  KEditToolbar *dlg = new KEditToolbar(guiFactory(),this);
  if (dlg->exec()) {
    //guiFactory()->removeClient(artW->part());
    createGUI("knreaderui.rc",false);
    //guiFactory()->addClient(artW->part());
    conserveMemory();
  }
  delete dlg;
}

//--------------------------------

#include "knarticlewindow.moc"
<|endoftext|>


<commit_before>/*
    KNode, the KDE newsreader
    Copyright (c) 1999-2005 the KNode authors.
    See file AUTHORS for details

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software Foundation,
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
*/

#include <kdebug.h>

#include "knmemorymanager.h"
#include "knfolder.h"
#include "knglobals.h"
#include "knconfigmanager.h"
#include "knarticlemanager.h"
#include "kngroupmanager.h"
#include "knfoldermanager.h"

KNMemoryManager::KNMemoryManager()
  : c_ollCacheSize(0), a_rtCacheSize(0)
{
}

KNMemoryManager::~KNMemoryManager()
{
  for ( QValueList<CollectionItem*>::Iterator it = mColList.begin(); it != mColList.end(); ++it )
    delete (*it);
  for ( QValueList<ArticleItem*>::Iterator it = mArtList.begin(); it != mArtList.end(); ++it )
    delete (*it);
}

void KNMemoryManager::updateCacheEntry(KNArticleCollection *c)
{
  CollectionItem *ci;
  int oldSize=0;

  if( (ci=findCacheEntry(c, true)) ) { // item is taken from the list
    oldSize=ci->storageSize;
    ci->sync();
    kdDebug(5003) << "KNMemoryManager::updateCacheEntry() : collection (" << c->name() << ") updated" << endl;
  }
  else {
    ci=new CollectionItem(c);
    kdDebug(5003) << "KNMemoryManager::updateCacheEntry() : collection (" << c->name() << ") added" << endl;
  }

  mColList.append(ci);
  c_ollCacheSize += (ci->storageSize - oldSize);
  checkMemoryUsageCollections();
}

void KNMemoryManager::removeCacheEntry(KNArticleCollection *c)
{
  CollectionItem *ci;
  ci=findCacheEntry(c, true);

  if(ci) {
    c_ollCacheSize -= ci->storageSize;
    delete ci;

    kdDebug(5003) << "KNMemoryManager::removeCacheEntry() : collection removed (" << c->name() << "), "
                  << mColList.count() << " collections left in cache" << endl;
  }
}

void KNMemoryManager::prepareLoad(KNArticleCollection *c)
{
  CollectionItem ci(c);

  c_ollCacheSize += ci.storageSize;
  checkMemoryUsageCollections();
  c_ollCacheSize -= ci.storageSize;
}

void KNMemoryManager::updateCacheEntry(KNArticle *a)
{
  ArticleItem *ai;
  int oldSize=0;

  if( (ai=findCacheEntry(a, true)) ) {
    oldSize=ai->storageSize;
    ai->sync();
    kdDebug(5003) << "KNMemoryManager::updateCacheEntry() : article updated" << endl;
  }
  else {
    ai=new ArticleItem(a);
    kdDebug(5003) << "KNMemoryManager::updateCacheEntry() : article added" << endl;
  }

  mArtList.append(ai);
  a_rtCacheSize += (ai->storageSize - oldSize);
  checkMemoryUsageArticles();
}

void KNMemoryManager::removeCacheEntry(KNArticle *a)
{
  ArticleItem *ai;

  if( (ai=findCacheEntry(a, true)) ) {
    a_rtCacheSize -= ai->storageSize;
    delete ai;

    kdDebug(5003) << "KNMemoryManager::removeCacheEntry() : article removed, "
                  << mArtList.count() << " articles left in cache" << endl;

  }
}

KNMemoryManager::CollectionItem* KNMemoryManager::findCacheEntry(KNArticleCollection *c, bool take)
{
  for ( QValueList<CollectionItem*>::Iterator it = mColList.begin(); it != mColList.end(); ++it ) {
    if ( (*it)->col == c ) {
      if ( take )
        mColList.remove( it );
      return (*it);
    }
  }

  return 0;
}

KNMemoryManager::ArticleItem* KNMemoryManager::findCacheEntry(KNArticle *a, bool take)
{
  for ( QValueList<ArticleItem*>::Iterator it = mArtList.begin(); it != mArtList.end(); ++it ) {
    if ( (*it)->art == a ) {
      if ( take )
        mArtList.remove( it );
      return (*it);
    }
  }

  return 0;
}

void KNMemoryManager::checkMemoryUsageCollections()
{
  int maxSize = knGlobals.configManager()->readNewsGeneral()->collCacheSize() * 1024;
  KNArticleCollection *c=0;

  if (c_ollCacheSize > maxSize) {
    QValueList<CollectionItem*> tempList( mColList ); // work on a copy, KNGroup-/Foldermanager will
                                                      // modify the original list

    for ( QValueList<CollectionItem*>::Iterator it = tempList.begin(); it != tempList.end(); ) {
      if ( c_ollCacheSize <= maxSize )
        break;
      // unloadHeaders() will remove the cache entry and thus invalidate the iterator!
      c = (*it)->col;
      ++it;

      if (c->type() == KNCollection::CTgroup)
        knGlobals.groupManager()->unloadHeaders(static_cast<KNGroup*>(c), false);   // *try* to unload
      else
        if (c->type() == KNCollection::CTfolder)
          knGlobals.folderManager()->unloadHeaders(static_cast<KNFolder*>(c), false);   // *try* to unload
    }
  }

  kdDebug(5003) << "KNMemoryManager::checkMemoryUsageCollections() : "
                << mColList.count() << " collections in cache => Usage : "
                << ( c_ollCacheSize*100.0 / maxSize ) << "%" << endl;
}

void KNMemoryManager::checkMemoryUsageArticles()
{
  int maxSize = knGlobals.configManager()->readNewsGeneral()->artCacheSize() * 1024;

  if (a_rtCacheSize > maxSize) {
    QValueList<ArticleItem*> tempList( mArtList ); // work on a copy, KNArticlemanager will
                                                   // modify the original list

    for ( QValueList<ArticleItem*>::Iterator it = mArtList.begin(); it != mArtList.end(); ) {
      if ( a_rtCacheSize <= maxSize )
        break;
      // unloadArticle() will remove the cache entry and thus invalidate the iterator!
      KNArticle *art = (*it)->art;
      ++it;
      knGlobals.articleManager()->unloadArticle( art, false );   // *try* to unload
    }
  }

  kdDebug(5003) << "KNMemoryManager::checkMemoryUsageArticles() : "
                << mArtList.count() << " articles in cache => Usage : "
                << ( a_rtCacheSize*100.0 / maxSize ) << "%" << endl;
}

void KNMemoryManager::ArticleItem::sync()
{
  storageSize=art->storageSize();
}

void KNMemoryManager::CollectionItem::sync()
{
  storageSize=col->length()*1024; // rule of thumb : ~1k per header
}

<commit_msg>Fix crash.<commit_after>/*
    KNode, the KDE newsreader
    Copyright (c) 1999-2005 the KNode authors.
    See file AUTHORS for details

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software Foundation,
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
*/

#include <kdebug.h>

#include "knmemorymanager.h"
#include "knfolder.h"
#include "knglobals.h"
#include "knconfigmanager.h"
#include "knarticlemanager.h"
#include "kngroupmanager.h"
#include "knfoldermanager.h"

KNMemoryManager::KNMemoryManager()
  : c_ollCacheSize(0), a_rtCacheSize(0)
{
}

KNMemoryManager::~KNMemoryManager()
{
  for ( QValueList<CollectionItem*>::Iterator it = mColList.begin(); it != mColList.end(); ++it )
    delete (*it);
  for ( QValueList<ArticleItem*>::Iterator it = mArtList.begin(); it != mArtList.end(); ++it )
    delete (*it);
}

void KNMemoryManager::updateCacheEntry(KNArticleCollection *c)
{
  CollectionItem *ci;
  int oldSize=0;

  if( (ci=findCacheEntry(c, true)) ) { // item is taken from the list
    oldSize=ci->storageSize;
    ci->sync();
    kdDebug(5003) << "KNMemoryManager::updateCacheEntry() : collection (" << c->name() << ") updated" << endl;
  }
  else {
    ci=new CollectionItem(c);
    kdDebug(5003) << "KNMemoryManager::updateCacheEntry() : collection (" << c->name() << ") added" << endl;
  }

  mColList.append(ci);
  c_ollCacheSize += (ci->storageSize - oldSize);
  checkMemoryUsageCollections();
}

void KNMemoryManager::removeCacheEntry(KNArticleCollection *c)
{
  CollectionItem *ci;
  ci=findCacheEntry(c, true);

  if(ci) {
    c_ollCacheSize -= ci->storageSize;
    delete ci;

    kdDebug(5003) << "KNMemoryManager::removeCacheEntry() : collection removed (" << c->name() << "), "
                  << mColList.count() << " collections left in cache" << endl;
  }
}

void KNMemoryManager::prepareLoad(KNArticleCollection *c)
{
  CollectionItem ci(c);

  c_ollCacheSize += ci.storageSize;
  checkMemoryUsageCollections();
  c_ollCacheSize -= ci.storageSize;
}

void KNMemoryManager::updateCacheEntry(KNArticle *a)
{
  ArticleItem *ai;
  int oldSize=0;

  if( (ai=findCacheEntry(a, true)) ) {
    oldSize=ai->storageSize;
    ai->sync();
    kdDebug(5003) << "KNMemoryManager::updateCacheEntry() : article updated" << endl;
  }
  else {
    ai=new ArticleItem(a);
    kdDebug(5003) << "KNMemoryManager::updateCacheEntry() : article added" << endl;
  }

  mArtList.append(ai);
  a_rtCacheSize += (ai->storageSize - oldSize);
  checkMemoryUsageArticles();
}

void KNMemoryManager::removeCacheEntry(KNArticle *a)
{
  ArticleItem *ai;

  if( (ai=findCacheEntry(a, true)) ) {
    a_rtCacheSize -= ai->storageSize;
    delete ai;

    kdDebug(5003) << "KNMemoryManager::removeCacheEntry() : article removed, "
                  << mArtList.count() << " articles left in cache" << endl;

  }
}

KNMemoryManager::CollectionItem* KNMemoryManager::findCacheEntry(KNArticleCollection *c, bool take)
{
  for ( QValueList<CollectionItem*>::Iterator it = mColList.begin(); it != mColList.end(); ++it ) {
    if ( (*it)->col == c ) {
      CollectionItem *ret = (*it);
      if ( take )
        mColList.remove( it );
      return ret;
    }
  }

  return 0;
}

KNMemoryManager::ArticleItem* KNMemoryManager::findCacheEntry(KNArticle *a, bool take)
{
  for ( QValueList<ArticleItem*>::Iterator it = mArtList.begin(); it != mArtList.end(); ++it ) {
    if ( (*it)->art == a ) {
      ArticleItem *ret = (*it);
      if ( take )
        mArtList.remove( it );
      return ret;
    }
  }

  return 0;
}

void KNMemoryManager::checkMemoryUsageCollections()
{
  int maxSize = knGlobals.configManager()->readNewsGeneral()->collCacheSize() * 1024;
  KNArticleCollection *c=0;

  if (c_ollCacheSize > maxSize) {
    QValueList<CollectionItem*> tempList( mColList ); // work on a copy, KNGroup-/Foldermanager will
                                                      // modify the original list

    for ( QValueList<CollectionItem*>::Iterator it = tempList.begin(); it != tempList.end(); ) {
      if ( c_ollCacheSize <= maxSize )
        break;
      // unloadHeaders() will remove the cache entry and thus invalidate the iterator!
      c = (*it)->col;
      ++it;

      if (c->type() == KNCollection::CTgroup)
        knGlobals.groupManager()->unloadHeaders(static_cast<KNGroup*>(c), false);   // *try* to unload
      else
        if (c->type() == KNCollection::CTfolder)
          knGlobals.folderManager()->unloadHeaders(static_cast<KNFolder*>(c), false);   // *try* to unload
    }
  }

  kdDebug(5003) << "KNMemoryManager::checkMemoryUsageCollections() : "
                << mColList.count() << " collections in cache => Usage : "
                << ( c_ollCacheSize*100.0 / maxSize ) << "%" << endl;
}

void KNMemoryManager::checkMemoryUsageArticles()
{
  int maxSize = knGlobals.configManager()->readNewsGeneral()->artCacheSize() * 1024;

  if (a_rtCacheSize > maxSize) {
    QValueList<ArticleItem*> tempList( mArtList ); // work on a copy, KNArticlemanager will
                                                   // modify the original list

    for ( QValueList<ArticleItem*>::Iterator it = mArtList.begin(); it != mArtList.end(); ) {
      if ( a_rtCacheSize <= maxSize )
        break;
      // unloadArticle() will remove the cache entry and thus invalidate the iterator!
      KNArticle *art = (*it)->art;
      ++it;
      knGlobals.articleManager()->unloadArticle( art, false );   // *try* to unload
    }
  }

  kdDebug(5003) << "KNMemoryManager::checkMemoryUsageArticles() : "
                << mArtList.count() << " articles in cache => Usage : "
                << ( a_rtCacheSize*100.0 / maxSize ) << "%" << endl;
}

void KNMemoryManager::ArticleItem::sync()
{
  storageSize=art->storageSize();
}

void KNMemoryManager::CollectionItem::sync()
{
  storageSize=col->length()*1024; // rule of thumb : ~1k per header
}

<|endoftext|>


<commit_before>/*
    This file is part of KOrganizer.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

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

    This program 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 General Public License for more details.

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

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "urihandler.h"

#ifndef KORG_NODCOP
#include <dcopclient.h>
#include "kmailIface_stub.h"
#endif

#include <kiconloader.h>
#include <krun.h>
#include <kapplication.h>
#include <kprocess.h>
#include <kdebug.h>

bool UriHandler::process( const QString &uri )
{
  kdDebug(5850) << "UriHandler::process(): " << uri << endl;

#ifndef KORG_NODCOP
  if ( uri.startsWith( "kmail:" ) ) {
    // make sure kmail is running or the part is shown
    kapp->startServiceByDesktopPath("kmail");
    // parse string, show
    int start = uri.find( ':' ) + 1;
    int delimiter = uri.find( '/', start );
    QString serialNumberStr = uri.mid( start, delimiter-start );
    Q_UINT32 serialNumber = serialNumberStr.toUInt();
    QString messageId = uri.mid( delimiter+1 );
    kdDebug(5850) << "SERIALNUMBERSTR: " << serialNumberStr << " MESSAGEID: "
      << messageId << endl;
    KMailIface_stub kmailIface( "kmail", "KMailIface" );
    kmailIface.showMail( serialNumber, messageId );
    return true;
  } else if ( uri.startsWith( "mailto:" ) ) {
    KApplication::kApplication()->invokeMailer( uri.mid(7), QString::null );
    return true;
  } else if ( uri.startsWith( "uid:" ) ) {
    DCOPClient *client = KApplication::kApplication()->dcopClient();
    const QByteArray noParamData;
    const QByteArray paramData;
    QByteArray replyData;
    QCString replyTypeStr;
    bool foundAbbrowser = client->call( "kaddressbook", "KAddressBookIface",
                                        "interfaces()",  noParamData,
                                        replyTypeStr, replyData );
    if ( foundAbbrowser ) {
      //KAddressbook is already running, so just DCOP to it to bring up the contact editor
      //client->send("kaddressbook","KAddressBookIface",
      QDataStream arg( paramData, IO_WriteOnly );
      arg << uri.mid( 6 );
#if KDE_IS_VERSION( 3, 2, 90 )
      kapp->updateRemoteUserTimestamp("kaddressbook");
#endif
      client->send( "kaddressbook", "KAddressBookIface",
                    "showContactEditor( QString )", paramData );
      return true;
    } else {
      /*
        KaddressBook is not already running.  Pass it the UID of the contact via the command line while starting it - its neater.
        We start it without its main interface
      */
      KIconLoader *iconLoader = new KIconLoader();
      QString iconPath = iconLoader->iconPath( "go", KIcon::Small );
      QString tmpStr = "kaddressbook --editor-only --uid ";
      tmpStr += KProcess::quote( uri.mid( 6 ) );
      KRun::runCommand( tmpStr, "KAddressBook", iconPath );
      return true;
    }
  }
  else {  // no special URI, let KDE handle it
    new KRun(KURL( uri ));
  }
#endif

  return false;
}
<commit_msg>Backport fix for failing DCOP call<commit_after>/*
    This file is part of KOrganizer.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

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

    This program 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 General Public License for more details.

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

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "urihandler.h"

#ifndef KORG_NODCOP
#include <dcopclient.h>
#include "kmailIface_stub.h"
#endif

#include <kiconloader.h>
#include <krun.h>
#include <kapplication.h>
#include <kprocess.h>
#include <kdebug.h>

bool UriHandler::process( const QString &uri )
{
  kdDebug(5850) << "UriHandler::process(): " << uri << endl;

#ifndef KORG_NODCOP
  if ( uri.startsWith( "kmail:" ) ) {
    // make sure kmail is running or the part is shown
    kapp->startServiceByDesktopPath("kmail");
    // parse string, show
    int start = uri.find( ':' ) + 1;
    int delimiter = uri.find( '/', start );
    QString serialNumberStr = uri.mid( start, delimiter-start );
    Q_UINT32 serialNumber = serialNumberStr.toUInt();
    QString messageId = uri.mid( delimiter+1 );
    kdDebug(5850) << "SERIALNUMBERSTR: " << serialNumberStr << " MESSAGEID: "
      << messageId << endl;
    KMailIface_stub kmailIface( "kmail", "KMailIface" );
    kmailIface.showMail( serialNumber, messageId );
    return true;
  } else if ( uri.startsWith( "mailto:" ) ) {
    KApplication::kApplication()->invokeMailer( uri.mid(7), QString::null );
    return true;
  } else if ( uri.startsWith( "uid:" ) ) {
    DCOPClient *client = KApplication::kApplication()->dcopClient();
    const QByteArray noParamData;
    const QByteArray paramData;
    QByteArray replyData;
    QCString replyTypeStr;
    bool foundAbbrowser = client->call( "kaddressbook", "KAddressBookIface",
                                        "interfaces()",  noParamData,
                                        replyTypeStr, replyData );
    if ( foundAbbrowser ) {
      //KAddressbook is already running, so just DCOP to it to bring up the contact editor
#if KDE_IS_VERSION( 3, 2, 90 )
      kapp->updateRemoteUserTimestamp("kaddressbook");
#endif
      DCOPRef kaddressbook( "kaddressbook", "KAddressBookIface" );
      kaddressbook.send( "showContactEditor", uri.mid( 6 ) );
      return true;
    } else {
      /*
        KaddressBook is not already running.  Pass it the UID of the contact via the command line while starting it - its neater.
        We start it without its main interface
      */
      KIconLoader *iconLoader = new KIconLoader();
      QString iconPath = iconLoader->iconPath( "go", KIcon::Small );
      QString tmpStr = "kaddressbook --editor-only --uid ";
      tmpStr += KProcess::quote( uri.mid( 6 ) );
      KRun::runCommand( tmpStr, "KAddressBook", iconPath );
      return true;
    }
  }
  else {  // no special URI, let KDE handle it
    new KRun(KURL( uri ));
  }
#endif

  return false;
}
<|endoftext|>


<commit_before>// Copyright 2019 DeepMind Technologies Ltd. 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.

#include "open_spiel/bots/human/human_bot.h"

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>

namespace open_spiel {
namespace {

const int kMaxWidth = 80;
const int kPadding = 2;

void PrintColumns(const std::vector<std::string>& strings) {
  std::string padding_string(kPadding, ' ');

  int longest_string_length = 0;
  for (const std::string& string : strings) {
    if (string.length() > longest_string_length) {
      longest_string_length = string.length();
    }
  }

  int max_columns = (kMaxWidth - 1) / (longest_string_length + 2 * kPadding);
  int rows = ceil((float) strings.size() / (float) max_columns);
  int columns = ceil((float) strings.size() / (float) rows);
  for (int row = 0; row < rows; ++row) {
    for (int column = 0; column < columns; ++column) {
      int index = row + column * rows;
      if (index < strings.size()) {
        std::cout << std::left << std::setw(longest_string_length + kPadding)
                  << padding_string << strings[index];
      }
    }
    std::cout << "\n";
  }
}

}  // namespace

Action HumanBot::Step(const State& state) {
  std::vector<Action> legal_actions = state.LegalActions(state.CurrentPlayer());

  if (legal_actions.empty()) {
    return kInvalidAction;
  }

  std::unordered_map<std::string, Action> action_map;
  for (Action legal_action : legal_actions) {
    action_map[state.ActionToString(legal_action)] = legal_action;
  }

  while (true) {
    Action action;
    std::string action_string = "";

    std::cout << "Choose an action (empty to print legal actions): ";
    std::getline(std::cin, action_string);

    // Print the legal actions if no action is given.
    if (action_string.empty()) {
      std::cout << "Legal action(s):\n";

      std::vector<std::string> legal_action_strings;
      std::vector<std::pair<std::string, Action>> sorted_action_map(
          action_map.begin(), action_map.end());

      std::sort(sorted_action_map.begin(),
                sorted_action_map.end(),
                [](const auto& left, const auto& right) {
                  return left.first.compare(right.first);
                });

      int longest_action_length = 0;
      for (const Action& legal_action : legal_actions) {
        int action_length = std::to_string(legal_action).length();
        if (action_length > longest_action_length) {
          longest_action_length = action_length;
        }
      }

      for (const auto& string_action_pair : sorted_action_map) {
        std::string action_string = string_action_pair.first;
        std::string action_int_string =
            std::to_string(string_action_pair.second);
        std::string action_padding(
            longest_action_length - action_int_string.length(), ' ');
        legal_action_strings.push_back(absl::StrCat(
            action_padding, action_int_string, ": ", action_string));
      }
      PrintColumns(legal_action_strings);
      continue;
    }

    // Return the action if a valid string is given.
    if (action_map.find(action_string) != action_map.end()) {
      return action_map[action_string];
    }

    // Return the action if a valid integer is given.
    try {
      action = std::stoi(action_string);
    } catch (const std::exception& e) {
      std::cout << "Could not parse the action: " << action_string << "\n";
      continue;
    }

    for (Action legal_action : legal_actions) {
      if (action == legal_action) {
        return action;
      }
    }

    // The input was not valid.
    std::cout << "Illegal action selected: " << action_string << "\n";
  }
}

}  // namespace open_spiel
<commit_msg>Flush output in human bot<commit_after>// Copyright 2019 DeepMind Technologies Ltd. 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.

#include "open_spiel/bots/human/human_bot.h"

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>

namespace open_spiel {
namespace {

const int kMaxWidth = 80;
const int kPadding = 2;

void PrintColumns(const std::vector<std::string>& strings) {
  std::string padding_string(kPadding, ' ');

  int longest_string_length = 0;
  for (const std::string& string : strings) {
    if (string.length() > longest_string_length) {
      longest_string_length = string.length();
    }
  }

  int max_columns = (kMaxWidth - 1) / (longest_string_length + 2 * kPadding);
  int rows = ceil((float) strings.size() / (float) max_columns);
  int columns = ceil((float) strings.size() / (float) rows);
  for (int row = 0; row < rows; ++row) {
    for (int column = 0; column < columns; ++column) {
      int index = row + column * rows;
      if (index < strings.size()) {
        std::cout << std::left << std::setw(longest_string_length + kPadding)
                  << padding_string << strings[index];
      }
    }
    std::cout << std::endl;
  }
}

}  // namespace

Action HumanBot::Step(const State& state) {
  std::vector<Action> legal_actions = state.LegalActions(state.CurrentPlayer());

  if (legal_actions.empty()) {
    return kInvalidAction;
  }

  std::unordered_map<std::string, Action> action_map;
  for (Action legal_action : legal_actions) {
    action_map[state.ActionToString(legal_action)] = legal_action;
  }

  while (true) {
    Action action;
    std::string action_string = "";

    std::cout << "Choose an action (empty to print legal actions): ";
    std::getline(std::cin, action_string);

    // Print the legal actions if no action is given.
    if (action_string.empty()) {
      std::cout << "Legal action(s):" << std::endl;

      std::vector<std::string> legal_action_strings;
      std::vector<std::pair<std::string, Action>> sorted_action_map(
          action_map.begin(), action_map.end());

      std::sort(sorted_action_map.begin(),
                sorted_action_map.end(),
                [](const auto& left, const auto& right) {
                  return left.first.compare(right.first);
                });

      int longest_action_length = 0;
      for (const Action& legal_action : legal_actions) {
        int action_length = std::to_string(legal_action).length();
        if (action_length > longest_action_length) {
          longest_action_length = action_length;
        }
      }

      for (const auto& string_action_pair : sorted_action_map) {
        std::string action_string = string_action_pair.first;
        std::string action_int_string =
            std::to_string(string_action_pair.second);
        std::string action_padding(
            longest_action_length - action_int_string.length(), ' ');
        legal_action_strings.push_back(absl::StrCat(
            action_padding, action_int_string, ": ", action_string));
      }
      PrintColumns(legal_action_strings);
      continue;
    }

    // Return the action if a valid string is given.
    if (action_map.find(action_string) != action_map.end()) {
      return action_map[action_string];
    }

    // Return the action if a valid integer is given.
    try {
      action = std::stoi(action_string);
    } catch (const std::exception& e) {
      std::cout << "Could not parse the action: " << action_string << std::endl;
      continue;
    }

    for (Action legal_action : legal_actions) {
      if (action == legal_action) {
        return action;
      }
    }

    // The input was not valid.
    std::cout << "Illegal action selected: " << action_string << std::endl;
  }
}

}  // namespace open_spiel
<|endoftext|>