<commit_before>/*
 * Copyright 2004-2014 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is 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 "optimizations.h"

#include "astutil.h"
#include "bb.h"
#include "expr.h"
#include "passes.h"
#include "stlUtil.h"
#include "stmt.h"
#include "view.h"

#include <queue>
#include <set>

//
// Static function declarations.
//
static void deadBlockElimination(FnSymbol* fn);
// static void deadGotoElimination(FnSymbol* fn);

// Static variables.
static unsigned deadBlockCount;
static unsigned deadModuleCount;

// Determines if an expr is used inside of the header for a c for loop. c for
// loop header is of the form '"c for loop" {inits}, {test}, {incrs}'
//
// Only returns true for exprs in the init, test, incr blocks, not for the
// blocks themselves.
//
// TODO should this be updated to only look for exprs in the test segment that
// are conditional primitives?
static bool isInCForLoopHeader(Expr* expr) {
  if (expr->parentExpr && expr->parentExpr->parentExpr) {
    if (CallExpr* call = toCallExpr(expr->parentExpr->parentExpr)) {
      if (call->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) {
        return true;
      }
    }
  }
  return false;
}

//
// Removes local variables that are only targets for moves, but are
// never used anywhere.
//
static bool isDeadVariable(Symbol* var,
                           Map<Symbol*,Vec<SymExpr*>*>& defMap,
                           Map<Symbol*,Vec<SymExpr*>*>& useMap) {
  if (var->type->symbol->hasFlag(FLAG_REF)) {
    Vec<SymExpr*>* uses = useMap.get(var);
    Vec<SymExpr*>* defs = defMap.get(var);
    return (!uses || uses->n == 0) && (!defs || defs->n <= 1);
  } else {
    Vec<SymExpr*>* uses = useMap.get(var);
    return !uses || uses->n == 0;
  }
}

void deadVariableElimination(FnSymbol* fn) {
  Vec<Symbol*> symSet;
  Vec<SymExpr*> symExprs;
  collectSymbolSetSymExprVec(fn, symSet, symExprs);

  Map<Symbol*,Vec<SymExpr*>*> defMap;
  Map<Symbol*,Vec<SymExpr*>*> useMap;
  buildDefUseMaps(symSet, symExprs, defMap, useMap);

  forv_Vec(Symbol, sym, symSet)
  {
    // We're interested only in VarSymbols.
    if (!isVarSymbol(sym))
      continue;

    // A method must have a _this symbol, even if it is not used.
    if (sym == fn->_this)
      continue;

    if (isDeadVariable(sym, defMap, useMap)) {
      for_defs(se, defMap, sym) {
        CallExpr* call = toCallExpr(se->parentExpr);
        INT_ASSERT(call &&
                   (call->isPrimitive(PRIM_MOVE) ||
                    call->isPrimitive(PRIM_ASSIGN)));
        Expr* rhs = call->get(2)->remove();
        if (!isSymExpr(rhs))
          call->replace(rhs);
        else
          call->remove();
      }
      sym->defPoint->remove();
    }
  }

  freeDefUseMaps(defMap, useMap);
}

//
// Removes expression statements that have no effect.
//
void deadExpressionElimination(FnSymbol* fn) {
  Vec<BaseAST*> asts;
  collect_asts(fn, asts);
  forv_Vec(BaseAST, ast, asts) {
    Expr *expr = toExpr(ast);
    if (expr && expr->parentExpr == NULL) // expression already removed
      continue;
    if (SymExpr* expr = toSymExpr(ast)) {
      if (isInCForLoopHeader(expr)) {
        continue;
      }
      if (expr == expr->getStmtExpr())
        expr->remove();
    } else if (CallExpr* expr = toCallExpr(ast)) {
      if (expr->isPrimitive(PRIM_CAST) ||
          expr->isPrimitive(PRIM_GET_MEMBER_VALUE) ||
          expr->isPrimitive(PRIM_GET_MEMBER) ||
          expr->isPrimitive(PRIM_DEREF) ||
          expr->isPrimitive(PRIM_ADDR_OF))
        if (expr == expr->getStmtExpr())
          expr->remove();
      if (expr->isPrimitive(PRIM_MOVE) || expr->isPrimitive(PRIM_ASSIGN))
        if (SymExpr* lhs = toSymExpr(expr->get(1)))
          if (SymExpr* rhs = toSymExpr(expr->get(2)))
            if (lhs->var == rhs->var)
              expr->remove();
    } else if (CondStmt* cond = toCondStmt(ast)) {
      cond->fold_cond_stmt();
    }
  }
}

void deadCodeElimination(FnSymbol* fn)
{
// TODO: Factor this long function?
  buildBasicBlocks(fn);

  std::map<SymExpr*,Vec<SymExpr*>*> DU;
  std::map<SymExpr*,Vec<SymExpr*>*> UD;
  buildDefUseChains(fn, DU, UD);

  std::map<Expr*,Expr*> exprMap;
  Vec<Expr*> liveCode;
  Vec<Expr*> workSet;
  for_vector(BasicBlock, bb, *fn->basicBlocks) {
    for_vector(Expr, expr, bb->exprs) {
      bool essential = false;
      Vec<BaseAST*> asts;
      collect_asts(expr, asts);
      forv_Vec(BaseAST, ast, asts) {
        if (isInCForLoopHeader(expr)) {
          essential = true;
        }
        if (CallExpr* call = toCallExpr(ast)) {
          // mark function calls and essential primitives as essential
          if (call->isResolved() ||
              (call->primitive && call->primitive->isEssential))
            essential = true;
          // mark assignments to global variables as essential
          if (call->isPrimitive(PRIM_MOVE) || call->isPrimitive(PRIM_ASSIGN))
            if (SymExpr* se = toSymExpr(call->get(1)))
              if (DU.count(se) == 0 || // DU chain only contains locals
                  !se->var->type->refType) // reference issue
                essential = true;
        }
        if (Expr* sub = toExpr(ast)) {
          exprMap[sub] = expr;
          if (BlockStmt* block = toBlockStmt(sub->parentExpr))
            if (block->blockInfoGet() == sub)
              essential = true;
          if (CondStmt* cond = toCondStmt(sub->parentExpr))
            if (cond->condExpr == sub)
              essential = true;
        }
      }
      if (essential) {
        liveCode.set_add(expr);
        workSet.add(expr);
      }
    }
  }

  forv_Vec(Expr, expr, workSet) {
    Vec<SymExpr*> symExprs;
    collectSymExprs(expr, symExprs);
    forv_Vec(SymExpr, se, symExprs) {
      if (UD.count(se) != 0) {
        Vec<SymExpr*>* defs = UD[se];
        forv_Vec(SymExpr, def, *defs) {
          INT_ASSERT(exprMap.count(def) != 0);
          Expr* expr = exprMap[def];
          if (!liveCode.set_in(expr)) {
            liveCode.set_add(expr);
            workSet.add(expr);
          }
        }
      }
    }
  }

  // This removes dead expressions from each block.
  for_vector(BasicBlock, bb1, *fn->basicBlocks) {
    for_vector(Expr, expr, bb1->exprs) {
      if (isSymExpr(expr) || isCallExpr(expr))
        if (!liveCode.set_in(expr))
          expr->remove();
    }
  }

  freeDefUseChains(DU, UD);
}

// Determines if a module is dead. A module is dead if the module's init
// function can only be called from module code, and the init function
// is empty, and the init function is the only thing in the module, and the
// module is not a nested module.
static bool isDeadModule(ModuleSymbol* mod) {
  // The main module and any module whose init function is exported
  // should never be considered dead, as the init function can be
  // explicitly called from the runtime, or other c code
  if (mod == mainModule || mod->hasFlag(FLAG_EXPORT_INIT)) return false;

  // because of the way modules are initialized, we don't want to consider a
  // nested function as dead as its outer module and all of its uses should
  // have their initializer called by the inner module.
  if (mod->defPoint->getModule() != theProgram &&
      mod->defPoint->getModule() != rootModule)
    return false;

  // if there is only one thing in the module
  if (mod->block->body.length == 1) {
    // and that thing is the init function
    if (mod->block->body.only() == mod->initFn->defPoint) {
      // and the init function is empty (only has a return)
      if (mod->initFn->body->body.length == 1) {
        // then the module is dead
        return true;
      }
    }
  }
  return false;
}

// Eliminates all dead modules
static void deadModuleElimination() {
  forv_Vec(ModuleSymbol, mod, allModules) {
    if (isDeadModule(mod) == true) {
      deadModuleCount++;

      // remove the dead module and its initFn
      mod->defPoint->remove();
      mod->initFn->defPoint->remove();

      // Inform every module about the dead module
      forv_Vec(ModuleSymbol, modThatMightUse, allModules) {
        if (modThatMightUse != mod) {
          modThatMightUse->moduleUseRemove(mod);
        }
      }
    }
  }
}

void deadCodeElimination() {
  if (!fNoDeadCodeElimination) {
    deadBlockCount = 0;
    deadModuleCount = 0;
    forv_Vec(FnSymbol, fn, gFnSymbols) {
      deadBlockElimination(fn);
//      deadGotoElimination(fn);
      deadCodeElimination(fn);
      deadVariableElimination(fn);
      deadExpressionElimination(fn);
    }
    deadModuleElimination();

    if (fReportDeadBlocks)
      printf("\tRemoved %d dead blocks.\n", deadBlockCount);
    if (fReportDeadModules)
      printf("Removed %d dead modules.\n", deadModuleCount);

  }
}

// Look for and remove unreachable blocks.
// Muchnick says we can enumerate the unreachable blocks first and then just
// remove them.  We only need to do this once, because removal of an
// unreachable block cannot possibly make any reachable block unreachable.
static void deadBlockElimination(FnSymbol* fn)
{
  // We need the basic block information to be correct, so recompute it.
  buildBasicBlocks(fn);

  // Find the reachable basic blocks within this function.
  std::set<BasicBlock*> reachable;

  // We set up a work queue to perform a BFS on reachable blocks, and seed it
  // with the first block in the function.
  std::queue<BasicBlock*> work_queue;
  work_queue.push((*fn->basicBlocks)[0]);

  // Then we iterate until there are no more blocks to visit.
  while (!work_queue.empty())
  {
    // Fetch and remove the next block.
    BasicBlock* bb = work_queue.front();
    work_queue.pop();

    // Ignore it if we've already seen it.
    if (reachable.count(bb))
      continue;

    // Otherwise, mark it as reachable, and append all of its successors to the
    // work queue.
    reachable.insert(bb);
    for_vector(BasicBlock, out, bb->outs)
      work_queue.push(out);
  }

  // Now we simply visit all the blocks, deleting all those that are not
  // rechable.
  for_vector(BasicBlock, bb, *fn->basicBlocks)
  {
    if (reachable.count(bb))
      continue;

    ++deadBlockCount;

    // Remove all of its expressions.
    for_vector(Expr, expr, bb->exprs)
    {
      if (! expr->parentExpr)
        continue;   // This node is no longer in the tree.

      // Do not remove def expressions (for now)
      // In some cases (associated with iterator code), defs appear in dead
      // blocks but are used in later blocks, so removing the defs results
      // in a verify error.
      // TODO: Perhaps this reformulation of unreachable block removal does a better
      // job and those blocks are now removed as well.  If so, this IF can be removed.
      if (toDefExpr(expr))
        continue;

      CondStmt* cond = toCondStmt(expr->parentExpr);
      if (cond && cond->condExpr == expr)
        // If expr is the condition expression in an if statement,
        // then remove the entire if.
        cond->remove();
      else
        expr->remove();
    }
  }
}

//
// See if any iterator resume labels have been remove (and not re-inserted).
// If so, remove the matching gotos, if they haven't been yet.
//
void removeDeadIterResumeGotos() {
  forv_Vec(LabelSymbol, labsym, removedIterResumeLabels) {
    if (!isAlive(labsym) && isAlive(labsym->iterResumeGoto))
      labsym->iterResumeGoto->remove();
  }
  removedIterResumeLabels.clear();
}

//
// Make sure there are no iterResumeGotos to remove.
// Reset removedIterResumeLabels.
//
void verifyNcleanRemovedIterResumeGotos() {
  forv_Vec(LabelSymbol, labsym, removedIterResumeLabels) {
    if (!isAlive(labsym) && isAlive(labsym->iterResumeGoto))
      INT_FATAL("unexpected live goto for a dead removedIterResumeLabels label - missing a call to removeDeadIterResumeGotos?");
  }
  removedIterResumeLabels.clear();
}

// Look for pointless gotos and remove them.
// Probably the best way to do this is to scan the AST and remove gotos
// whose target labels follow immediately.
#if 0
static void deadGotoElimination(FnSymbol* fn)
{
  // We recompute basic blocks because deadBlockElimination may cause them
  // to be out of sequence.
  buildBasicBlocks(fn);
  forv_Vec(BasicBlock, bb, *fn->basicBlocks)
  {
    // Get the last expression in the block as a goto.
    int last = bb->exprs.length() - 1;
    if (last < 0)
      continue;

    Expr* e = bb->exprs.v[last];
    GotoStmt* s = toGotoStmt(e);
    if (!s)
      continue;

    // If there is only one successor to this block and it is the next block,
    // then the goto must point to it and is therefore pointless [sts].
    // This test should be more foolproof using the structure of the AST.
    if (bb->outs.n == 1 && bb->outs.v[0]->id == bb->id + 1)
      e->remove();
  }
}
#endif
<commit_msg>DCE can create degenerate nodes.  Add a post-pass to clean these up so that they don't propagate<commit_after>/*
 * Copyright 2004-2014 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is 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 "optimizations.h"

#include "astutil.h"
#include "bb.h"
#include "expr.h"
#include "passes.h"
#include "stlUtil.h"
#include "stmt.h"
#include "view.h"

#include <queue>
#include <set>

//
// Static function declarations.
//
static void deadBlockElimination(FnSymbol* fn);
static void postPassCleanup();

// Static variables.
static unsigned int deadBlockCount;
static unsigned int deadModuleCount;

// Determines if an expr is used inside of the header for a c for loop. c for
// loop header is of the form '"c for loop" {inits}, {test}, {incrs}'
//
// Only returns true for exprs in the init, test, incr blocks, not for the
// blocks themselves.
//
// TODO should this be updated to only look for exprs in the test segment that
// are conditional primitives?
static bool isInCForLoopHeader(Expr* expr) {
  if (expr->parentExpr && expr->parentExpr->parentExpr) {
    if (CallExpr* call = toCallExpr(expr->parentExpr->parentExpr)) {
      if (call->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) {
        return true;
      }
    }
  }
  return false;
}

//
// Removes local variables that are only targets for moves, but are
// never used anywhere.
//
static bool isDeadVariable(Symbol* var,
                           Map<Symbol*,Vec<SymExpr*>*>& defMap,
                           Map<Symbol*,Vec<SymExpr*>*>& useMap) {
  if (var->type->symbol->hasFlag(FLAG_REF)) {
    Vec<SymExpr*>* uses = useMap.get(var);
    Vec<SymExpr*>* defs = defMap.get(var);
    return (!uses || uses->n == 0) && (!defs || defs->n <= 1);
  } else {
    Vec<SymExpr*>* uses = useMap.get(var);
    return !uses || uses->n == 0;
  }
}

void deadVariableElimination(FnSymbol* fn) {
  Vec<Symbol*> symSet;
  Vec<SymExpr*> symExprs;
  collectSymbolSetSymExprVec(fn, symSet, symExprs);

  Map<Symbol*,Vec<SymExpr*>*> defMap;
  Map<Symbol*,Vec<SymExpr*>*> useMap;
  buildDefUseMaps(symSet, symExprs, defMap, useMap);

  forv_Vec(Symbol, sym, symSet)
  {
    // We're interested only in VarSymbols.
    if (!isVarSymbol(sym))
      continue;

    // A method must have a _this symbol, even if it is not used.
    if (sym == fn->_this)
      continue;

    if (isDeadVariable(sym, defMap, useMap)) {
      for_defs(se, defMap, sym) {
        CallExpr* call = toCallExpr(se->parentExpr);
        INT_ASSERT(call &&
                   (call->isPrimitive(PRIM_MOVE) ||
                    call->isPrimitive(PRIM_ASSIGN)));
        Expr* rhs = call->get(2)->remove();
        if (!isSymExpr(rhs))
          call->replace(rhs);
        else
          call->remove();
      }
      sym->defPoint->remove();
    }
  }

  freeDefUseMaps(defMap, useMap);
}

//
// Removes expression statements that have no effect.
//
void deadExpressionElimination(FnSymbol* fn) {
  Vec<BaseAST*> asts;
  collect_asts(fn, asts);
  forv_Vec(BaseAST, ast, asts) {
    Expr *expr = toExpr(ast);
    if (expr && expr->parentExpr == NULL) // expression already removed
      continue;
    if (SymExpr* expr = toSymExpr(ast)) {
      if (isInCForLoopHeader(expr)) {
        continue;
      }
      if (expr == expr->getStmtExpr())
        expr->remove();
    } else if (CallExpr* expr = toCallExpr(ast)) {
      if (expr->isPrimitive(PRIM_CAST) ||
          expr->isPrimitive(PRIM_GET_MEMBER_VALUE) ||
          expr->isPrimitive(PRIM_GET_MEMBER) ||
          expr->isPrimitive(PRIM_DEREF) ||
          expr->isPrimitive(PRIM_ADDR_OF))
        if (expr == expr->getStmtExpr())
          expr->remove();
      if (expr->isPrimitive(PRIM_MOVE) || expr->isPrimitive(PRIM_ASSIGN))
        if (SymExpr* lhs = toSymExpr(expr->get(1)))
          if (SymExpr* rhs = toSymExpr(expr->get(2)))
            if (lhs->var == rhs->var)
              expr->remove();
    } else if (CondStmt* cond = toCondStmt(ast)) {
      cond->fold_cond_stmt();
    }
  }
}

void deadCodeElimination(FnSymbol* fn)
{
// TODO: Factor this long function?
  buildBasicBlocks(fn);

  std::map<SymExpr*,Vec<SymExpr*>*> DU;
  std::map<SymExpr*,Vec<SymExpr*>*> UD;
  buildDefUseChains(fn, DU, UD);

  std::map<Expr*,Expr*> exprMap;
  Vec<Expr*> liveCode;
  Vec<Expr*> workSet;
  for_vector(BasicBlock, bb, *fn->basicBlocks) {
    for_vector(Expr, expr, bb->exprs) {
      bool essential = false;
      Vec<BaseAST*> asts;
      collect_asts(expr, asts);
      forv_Vec(BaseAST, ast, asts) {
        if (isInCForLoopHeader(expr)) {
          essential = true;
        }
        if (CallExpr* call = toCallExpr(ast)) {
          // mark function calls and essential primitives as essential
          if (call->isResolved() ||
              (call->primitive && call->primitive->isEssential))
            essential = true;
          // mark assignments to global variables as essential
          if (call->isPrimitive(PRIM_MOVE) || call->isPrimitive(PRIM_ASSIGN))
            if (SymExpr* se = toSymExpr(call->get(1)))
              if (DU.count(se) == 0 || // DU chain only contains locals
                  !se->var->type->refType) // reference issue
                essential = true;
        }
        if (Expr* sub = toExpr(ast)) {
          exprMap[sub] = expr;
          if (BlockStmt* block = toBlockStmt(sub->parentExpr))
            if (block->blockInfoGet() == sub)
              essential = true;
          if (CondStmt* cond = toCondStmt(sub->parentExpr))
            if (cond->condExpr == sub)
              essential = true;
        }
      }
      if (essential) {
        liveCode.set_add(expr);
        workSet.add(expr);
      }
    }
  }

  forv_Vec(Expr, expr, workSet) {
    Vec<SymExpr*> symExprs;
    collectSymExprs(expr, symExprs);
    forv_Vec(SymExpr, se, symExprs) {
      if (UD.count(se) != 0) {
        Vec<SymExpr*>* defs = UD[se];
        forv_Vec(SymExpr, def, *defs) {
          INT_ASSERT(exprMap.count(def) != 0);
          Expr* expr = exprMap[def];
          if (!liveCode.set_in(expr)) {
            liveCode.set_add(expr);
            workSet.add(expr);
          }
        }
      }
    }
  }

  // This removes dead expressions from each block.
  for_vector(BasicBlock, bb1, *fn->basicBlocks) {
    for_vector(Expr, expr, bb1->exprs) {
      if (isSymExpr(expr) || isCallExpr(expr))
        if (!liveCode.set_in(expr))
          expr->remove();
    }
  }

  freeDefUseChains(DU, UD);
}

// Determines if a module is dead. A module is dead if the module's init
// function can only be called from module code, and the init function
// is empty, and the init function is the only thing in the module, and the
// module is not a nested module.
static bool isDeadModule(ModuleSymbol* mod) {
  // The main module and any module whose init function is exported
  // should never be considered dead, as the init function can be
  // explicitly called from the runtime, or other c code
  if (mod == mainModule || mod->hasFlag(FLAG_EXPORT_INIT)) return false;

  // because of the way modules are initialized, we don't want to consider a
  // nested function as dead as its outer module and all of its uses should
  // have their initializer called by the inner module.
  if (mod->defPoint->getModule() != theProgram &&
      mod->defPoint->getModule() != rootModule)
    return false;

  // if there is only one thing in the module
  if (mod->block->body.length == 1) {
    // and that thing is the init function
    if (mod->block->body.only() == mod->initFn->defPoint) {
      // and the init function is empty (only has a return)
      if (mod->initFn->body->body.length == 1) {
        // then the module is dead
        return true;
      }
    }
  }
  return false;
}

// Eliminates all dead modules
static void deadModuleElimination() {
  forv_Vec(ModuleSymbol, mod, allModules) {
    if (isDeadModule(mod) == true) {
      deadModuleCount++;

      // remove the dead module and its initFn
      mod->defPoint->remove();
      mod->initFn->defPoint->remove();

      // Inform every module about the dead module
      forv_Vec(ModuleSymbol, modThatMightUse, allModules) {
        if (modThatMightUse != mod) {
          modThatMightUse->moduleUseRemove(mod);
        }
      }
    }
  }
}

void deadCodeElimination() {
  if (!fNoDeadCodeElimination) {

    deadBlockCount  = 0;
    deadModuleCount = 0;

    forv_Vec(FnSymbol, fn, gFnSymbols) {
      deadBlockElimination(fn);
      deadCodeElimination(fn);
      deadVariableElimination(fn);
      deadExpressionElimination(fn);
    }

    deadModuleElimination();

    postPassCleanup();

    if (fReportDeadBlocks)
      printf("\tRemoved %d dead blocks.\n", deadBlockCount);

    if (fReportDeadModules)
      printf("Removed %d dead modules.\n", deadModuleCount);
  }
}

// Look for and remove unreachable blocks.
// Muchnick says we can enumerate the unreachable blocks first and then just
// remove them.  We only need to do this once, because removal of an
// unreachable block cannot possibly make any reachable block unreachable.
static void deadBlockElimination(FnSymbol* fn)
{
  // We need the basic block information to be correct, so recompute it.
  buildBasicBlocks(fn);

  // Find the reachable basic blocks within this function.
  std::set<BasicBlock*> reachable;

  // We set up a work queue to perform a BFS on reachable blocks, and seed it
  // with the first block in the function.
  std::queue<BasicBlock*> work_queue;
  work_queue.push((*fn->basicBlocks)[0]);

  // Then we iterate until there are no more blocks to visit.
  while (!work_queue.empty())
  {
    // Fetch and remove the next block.
    BasicBlock* bb = work_queue.front();
    work_queue.pop();

    // Ignore it if we've already seen it.
    if (reachable.count(bb))
      continue;

    // Otherwise, mark it as reachable, and append all of its successors to the
    // work queue.
    reachable.insert(bb);
    for_vector(BasicBlock, out, bb->outs)
      work_queue.push(out);
  }

  // Now we simply visit all the blocks, deleting all those that are not
  // rechable.
  for_vector(BasicBlock, bb, *fn->basicBlocks)
  {
    if (reachable.count(bb))
      continue;

    ++deadBlockCount;

    // Remove all of its expressions.
    for_vector(Expr, expr, bb->exprs)
    {
      if (! expr->parentExpr)
        continue;   // This node is no longer in the tree.

      // Do not remove def expressions (for now)
      // In some cases (associated with iterator code), defs appear in dead
      // blocks but are used in later blocks, so removing the defs results
      // in a verify error.
      // TODO: Perhaps this reformulation of unreachable block removal does a better
      // job and those blocks are now removed as well.  If so, this IF can be removed.
      if (toDefExpr(expr))
        continue;

      CondStmt* cond = toCondStmt(expr->parentExpr);
      if (cond && cond->condExpr == expr)
        // If expr is the condition expression in an if statement,
        // then remove the entire if.
        cond->remove();
      else
        expr->remove();
    }
  }
}

//
// See if any iterator resume labels have been remove (and not re-inserted).
// If so, remove the matching gotos, if they haven't been yet.
//
void removeDeadIterResumeGotos() {
  forv_Vec(LabelSymbol, labsym, removedIterResumeLabels) {
    if (!isAlive(labsym) && isAlive(labsym->iterResumeGoto))
      labsym->iterResumeGoto->remove();
  }
  removedIterResumeLabels.clear();
}

//
// Make sure there are no iterResumeGotos to remove.
// Reset removedIterResumeLabels.
//
void verifyNcleanRemovedIterResumeGotos() {
  forv_Vec(LabelSymbol, labsym, removedIterResumeLabels) {
    if (!isAlive(labsym) && isAlive(labsym->iterResumeGoto))
      INT_FATAL("unexpected live goto for a dead removedIterResumeLabels label - missing a call to removeDeadIterResumeGotos?");
  }
  removedIterResumeLabels.clear();
}

//
// Dead code elimination can create a handful of degenerate nodes.
// This is a place to sweep those away.
//

static void postPassCleanup() {

  // Remove degenerate C-For loops.  These could be misinterpreted
  // as Infinite loops and currently break the LLVM backend
  forv_Vec(BlockStmt, stmt, gBlockStmts) {
    if (CallExpr* loop = stmt->blockInfoGet()) {
      if (loop->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) {
        if (BlockStmt* test = toBlockStmt(loop->get(2))) {
          if (test->body.length == 0) {
            stmt->remove();
          }
        }
      }
    }
  }
}

// Look for pointless gotos and remove them.
// Probably the best way to do this is to scan the AST and remove gotos
// whose target labels follow immediately.
#if 0
static void deadGotoElimination(FnSymbol* fn)
{
  // We recompute basic blocks because deadBlockElimination may cause them
  // to be out of sequence.
  buildBasicBlocks(fn);
  forv_Vec(BasicBlock, bb, *fn->basicBlocks)
  {
    // Get the last expression in the block as a goto.
    int last = bb->exprs.length() - 1;
    if (last < 0)
      continue;

    Expr* e = bb->exprs.v[last];
    GotoStmt* s = toGotoStmt(e);
    if (!s)
      continue;

    // If there is only one successor to this block and it is the next block,
    // then the goto must point to it and is therefore pointless [sts].
    // This test should be more foolproof using the structure of the AST.
    if (bb->outs.n == 1 && bb->outs.v[0]->id == bb->id + 1)
      e->remove();
  }
}
#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: TTableHelper.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: ihi $ $Date: 2006-08-28 14:51:27 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/

#ifndef CONNECTIVITY_TABLEHELPER_HXX
#define CONNECTIVITY_TABLEHELPER_HXX

#ifndef _CONNECTIVITY_SDBCX_TABLE_HXX_
#include "connectivity/sdbcx/VTable.hxx"
#endif
#ifndef CONNECTIVITY_STDTYPEDEFS_HXX
#include "connectivity/StdTypeDefs.hxx"
#endif

namespace connectivity
{
    typedef connectivity::sdbcx::OTable OTable_TYPEDEF;

    ::rtl::OUString getTypeString(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xColProp);

    class OTableHelper :    public OTable_TYPEDEF
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >   m_xMetaData;
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >         m_xConnection;

        void refreshPrimaryKeys(std::vector< ::rtl::OUString>& _rKeys);
        void refreshForgeinKeys(std::vector< ::rtl::OUString>& _rKeys);

    protected:
        /** creates the column collection for the table
            @param  _rNames
                The column names.
        */
        virtual sdbcx::OCollection* createColumns(const TStringVector& _rNames) = 0;

        /** creates the key collection for the table
            @param  _rNames
                The key names.
        */
        virtual sdbcx::OCollection* createKeys(const TStringVector& _rNames) = 0;

        /** creates the index collection for the table
            @param  _rNames
                The index names.
        */
        virtual sdbcx::OCollection* createIndexes(const TStringVector& _rNames) = 0;

        /** this function is called upon disposing the component
        */
        virtual void SAL_CALL disposing();

        /** The default returns "RENAME TABLE " or "RENAME VIEW " depending on the type.
        *
        * \return The start of the rename statement.
        */
        virtual ::rtl::OUString getRenameStart() const;

    public:
        virtual void refreshColumns();
        virtual void refreshKeys();
        virtual void refreshIndexes();

    public:
        OTableHelper(   sdbcx::OCollection* _pTables,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xConnection,
                        sal_Bool _bCase);
        OTableHelper(   sdbcx::OCollection* _pTables,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xConnection,
                        sal_Bool _bCase,
                        const ::rtl::OUString& _Name,
                        const ::rtl::OUString& _Type,
                        const ::rtl::OUString& _Description = ::rtl::OUString(),
                        const ::rtl::OUString& _SchemaName = ::rtl::OUString(),
                        const ::rtl::OUString& _CatalogName = ::rtl::OUString()
            );

        virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData> getMetaData() const;
        inline ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection> getConnection() const { return m_xConnection; }

        virtual void SAL_CALL acquire() throw();
        virtual void SAL_CALL release() throw();

        // XRename
        virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);

        // XAlterTable
        virtual void SAL_CALL alterColumnByIndex( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
        // XNamed
        virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
    };
}
#endif // CONNECTIVITY_TABLEHELPER_HXX

<commit_msg>INTEGRATION: CWS dba205b (1.3.146); FILE MERGED 2006/09/04 11:04:24 oj 1.3.146.2: RESYNC: (1.3-1.4); FILE MERGED 2006/08/09 19:59:41 fs 1.3.146.1: #b6248060#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: TTableHelper.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: ihi $ $Date: 2006-10-18 13:05:46 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/

#ifndef CONNECTIVITY_TABLEHELPER_HXX
#define CONNECTIVITY_TABLEHELPER_HXX

#ifndef _CONNECTIVITY_SDBCX_TABLE_HXX_
#include "connectivity/sdbcx/VTable.hxx"
#endif
#ifndef CONNECTIVITY_STDTYPEDEFS_HXX
#include "connectivity/StdTypeDefs.hxx"
#endif

namespace connectivity
{
    typedef connectivity::sdbcx::OTable OTable_TYPEDEF;

    ::rtl::OUString getTypeString(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xColProp);

    class OTableHelper : public OTable_TYPEDEF
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >   m_xMetaData;
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >         m_xConnection;

        void refreshPrimaryKeys(std::vector< ::rtl::OUString>& _rKeys);
        void refreshForgeinKeys(std::vector< ::rtl::OUString>& _rKeys);

    protected:
        /** creates the column collection for the table
            @param  _rNames
                The column names.
        */
        virtual sdbcx::OCollection* createColumns(const TStringVector& _rNames) = 0;

        /** creates the key collection for the table
            @param  _rNames
                The key names.
        */
        virtual sdbcx::OCollection* createKeys(const TStringVector& _rNames) = 0;

        /** creates the index collection for the table
            @param  _rNames
                The index names.
        */
        virtual sdbcx::OCollection* createIndexes(const TStringVector& _rNames) = 0;

        /** this function is called upon disposing the component
        */
        virtual void SAL_CALL disposing();

        /** The default returns "RENAME TABLE " or "RENAME VIEW " depending on the type.
        *
        * \return The start of the rename statement.
        */
        virtual ::rtl::OUString getRenameStart() const;

    public:
        virtual void refreshColumns();
        virtual void refreshKeys();
        virtual void refreshIndexes();

    public:
        OTableHelper(   sdbcx::OCollection* _pTables,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xConnection,
                        sal_Bool _bCase);
        OTableHelper(   sdbcx::OCollection* _pTables,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xConnection,
                        sal_Bool _bCase,
                        const ::rtl::OUString& _Name,
                        const ::rtl::OUString& _Type,
                        const ::rtl::OUString& _Description = ::rtl::OUString(),
                        const ::rtl::OUString& _SchemaName = ::rtl::OUString(),
                        const ::rtl::OUString& _CatalogName = ::rtl::OUString()
            );

        virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData> getMetaData() const;
        inline ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection> getConnection() const { return m_xConnection; }

        virtual void SAL_CALL acquire() throw();
        virtual void SAL_CALL release() throw();

        // XRename
        virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);

        // XAlterTable
        virtual void SAL_CALL alterColumnByIndex( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
        // XNamed
        virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
    };
}
#endif // CONNECTIVITY_TABLEHELPER_HXX

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: cjkoptions.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: os $ $Date: 2001-05-07 10:21:13 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _SVTOOLS_CJKOPTIONS_HXX
#include "cjkoptions.hxx"
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

using namespace ::com::sun::star::uno;
using namespace ::rtl;

#define C2U(cChar) OUString::createFromAscii(cChar)
/* -----------------------------10.04.01 12:39--------------------------------

 ---------------------------------------------------------------------------*/
class SvtCJKOptions_Impl : public utl::ConfigItem
{
    static Sequence<OUString> aPropertyNames;

    sal_Bool        bIsLoaded;
    sal_Bool        bCJKFont;
    sal_Bool        bVerticalText;
    sal_Bool        bAsianTypography;
    sal_Bool        bJapaneseFind;
    sal_Bool        bRuby;
    sal_Bool        bChangeCaseMap;
    sal_Bool        bDoubleLines;
    sal_Bool        bEmphasisMarks;
    sal_Bool        bVerticalCallOut;

public:
    SvtCJKOptions_Impl();
    ~SvtCJKOptions_Impl();

    virtual void    Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
    virtual void    Commit();
    void            Load();

    sal_Bool IsLoaded()                         { return bIsLoaded;         }

    sal_Bool IsCJKFontEnabled() const           { return bCJKFont;          }
    sal_Bool IsVerticalTextEnabled() const      { return bVerticalText;     }
    sal_Bool IsAsianTypographyEnabled() const   { return bAsianTypography;  }
    sal_Bool IsJapaneseFindEnabled() const      { return bJapaneseFind;     }
    sal_Bool IsRubyEnabled() const              { return bRuby;             }
    sal_Bool IsChangeCaseMapEnabled() const     { return bChangeCaseMap;    }
    sal_Bool IsDoubleLinesEnabled() const       { return bDoubleLines;      }
    sal_Bool IsEmphasisMarksEnabled() const     { return bEmphasisMarks;    }
    sal_Bool IsVerticalCallOutEnabled() const   { return bVerticalCallOut;  }

    sal_Bool IsAnyEnabled() const {
        return  bCJKFont||bVerticalText||bAsianTypography||bJapaneseFind||
                bRuby||bChangeCaseMap||bDoubleLines||bEmphasisMarks||bVerticalCallOut;   }
    void    SetAll(sal_Bool bSet);
};
/*-- 10.04.01 12:41:57---------------------------------------------------

  -----------------------------------------------------------------------*/
Sequence<OUString> SvtCJKOptions_Impl::aPropertyNames;

SvtCJKOptions_Impl::SvtCJKOptions_Impl() :
    utl::ConfigItem(C2U("Setup/CJK/Enable")),
    bIsLoaded(sal_False),
    bCJKFont(sal_True),
    bVerticalText(sal_True),
    bAsianTypography(sal_True),
    bJapaneseFind(sal_True),
    bRuby(sal_True),
    bChangeCaseMap(sal_True),
    bDoubleLines(sal_True),
    bEmphasisMarks(sal_True),
    bVerticalCallOut(sal_True)
{
}
/*-- 10.04.01 12:41:57---------------------------------------------------

  -----------------------------------------------------------------------*/
SvtCJKOptions_Impl::~SvtCJKOptions_Impl()
{
}
/* -----------------------------20.04.01 14:34--------------------------------

 ---------------------------------------------------------------------------*/
void    SvtCJKOptions_Impl::SetAll(sal_Bool bSet)
{
    bCJKFont = bVerticalText = bAsianTypography = bJapaneseFind =
            bRuby = bChangeCaseMap = bDoubleLines = bEmphasisMarks = bVerticalCallOut = bSet;
    SetModified();
}
/*-- 10.04.01 12:41:56---------------------------------------------------

  -----------------------------------------------------------------------*/
void SvtCJKOptions_Impl::Load()
{
    if(!aPropertyNames.getLength())
    {
        aPropertyNames.realloc(9);
        OUString* pNames = aPropertyNames.getArray();
        pNames[0] = C2U("CJKFont");
        pNames[1] = C2U("VerticalText");
        pNames[2] = C2U("AsianTypography");
        pNames[3] = C2U("JapaneseFind");
        pNames[4] = C2U("Ruby");
        pNames[5] = C2U("ChangeCaseMap");
        pNames[6] = C2U("DoubleLines");
        pNames[7] = C2U("EmphasisMarks");
        pNames[8] = C2U("VerticalCallOut");
        EnableNotification( aPropertyNames );
    }
    Sequence< Any > aValues = GetProperties(aPropertyNames);
    const Any* pValues = aValues.getConstArray();
    DBG_ASSERT( aValues.getLength() == aPropertyNames.getLength(), "GetProperties failed" );
    if ( aValues.getLength() == aPropertyNames.getLength() )
    {
        for ( int nProp = 0; nProp < aPropertyNames.getLength(); nProp++ )
        {
            if( pValues[nProp].hasValue() )
            {
                sal_Bool bValue = *(sal_Bool*)pValues[nProp].getValue();
                switch ( nProp )
                {
                    case 0: bCJKFont = bValue; break;
                    case 1: bVerticalText = bValue; break;
                    case 2: bAsianTypography = bValue; break;
                    case 3: bJapaneseFind = bValue; break;
                    case 4: bRuby = bValue; break;
                    case 5: bChangeCaseMap = bValue; break;
                    case 6: bDoubleLines = bValue; break;
                    case 7: bEmphasisMarks = bValue; break;
                    case 8: bVerticalCallOut = bValue; break;
                }
            }
        }
    }
    bIsLoaded = sal_True;
}
/*-- 10.04.01 12:41:57---------------------------------------------------

  -----------------------------------------------------------------------*/
void    SvtCJKOptions_Impl::Notify( const Sequence< OUString >& aPropertyNames )
{
    Load();
}
/*-- 10.04.01 12:41:57---------------------------------------------------

  -----------------------------------------------------------------------*/
void    SvtCJKOptions_Impl::Commit()
{
    OUString* pNames = aPropertyNames.getArray();
    Sequence<Any> aValues(aPropertyNames.getLength());
    Any* pValues = aValues.getArray();

    const Type& rType = ::getBooleanCppuType();
    BOOL bVal;
    for(int nProp = 0; nProp < aPropertyNames.getLength(); nProp++)
    {
        switch(nProp)
        {
            case  0: bVal = bCJKFont; break;
            case  1: bVal = bVerticalText; break;
            case  2: bVal = bAsianTypography; break;
            case  3: bVal = bJapaneseFind; break;
            case  4: bVal = bRuby; break;
            case  5: bVal = bChangeCaseMap; break;
            case  6: bVal = bDoubleLines; break;
            case  7: bVal = bEmphasisMarks; break;
            case  8: bVal = bVerticalCallOut; break;
        }
        pValues[nProp].setValue(&bVal, getBooleanCppuType());
    }
    PutProperties(aPropertyNames, aValues);
}
// global ----------------------------------------------------------------

static SvtCJKOptions_Impl*  pCJKOptions = NULL;
static sal_Int32            nCJKRefCount = 0;
static ::osl::Mutex         aCJKMutex;

// class SvtCJKOptions --------------------------------------------------

SvtCJKOptions::SvtCJKOptions(sal_Bool bDontLoad)
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aCJKMutex );
    if ( !pCJKOptions )
        pCJKOptions = new SvtCJKOptions_Impl;
    if( !bDontLoad && !pCJKOptions->IsLoaded())
        pCJKOptions->Load();

    ++nCJKRefCount;
    pImp = pCJKOptions;
}

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

SvtCJKOptions::~SvtCJKOptions()
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aCJKMutex );
    if ( !--nCJKRefCount )
        DELETEZ( pCJKOptions );
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsCJKFontEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsCJKFontEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsVerticalTextEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsVerticalTextEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsAsianTypographyEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsAsianTypographyEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsJapaneseFindEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsJapaneseFindEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsRubyEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsRubyEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsChangeCaseMapEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsChangeCaseMapEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsDoubleLinesEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsDoubleLinesEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsEmphasisMarksEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsEmphasisMarksEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsVerticalCallOutEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsVerticalCallOutEnabled();
}
/*-- 20.04.01 14:32:04---------------------------------------------------

  -----------------------------------------------------------------------*/
void        SvtCJKOptions::SetAll(sal_Bool bSet)
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    pCJKOptions->SetAll(bSet);
}
/*-- 20.04.01 14:32:06---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_Bool    SvtCJKOptions::IsAnyEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsAnyEnabled();
}

<commit_msg>#88512# changes for TF_CFGDATA<commit_after>/*************************************************************************
 *
 *  $RCSfile: cjkoptions.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: dg $ $Date: 2001-06-22 08:05:59 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _SVTOOLS_CJKOPTIONS_HXX
#include "cjkoptions.hxx"
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

using namespace ::com::sun::star::uno;
using namespace ::rtl;

#define C2U(cChar) OUString::createFromAscii(cChar)
/* -----------------------------10.04.01 12:39--------------------------------

 ---------------------------------------------------------------------------*/
class SvtCJKOptions_Impl : public utl::ConfigItem
{
    static Sequence<OUString> aPropertyNames;

    sal_Bool        bIsLoaded;
    sal_Bool        bCJKFont;
    sal_Bool        bVerticalText;
    sal_Bool        bAsianTypography;
    sal_Bool        bJapaneseFind;
    sal_Bool        bRuby;
    sal_Bool        bChangeCaseMap;
    sal_Bool        bDoubleLines;
    sal_Bool        bEmphasisMarks;
    sal_Bool        bVerticalCallOut;

public:
    SvtCJKOptions_Impl();
    ~SvtCJKOptions_Impl();

    virtual void    Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
    virtual void    Commit();
    void            Load();

    sal_Bool IsLoaded()                         { return bIsLoaded;         }

    sal_Bool IsCJKFontEnabled() const           { return bCJKFont;          }
    sal_Bool IsVerticalTextEnabled() const      { return bVerticalText;     }
    sal_Bool IsAsianTypographyEnabled() const   { return bAsianTypography;  }
    sal_Bool IsJapaneseFindEnabled() const      { return bJapaneseFind;     }
    sal_Bool IsRubyEnabled() const              { return bRuby;             }
    sal_Bool IsChangeCaseMapEnabled() const     { return bChangeCaseMap;    }
    sal_Bool IsDoubleLinesEnabled() const       { return bDoubleLines;      }
    sal_Bool IsEmphasisMarksEnabled() const     { return bEmphasisMarks;    }
    sal_Bool IsVerticalCallOutEnabled() const   { return bVerticalCallOut;  }

    sal_Bool IsAnyEnabled() const {
        return  bCJKFont||bVerticalText||bAsianTypography||bJapaneseFind||
                bRuby||bChangeCaseMap||bDoubleLines||bEmphasisMarks||bVerticalCallOut;   }
    void    SetAll(sal_Bool bSet);
};
/*-- 10.04.01 12:41:57---------------------------------------------------

  -----------------------------------------------------------------------*/
Sequence<OUString> SvtCJKOptions_Impl::aPropertyNames;

SvtCJKOptions_Impl::SvtCJKOptions_Impl() :
#ifdef TF_CFGDATA
    utl::ConfigItem(C2U("Office/Common/I18N/CJK")),
#else
    utl::ConfigItem(C2U("Setup/CJK/Enable")),
#endif
    bIsLoaded(sal_False),
    bCJKFont(sal_True),
    bVerticalText(sal_True),
    bAsianTypography(sal_True),
    bJapaneseFind(sal_True),
    bRuby(sal_True),
    bChangeCaseMap(sal_True),
    bDoubleLines(sal_True),
    bEmphasisMarks(sal_True),
    bVerticalCallOut(sal_True)
{
}
/*-- 10.04.01 12:41:57---------------------------------------------------

  -----------------------------------------------------------------------*/
SvtCJKOptions_Impl::~SvtCJKOptions_Impl()
{
}
/* -----------------------------20.04.01 14:34--------------------------------

 ---------------------------------------------------------------------------*/
void    SvtCJKOptions_Impl::SetAll(sal_Bool bSet)
{
    bCJKFont = bVerticalText = bAsianTypography = bJapaneseFind =
            bRuby = bChangeCaseMap = bDoubleLines = bEmphasisMarks = bVerticalCallOut = bSet;
    SetModified();
}
/*-- 10.04.01 12:41:56---------------------------------------------------

  -----------------------------------------------------------------------*/
void SvtCJKOptions_Impl::Load()
{
    if(!aPropertyNames.getLength())
    {
        aPropertyNames.realloc(9);
        OUString* pNames = aPropertyNames.getArray();

        pNames[0] = C2U("CJKFont");
        pNames[1] = C2U("VerticalText");
        pNames[2] = C2U("AsianTypography");
        pNames[3] = C2U("JapaneseFind");
        pNames[4] = C2U("Ruby");
        pNames[5] = C2U("ChangeCaseMap");
        pNames[6] = C2U("DoubleLines");
        pNames[7] = C2U("EmphasisMarks");
        pNames[8] = C2U("VerticalCallOut");

        EnableNotification( aPropertyNames );
    }
    Sequence< Any > aValues = GetProperties(aPropertyNames);
    const Any* pValues = aValues.getConstArray();
    DBG_ASSERT( aValues.getLength() == aPropertyNames.getLength(), "GetProperties failed" );
    if ( aValues.getLength() == aPropertyNames.getLength() )
    {
        for ( int nProp = 0; nProp < aPropertyNames.getLength(); nProp++ )
        {
            if( pValues[nProp].hasValue() )
            {
                sal_Bool bValue = *(sal_Bool*)pValues[nProp].getValue();
                switch ( nProp )
                {
                    case 0: bCJKFont = bValue; break;
                    case 1: bVerticalText = bValue; break;
                    case 2: bAsianTypography = bValue; break;
                    case 3: bJapaneseFind = bValue; break;
                    case 4: bRuby = bValue; break;
                    case 5: bChangeCaseMap = bValue; break;
                    case 6: bDoubleLines = bValue; break;
                    case 7: bEmphasisMarks = bValue; break;
                    case 8: bVerticalCallOut = bValue; break;
                }
            }
        }
    }
    bIsLoaded = sal_True;
}
/*-- 10.04.01 12:41:57---------------------------------------------------

  -----------------------------------------------------------------------*/
void    SvtCJKOptions_Impl::Notify( const Sequence< OUString >& aPropertyNames )
{
    Load();
}
/*-- 10.04.01 12:41:57---------------------------------------------------

  -----------------------------------------------------------------------*/
void    SvtCJKOptions_Impl::Commit()
{
    OUString* pNames = aPropertyNames.getArray();
    Sequence<Any> aValues(aPropertyNames.getLength());
    Any* pValues = aValues.getArray();

    const Type& rType = ::getBooleanCppuType();
    BOOL bVal;
    for(int nProp = 0; nProp < aPropertyNames.getLength(); nProp++)
    {
        switch(nProp)
        {
            case  0: bVal = bCJKFont; break;
            case  1: bVal = bVerticalText; break;
            case  2: bVal = bAsianTypography; break;
            case  3: bVal = bJapaneseFind; break;
            case  4: bVal = bRuby; break;
            case  5: bVal = bChangeCaseMap; break;
            case  6: bVal = bDoubleLines; break;
            case  7: bVal = bEmphasisMarks; break;
            case  8: bVal = bVerticalCallOut; break;
        }
        pValues[nProp].setValue(&bVal, getBooleanCppuType());
    }
    PutProperties(aPropertyNames, aValues);
}
// global ----------------------------------------------------------------

static SvtCJKOptions_Impl*  pCJKOptions = NULL;
static sal_Int32            nCJKRefCount = 0;
static ::osl::Mutex         aCJKMutex;

// class SvtCJKOptions --------------------------------------------------

SvtCJKOptions::SvtCJKOptions(sal_Bool bDontLoad)
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aCJKMutex );
    if ( !pCJKOptions )
        pCJKOptions = new SvtCJKOptions_Impl;
    if( !bDontLoad && !pCJKOptions->IsLoaded())
        pCJKOptions->Load();

    ++nCJKRefCount;
    pImp = pCJKOptions;
}

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

SvtCJKOptions::~SvtCJKOptions()
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aCJKMutex );
    if ( !--nCJKRefCount )
        DELETEZ( pCJKOptions );
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsCJKFontEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsCJKFontEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsVerticalTextEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsVerticalTextEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsAsianTypographyEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsAsianTypographyEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsJapaneseFindEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsJapaneseFindEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsRubyEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsRubyEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsChangeCaseMapEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsChangeCaseMapEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsDoubleLinesEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsDoubleLinesEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsEmphasisMarksEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsEmphasisMarksEnabled();
}
// -----------------------------------------------------------------------
sal_Bool SvtCJKOptions::IsVerticalCallOutEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsVerticalCallOutEnabled();
}
/*-- 20.04.01 14:32:04---------------------------------------------------

  -----------------------------------------------------------------------*/
void        SvtCJKOptions::SetAll(sal_Bool bSet)
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    pCJKOptions->SetAll(bSet);
}
/*-- 20.04.01 14:32:06---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_Bool    SvtCJKOptions::IsAnyEnabled() const
{
    DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded")
    return pCJKOptions->IsAnyEnabled();
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <svtools/foldertree.hxx>

#include "contentenumeration.hxx"

FolderTree::FolderTree( vcl::Window* pParent, WinBits nBits )
    : SvTreeListBox( pParent, nBits | WB_SORT | WB_TABSTOP )
    , m_aFolderImage( SvtResId( IMG_SVT_FOLDER ) )
    , m_aFolderExpandedImage( SvtResId( IMG_SVT_FOLDER_OPEN ) )
{
    Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    Reference< XInteractionHandler > xInteractionHandler(
                InteractionHandler::createWithParent( xContext, 0 ), UNO_QUERY_THROW );
    m_xEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );

    SetDefaultCollapsedEntryBmp( m_aFolderImage );
    SetDefaultExpandedEntryBmp( m_aFolderExpandedImage );
}

void FolderTree::RequestingChildren( SvTreeListEntry* pEntry )
{
    FillTreeEntry( pEntry );
}

void FolderTree::FillTreeEntry( SvTreeListEntry* pEntry )
{
    if( pEntry )
    {
        while( GetChildCount( pEntry ) > 0 )
        {
            SvTreeListEntry* pChild = FirstChild( pEntry );
            GetModel()->Remove( pChild );
        }

        ::std::vector< SortingData_Impl* > aContent;

        ::rtl::Reference< ::svt::FileViewContentEnumerator >
            xContentEnumerator(new FileViewContentEnumerator(
            m_xEnv, aContent, m_aMutex, NULL));

        OUString* pURL = static_cast< OUString* >( pEntry->GetUserData() );

        if( pURL )
        {
            FolderDescriptor aFolder( *pURL );

            EnumerationResult eResult =
                xContentEnumerator->enumerateFolderContentSync( aFolder, m_aBlackList );

            if ( SUCCESS == eResult )
            {
                for( std::vector<SortingData_Impl *>::size_type i = 0; i < aContent.size(); i++ )
                {
                    if( aContent[i]->mbIsFolder )
                    {
                        SvTreeListEntry* pNewEntry = InsertEntry( aContent[i]->GetTitle(), pEntry, true );

                        OUString* sData = new OUString( aContent[i]->maTargetURL );
                        pNewEntry->SetUserData( static_cast< void* >( sData ) );
                    }
                }
            }
        }
    }
}

void FolderTree::SetTreePath( OUString const & sUrl )
{
    INetURLObject aUrl( sUrl );
    aUrl.setFinalSlash();

    OUString sPath = aUrl.GetURLPath( INetURLObject::DECODE_WITH_CHARSET );

    SvTreeListEntry* pEntry = First();
    bool end = false;

    while( pEntry && !end )
    {
        if( pEntry->GetUserData() )
        {
            OUString sNodeUrl = *static_cast< OUString* >( pEntry->GetUserData() );

            INetURLObject aUrlObj( sNodeUrl );
            aUrlObj.setFinalSlash();

            sNodeUrl = aUrlObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET );

            if( sPath == sNodeUrl )
            {
                Select( pEntry );
                end = true;
            }
            else if( sPath.startsWith( sNodeUrl ) )
            {
                if( !IsExpanded( pEntry ) )
                    Expand( pEntry );

                pEntry = FirstChild( pEntry );
            }
            else
            {
                pEntry = NextSibling( pEntry );
            }
        }
        else
            break;
    }
}

void FolderTree::SetBlackList( const ::com::sun::star::uno::Sequence< OUString >& rBlackList )
{
    m_aBlackList = rBlackList;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>coverity#1315003 Dereference null return value<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <svtools/foldertree.hxx>

#include "contentenumeration.hxx"

FolderTree::FolderTree( vcl::Window* pParent, WinBits nBits )
    : SvTreeListBox( pParent, nBits | WB_SORT | WB_TABSTOP )
    , m_aFolderImage( SvtResId( IMG_SVT_FOLDER ) )
    , m_aFolderExpandedImage( SvtResId( IMG_SVT_FOLDER_OPEN ) )
{
    Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    Reference< XInteractionHandler > xInteractionHandler(
                InteractionHandler::createWithParent( xContext, 0 ), UNO_QUERY_THROW );
    m_xEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );

    SetDefaultCollapsedEntryBmp( m_aFolderImage );
    SetDefaultExpandedEntryBmp( m_aFolderExpandedImage );
}

void FolderTree::RequestingChildren( SvTreeListEntry* pEntry )
{
    FillTreeEntry( pEntry );
}

void FolderTree::FillTreeEntry( SvTreeListEntry* pEntry )
{
    if( pEntry )
    {
        while (SvTreeListEntry* pChild = FirstChild(pEntry))
        {
            GetModel()->Remove(pChild);
        }

        ::std::vector< SortingData_Impl* > aContent;

        ::rtl::Reference< ::svt::FileViewContentEnumerator >
            xContentEnumerator(new FileViewContentEnumerator(
            m_xEnv, aContent, m_aMutex, NULL));

        OUString* pURL = static_cast< OUString* >( pEntry->GetUserData() );

        if( pURL )
        {
            FolderDescriptor aFolder( *pURL );

            EnumerationResult eResult =
                xContentEnumerator->enumerateFolderContentSync( aFolder, m_aBlackList );

            if ( SUCCESS == eResult )
            {
                for( std::vector<SortingData_Impl *>::size_type i = 0; i < aContent.size(); i++ )
                {
                    if( aContent[i]->mbIsFolder )
                    {
                        SvTreeListEntry* pNewEntry = InsertEntry( aContent[i]->GetTitle(), pEntry, true );

                        OUString* sData = new OUString( aContent[i]->maTargetURL );
                        pNewEntry->SetUserData( static_cast< void* >( sData ) );
                    }
                }
            }
        }
    }
}

void FolderTree::SetTreePath( OUString const & sUrl )
{
    INetURLObject aUrl( sUrl );
    aUrl.setFinalSlash();

    OUString sPath = aUrl.GetURLPath( INetURLObject::DECODE_WITH_CHARSET );

    SvTreeListEntry* pEntry = First();
    bool end = false;

    while( pEntry && !end )
    {
        if( pEntry->GetUserData() )
        {
            OUString sNodeUrl = *static_cast< OUString* >( pEntry->GetUserData() );

            INetURLObject aUrlObj( sNodeUrl );
            aUrlObj.setFinalSlash();

            sNodeUrl = aUrlObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET );

            if( sPath == sNodeUrl )
            {
                Select( pEntry );
                end = true;
            }
            else if( sPath.startsWith( sNodeUrl ) )
            {
                if( !IsExpanded( pEntry ) )
                    Expand( pEntry );

                pEntry = FirstChild( pEntry );
            }
            else
            {
                pEntry = NextSibling( pEntry );
            }
        }
        else
            break;
    }
}

void FolderTree::SetBlackList( const ::com::sun::star::uno::Sequence< OUString >& rBlackList )
{
    m_aBlackList = rBlackList;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright (c) 2014, Hobu Inc. (hobu@hobu.co)
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following
 * conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of the Martin Isenburg or Iowa Department
 *       of Natural Resources nor the names of its contributors may be
 *       used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 ****************************************************************************/

#include <deque>
#include <string>

#include "Header.hpp"
#include "Vlr.hpp"

namespace pdal
{

class ILeStream;

namespace lasdump
{

class Dumper
{

public:
    Dumper(const std::deque<std::string>& args) : m_out(&std::cout)
        { m_error = processArgs(args); }
    void dump();
    int error()
        { return m_error; }

private:
    std::string m_filename;
    Header m_header;
    Vlr m_zipVlr;
    int m_error;
    ofstream m_fout;
    ostream *m_out;

    int processArgs(std::deque<std::string> args);
    void readPoints(ILeStream& in);
    void readCompressedPoints(ILeStream& in);
};

} // namespace lasdump
} // namespace pdal

<commit_msg>need <iostream> in Dumper for std::cout<commit_after>/******************************************************************************
 * Copyright (c) 2014, Hobu Inc. (hobu@hobu.co)
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following
 * conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of the Martin Isenburg or Iowa Department
 *       of Natural Resources nor the names of its contributors may be
 *       used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 ****************************************************************************/

#include <deque>
#include <string>
#include <iostream>

#include "Header.hpp"
#include "Vlr.hpp"

namespace pdal
{

class ILeStream;

namespace lasdump
{

class Dumper
{

public:
    Dumper(const std::deque<std::string>& args) : m_out(&std::cout)
        { m_error = processArgs(args); }
    void dump();
    int error()
        { return m_error; }

private:
    std::string m_filename;
    Header m_header;
    Vlr m_zipVlr;
    int m_error;
    ofstream m_fout;
    ostream *m_out;

    int processArgs(std::deque<std::string> args);
    void readPoints(ILeStream& in);
    void readCompressedPoints(ILeStream& in);
};

} // namespace lasdump
} // namespace pdal

<|endoftext|>