Compare commits

..

2 Commits

Author SHA1 Message Date
fur%netscape.com
1c43d4984f This is a copy of regalloc_code2_BRANCH from Netscape's private repository,
as it existed in January of 1998.


git-svn-id: svn://10.0.0.236/branches/regalloc_code2_BRANCH@22571 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-02 16:12:08 +00:00
(no author)
cfe021ff88 This commit was manufactured by cvs2svn to create branch
'regalloc_code2_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/regalloc_code2_BRANCH@22567 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-02 15:57:58 +00:00
195 changed files with 5324 additions and 30033 deletions

View File

@@ -0,0 +1,134 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "BitSet.h"
// Return the next bit after index set to true or -1 if none.
//
Int32 BitSet::nextOne(Int32 pos) const
{
++pos;
if (pos < 0 || Uint32(pos) >= universeSize)
return -1;
Uint32 offset = getWordOffset(pos);
Uint8 index = getBitOffset(pos);
Word* ptr = &word[offset];
Word currentWord = *ptr++ >> index;
if (currentWord != Word(0)) {
while ((currentWord & Word(1)) == 0) {
++index;
currentWord >>= 1;
}
return (offset << nBitsInWordLog2) + index;
}
Word* limit = &word[getSizeInWords(universeSize)];
while (ptr < limit) {
++offset;
currentWord = *ptr++;
if (currentWord != Word(0)) {
index = 0;
while ((currentWord & Word(1)) == 0) {
++index;
currentWord >>= 1;
}
return (offset << nBitsInWordLog2) + index;
}
}
return -1;
}
// Return the next bit after index set to false or -1 if none.
//
Int32 BitSet::nextZero(Int32 pos) const
{
++pos;
if (pos < 0 || Uint32(pos) >= universeSize)
return -1;
Uint32 offset = getWordOffset(pos);
Uint8 index = getBitOffset(pos);
Word* ptr = &word[offset];
Word currentWord = *ptr++ >> index;
if (currentWord != Word(~0)) {
for (; index < nBitsInWord; ++index) {
if ((currentWord & Word(1)) == 0) {
Int32 ret = (offset << nBitsInWordLog2) + index;
return (Uint32(ret) < universeSize) ? ret : -1;
}
currentWord >>= 1;
}
}
Word* limit = &word[getSizeInWords(universeSize)];
while (ptr < limit) {
++offset;
currentWord = *ptr++;
if (currentWord != Word(~0)) {
for (index = 0; index < nBitsInWord; ++index) {
if ((currentWord & Word(1)) == 0) {
Int32 ret = (offset << nBitsInWordLog2) + index;
return (Uint32(ret) < universeSize) ? ret : -1;
}
currentWord >>= 1;
}
}
}
return -1;
}
#ifdef DEBUG_LOG
// Print the set.
//
void BitSet::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("[ "));
for (Int32 i = firstOne(); i != -1; i = nextOne(i)) {
Int32 currentBit = i;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", currentBit));
Int32 nextBit = nextOne(currentBit);
if (nextBit != currentBit + 1) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" "));
continue;
}
while ((nextBit != -1) && (nextBit == (currentBit + 1))) {
currentBit = nextBit;
nextBit = nextOne(nextBit);
}
if (currentBit > (i+1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("-%d ", currentBit));
else
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" %d ", currentBit));
i = currentBit;
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("]\n"));
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,195 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _BITSET_H_
#define _BITSET_H_
#include "Fundamentals.h"
#include "LogModule.h"
#include "Pool.h"
#include <string.h>
//------------------------------------------------------------------------------
// BitSet -
class BitSet
{
private:
#if (PR_BITS_PER_WORD == 64)
typedef Uint64 Word;
#elif (PR_BITS_PER_WORD == 32)
typedef Uint32 Word;
#endif
static const nBitsInWord = PR_BITS_PER_WORD;
static const nBytesInWord = PR_BYTES_PER_WORD;
static const nBitsInWordLog2 = PR_BITS_PER_WORD_LOG2;
static const nBytesInWordLog2 = PR_BYTES_PER_WORD_LOG2;
// Return the number of Word need to store the universe.
static Uint32 getSizeInWords(Uint32 sizeOfUniverse) {return (sizeOfUniverse + (nBitsInWord - 1)) >> nBitsInWordLog2;}
// Return the given element offset in its containing Word.
static Uint32 getBitOffset(Uint32 element) {return element & (nBitsInWord - 1);}
// Return the Word offset for the given element int the universe.
static Uint32 getWordOffset(Uint32 element) {return element >> nBitsInWordLog2;}
// Return the mask for the given bit index.
static Word getMask(Uint8 index) {return Word(1) << index;}
private:
Uint32 universeSize; // Size of the universe
Word* word; // universe memory.
private:
// No copy constructor.
BitSet(const BitSet&);
// Check if the given set's universe is of the same size than this universe.
void checkUniverseCompatibility(const BitSet& set) const {assert(set.universeSize == universeSize);}
// Check if pos is valid for this set's universe.
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
public:
// Create a bitset of universeSize bits.
BitSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {word = new(pool) Word[getSizeInWords(universeSize)]; clear();}
// Return the size of this bitset.
Uint32 getSize() const {return universeSize;}
// Clear the bitset.
void clear() {memset(word, 0x00, getSizeInWords(universeSize) << nBytesInWordLog2);}
// Clear the bit at index.
void clear(Uint32 index) {checkMember(index); word[getWordOffset(index)] &= ~getMask(index);}
// Set the bitset.
void set() {memset(word, 0xFF, getSizeInWords(universeSize) << nBytesInWordLog2);}
// Set the bit at index.
void set(Uint32 index) {checkMember(index); word[getWordOffset(index)] |= getMask(index);}
// Return true if the bit at index is set.
bool test(Uint32 index) const {checkMember(index); return (word[getWordOffset(index)] & getMask(index)) != 0;}
// Union with the given bitset.
inline void or(const BitSet& set);
// Intersection with the given bitset.
inline void and(const BitSet& set);
// Difference with the given bitset.
inline void difference(const BitSet& set);
// Copy set.
inline BitSet& operator = (const BitSet& set);
// Return true if the bitset are identical.
friend bool operator == (const BitSet& set1, const BitSet& set2);
// Return true if the bitset are different.
friend bool operator != (const BitSet& set1, const BitSet& set2);
// Logical operators.
BitSet& operator |= (const BitSet& set) {or(set); return *this;}
BitSet& operator &= (const BitSet& set) {and(set); return *this;}
BitSet& operator -= (const BitSet& set) {difference(set); return *this;}
// Return the first bit at set to true or -1 if none.
Int32 firstOne() const {return nextOne(-1);}
// Return the next bit after index set to true or -1 if none.
Int32 nextOne(Int32 pos) const;
// Return the first bit at set to false or -1 if none.
Int32 firstZero() const {return nextZero(-1);}
// Return the next bit after index set to false or -1 if none.
Int32 nextZero(Int32 pos) const;
// Iterator to conform with the set API.
typedef Int32 iterator;
// Return true if the walk is ordered.
static bool isOrdered() {return true;}
// Return the iterator for the first element of this set.
iterator begin() const {return firstOne();}
// Return the next iterator.
iterator advance(iterator pos) const {return nextOne(pos);}
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos == -1;}
// Return the element corresponding to the given iterator.
Uint32 get(iterator pos) const {return pos;}
#ifdef DEBUG_LOG
// Print the set.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
// Union with the given bitset.
//
inline void BitSet::or(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ |= *src++;
}
// Intersection with the given bitset.
//
inline void BitSet::and(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ &= *src++;
}
// Difference with the given bitset.
//
inline void BitSet::difference(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ &= ~*src++;
}
// Copy the given set into this set.
//
inline BitSet& BitSet::operator = (const BitSet& set)
{
checkUniverseCompatibility(set);
if (this != &set)
memcpy(word, set.word, getSizeInWords(universeSize) << nBytesInWordLog2);
return *this;
}
// Return true if the given set is identical to this set.
inline bool operator == (const BitSet& set1, const BitSet& set2)
{
set1.checkUniverseCompatibility(set2);
if (&set1 == &set2)
return true;
return memcmp(set1.word, set2.word, BitSet::getSizeInWords(set1.universeSize) << BitSet::nBytesInWordLog2) == 0;
}
inline bool operator != (const BitSet& set1, const BitSet& set2) {return !(set1 == set2);}
#endif // _BITSET_H

View File

@@ -0,0 +1,159 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _COALESCING_H_
#define _COALESCING_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "RegisterPressure.h"
#include "InterferenceGraph.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "SparseSet.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
#if 1
// Performing an ultra conservative coalescing meens that when we look at
// candidates (source,destination) for coalescing we need to make sure
// that the combined interference of the source and destination register
// will not exceed the total number of register available for the register
// class.
#define ULTRA_CONSERVATIVE_COALESCING
#else
// If we are not doing an ultra conservative coalescing we have to make sure
// that the total number of neighbor whose degree is greater than the total
// number of register is not greater than the total number of register.
#undef ULTRA_CONSERVATIVE_COALESCING
#endif
template <class RegisterPressure>
struct Coalescing
{
static bool coalesce(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
bool Coalescing<RegisterPressure>::coalesce(RegisterAllocator& registerAllocator)
{
Pool& pool = registerAllocator.pool;
// Initialize the lookup table
//
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* newRange = new RegisterName[2 * rangeCount];
RegisterName* coalescedRange = &newRange[rangeCount];
RegisterName* name2range = registerAllocator.name2range;
init(coalescedRange, rangeCount);
SparseSet interferences(pool, rangeCount);
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
bool removedInstructions = false;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.lndList;
Uint32 nNodes = controlGraph.nNodes;
// Walk the nodes in the loop nesting depth list.
for (Int32 n = nNodes - 1; n >= 0; n--) {
InstructionList& instructions = nodes[n]->getInstructions();
InstructionList::iterator it = instructions.begin();
while (!instructions.done(it)) {
Instruction& instruction = instructions.get(it);
it = instructions.advance(it);
if ((instruction.getFlags() & ifCopy) != 0) {
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
RegisterName source = findRoot(name2range[instruction.getInstructionUseBegin()[0].getRegisterName()], coalescedRange);
RegisterName destination = findRoot(name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()], coalescedRange);
if (source == destination) {
instruction.remove();
} else if (!iGraph.interfere(source, destination)) {
InterferenceVector* sourceVector = iGraph.getInterferenceVector(source);
InterferenceVector* destinationVector = iGraph.getInterferenceVector(destination);
#ifdef ULTRA_CONSERVATIVE_COALESCING
interferences.clear();
InterferenceVector* vector;
for (vector = sourceVector; vector != NULL; vector = vector->next) {
RegisterName* neighbors = vector->neighbors;
for (Uint32 i = 0; i < vector->count; i++)
interferences.set(findRoot(neighbors[i], coalescedRange));
}
for (vector = destinationVector; vector != NULL; vector = vector->next) {
RegisterName* neighbors = vector->neighbors;
for (Uint32 i = 0; i < vector->count; i++)
interferences.set(findRoot(neighbors[i], coalescedRange));
}
Uint32 count = interferences.getSize();
#else // ULTRA_CONSERVATIVE_COALESCING
trespass("not implemented");
Uint32 count = 0;
#endif // ULTRA_CONSERVATIVE_COALESCING
if (count < 6 /* FIX: should get the number from the class */) {
// Update the interferences vector.
if (sourceVector == NULL) {
iGraph.setInterferenceVector(source, destinationVector);
sourceVector = destinationVector;
} else if (destinationVector == NULL)
iGraph.setInterferenceVector(destination, sourceVector);
else {
InterferenceVector* last = NULL;
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next)
last = v;
assert(last);
last->next = destinationVector;
iGraph.setInterferenceVector(destination, sourceVector);
}
// Update the interference matrix.
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next) {
RegisterName* neighbors = v->neighbors;
for (Uint32 i = 0; i < v->count; i++) {
RegisterName neighbor = findRoot(neighbors[i], coalescedRange);
iGraph.setInterference(neighbor, source);
iGraph.setInterference(neighbor, destination);
}
}
instruction.remove();
coalescedRange[source] = destination;
removedInstructions = true;
}
}
}
}
}
registerAllocator.rangeCount = compress(registerAllocator.name2range, coalescedRange, registerAllocator.nameCount, rangeCount);
delete newRange;
return removedInstructions;
}
#endif // _COALESCING_H_

View File

@@ -0,0 +1,283 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef NEW_LAURENTM_CODE
#include "Coloring.h"
#include "VirtualRegister.h"
#include "FastBitSet.h"
#include "FastBitMatrix.h"
#include "CpuInfo.h"
bool Coloring::
assignRegisters(FastBitMatrix& interferenceMatrix)
{
PRUint32 *stackPtr = new(pool) PRUint32[vRegManager.count()];
return select(interferenceMatrix, stackPtr, simplify(interferenceMatrix, stackPtr));
}
PRInt32 Coloring::
getLowestSpillCostRegister(FastBitSet& bitset)
{
PRInt32 lowest = bitset.firstOne();
if (lowest != -1)
{
Flt32 cost = vRegManager.getVirtualRegister(lowest).spillInfo.spillCost;
for (PRInt32 r = bitset.nextOne(lowest); r != -1; r = bitset.nextOne(r))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
if (!vReg.spillInfo.infiniteSpillCost && (vReg.spillInfo.spillCost < cost))
{
cost = vReg.spillInfo.spillCost;
lowest = r;
}
}
}
return lowest;
}
PRUint32* Coloring::
simplify(FastBitMatrix interferenceMatrix, PRUint32* stackPtr)
{
// first we construct the sets low and high. low contains all nodes of degree
// inferior to the number of register available on the processor. All the
// nodes with an high degree and a finite spill cost are placed in high.
// Nodes of high degree and infinite spill cost are not included in either sets.
PRUint32 nRegisters = vRegManager.count();
FastBitSet low(pool, nRegisters);
FastBitSet high(pool, nRegisters);
FastBitSet stack(pool, nRegisters);
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
if (vReg.getClass() == vrcStackSlot)
{
stack.set(i);
vReg.colorRegister(nRegisters);
}
else
{
if (vReg.colorInfo.interferenceDegree < NUMBER_OF_REGISTERS)
low.set(i);
else // if (!vReg.spillInfo.infiniteSpillCost)
high.set(i);
// Set coloring info.
vReg.spillInfo.willSpill = false;
switch(vReg.getClass())
{
case vrcInteger:
vReg.colorRegister(LAST_GREGISTER + 1);
break;
case vrcFloatingPoint:
case vrcFixedPoint:
vReg.colorRegister(LAST_FPREGISTER + 1);
break;
default:
PR_ASSERT(false); // Cannot happen.
}
}
}
// push the stack registers
PRInt32 j;
for (j = stack.firstOne(); j != -1; j = stack.nextOne(j))
*stackPtr++ = j;
// simplify
while (true)
{
PRInt32 r;
while ((r = getLowestSpillCostRegister(low)) != -1)
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
/* update low and high */
FastBitSet inter(interferenceMatrix.getRow(r), nRegisters);
for (j = inter.firstOne(); j != -1; j = inter.nextOne(j))
{
VirtualRegister& neighbor = vRegManager.getVirtualRegister(j);
// if the new interference degree of one of his neighbor becomes
// NUMBER_OF_REGISTERS - 1 then it is added to the set 'low'.
PRUint32 maxInterference = 0;
switch (neighbor.getClass())
{
case vrcInteger:
maxInterference = NUMBER_OF_GREGISTERS;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
maxInterference = NUMBER_OF_FPREGISTERS;
break;
default:
PR_ASSERT(false);
}
if ((vRegManager.getVirtualRegister(j).colorInfo.interferenceDegree-- == maxInterference))
{
high.clear(j);
low.set(j);
}
vReg.colorInfo.interferenceDegree--;
interferenceMatrix.clear(r, j);
interferenceMatrix.clear(j, r);
}
low.clear(r);
// Push this register.
*stackPtr++ = r;
}
if ((r = getLowestSpillCostRegister(high)) != -1)
{
high.clear(r);
low.set(r);
}
else
break;
}
return stackPtr;
}
bool Coloring::
select(FastBitMatrix& interferenceMatrix, PRUint32* stackBase, PRUint32* stackPtr)
{
PRUint32 nRegisters = vRegManager.count();
FastBitSet usedRegisters(NUMBER_OF_REGISTERS + 1); // usedRegisters if used for both GR & FPR.
FastBitSet preColoredRegisters(NUMBER_OF_REGISTERS + 1);
FastBitSet usedStack(nRegisters + 1);
bool success = true;
Int32 lastUsedSSR = -1;
// select
while (stackPtr != stackBase)
{
// Pop one register.
PRUint32 r = *--stackPtr;
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
FastBitSet neighbors(interferenceMatrix.getRow(r), nRegisters);
if (vReg.getClass() == vrcStackSlot)
// Stack slots coloring.
{
usedStack.clear();
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
usedStack.set(vRegManager.getVirtualRegister(i).getColor());
Int32 color = usedStack.firstZero();
vReg.colorRegister(color);
if (color > lastUsedSSR)
lastUsedSSR = color;
}
else
// Integer & Floating point register coloring.
{
usedRegisters.clear();
preColoredRegisters.clear();
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
{
VirtualRegister& nvReg = vRegManager.getVirtualRegister(i);
usedRegisters.set(nvReg.getColor());
if (nvReg.isPreColored())
preColoredRegisters.set(nvReg.getPreColor());
}
if (vReg.hasSpecialInterference)
usedRegisters |= vReg.specialInterference;
PRInt8 c = -1;
PRInt8 maxColor = 0;
PRInt8 firstColor = 0;
switch (vReg.getClass())
{
case vrcInteger:
firstColor = FIRST_GREGISTER;
maxColor = LAST_GREGISTER;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
firstColor = FIRST_FPREGISTER;
maxColor = LAST_FPREGISTER;
break;
default:
PR_ASSERT(false);
}
if (vReg.isPreColored())
{
c = vReg.getPreColor();
if (usedRegisters.test(c))
c = -1;
}
else
{
for (c = usedRegisters.nextZero(firstColor - 1); (c >= 0) && (c <= maxColor) && (preColoredRegisters.test(c));
c = usedRegisters.nextZero(c)) {}
}
if ((c >= 0) && (c <= maxColor))
{
vReg.colorRegister(c);
}
else
{
VirtualRegister& stackRegister = vRegManager.newVirtualRegister(vrcStackSlot);
vReg.equivalentRegister[vrcStackSlot] = &stackRegister;
vReg.spillInfo.willSpill = true;
success = false;
}
}
}
#ifdef DEBUG
if (success)
{
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
switch (vReg.getClass())
{
case vrcInteger:
if (vReg.getColor() > LAST_GREGISTER)
PR_ASSERT(false);
break;
case vrcFloatingPoint:
case vrcFixedPoint:
#if NUMBER_OF_FPREGISTERS != 0
if (vReg.getColor() > LAST_FPREGISTER)
PR_ASSERT(false);
#endif
break;
default:
break;
}
}
}
#endif
vRegManager.nUsedStackSlots = lastUsedSSR + 1;
return success;
}
#endif // NEW_LAURENTM_CODE

View File

@@ -0,0 +1,284 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "VirtualRegister.h"
#include "InterferenceGraph.h"
#include "SparseSet.h"
#include "Spilling.h"
#include "Splits.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
template <class RegisterPressure>
class Coloring
{
private:
static RegisterName* simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack);
static bool select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr);
public:
static bool color(RegisterAllocator& registerAllocator);
static void finalColoring(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
void Coloring<RegisterPressure>::finalColoring(RegisterAllocator& registerAllocator)
{
RegisterName* color = registerAllocator.color;
RegisterName* name2range = registerAllocator.name2range;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
usePtr->setRegisterName(color[name2range[usePtr->getRegisterName()]]);
#ifdef DEBUG
RegisterID rid = usePtr->getRegisterID();
setColoredRegister(rid);
usePtr->setRegisterID(rid);
#endif // DEBUG
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
definePtr->setRegisterName(color[name2range[definePtr->getRegisterName()]]);
#ifdef DEBUG
RegisterID rid = definePtr->getRegisterID();
setColoredRegister(rid);
definePtr->setRegisterID(rid);
#endif // DEBUG
}
}
}
}
template <class RegisterPressure>
bool Coloring<RegisterPressure>::select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* color = new RegisterName[rangeCount];
registerAllocator.color = color;
for (Uint32 r = 1; r < rangeCount; r++)
color[r] = RegisterName(6); // FIX;
// Color the preColored registers.
//
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
RegisterName* name2range = registerAllocator.name2range;
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
if (machinePtr->id != invalidID) {
color[name2range[getName(machinePtr->id)]] = machinePtr->color;
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill preColor range %d as %d\n", name2range[getName(machinePtr->id)], machinePtr->color));
}
SpillCost* cost = registerAllocator.spillCost;
Pool& pool = registerAllocator.pool;
SparseSet& spill = *new(pool) SparseSet(pool, rangeCount);
registerAllocator.willSpill = &spill;
SparseSet neighborColors(pool, 6); // FIX
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
bool coloringFailed = false;
while (coloringStackPtr > coloringStack) {
RegisterName range = *--coloringStackPtr;
if (!cost[range].infinite && cost[range].cost < 0) {
coloringFailed = true;
spill.set(range);
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, will spill.\n", range));
} else {
neighborColors.clear();
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = vector->count - 1; i >= 0; --i) {
RegisterName neighborColor = color[vector->neighbors[i]];
if (neighborColor < 6) // FIX
neighborColors.set(neighborColor);
}
if (neighborColors.getSize() == 6) { // FIX
coloringFailed = true;
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, ", range));
if (!Splits<RegisterPressure>::findSplit(registerAllocator, color, range)) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will spill.\n"));
spill.set(range);
} else
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will split.\n"));
} else {
for (Uint32 i = 0; i < 6; i++) // FIX
if (!neighborColors.test(i)) {
fprintf(stdout, "\twill color %d as %d\n", range, i);
color[range] = RegisterName(i);
break;
}
}
}
}
#ifdef DEBUG_LOG
if (coloringFailed) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring failed:\n"));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill spill: "));
spill.printPretty(UT_LOG_MODULE(RegAlloc));
} else {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring succeeded:\n"));
for (Uint32 i = 1; i < rangeCount; i++)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\trange %d colored as %d\n", i, color[i]));
}
#endif
return !coloringFailed;
}
template <class RegisterPressure>
RegisterName* Coloring<RegisterPressure>::simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack)
{
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
SpillCost* spillCost = registerAllocator.spillCost;
Uint32 rangeCount = registerAllocator.rangeCount;
Uint32* degree = new Uint32[rangeCount];
for (RegisterName i = RegisterName(1); i < rangeCount; i = RegisterName(i + 1)) {
InterferenceVector* vector = iGraph.getInterferenceVector(i);
degree[i] = (vector != NULL) ? vector->count : 0;
}
Pool& pool = registerAllocator.pool;
SparseSet low(pool, rangeCount);
SparseSet high(pool, rangeCount);
SparseSet highInfinite(pool, rangeCount);
SparseSet preColored(pool, rangeCount);
// Get the precolored registers.
//
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
RegisterName* name2range = registerAllocator.name2range;
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
if (machinePtr->id != invalidID)
preColored.set(name2range[getName(machinePtr->id)]);
// Insert the live ranges in the sets.
//
for (Uint32 range = 1; range < rangeCount; range++)
if (!preColored.test(range))
if (degree[range] < 6) // FIX
low.set(range);
else if (!spillCost[range].infinite)
high.set(range);
else
highInfinite.set(range);
#ifdef DEBUG_LOG
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring sets:\n\tlow = "));
low.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thigh = "));
high.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thighInfinite = "));
highInfinite.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tpreColored = "));
preColored.printPretty(UT_LOG_MODULE(RegAlloc));
#endif // DEBUG_LOG
RegisterName* coloringStackPtr = coloringStack;
while (low.getSize() != 0 || high.getSize() != 0) {
while (low.getSize() != 0) {
RegisterName range = RegisterName(low.getOne());
low.clear(range);
*coloringStackPtr++ = range;
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = (vector->count - 1); i >= 0; --i) {
RegisterName neighbor = vector->neighbors[i];
degree[neighbor]--;
if (degree[neighbor] < 6) // FIX
if (high.test(neighbor)) {
high.clear(neighbor);
low.set(neighbor);
} else if (highInfinite.test(neighbor)) {
highInfinite.clear(neighbor);
low.set(neighbor);
}
}
}
if (high.getSize() != 0) {
RegisterName best = RegisterName(high.getOne());
double bestCost = spillCost[best].cost;
double bestDegree = degree[best];
// Choose the next best candidate.
//
for (SparseSet::iterator i = high.begin(); !high.done(i); i = high.advance(i)) {
RegisterName range = RegisterName(high.get(i));
double thisCost = spillCost[range].cost;
double thisDegree = degree[range];
if (thisCost * bestDegree < bestCost * thisDegree) {
best = range;
bestCost = thisCost;
bestDegree = thisDegree;
}
}
high.clear(best);
low.set(best);
}
}
assert(highInfinite.getSize() == 0);
delete degree;
#ifdef DEBUG_LOG
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring stack:\n\t"));
for (RegisterName* sp = coloringStack; sp < coloringStackPtr; ++sp)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("%d ", *sp));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\n"));
#endif // DEBUG_LOG
return coloringStackPtr;
}
template <class RegisterPressure>
bool Coloring<RegisterPressure>::color(RegisterAllocator& registerAllocator)
{
RegisterName* coloringStack = new RegisterName[registerAllocator.rangeCount];
return select(registerAllocator, coloringStack, simplify(registerAllocator, coloringStack));
}

View File

@@ -0,0 +1,212 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include <string.h>
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "DominatorGraph.h"
DominatorGraph::DominatorGraph(ControlGraph& controlGraph) : controlGraph(controlGraph)
{
Uint32 nNodes = controlGraph.nNodes;
GtoV = new Uint32[nNodes + 1];
VtoG = new Uint32[nNodes + 1];
Uint32 v = 1;
for (Uint32 n = 0; n < nNodes; n++) {
VtoG[v] = n;
GtoV[n] = v++;
}
// Initialize all the 1-based arrays.
//
parent = new Uint32[v];
semi = new Uint32[v];
vertex = new Uint32[v];
label = new Uint32[v];
size = new Uint32[v];
ancestor = new Uint32[v];
child = new Uint32[v];
dom = new Uint32[v];
bucket = new DGLinkedList*[v];
memset(semi, '\0', v * sizeof(Uint32));
memset(bucket, '\0', v * sizeof(DGLinkedList*));
vCount = v;
build();
delete parent;
delete semi;
delete vertex;
delete label;
delete size;
delete ancestor;
delete child;
delete dom;
delete bucket;
}
Uint32 DominatorGraph::DFS(Uint32 vx, Uint32 n)
{
semi[vx] = ++n;
vertex[n] = label[vx] = vx;
ancestor[vx] = child[vx] = 0;
size[vx] = 1;
ControlNode& node = *controlGraph.dfsList[VtoG[vx]];
ControlEdge* successorEnd = node.getSuccessorsEnd();
for (ControlEdge* successorPtr = node.getSuccessorsBegin(); successorPtr < successorEnd; successorPtr++) {
Uint32 w = GtoV[successorPtr->getTarget().dfsNum];
if (semi[w] == 0) {
parent[w] = vx;
n = DFS(w, n);
}
}
return n;
}
void DominatorGraph::LINK(Uint32 vx, Uint32 w)
{
Uint32 s = w;
while (semi[label[w]] < semi[label[child[s]]]) {
if (size[s] + size[child[child[s]]] >= (size[child[s]] << 1)) {
ancestor[child[s]] = s;
child[s] = child[child[s]];
} else {
size[child[s]] = size[s];
s = ancestor[s] = child[s];
}
}
label[s] = label[w];
size[vx] += size[w];
if(size[vx] < (size[w] << 1)) {
Uint32 t = s;
s = child[vx];
child[vx] = t;
}
while( s != 0 ) {
ancestor[s] = vx;
s = child[s];
}
}
void DominatorGraph::COMPRESS(Uint32 vx)
{
if(ancestor[ancestor[vx]] != 0) {
COMPRESS(ancestor[vx]);
if(semi[label[ancestor[vx]]] < semi[label[vx]])
label[vx] = label[ancestor[vx]];
ancestor[vx] = ancestor[ancestor[vx]];
}
}
Uint32 DominatorGraph::EVAL(Uint32 vx)
{
if(ancestor[vx] == 0)
return label[vx];
COMPRESS(vx);
return (semi[label[ancestor[vx]]] >= semi[label[vx]]) ? label[vx] : label[ancestor[vx]];
}
void DominatorGraph::build()
{
Uint32 n = DFS(GtoV[0], 0);
size[0] = label[0] = semi[0];
for (Uint32 i = n; i >= 2; i--) {
Uint32 w = vertex[i];
ControlNode& node = *controlGraph.dfsList[VtoG[w]];
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p)) {
Uint32 vx = GtoV[predecessors.get(p).getSource().dfsNum];
Uint32 u = EVAL(vx);
if(semi[u] < semi[w])
semi[w] = semi[u];
}
DGLinkedList* elem = new DGLinkedList();
elem->next = bucket[vertex[semi[w]]];
elem->index = w;
bucket[vertex[semi[w]]] = elem;
LINK(parent[w], w);
elem = bucket[parent[w]];
while(elem != NULL) {
Uint32 vx = elem->index;
Uint32 u = EVAL(vx);
dom[vx] = (semi[u] < semi[vx]) ? u : parent[w];
elem = elem->next;
}
}
memset(size, '\0', n * sizeof(Uint32));
Pool& pool = controlGraph.pool;
nodes = new(pool) DGNode[n];
for(Uint32 j = 2; j <= n; j++) {
Uint32 w = vertex[j];
Uint32 d = dom[w];
if(d != vertex[semi[w]]) {
d = dom[d];
dom[w] = d;
}
size[d]++;
}
dom[GtoV[0]] = 0;
for (Uint32 k = 1; k <= n; k++) {
DGNode& node = nodes[VtoG[k]];
Uint32 count = size[k];
node.successorsEnd = node.successorsBegin = (count) ? new(pool) Uint32[count] : (Uint32*) 0;
}
for (Uint32 l = 2; l <= n; l++)
*(nodes[VtoG[dom[l]]].successorsEnd)++ = VtoG[l];
}
#ifdef DEBUG_LOG
void DominatorGraph::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Dominator Graph:\n"));
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 i = 0; i < nNodes; i++) {
DGNode& node = nodes[i];
if (node.successorsBegin != node.successorsEnd) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tN%d dominates ", i));
for (Uint32* successorsPtr = node.successorsBegin; successorsPtr < node.successorsEnd; successorsPtr++)
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d ", *successorsPtr));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _DOMINATOR_GRAPH_H_
#define _DOMINATOR_GRAPH_H_
#include "LogModule.h"
class ControlGraph;
struct DGNode
{
Uint32* successorsBegin;
Uint32* successorsEnd;
};
struct DGLinkedList
{
DGLinkedList* next;
Uint32 index;
};
class DominatorGraph
{
private:
ControlGraph& controlGraph;
Uint32 vCount;
Uint32* VtoG;
Uint32* GtoV;
Uint32* parent;
Uint32* semi;
Uint32* vertex;
Uint32* label;
Uint32* size;
Uint32* ancestor;
Uint32* child;
Uint32* dom;
DGLinkedList** bucket;
DGNode* nodes;
private:
void build();
Uint32 DFS(Uint32 vx, Uint32 n);
void LINK(Uint32 vx, Uint32 w);
void COMPRESS(Uint32 vx);
Uint32 EVAL(Uint32 vx);
public:
DominatorGraph(ControlGraph& controlGraph);
Uint32* getSuccessorsBegin(Uint32 n) const {return nodes[n].successorsBegin;}
Uint32* getSuccessorsEnd(Uint32 n) const {return nodes[n].successorsEnd;}
#ifdef DEBUG_LOG
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
#endif // _DOMINATOR_GRAPH_H_

View File

@@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "HashSet.h"

View File

@@ -0,0 +1,97 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _HASH_SET_H_
#define _HASH_SET_H_
#include "Fundamentals.h"
#include "Pool.h"
#include <string.h>
struct HashSetElement
{
Uint32 index;
HashSetElement* next;
};
class HashSet
{
private:
static const hashSize = 64;
// Return the hash code for the given element index.
static Uint32 getHashCode(Uint32 index) {return index & (hashSize - 1);} // Could be better !
private:
Pool& allocationPool;
HashSetElement** bucket;
HashSetElement* free;
private:
// No copy constructor.
HashSet(const HashSet&);
// No copy operator.
void operator = (const HashSet&);
public:
// Create a new HashSet.
inline HashSet(Pool& pool, Uint32 universeSize);
// Clear the hashset.
void clear();
// Clear the element for the given index.
void clear(Uint32 index);
// Set the element for the given index.
void set(Uint32 index);
// Return true if the element at index is a member.
bool test(Uint32 index) const;
// Union with the given hashset.
inline void or(const HashSet& set);
// Intersection with the given hashset.
inline void and(const HashSet& set);
// Difference with the given hashset.
inline void difference(const HashSet& set);
// Logical operators.
HashSet& operator |= (const HashSet& set) {or(set); return *this;}
HashSet& operator &= (const HashSet& set) {and(set); return *this;}
HashSet& operator -= (const HashSet& set) {difference(set); return *this;}
// Iterator to conform with the set API.
typedef HashSetElement* iterator;
// Return the iterator for the first element of this set.
iterator begin() const;
// Return the next iterator.
iterator advance(iterator pos) const;
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos == NULL;}
};
inline HashSet::HashSet(Pool& pool, Uint32 /*universeSize*/)
: allocationPool(pool), free(NULL)
{
bucket = new(pool) HashSetElement*[hashSize];
memset(bucket, '\0', sizeof(HashSetElement*));
}
#endif // _HASH_SET_H_

View File

@@ -0,0 +1,213 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _INDEXED_POOL_H_
#define _INDEXED_POOL_H_
#include "Fundamentals.h"
#include <string.h>
#include <stdlib.h>
//------------------------------------------------------------------------------
// IndexedPool<IndexedObjectSubclass> is an indexed pool of objects. The
// template parameter 'IndexedObjectSubclass' must be a subclass of the struct
// IndexedObject.
//
// When the indexed pool is ask to allocate and initialize a new object (using
// the operator new(anIndexedPool) it will zero the memory used to store the
// object and initialize the field 'index' of this object to its position in
// the pool.
//
// An object allocated by the indexed pool can be freed by calling the method
// IndexedPool::release(IndexedElement& objectIndex).
//
// example:
//
// IndexedPool<IndexedElement> elementPool;
//
// IndexedElement& element1 = *new(elementPool) IndexedElement();
// IndexedElement& element2 = *new(elementPool) IndexedElement();
//
// indexedPool.release(element1);
// IndexedElement& element3 = *new(elementPool) IndexedElement();
//
// At this point element1 is no longer a valid object, element2 is at
// index 2 and element3 is at index 1.
//
//------------------------------------------------------------------------------
// IndexedObject -
//
template<class Object>
struct IndexedObject
{
Uint32 index; // Index in the pool.
Object* next; // Used to link IndexedObject together.
Uint32 getIndex() {return index;}
};
//------------------------------------------------------------------------------
// IndexedPool<IndexedObject> -
//
template <class IndexedObject>
class IndexedPool
{
private:
static const blockSize = 4; // Size of one block.
Uint32 nBlocks; // Number of blocks in the pool.
IndexedObject** block; // Array of block pointers.
IndexedObject* freeObjects; // Chained list of free IndexedObjects.
Uint32 nextIndex; // Index of the next free object in the last block.
private:
void allocateAnotherBlock();
IndexedObject& newObject();
public:
IndexedPool() : nBlocks(0), block(NULL), freeObjects(NULL), nextIndex(1) {}
~IndexedPool();
IndexedObject& get(Uint32 index) const;
void release(IndexedObject& object);
void setSize(Uint32 size) {assert(size < nextIndex); nextIndex = size;}
// Return the universe size.
Uint32 getSize() {return nextIndex;}
friend void* operator new(size_t, IndexedPool<IndexedObject>& pool); // Needs to call newObject().
};
// Free all the memory allocated for this object.
//
template <class IndexedObject>
IndexedPool<IndexedObject>::~IndexedPool()
{
for (Uint32 n = 0; n < nBlocks; n++)
free(&((IndexedObject **) &block[n][n*blockSize])[-(n + 1)]);
}
// Release the given. This object will be iserted in the chained
// list of free IndexedObjects. To minimize the fragmentation the chained list
// is ordered by ascending indexes.
//
template <class IndexedObject>
void IndexedPool<IndexedObject>::release(IndexedObject& object)
{
Uint32 index = object.index;
IndexedObject* list = freeObjects;
assert(&object == &get(index)); // Make sure that object is owned by this pool.
if (list == NULL) { // The list is empty.
freeObjects = &object;
object.next = NULL;
} else { // The list contains at least 1 element.
if (index < list->index) { // insert as first element.
freeObjects = &object;
object.next = list;
} else { // Find this object's place.
while ((list->next) != NULL && (list->next->index < index))
list = list->next;
object.next = list->next;
list->next = &object;
}
}
#ifdef DEBUG
// Sanity check to be sure that the list is correctly ordered.
for (IndexedObject* obj = freeObjects; obj != NULL; obj = obj->next)
if (obj->next != NULL)
assert(obj->index < obj->next->index);
#endif
}
// Create a new block of IndexedObjects. We will allocate the memory to
// store IndexedPool::blockSize IndexedObject and the new Array of block
// pointers.
// The newly created IndexedObjects will not be initialized.
//
template <class IndexedObject>
void IndexedPool<IndexedObject>::allocateAnotherBlock()
{
void* memory = (void *) malloc((nBlocks + 1) * sizeof(Uint32) + blockSize * sizeof(IndexedObject));
memcpy(memory, block, nBlocks * sizeof(Uint32));
block = (IndexedObject **) memory;
IndexedObject* objects = (IndexedObject *) &block[nBlocks + 1];
block[nBlocks] = &objects[-(nBlocks * blockSize)];
nBlocks++;
}
// Return the IndexedObject at the position 'index' in the pool.
//
template <class IndexedObject>
IndexedObject& IndexedPool<IndexedObject>::get(Uint32 index) const
{
Uint32 blockIndex = index / blockSize;
assert(blockIndex < nBlocks);
return block[blockIndex][index];
}
// Return the reference of an unused object in the pool.
//
template <class IndexedObject>
IndexedObject& IndexedPool<IndexedObject>::newObject()
{
if (freeObjects != NULL) {
IndexedObject& newObject = *freeObjects;
freeObjects = newObject.next;
return newObject;
}
Uint32 nextIndex = this->nextIndex++;
Uint32 blockIndex = nextIndex / blockSize;
while (blockIndex >= nBlocks)
allocateAnotherBlock();
IndexedObject& newObject = block[blockIndex][nextIndex];
newObject.index = nextIndex;
return newObject;
}
// Return the address of the next unsused object in the given
// indexed pool. The field index of the newly allocated object
// will be initialized to the corresponding index of this object
// in the pool.
//
template <class IndexedObject>
void* operator new(size_t size, IndexedPool<IndexedObject>& pool)
{
assert(size == sizeof(IndexedObject));
return (void *) &pool.newObject();
}
#endif // _INDEXED_POOL_H_

View File

@@ -0,0 +1,258 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _INTERFERENCE_GRAPH_H_
#define _INTERFERENCE_GRAPH_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "Primitives.h"
#include "Instruction.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h"
#include "SparseSet.h"
#include <string.h>
struct InterferenceVector
{
Uint32 count;
InterferenceVector* next;
RegisterName* neighbors;
InterferenceVector() : count(0), next(NULL) {}
};
class RegisterAllocator;
template <class RegisterPressure>
class InterferenceGraph
{
private:
RegisterAllocator& registerAllocator;
RegisterPressure::Set* interferences;
InterferenceVector** vector;
Uint32* offset;
Uint32 rangeCount;
private:
// No copy constructor.
InterferenceGraph(const InterferenceGraph&);
// No copy operator.
void operator = (const InterferenceGraph&);
// Check if reg is a member of the universe.
void checkMember(RegisterName name) {assert(name < rangeCount);}
// Return the edge index for the interference between name1 and name2.
Uint32 getEdgeIndex(RegisterName name1, RegisterName name2);
public:
InterferenceGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
// Calculate the interferences.
void build();
// Return true if reg1 and reg2 interfere.
bool interfere(RegisterName name1, RegisterName name2);
// Return the interference vector for the given register or NULL if there is none.
InterferenceVector* getInterferenceVector(RegisterName name) {return vector[name];}
// Set the interference between name1 and name2.
void setInterference(RegisterName name1, RegisterName name2);
// Set the interference vector for the given register.
void setInterferenceVector(RegisterName name, InterferenceVector* v) {vector[name] = v;}
#ifdef DEBUG_LOG
// Print the interferences.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::build()
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
this->rangeCount = rangeCount;
// Initialize the structures.
//
offset = new(pool) Uint32[rangeCount + 1];
vector = new(pool) InterferenceVector*[rangeCount];
memset(vector, '\0', sizeof(InterferenceVector*) * rangeCount);
Uint32 o = 0;
offset[0] = 0;
for (Uint32 i = 1; i <= rangeCount; ++i) {
offset[i] = o;
o += i;
}
interferences = new(pool) RegisterPressure::Set(pool, (rangeCount * rangeCount) / 2);
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
LivenessInfo<RegisterPressure> liveness = Liveness<RegisterPressure>::analysis(controlGraph, rangeCount, name2range);
registerAllocator.liveness = liveness;
SparseSet currentLive(pool, rangeCount);
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
currentLive = liveness.liveOut[n];
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
// Handle the copy instruction to avoid unnecessary interference between the 2 registers.
if ((instruction.getFlags() & ifCopy) != 0) {
assert(useBegin != useEnd && useBegin[0].isRegister());
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
}
// Create the interferences.
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName define = name2range[definePtr->getRegisterName()];
for (SparseSet::iterator e = currentLive.begin(); !currentLive.done(e); e = currentLive.advance(e)) {
RegisterName live = RegisterName(currentLive.get(e));
if ((live != define) && !interfere(live, define) && registerAllocator.canInterfere(live, define)) {
if (vector[define] == NULL)
vector[define] = new(pool) InterferenceVector();
vector[define]->count++;
if (vector[live] == NULL)
vector[live] = new(pool) InterferenceVector();
vector[live]->count++;
setInterference(live, define);
}
}
}
// Now update the liveness.
//
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
currentLive.set(name2range[usePtr->getRegisterName()]);
}
}
// Allocate the memory to store the interferences.
//
for (Uint32 e = 0; e < rangeCount; e++)
if (vector[e] != NULL) {
InterferenceVector& v = *vector[e];
v.neighbors = new(pool) RegisterName[v.count];
v.count = 0;
}
// Initialize the edges.
//
if (RegisterPressure::Set::isOrdered()) {
RegisterName name1 = RegisterName(0);
for (RegisterPressure::Set::iterator i = interferences->begin(); !interferences->done(i); i = interferences->advance(i)) {
Uint32 interferenceIndex = interferences->get(i);
while(interferenceIndex >= offset[name1 + 1])
name1 = RegisterName(name1 + 1);
assert((interferenceIndex >= offset[name1]) && (interferenceIndex < offset[name1 + 1]));
RegisterName name2 = RegisterName(interferenceIndex - offset[name1]);
assert(interfere(name1, name2));
InterferenceVector& vector1 = *vector[name1];
vector1.neighbors[vector1.count++] = name2;
InterferenceVector& vector2 = *vector[name2];
vector2.neighbors[vector2.count++] = name1;
}
} else {
trespass("not Implemented"); // FIX: need one more pass to initialize the vectors.
}
}
template <class RegisterPressure>
Uint32 InterferenceGraph<RegisterPressure>::getEdgeIndex(RegisterName name1, RegisterName name2)
{
checkMember(name1); checkMember(name2);
assert(name1 != name2); // This is not possible.
return (name1 < name2) ? offset[name2] + name1 : offset[name1] + name2;
}
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::setInterference(RegisterName name1, RegisterName name2)
{
interferences->set(getEdgeIndex(name1, name2));
}
template <class RegisterPressure>
bool InterferenceGraph<RegisterPressure>::interfere(RegisterName name1, RegisterName name2)
{
return interferences->test(getEdgeIndex(name1, name2));
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Vectors:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
if (vector[i] != NULL) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tvr%d: (", i));
for (InterferenceVector* v = vector[i]; v != NULL; v = v->next)
for (Uint32 j = 0; j < v->count; j++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", v->neighbors[j]));
if (v->next != NULL || j != (v->count - 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (","));
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (")\n"));
}
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Matrix:\n"));
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && interfere(name1, name2)) ? '1' : '0'));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _INTERFERENCE_GRAPH_H_

View File

@@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _LIVE_RANGE_H_
#define _LIVE_RANGE_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Primitives.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
template <class RegisterPressure>
struct LiveRange
{
static void build(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
void LiveRange<RegisterPressure>::build(RegisterAllocator& registerAllocator)
{
// Intialize the lookup table.
//
Uint32 nameCount = registerAllocator.nameCount;
RegisterName* nameTable = new(registerAllocator.pool) RegisterName[2*nameCount];
RegisterName* rangeName = &nameTable[nameCount];
init(rangeName, nameCount);
// Walk the graph.
//
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
SparseSet destination(registerAllocator.pool, nameCount);
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
destination.clear();
for (InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
Instruction& phiNode = phiNodes.get(i);
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
destination.set(findRoot(phiNode.getInstructionDefineBegin()[0].getRegisterName(), rangeName));
}
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
RegisterName destinationName = phiNode.getInstructionDefineBegin()[0].getRegisterName();
RegisterName destinationRoot = findRoot(destinationName, rangeName);
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
assert(usePtr->isRegister());
RegisterName sourceName = usePtr->getRegisterName();
RegisterName sourceRoot = findRoot(sourceName, rangeName);
if (sourceRoot != destinationRoot && !destination.test(sourceRoot))
rangeName[sourceRoot] = destinationRoot;
}
}
}
registerAllocator.rangeCount = compress(registerAllocator.name2range, rangeName, nameCount, nameCount);
}
#endif // _LIVE_RANGE_H_

View File

@@ -0,0 +1,163 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _LIVE_RANGE_GRAPH_
#define _LIVE_RANGE_GRAPH_
#include "Fundamentals.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterTypes.h"
class RegisterAllocator;
template <class RegisterPressure>
class LiveRangeGraph
{
private:
RegisterAllocator& registerAllocator;
RegisterPressure::Set* edges;
Uint32 rangeCount;
public:
//
//
LiveRangeGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
//
//
void build();
//
//
void addEdge(RegisterName name1, RegisterName name2);
//
//
bool haveEdge(RegisterName name1, RegisterName name2);
#ifdef DEBUG_LOG
//
//
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::build()
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
this->rangeCount = rangeCount;
edges = new(pool) RegisterPressure::Set(pool, rangeCount * rangeCount);
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
LivenessInfo<RegisterPressure>& liveness = registerAllocator.liveness;
SparseSet currentLive(pool, rangeCount);
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
currentLive = liveness.liveOut[n];
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
if ((instruction.getFlags() & ifCopy) != 0) {
assert(useBegin != useEnd && useBegin[0].isRegister());
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName define = name2range[definePtr->getRegisterName()];
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
RegisterName live = RegisterName(currentLive.get(l));
if (define != live && registerAllocator.canInterfere(define, live))
addEdge(define, live);
}
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
currentLive.set(name2range[usePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName use = name2range[usePtr->getRegisterName()];
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
RegisterName live = RegisterName(currentLive.get(l));
if (use != live && registerAllocator.canInterfere(use, live))
addEdge(use, live);
}
}
}
}
}
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::addEdge(RegisterName name1, RegisterName name2)
{
assert(name1 != name2);
edges->set(name1 * rangeCount + name2);
}
template <class RegisterPressure>
bool LiveRangeGraph<RegisterPressure>::haveEdge(RegisterName name1, RegisterName name2)
{
assert(name1 != name2);
return edges->test(name1 * rangeCount + name2);
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Live ranges graph:\n"));
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && haveEdge(name1, name2)) ? '1' : '0'));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _LIVE_RANGE_GRAPH_

View File

@@ -0,0 +1,21 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "Liveness.h"

View File

@@ -0,0 +1,301 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _LIVENESS_H_
#define _LIVENESS_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterTypes.h"
// ----------------------------------------------------------------------------
// LivenessInfo -
template <class RegisterPressure>
struct LivenessInfo
{
RegisterPressure::Set* liveIn;
RegisterPressure::Set* liveOut;
DEBUG_LOG_ONLY(Uint32 size);
#ifdef DEBUG_LOG
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
// ----------------------------------------------------------------------------
// Liveness
//
// The liveness is defined by the following data-flow equations:
//
// LiveIn(n) = LocalLive(n) U (LiveOut(n) - Killed(n)).
// LiveOut(n) = U LiveIn(s) (s a successor of n).
//
// where LocalLive(n) is the set of used registers in the block n, Killed(n)
// is the set of defined registers in the block n, LiveIn(n) is the set of
// live registers at the begining of the block n and LiveOut(n) is the set
// of live registers at the end of the block n.
//
//
// We will compute the liveness analysis in two stages:
//
// 1- Build LocalLive(n) (wich is an approximation of LiveIn(n)) and Killed(n)
// for each block n.
// 2- Perform a backward data-flow analysis to propagate the liveness information
// through the entire control-flow graph.
//
template <class RegisterPressure>
struct Liveness
{
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range);
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 nameCount);
};
template <class RegisterPressure>
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Allocate the temporary sets.
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
// Allocate the globals sets.
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
//
for (Uint32 n = 0; n < (nNodes - 1); n++) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLocalLive = liveIn[n];
RegisterPressure::Set& currentKilled = killed[n];
// Find the instructions contributions to the sets LocalLive and Killed.
//
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
Uint32 index = name2range[usePtr->getRegisterName()];
if (!currentKilled.test(index))
currentLocalLive.set(index);
}
// If a Virtualregister is 'defined' then we add it to the set Killed.
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentKilled.set(name2range[definePtr->getRegisterName()]);
}
}
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
// control-flow graph.
//
RegisterPressure::Set temp(pool, rangeCount);
bool changed;
do {
changed = false;
// For all nodes is this graph except the endNode.
for (Int32 n = (nNodes - 2); n >= 0; n--) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLiveIn = liveIn[n];
RegisterPressure::Set& currentLiveOut = liveOut[n];
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
// temp will be the new LiveOut(n).
Uint32 nSuccessors = node.nSuccessors();
if (nSuccessors != 0) {
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
for (Uint32 s = 1; s < nSuccessors; s++)
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
} else
temp.clear();
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
// new LiveIn(n).
if (currentLiveOut != temp) {
currentLiveOut = temp;
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
temp |= currentLiveIn;
if (currentLiveIn != temp) {
currentLiveIn = temp;
changed = true;
}
}
}
} while(changed);
LivenessInfo<RegisterPressure> liveness;
liveness.liveIn = liveIn;
liveness.liveOut = liveOut;
DEBUG_LOG_ONLY(liveness.size = nNodes);
return liveness;
}
template <class RegisterPressure>
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 nameCount)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Allocate the temporary sets.
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
RegisterPressure::Set* usedByPhiNodes = NULL;
// Allocate the globals sets.
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
//
for (Uint32 n = 0; n < (nNodes - 1); n++) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLocalLive = liveIn[n];
RegisterPressure::Set& currentKilled = killed[n];
InstructionList& phiNodes = node.getPhiNodeInstructions();
if ((usedByPhiNodes == NULL) && !phiNodes.empty())
usedByPhiNodes = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
InstructionDefine& define = phiNode.getInstructionDefineBegin()[0];
currentKilled.set(define.getRegisterName());
typedef DoublyLinkedList<ControlEdge> ControlEdgeList;
const ControlEdgeList& predecessors = node.getPredecessors();
ControlEdgeList::iterator p = predecessors.begin();
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++, p = predecessors.advance(p))
if (usePtr->isRegister())
usedByPhiNodes[predecessors.get(p).getSource().dfsNum].set(usePtr->getRegisterName());
}
// Find the instructions contributions to the sets LocalLive and Killed.
//
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
Uint32 index = usePtr->getRegisterName();
if (!currentKilled.test(index))
currentLocalLive.set(index);
}
// If a Virtualregister is 'defined' then we add it to the set Killed.
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentKilled.set(definePtr->getRegisterName());
}
}
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
// control-flow graph.
//
RegisterPressure::Set temp(pool, nameCount);
bool changed;
do {
changed = false;
// For all nodes is this graph except the endNode.
for (Int32 n = (nNodes - 2); n >= 0; n--) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLiveIn = liveIn[n];
RegisterPressure::Set& currentLiveOut = liveOut[n];
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
// temp will be the new LiveOut(n).
Uint32 nSuccessors = node.nSuccessors();
if (nSuccessors != 0) {
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
for (Uint32 s = 1; s < nSuccessors; s++)
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
} else
temp.clear();
// Insert the phiNodes contribution.
if (usedByPhiNodes != NULL)
temp |= usedByPhiNodes[n];
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
// new LiveIn(n).
if (currentLiveOut != temp) {
currentLiveOut = temp;
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
temp |= currentLiveIn;
if (currentLiveIn != temp) {
currentLiveIn = temp;
changed = true;
}
}
}
} while(changed);
LivenessInfo<RegisterPressure> liveness;
liveness.liveIn = liveIn;
liveness.liveOut = liveOut;
DEBUG_LOG_ONLY(liveness.size = nNodes);
return liveness;
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void LivenessInfo<RegisterPressure>::printPretty(LogModuleObject log)
{
for (Uint32 n = 0; n < size; n++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Node N%d:\n\tliveIn = ", n));
liveIn[n].printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tliveOut = "));
liveOut[n].printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _LIVENESS_H_

View File

@@ -0,0 +1,40 @@
#! gmake
DEPTH = ../..
MODULE_NAME = RegisterAllocator
include $(DEPTH)/config/config.mk
INCLUDES += \
-I$(DEPTH)/Utilities/General \
-I$(DEPTH)/Utilities/zlib \
-I$(DEPTH)/Runtime/ClassReader \
-I$(DEPTH)/Runtime/NativeMethods \
-I$(DEPTH)/Runtime/System \
-I$(DEPTH)/Runtime/ClassInfo \
-I$(DEPTH)/Runtime/FileReader \
-I$(DEPTH)/Compiler/PrimitiveGraph \
-I$(DEPTH)/Compiler/FrontEnd \
-I$(DEPTH)/Compiler/Optimizer \
-I$(DEPTH)/Compiler/CodeGenerator \
-I$(DEPTH)/Compiler/CodeGenerator/md \
-I$(DEPTH)/Compiler/CodeGenerator/md/$(CPU_ARCH) \
-I$(DEPTH)/Compiler/RegisterAllocator \
-I$(DEPTH)/Driver/StandAloneJava \
-I$(DEPTH)/Debugger \
$(NULL)
CXXSRCS = \
RegisterAllocator.cpp \
RegisterAllocatorTools.cpp \
DominatorGraph.cpp \
VirtualRegister.cpp \
BitSet.cpp \
SparseSet.cpp \
$(NULL)
include $(DEPTH)/config/rules.mk
libs:: $(MODULE)

View File

@@ -0,0 +1,392 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _PHI_NODE_REMOVER_H_
#define _PHI_NODE_REMOVER_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "DominatorGraph.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h"
#include "Liveness.h"
#include "Instruction.h"
#include "InstructionEmitter.h"
#include "SparseSet.h"
#include <string.h>
//------------------------------------------------------------------------------
// RegisterNameNode -
struct RegisterNameNode
{
RegisterNameNode* next;
RegisterName newName;
Uint32 nextPushed;
};
//------------------------------------------------------------------------------
// CopyData -
struct CopyData
{
RegisterName source;
RegisterClassKind classKind;
Uint32 useCount;
bool isLiveOut;
RegisterName sourceNameToUse;
RegisterName temporaryName;
RegisterNameNode* newName;
};
//------------------------------------------------------------------------------
// PhiNodeRemover<RegisterPressure> -
template <class RegisterPressure>
struct PhiNodeRemover
{
// Replace the phi nodes by copy instructions.
static void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
};
// Split some of the critical edges and return true if there are still some
// in the graph after that.
//
static bool splitCriticalEdges(ControlGraph& /*cg*/)
{
// FIX: not implemented.
return true;
}
inline void pushName(Pool& pool, RegisterNameNode** stack, SparseSet& pushed, Uint32* nodeListPointer, RegisterName oldName, RegisterName newName)
{
RegisterNameNode& newNode = *new(pool) RegisterNameNode();
if (pushed.test(oldName))
(*stack)->newName = newName;
else {
newNode.newName = newName;
newNode.nextPushed = *nodeListPointer;
*nodeListPointer = oldName;
newNode.next = *stack;
*stack = &newNode;
pushed.set(oldName);
}
}
template <class RegisterPressure>
void PhiNodeRemover<RegisterPressure>::replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Initialize the local variables.
//
// When we insert the copies we will also need to create new VirtualRegisters for
// the insertion of temporaries. The maximum number of temporary register will not
// exceed the number of phiNodes in the primitive graph.
Uint32 nameCount = vrManager.getSize();
Uint32 maxNameCount = nameCount;
for (Uint32 n = 0; n < nNodes; n++)
maxNameCount += nodes[n]->getPhiNodes().length();
// If the CFG contains some critical edges (backward edge which source has more than one
// outgoing edge and destination has more than one incomimg edge) then we need the liveness
// information to be able to insert temporary copies.
RegisterPressure::Set* liveOut = NULL;
if (splitCriticalEdges(controlGraph))
liveOut = Liveness<LowRegisterPressure>::analysis(controlGraph, nameCount).liveOut;
DominatorGraph dGraph(controlGraph);
SparseSet pushed(pool, maxNameCount);
SparseSet destinationList(pool, maxNameCount);
SparseSet workList(pool, maxNameCount);
CopyData* copyStats = new(pool) CopyData[maxNameCount];
memset(copyStats, '\0', maxNameCount*sizeof(CopyData));
struct NodeStack {
Uint32* next;
Uint32* limit;
Uint32 pushedList;
};
// Allocate the node stack and initialize the node stack pointer.
NodeStack* nodeStack = new(pool) NodeStack[nNodes + 1];
NodeStack* nodeStackPtr = nodeStack;
// We start by the begin node.
Uint32 startNode = 0;
Uint32* next = &startNode;
Uint32* limit = &startNode + 1;
while (true) {
if (next == limit) {
// If there are no more node in the sibling, we have to pop the current
// frame from the stack and update the copyStats of the pushed nodes.
//
if (nodeStackPtr == nodeStack)
// We are at the bottom of the stack and there are no more nodes
// to look at. We are done !
break;
--nodeStackPtr;
// We are done with all the children of this node in the dominator tree.
// We need to update the copy information of all the new names pushed
// during the walk over this node.
Uint32 pushedList = nodeStackPtr->pushedList;
while (pushedList != 0) {
Uint32 nextName = copyStats[pushedList].newName->nextPushed;
copyStats[pushedList].newName = copyStats[pushedList].newName->next;
pushedList = nextName;
}
// restore the previous frame.
next = nodeStackPtr->next;
limit = nodeStackPtr->limit;
} else {
Uint32 currentNode = *next++;
Uint32 pushedList = 0;
// Initialize the sets.
pushed.clear();
destinationList.clear();
// STEP1:
// Walk the instruction list and to replace all the instruction uses with their new name.
// If the instruction is a phi node and its defined register is alive at the end of this
// block then we push the defined register into the stack.
//
ControlNode& node = *nodes[currentNode];
RegisterPressure::Set* currentLiveOut = (liveOut != NULL) ? &liveOut[currentNode] : (RegisterPressure::Set*) 0;
InstructionList& phiNodes = node.getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
assert(usePtr->isRegister());
RegisterName name = usePtr->getRegisterName();
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
usePtr->setRegisterName(copyStats[name].newName->newName);
}
if (currentLiveOut != NULL) {
// This is a phi node and we have to push its defined name if it is live
// at the end of the node. We only need to do this if the CFG has critical edges.
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
RegisterName name = phiNode.getInstructionDefineBegin()[0].getRegisterName();
if (currentLiveOut->test(name))
pushName(pool, &(copyStats[name].newName), pushed, &pushedList, name, name);
}
}
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
usePtr->setRegisterName(copyStats[name].newName->newName);
}
}
// STEP2:
// Look at this node's successors' phiNodes. We keep track of the number of time
// a VR will be used by another copy instruction and insert each definition into the
// destinationList. This is the only pass over this node's successors as we will
// get all the information we need in the CopyData structures.
//
ControlEdge* successorEdgeEnd = node.getSuccessorsEnd();
for (ControlEdge* successorEdgePtr = node.getSuccessorsBegin(); successorEdgePtr < successorEdgeEnd; successorEdgePtr++) {
Uint32 useIndex = successorEdgePtr->getIndex();
ControlNode& successor = successorEdgePtr->getTarget();
// Look at its phi nodes. The phi nodes are at the top of the instruction list. We exit
// as soon as we find an instruction which is not a phi node
InstructionList& phiNodes = successor.getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
assert((phiNode.getInstructionUseBegin() + useIndex) < phiNode.getInstructionUseEnd());
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd());
InstructionUse& source = phiNode.getInstructionUseBegin()[useIndex];
InstructionDefine& destination = phiNode.getInstructionDefineBegin()[0];
assert(source.isRegister() && destination.isRegister());
RegisterName sourceName = source.getRegisterName();
RegisterName destinationName = destination.getRegisterName();
// Get the correct name for the source.
if (copyStats[sourceName].newName != NULL)
sourceName = copyStats[sourceName].newName->newName;
// Update the CopyData structures.
if ((sourceName != rnInvalid) && (sourceName != destinationName)) {
copyStats[destinationName].source = sourceName;
copyStats[destinationName].classKind = destination.getRegisterClass();
copyStats[destinationName].isLiveOut = (currentLiveOut != NULL) ? currentLiveOut->test(destinationName) : false;
copyStats[destinationName].sourceNameToUse = destinationName;
copyStats[sourceName].sourceNameToUse = sourceName;
copyStats[sourceName].useCount++;
destinationList.set(destinationName);
}
}
}
// STEP3:
// Insert into the worklist only the destination registers that will be not used in
// another copy instruction in this block.
//
assert(workList.getSize() == 0);
for (SparseSet::iterator d = destinationList.begin(); !destinationList.done(d); d = destinationList.advance(d)) {
Uint32 dest = destinationList.get(d);
if (copyStats[dest].useCount == 0)
workList.set(dest);
}
// STEP4:
// Insert the copy instructions.
//
Uint32 destinationListSize = destinationList.getSize();
InstructionList::iterator endOfTheNode = instructions.end();
// Find the right place to insert the copy instructions.
if (destinationListSize != 0)
while (instructions.get(endOfTheNode).getFlags() & ifControl)
endOfTheNode = instructions.retreat(endOfTheNode);
while (destinationListSize != 0) {
while(workList.getSize()) {
RegisterName destinationName = RegisterName(workList.getOne());
RegisterName sourceName = copyStats[destinationName].source;
workList.clear(destinationName);
if (copyStats[destinationName].isLiveOut && !copyStats[destinationName].temporaryName) {
// Lost copy problem.
copyStats[destinationName].isLiveOut = false;
RegisterName sourceName = destinationName;
RegisterClassKind classKind = copyStats[sourceName].classKind;
RegisterName destinationName = getName(vrManager.newVirtualRegister(classKind));
assert(destinationName < maxNameCount);
copyStats[destinationName].classKind = classKind;
copyStats[sourceName].useCount = 0;
// We need to insert a copy to a temporary register to keep the
// source register valid at the end of the node defining it.
// This copy will be inserted right after the phi node defining it.
RegisterName from = copyStats[sourceName].sourceNameToUse;
Instruction* definingPhiNode = vrManager.getVirtualRegister(from).getDefiningInstruction();
assert(definingPhiNode && (definingPhiNode->getFlags() & ifPhiNode) != 0);
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*definingPhiNode->getPrimitive(), fromID, toID);
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
definingPhiNode->getPrimitive()->getContainer()->getInstructions().addFirst(copy);
copyStats[sourceName].temporaryName = destinationName;
copyStats[sourceName].sourceNameToUse = destinationName;
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
}
// Insert the copy instruction at the end of the current node.
RegisterName from = copyStats[sourceName].sourceNameToUse;
RegisterClassKind classKind = copyStats[destinationName].classKind;
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
instructions.insertAfter(copy, endOfTheNode);
endOfTheNode = instructions.advance(endOfTheNode);
copyStats[sourceName].useCount = 0;
if (destinationList.test(sourceName) && copyStats[sourceName].isLiveOut)
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
copyStats[sourceName].isLiveOut = false;
copyStats[sourceName].sourceNameToUse = destinationName;
if (destinationList.test(sourceName))
workList.set(sourceName);
destinationList.clear(destinationName);
}
destinationListSize = destinationList.getSize();
if (destinationListSize != 0) {
RegisterName sourceName = RegisterName(destinationList.getOne());
RegisterName destinationName;
if (!copyStats[sourceName].temporaryName) {
// Cycle problem.
RegisterClassKind classKind = copyStats[sourceName].classKind;
destinationName = getName(vrManager.newVirtualRegister(classKind));
assert(destinationName < maxNameCount);
copyStats[destinationName].classKind = classKind;
copyStats[sourceName].temporaryName = destinationName;
// Insert the copy instruction at the end of the current node.
RegisterName from = copyStats[sourceName].sourceNameToUse;
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
instructions.insertAfter(copy, endOfTheNode);
endOfTheNode = instructions.advance(endOfTheNode);
} else
destinationName = copyStats[sourceName].temporaryName;
copyStats[sourceName].useCount = 0;
copyStats[sourceName].isLiveOut = false;
copyStats[sourceName].sourceNameToUse = destinationName;
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
workList.set(sourceName);
}
}
nodeStackPtr->pushedList = pushedList;
nodeStackPtr->next = next;
nodeStackPtr->limit = limit;
++nodeStackPtr;
next = dGraph.getSuccessorsBegin(currentNode);
limit = dGraph.getSuccessorsEnd(currentNode);
}
}
}
#endif // _PHI_NODE_REMOVER_H_

View File

@@ -0,0 +1,155 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "LogModule.h"
#include "RegisterAllocator.h"
#include "RegisterPressure.h"
#include "RegisterAllocatorTools.h"
#include "PhiNodeRemover.h"
#include "LiveRange.h"
#include "Liveness.h"
#include "InterferenceGraph.h"
#include "LiveRangeGraph.h"
#include "Coalescing.h"
#include "Spilling.h"
#include "Coloring.h"
#include "Splits.h"
class Pool;
class ControlGraph;
class VirtualRegisterManager;
class InstructionEmitter;
UT_DEFINE_LOG_MODULE(RegAlloc);
void RegisterAllocator::allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
{
// Insert the phi node instructions. We want to do this to have a single defined register per instruction.
// If we keep the PhiNode (as a DataNode) and a PhiNode is of DoubleWordKind then we have to execute
// some special code for the high word annotation.
//
RegisterAllocatorTools::insertPhiNodeInstructions(controlGraph, emitter);
// Perform some tests on the instruction graph.
//
DEBUG_ONLY(RegisterAllocatorTools::testTheInstructionGraph(controlGraph, vrManager));
// Replace the phi node instructions by their equivalent copy instructions.
//
PhiNodeRemover<LowRegisterPressure>::replacePhiNodes(controlGraph, vrManager, emitter);
// Do the register allocation.
//
RegisterAllocator registerAllocator(pool, controlGraph, vrManager, emitter);
registerAllocator.doGraphColoring();
}
void RegisterAllocator::doGraphColoring()
{
// Initialize the liverange map.
//
initLiveRanges();
// Build the live ranges. We do this to compress the number of RegisterNames
// used in the insterference graph.
//
LiveRange<LowRegisterPressure>::build(*this);
// Remove unnecessary copies.
//
RegisterAllocatorTools::removeUnnecessaryCopies(*this);
for (Uint8 loop = 0; loop < 10; loop++) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********* RegisterAllocator loop %d *********\n", loop));
while(true) {
// Build the interference graph.
//
iGraph.build();
// Coalesce the copy instructions.
//
if (!Coalescing<LowRegisterPressure>::coalesce(*this))
break;
}
// Print the interference graph.
//
DEBUG_LOG_ONLY(iGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
// Calculate the spill costs.
//
Spilling<LowRegisterPressure>::calculateSpillCosts(*this);
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSpillCosts(*this));
// Calculate the split costs.
//
Splits<LowRegisterPressure>::calculateSplitCosts(*this);
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSplitCosts(*this));
// Build the live range graph.
//
lGraph.build();
DEBUG_LOG_ONLY(lGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
// Color the graph. If it succeeds then we're done with the
// register allocation.
//
if (Coloring<LowRegisterPressure>::color(*this)) {
// Write the final colors in the instruction graph.
//
Coloring<LowRegisterPressure>::finalColoring(*this);
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********** RegisterAllocator done **********\n"));
DEBUG_LOG_ONLY(RegisterAllocatorTools::printInstructions(*this));
return;
}
// We need to spill some registers.
//
Spilling<LowRegisterPressure>::insertSpillCode(*this);
// Insert the split instructions.
//
Splits<LowRegisterPressure>::insertSplitCode(*this);
// Update the live ranges.
//
// FIX
}
#ifdef DEBUG_LOG
RegisterAllocatorTools::updateInstructionGraph(*this);
RegisterAllocatorTools::printInstructions(*this);
#endif
fprintf(stderr, "!!! Coloring failed after 10 loops !!!\n");
abort();
}
void RegisterAllocator::initLiveRanges()
{
Uint32 count = this->nameCount;
RegisterName* name2range = new(pool) RegisterName[nameCount];
for (RegisterName r = RegisterName(1); r < count; r = RegisterName(r + 1))
name2range[r] = r;
this->name2range = name2range;
rangeCount = count;
}

View File

@@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _REGISTER_ALLOCATOR_H_
#define _REGISTER_ALLOCATOR_H_
class Pool;
class ControlGraph;
class InstructionEmitter;
struct SpillCost;
struct SplitCost;
#include "Liveness.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h" // This should included by Backend.cpp
#include "InterferenceGraph.h"
#include "LiveRangeGraph.h"
//template <class RegisterPressure>
class RegisterAllocator
{
public:
Pool& pool; //
ControlGraph& controlGraph; //
VirtualRegisterManager& vrManager; //
InstructionEmitter& emitter; //
RegisterName* name2range; //
RegisterName* color; //
SpillCost* spillCost; //
SparseSet* willSpill; //
SplitCost* splitCost; //
NameLinkedList** splitAround; //
InterferenceGraph<LowRegisterPressure> iGraph; //
LiveRangeGraph<LowRegisterPressure> lGraph; //
LivenessInfo<LowRegisterPressure> liveness; //
Uint32 nameCount; //
Uint32 rangeCount; //
bool splitFound; //
private:
//
//
void doGraphColoring();
public:
//
//
inline RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
//
//
bool canInterfere(RegisterName /*name1*/, RegisterName /*name2*/) const {return true;}
//
//
void initLiveRanges();
//
//
static void allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
};
//
//
inline RegisterAllocator::RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
: pool(pool), controlGraph(controlGraph), vrManager(vrManager), emitter(emitter), iGraph(*this), lGraph(*this), nameCount(vrManager.getSize()) {}
#endif // _REGISTER_ALLOCATOR_H_

View File

@@ -0,0 +1,355 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "LogModule.h"
#include "RegisterAllocatorTools.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Primitives.h"
#include "InstructionEmitter.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "Spilling.h"
#include "Splits.h"
#include "BitSet.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
#ifdef DEBUG
void RegisterAllocatorTools::testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
{
// Test the declared VirtualRegisters. The register allocator tries to condense the register universe.
// Any gap in the VirtualRegister names will be a loss of efficiency !!!!
Uint32 nameCount = vrManager.getSize();
BitSet registerSeen(controlGraph.pool, nameCount);
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
registerSeen.set(usePtr->getRegisterName());
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
registerSeen.set(definePtr->getRegisterName());
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
registerSeen.set(usePtr->getRegisterName());
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
registerSeen.set(definePtr->getRegisterName());
}
}
bool renameRegisters = false;
for (BitSet::iterator i = registerSeen.nextZero(0); !registerSeen.done(i); i = registerSeen.nextZero(i)) {
renameRegisters = true;
fprintf(stderr,
"WARNING: The VirtualRegister vr%d has been allocated during CodeGeneration but\n"
" is never used nor defined by any instruction in the instruction graph\n"
" PLEASE FIX \n",
i);
}
if (renameRegisters) {
Instruction** definingInstruction = new Instruction*[nameCount];
memset(definingInstruction, '\0', nameCount * sizeof(Instruction*));
RegisterName* newName = new RegisterName[nameCount];
memset(newName, '\0', nameCount * sizeof(RegisterName));
RegisterName nextName = RegisterName(1);
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
usePtr->setRegisterName(newName[name]);
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName name = definePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
definePtr->setRegisterName(newName[name]);
}
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
usePtr->setRegisterName(newName[name]);
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName name = definePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
definePtr->setRegisterName(newName[name]);
}
}
}
vrManager.setSize(nextName);
for (RegisterName r = RegisterName(1); r < nextName; r = RegisterName(r + 1))
vrManager.getVirtualRegister(r).definingInstruction = definingInstruction[r];
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("RegisterMap:\n"));
for (Uint32 i = 1; i < nameCount; i++)
if (newName[i] != 0)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d becomes vr%d.\n", i, newName[i]));
else
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d is dead.\n", i));
delete newName;
delete definingInstruction;
}
}
#endif // DEBUG
void RegisterAllocatorTools::removeUnnecessaryCopies(RegisterAllocator& registerAllocator)
{
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i);) {
Instruction& instruction = instructions.get(i);
i = instructions.advance(i);
if (instruction.getFlags() & ifCopy) {
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
RegisterName source = name2range[instruction.getInstructionUseBegin()[0].getRegisterName()];
RegisterName destination = name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()];
if (source == destination)
instruction.remove();
}
}
}
}
void RegisterAllocatorTools::updateInstructionGraph(RegisterAllocator& registerAllocator)
{
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
}
}
}
void RegisterAllocatorTools::insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
DoublyLinkedList<PhiNode>& phiNodes = node.getPhiNodes();
if (!phiNodes.empty()) {
// Set the index of the incoming edges.
Uint32 index = 0;
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p))
predecessors.get(p).setIndex(index++);
// Insert the phi node instruction in the instruction list.
for (DoublyLinkedList<PhiNode>::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
PhiNode& phiNode = phiNodes.get(i);
ValueKind kind = phiNode.getKind();
if (!isStorableKind(kind))
continue;
RegisterClassKind classKind = rckGeneral; // FIX: get class kind from phi node kind.
Uint32 nInputs = phiNode.nInputs();
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drLow);
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drLow);
node.addPhiNodeInstruction(phiNodeInstruction);
if (isDoublewordKind(kind)) {
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drHigh);
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drHigh);
node.addPhiNodeInstruction(phiNodeInstruction);
}
}
}
}
}
#ifdef DEBUG_LOG
void RegisterAllocatorTools::printSpillCosts(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
Uint32 rangeCount = registerAllocator.rangeCount;
SpillCost* cost = registerAllocator.spillCost;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Spill costs:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : ", i));
if (cost[i].infinite)
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("infinite\n"));
else
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%f\n", cost[i].cost));
}
}
void RegisterAllocatorTools::printSplitCosts(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
Uint32 rangeCount = registerAllocator.rangeCount;
SplitCost* cost = registerAllocator.splitCost;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Split costs:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : loads = %f stores = %f\n", i, cost[i].loads, cost[i].stores));
}
}
void RegisterAllocatorTools::printInstructions(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
ControlNode** nodes = registerAllocator.controlGraph.dfsList;
Uint32 nNodes = registerAllocator.controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d:\n", n));
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
InstructionList& instructions = nodes[n]->getInstructions();
if (!phiNodes.empty()) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" PhiNodes:\n", n));
for(InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
phiNodes.get(i).printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
if (!instructions.empty())
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" Instructions:\n", n));
}
for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
instructions.get(i).printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,117 @@
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
//
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
// NETSCAPE COMMUNICATIONS CORPORATION
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
// Reserved. Use of this Source Code is subject to the terms of the
// applicable license agreement from Netscape Communications Corporation.
// The copyright notice(s) in this Source Code does not indicate actual or
// intended publication of this Source Code.
//
// $Id: RegisterAllocatorTools.h,v 1.1.2.1 1999-03-02 16:12:05 fur%netscape.com Exp $
//
#ifndef _REGISTER_ALLOCATOR_TOOLS_H_
#define _REGISTER_ALLOCATOR_TOOLS_H_
#include "LogModule.h"
#include "RegisterTypes.h"
#include <string.h>
class RegisterAllocator;
class ControlGraph;
class InstructionEmitter;
class VirtualRegisterManager;
struct RegisterAllocatorTools
{
//
//
static void insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter);
//
//
static void updateInstructionGraph(RegisterAllocator& registerAllocator);
//
//
static void removeUnnecessaryCopies(RegisterAllocator& registerAllocator);
#ifdef DEBUG
//
//
static void testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
#endif // DEBUG
#ifdef DEBUG_LOG
//
//
static void printInstructions(RegisterAllocator& registerAllocator);
//
//
static void printSpillCosts(RegisterAllocator& registerAllocator);
//
//
static void printSplitCosts(RegisterAllocator& registerAllocator);
#endif // DEBUG_LOG
};
//
// FIX: this should go in a class (LookupTable ?)
//
inline RegisterName findRoot(RegisterName name, RegisterName* table)
{
RegisterName* stack = table;
RegisterName* stackPtr = stack;
RegisterName newName;
while((newName = table[name]) != name) {
*--stackPtr = name;
name = newName;
}
while (stackPtr != stack)
table[*stackPtr++] = name;
return name;
}
inline void init(RegisterName* table, Uint32 nameCount)
{
for (RegisterName r = RegisterName(0); r < nameCount; r = RegisterName(r + 1))
table[r] = r;
}
inline Uint32 compress(RegisterName* name2range, RegisterName* table, Uint32 nameCount, Uint32 tableSize)
{
RegisterName* liveRange = new RegisterName[tableSize];
memset(liveRange, '\0', tableSize * sizeof(RegisterName));
// Update the lookup table.
for (RegisterName r = RegisterName(1); r < tableSize; r = RegisterName(r + 1))
findRoot(r, table);
// Count the liveranges.
Uint32 liveRangeCount = 1;
for (RegisterName s = RegisterName(1); s < tableSize; s = RegisterName(s + 1))
if (table[s] == s)
liveRange[s] = RegisterName(liveRangeCount++);
for (RegisterName t = RegisterName(1); t < nameCount; t = RegisterName(t + 1))
name2range[t] = liveRange[table[name2range[t]]];
return liveRangeCount;
}
inline double doLog10(Uint32 power)
{
double log = 1.0;
while (power--)
log *= 10.0;
return log;
}
#endif // _REGISTER_ALLOCATOR_TOOLS_H_

View File

@@ -0,0 +1,38 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _REGISTER_ASSIGNER_H_
#define _REGISTER_ASSIGNER_H_
#include "Fundamentals.h"
#include "VirtualRegister.h"
class FastBitMatrix;
class RegisterAssigner
{
protected:
VirtualRegisterManager& vRegManager;
public:
RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {}
virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0;
};
#endif /* _REGISTER_ASSIGNER_H_ */

View File

@@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _REGISTER_CLASS_H_
#define _REGISTER_CLASS_H_
#include "Fundamentals.h"
#include "RegisterTypes.h"
#endif // _REGISTER_CLASS_H_

View File

@@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _REGISTER_PRESSURE_H_
#define _REGISTER_PRESSURE_H_
#include "BitSet.h"
#include "HashSet.h"
struct LowRegisterPressure
{
typedef BitSet Set;
static const bool setIsOrdered = true;
};
struct HighRegisterPressure
{
typedef HashSet Set;
static const bool setIsOrdered = false;
};
#endif // _REGISTER_PRESSURE_H_

View File

@@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _REGISTER_TYPES_H_
#define _REGISTER_TYPES_H_
#include "Fundamentals.h"
//------------------------------------------------------------------------------
// RegisterName -
//
enum RegisterName {
rnInvalid = 0,
};
//------------------------------------------------------------------------------
// RegisterClassKind -
//
enum RegisterClassKind {
rckInvalid = 0,
rckGeneral,
rckStackSlot,
nRegisterClassKind
};
//------------------------------------------------------------------------------
// RegisterID -
//
enum RegisterID {
invalidID = 0
};
//------------------------------------------------------------------------------
// RegisterKind -
//
enum RegisterKind {
rkCallerSave = 0,
rkCalleeSave,
};
struct NameLinkedList {
RegisterName name;
NameLinkedList* next;
};
#ifdef DEBUG
const registerNameMask = 0x03ffffff;
const coloredRegisterMask = 0x04000000;
const machineRegisterMask = 0x08000000;
const registerClassMask = 0xf0000000;
const registerNameShift = 0;
const coloredRegisterShift = 26;
const machineRegisterShift = 27;
const registerClassShift = 28;
#else // DEBUG
const registerNameMask = 0x0fffffff;
const registerClassMask = 0xf0000000;
const registerNameShift = 0;
const registerClassShift = 28;
#endif // DEBUG
inline RegisterClassKind getClass(RegisterID registerID) {return RegisterClassKind((registerID & registerClassMask) >> registerClassShift);}
inline RegisterName getName(RegisterID registerID) {return RegisterName((registerID & registerNameMask) >> registerNameShift);}
inline void setClass(RegisterID& registerID, RegisterClassKind classKind) {registerID = RegisterID((registerID & ~registerClassMask) | ((classKind << registerClassShift) & registerClassMask));}
inline void setName(RegisterID& registerID, RegisterName name) {assert((name & ~registerNameMask) == 0); registerID = RegisterID((registerID & ~registerNameMask) | ((name << registerNameShift) & registerNameMask));}
inline RegisterID buildRegisterID(RegisterName name, RegisterClassKind classKind) {return RegisterID(((classKind << registerClassShift) & registerClassMask) | ((name << registerNameShift) & registerNameMask));}
#ifdef DEBUG
inline bool isMachineRegister(RegisterID rid) {return (rid & machineRegisterMask) != 0;}
inline void setMachineRegister(RegisterID& rid) {rid = RegisterID(rid | machineRegisterMask);}
inline bool isColoredRegister(RegisterID rid) {return (rid & coloredRegisterMask) != 0;}
inline void setColoredRegister(RegisterID& rid) {rid = RegisterID(rid | coloredRegisterMask);}
#endif // DEBUG
#endif // _REGISTER_TYPES_H_

View File

@@ -0,0 +1,32 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "SSATools.h"
#include "ControlGraph.h"
#include "VirtualRegister.h"
#include "Liveness.h"
void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
{
if (!controlGraph.hasBackEdges)
return;
Liveness liveness(controlGraph.pool);
liveness.buildLivenessAnalysis(controlGraph, vrManager);
}

View File

@@ -0,0 +1,29 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _SSA_TOOLS_H_
#define _SSA_TOOLS_H_
#include "Fundamentals.h"
class ControlGraph;
class VirtualRegisterManager;
extern void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
#endif // _SSA_TOOLS_H_

View File

@@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "SparseSet.h"
#include "BitSet.h"
#include "Pool.h"
#ifdef DEBUG_LOG
// Print the set.
//
void SparseSet::printPretty(LogModuleObject log)
{
Pool pool;
BitSet set(pool, universeSize);
for (Uint32 i = 0; i < count; i++)
set.set(node[i].element);
set.printPretty(log);
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,168 @@
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
//
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
// NETSCAPE COMMUNICATIONS CORPORATION
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
// Reserved. Use of this Source Code is subject to the terms of the
// applicable license agreement from Netscape Communications Corporation.
// The copyright notice(s) in this Source Code does not indicate actual or
// intended publication of this Source Code.
//
// $Id: SparseSet.h,v 1.1.2.1 1999-03-02 16:12:07 fur%netscape.com Exp $
//
#ifndef _SPARSE_SET_H_
#define _SPARSE_SET_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "LogModule.h"
#include "BitSet.h"
class SparseSet
{
private:
struct Node {
Uint32 element;
Uint32 stackIndex;
};
Node* node;
Uint32 count;
Uint32 universeSize;
private:
// No copy constructor.
SparseSet(const SparseSet&);
// Check if the given set's universe is of the same size than this universe.
void checkUniverseCompatibility(const SparseSet& set) const {assert(set.universeSize == universeSize);}
// Check if pos is valid for this set's universe.
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
public:
SparseSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {node = new(pool) Node[universeSize]; clear();}
// Clear the sparse set.
void clear() {count = 0;}
// Clear the element at index.
inline void clear(Uint32 index);
// Set the element at index.
inline void set(Uint32 index);
// Return true if the element at index is set.
inline bool test(Uint32 index) const;
// Union with the given sparse set.
inline void or(const SparseSet& set);
// Intersection with the given sparse set.
inline void and(const SparseSet& set);
// Difference with the given sparse set.
inline void difference(const SparseSet& set);
// Copy set.
inline SparseSet& operator = (const SparseSet& set);
inline SparseSet& operator = (const BitSet& set);
// Return true if the sparse sets are identical.
friend bool operator == (const SparseSet& set1, const SparseSet& set2);
// Return true if the sparse sets are different.
friend bool operator != (const SparseSet& set1, const SparseSet& set2);
// Logical operators.
SparseSet& operator |= (const SparseSet& set) {or(set); return *this;}
SparseSet& operator &= (const SparseSet& set) {and(set); return *this;}
SparseSet& operator -= (const SparseSet& set) {difference(set); return *this;}
// Iterator to conform with the set API.
typedef Int32 iterator;
// Return the iterator for the first element of this set.
iterator begin() const {return count - 1;}
// Return the next iterator.
iterator advance(iterator pos) const {return --pos;}
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos < 0;}
// Return the element for the given iterator;
Uint32 get(iterator pos) const {return node[pos].element;}
// Return one element of this set.
Uint32 getOne() const {assert(count > 0); return node[0].element;}
// Return the size of this set.
Uint32 getSize() const {return count;}
#ifdef DEBUG_LOG
// Print the set.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
inline void SparseSet::clear(Uint32 element)
{
checkMember(element);
Uint32 count = this->count;
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
if ((stackIndex < count) && (node[stackIndex].element == element)) {
Uint32 stackTop = node[count - 1].element;
node[stackIndex].element = stackTop;
node[stackTop].stackIndex = stackIndex;
this->count = count - 1;
}
}
inline void SparseSet::set(Uint32 element)
{
checkMember(element);
Uint32 count = this->count;
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
if ((stackIndex >= count) || (node[stackIndex].element != element)) {
node[count].element = element;
node[element].stackIndex = count;
this->count = count + 1;
}
}
inline bool SparseSet::test(Uint32 element) const
{
checkMember(element);
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
return ((stackIndex < count) && (node[stackIndex].element == element));
}
inline SparseSet& SparseSet::operator = (const SparseSet& set)
{
checkUniverseCompatibility(set);
Uint32 sourceCount = set.getSize();
Node* node = this->node;
memcpy(node, set.node, sourceCount * sizeof(Node));
for (Uint32 i = 0; i < sourceCount; i++) {
Uint32 element = node[i].element;
node[element].stackIndex = i;
}
count = sourceCount;
return *this;
}
inline SparseSet& SparseSet::operator = (const BitSet& set)
{
// FIX: there's room for optimization here.
assert(universeSize == set.getSize());
clear();
for (Int32 i = set.firstOne(); i != -1; i = set.nextOne(i))
this->set(i);
return *this;
}
#endif // _SPARSE_SET_H_

View File

@@ -0,0 +1,270 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef NEW_LAURENTM_CODE
#define INCLUDE_EMITTER
#include "CpuInfo.h"
#include "Fundamentals.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "InstructionEmitter.h"
#include "Spilling.h"
void Spilling::
insertSpillCode(ControlNode** dfsList, Uint32 nNodes)
{
PRUint32 nVirtualRegisters = vRegManager.count();
FastBitSet currentLive(vRegManager.pool, nVirtualRegisters);
FastBitSet usedInThisInstruction(vRegManager.pool, nVirtualRegisters);
RegisterFifo grNeedLoad(nVirtualRegisters);
RegisterFifo fpNeedLoad(nVirtualRegisters);
for (PRInt32 n = nNodes - 1; n >= 0; n--)
{
PR_ASSERT(grNeedLoad.empty() & fpNeedLoad.empty());
ControlNode& node = *dfsList[n];
currentLive = node.liveAtEnd;
PRUint32 nGeneralAlive = 0;
PRUint32 nFloatingPointAlive = 0;
// Get the number of registers alive at the end of this node.
for (PRInt32 j = currentLive.firstOne(); j != -1; j = currentLive.nextOne(j))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(j);
if (vReg.spillInfo.willSpill)
{
currentLive.clear(j);
}
else
{
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive++;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive++;
break;
default:
break;
}
}
}
// if(node.dfsNum == 8) printf("\n________Begin Node %d________\n", node.dfsNum);
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i))
{
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defEnd = instruction.getInstructionDefineEnd();
InstructionDefine* defPtr;
// if(node.dfsNum == 8) { printf("\n");
// instruction.printPretty(stdout);
// printf("\n"); }
// Handle definitions
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
if (defPtr->isVirtualRegister())
{
VirtualRegister& vReg = defPtr->getVirtualRegister();
currentLive.clear(vReg.getRegisterIndex());
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive--;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive--;
break;
default:
break;
}
}
// Check for deaths
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isVirtualRegister())
{
VirtualRegister& vReg = usePtr->getVirtualRegister();
if (!currentLive.test(vReg.getRegisterIndex()))
// This is the last use of this register.
{
currentLive.set(vReg.getRegisterIndex());
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive++;
while (/*(nGeneralAlive > NUMBER_OF_GREGISTERS) &&*/ !grNeedLoad.empty())
{
PRUint32 toLoad = grNeedLoad.get();
currentLive.clear(toLoad);
nGeneralAlive--;
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
nReg.releaseSelf();
}
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive++;
while (/*(nFloatingPointAlive > NUMBER_OF_FPREGISTERS) &&*/ !fpNeedLoad.empty())
{
PRUint32 toLoad = fpNeedLoad.get();
currentLive.clear(toLoad);
nFloatingPointAlive--;
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
nReg.releaseSelf();
}
break;
default:
break;
}
}
}
// Handle uses
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isVirtualRegister())
{
VirtualRegister& vReg = usePtr->getVirtualRegister();
PRUint32 registerIndex = vReg.getRegisterIndex();
if (vReg.spillInfo.willSpill) {
#if defined(GENERATE_FOR_X86)
if (!instruction.switchUseToSpill((usePtr - useBegin), *vReg.equivalentRegister[vrcStackSlot]))
#endif
{
switch (vReg.getClass())
{
case vrcInteger:
if (!grNeedLoad.test(registerIndex))
{
grNeedLoad.put(registerIndex);
VirtualRegister& alias = vRegManager.newVirtualRegister(vrcInteger);
if (vReg.isPreColored())
alias.preColorRegister(vReg.getPreColor());
/* if (vReg.hasSpecialInterference) {
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
alias.specialInterference = vReg.specialInterference;
alias.hasSpecialInterference = true;
} */
vReg.setAlias(alias);
vReg.retainSelf();
}
break;
case vrcFloatingPoint:
case vrcFixedPoint:
if (!fpNeedLoad.test(registerIndex))
{
fpNeedLoad.put(registerIndex);
VirtualRegister& alias = vRegManager.newVirtualRegister(vReg.getClass());
if (vReg.isPreColored())
alias.preColorRegister(vReg.getPreColor());
/*if (vReg.hasSpecialInterference) {
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
alias.specialInterference = vReg.specialInterference;
alias.hasSpecialInterference = true;
} */
vReg.setAlias(alias);
vReg.retainSelf();
}
break;
default:
break;
}
usePtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
usedInThisInstruction.set(registerIndex);
vReg.spillInfo.lastUsingInstruction = &instruction;
}
currentLive.clear(registerIndex);
} else { // will not spill
currentLive.set(registerIndex);
}
}
// Handle definitions
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
if (defPtr->isVirtualRegister())
{
VirtualRegister& vReg = defPtr->getVirtualRegister();
if (vReg.spillInfo.willSpill)
#if defined(GENERATE_FOR_X86)
if (!instruction.switchDefineToSpill((defPtr - defBegin), *vReg.equivalentRegister[vrcStackSlot]))
#endif
{
if (usedInThisInstruction.test(vReg.getRegisterIndex()))
// this virtualRegister was used in this instruction and is also defined. We need to move
// this virtual register to its alias first and then save it to memory.
{
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
vReg.getAlias(), *vReg.equivalentRegister[vrcStackSlot]);
defPtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
}
else
{
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
vReg, *vReg.equivalentRegister[vrcStackSlot]);
}
}
}
}
while (!grNeedLoad.empty())
{
PRUint32 nl = grNeedLoad.get();
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
nlReg.releaseSelf();
}
while (!fpNeedLoad.empty())
{
PRUint32 nl = fpNeedLoad.get();
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
nlReg.releaseSelf();
}
// if(node.dfsNum == 8) printf("\n________End Node %d________\n", node.dfsNum);
}
}
#endif

View File

@@ -0,0 +1,269 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _SPILLING_H_
#define _SPILLING_H_
#include "Fundamentals.h"
#include <string.h>
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "SparseSet.h"
template <class RegisterPressure>
class Spilling
{
private:
static void insertStoreAfter(Instruction& instruction, RegisterName name);
static void insertLoadBefore(Instruction& instruction, RegisterName name);
public:
static void calculateSpillCosts(RegisterAllocator& registerAllocator);
static void insertSpillCode(RegisterAllocator& registerAllocator);
};
struct SpillCost
{
double loads;
double stores;
double copies;
double cost;
bool infinite;
};
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertSpillCode(RegisterAllocator& registerAllocator)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
Pool& pool = registerAllocator.pool;
SparseSet currentLive(pool, rangeCount);
SparseSet needLoad(pool, rangeCount);
SparseSet mustSpill(pool, rangeCount);
SparseSet& willSpill = *registerAllocator.willSpill;
ControlGraph& controlGraph = registerAllocator.controlGraph;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
needLoad.clear();
currentLive = liveOut[n];
mustSpill = currentLive;
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i);) {
Instruction& instruction = instructions.get(i);
i = instructions.retreat(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
bool foundLiveDefine = false;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
if (currentLive.test(name2range[definePtr->getRegisterName()])) {
foundLiveDefine = true;
break;
}
} else {
foundLiveDefine = true;
break;
}
if (defineBegin != defineEnd && !foundLiveDefine) {
fprintf(stderr, "!!! Removed instruction because it was only defining unused registers !!!\n");
instruction.remove();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName range = name2range[definePtr->getRegisterName()];
#ifdef DEBUG
if (needLoad.test(range))
if (!mustSpill.test(range) && registerAllocator.spillCost[range].infinite && willSpill.test(range)) {
fprintf(stderr, "Tried to spill a register with infinite spill cost\n");
abort();
}
#endif // DEBUG
if (willSpill.test(range))
insertStoreAfter(instruction, range);
needLoad.clear(range);
}
if (instruction.getFlags() & ifCopy)
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
if (!currentLive.test(range))
for (SparseSet::iterator r = needLoad.begin(); !needLoad.done(r); r = needLoad.advance(r)) {
RegisterName load = RegisterName(needLoad.get(r));
if (willSpill.test(load))
insertLoadBefore(instruction, load);
mustSpill.set(load);
}
needLoad.clear();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
currentLive.set(range);
needLoad.set(range);
}
}
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
RegisterName load = RegisterName(needLoad.get(l));
if (willSpill.test(load))
insertLoadBefore(instructions.first(), load);
}
}
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertLoadBefore(Instruction& /*instruction*/, RegisterName name)
{
fprintf(stdout, "will insert load for range %d\n", name);
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertStoreAfter(Instruction& /*instruction*/, RegisterName name)
{
fprintf(stdout, "will insert store for range %d\n", name);
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::calculateSpillCosts(RegisterAllocator& registerAllocator)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
Pool& pool = registerAllocator.pool;
SparseSet live(pool, rangeCount);
SparseSet needLoad(pool, rangeCount);
SparseSet mustSpill(pool, rangeCount);
SparseSet alreadyStored(pool, rangeCount); // FIX: should get this from previous spilling.
SpillCost* cost = new SpillCost[rangeCount];
memset(cost, '\0', rangeCount * sizeof(SpillCost));
ControlGraph& controlGraph = registerAllocator.controlGraph;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
double weight = doLog10(node.loopDepth);
needLoad.clear();
live = liveOut[n];
mustSpill = live;
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName range = name2range[definePtr->getRegisterName()];
if (needLoad.test(range))
if (!mustSpill.test(range))
cost[range].infinite = true;
if ((false /* !rematerializable(range) */ || !needLoad.test(range)) && !alreadyStored.test(range))
cost[range].stores += weight;
needLoad.clear(range);
}
if (instruction.getFlags() & ifCopy)
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
if (!live.test(name2range[usePtr->getRegisterName()])) {
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
Uint32 range = needLoad.get(l);
cost[range].loads += weight;
mustSpill.set(range);
}
needLoad.clear();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
live.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
live.set(range);
needLoad.set(range);
}
if (instruction.getFlags() & ifCopy) {
assert(useBegin != useEnd && useBegin[0].isRegister());
assert(defineBegin != defineEnd && defineBegin[0].isRegister());
RegisterName source = name2range[useBegin[0].getRegisterName()];
RegisterName destination = name2range[defineBegin[0].getRegisterName()];
cost[source].copies += weight;
cost[destination].copies += weight;
}
}
for (SparseSet::iterator s = needLoad.begin(); !needLoad.done(s); s = needLoad.advance(s))
cost[needLoad.get(s)].loads += weight;
}
for (Uint32 r = 0; r < rangeCount; r++) {
SpillCost& c = cost[r];
c.cost = 2 * (c.loads + c.stores) - c.copies;
}
registerAllocator.spillCost = cost;
}
#endif // _SPILLING_H_

View File

@@ -0,0 +1,239 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _SPLITS_H_
#define _SPLITS_H_
#include "Fundamentals.h"
#include <string.h>
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
template <class RegisterPressure>
struct Splits
{
static void calculateSplitCosts(RegisterAllocator& registerAllocator);
static bool findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range);
static void insertSplitCode(RegisterAllocator& registerAllocator);
};
struct SplitCost
{
double loads;
double stores;
};
template <class RegisterPressure>
void Splits<RegisterPressure>::insertSplitCode(RegisterAllocator& /*registerAllocator*/)
{
// FIX
}
template <class RegisterPressure>
bool Splits<RegisterPressure>::findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range)
{
Pool& pool = registerAllocator.pool;
NameLinkedList** neighborsWithColor = new(pool) NameLinkedList*[6]; // FIX
memset(neighborsWithColor, '\0', 6 * sizeof(NameLinkedList*));
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = vector->count - 1; i >=0; --i) {
RegisterName neighbor = vector->neighbors[i];
RegisterName c = color[neighbor];
if (c < 6) { // FIX
NameLinkedList* node = new(pool) NameLinkedList();
node->name = neighbor;
node->next = neighborsWithColor[c];
neighborsWithColor[c] = node;
}
}
bool splitAroundName = true;
LiveRangeGraph<RegisterPressure>& lGraph = registerAllocator.lGraph;
RegisterName bestColor = RegisterName(6); // FIX
double bestCost = registerAllocator.spillCost[range].cost;
SplitCost* splitCost = registerAllocator.splitCost;
for (RegisterName i = RegisterName(0); i < 6; i = RegisterName(i + 1)) { // FIX
double splitAroundNameCost = 0.0;
bool canSplitAroundName = true;
SplitCost& sCost = splitCost[range];
double addedCost = 2.0 * (sCost.stores + sCost.loads);
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
RegisterName neighbor = node->name;
if (lGraph.haveEdge(neighbor, range)) {
canSplitAroundName = false;
break;
} else
splitAroundNameCost += addedCost;
}
if (canSplitAroundName && splitAroundNameCost < bestCost) {
bestCost = splitAroundNameCost;
bestColor = i;
splitAroundName = true;
}
double splitAroundColorCost = 0.0;
bool canSplitAroundColor = true;
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
RegisterName neighbor = node->name;
if (lGraph.haveEdge(range, neighbor)) {
canSplitAroundColor = false;
break;
} else {
SplitCost& sCost = splitCost[neighbor];
double addedCost = 2.0 * (sCost.stores + sCost.loads);
splitAroundColorCost += addedCost;
}
}
if (canSplitAroundColor && splitAroundColorCost < bestCost) {
bestCost = splitAroundColorCost;
bestColor = i;
splitAroundName = false;
}
}
if (bestColor < RegisterName(6)) {
color[range] = bestColor;
registerAllocator.splitFound = true;
NameLinkedList** splitAround = registerAllocator.splitAround;
if (splitAroundName)
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
NameLinkedList* newNode = new(pool) NameLinkedList();
newNode->name = node->name;
newNode->next = splitAround[range];
splitAround[range] = newNode;
}
else
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
NameLinkedList* newNode = new(pool) NameLinkedList();
RegisterName neighbor = node->name;
newNode->name = range;
newNode->next = splitAround[neighbor];
splitAround[neighbor] = newNode;
}
trespass("Found a split");
return true;
}
return false;
}
template <class RegisterPressure>
void Splits<RegisterPressure>::calculateSplitCosts(RegisterAllocator& registerAllocator)
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
SplitCost* splitCost = new(pool) SplitCost[rangeCount];
memset(splitCost, '\0', rangeCount * sizeof(SplitCost));
SparseSet live(pool, rangeCount);
RegisterPressure::Set* liveIn = registerAllocator.liveness.liveIn;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
double weight = doLog10(node.loopDepth);
live = liveOut[n];
ControlEdge* successorsEnd = node.getSuccessorsEnd();
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++) {
ControlNode& successor = successorsPtr->getTarget();
if (successor.getControlKind() != ckEnd) {
RegisterPressure::Set& successorLiveIn = liveIn[successor.dfsNum];
for (SparseSet::iterator i = live.begin(); !live.done(i); i = live.advance(i)) {
RegisterName name = RegisterName(live.get(i));
if (!successorLiveIn.test(name))
splitCost[name].loads += doLog10(successor.loopDepth);
}
}
}
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
splitCost[name2range[definePtr->getRegisterName()]].stores += weight;
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
if (!live.test(range)) {
if (&instruction != &instructions.last())
splitCost[range].loads += weight;
else {
ControlEdge* successorsEnd = node.getSuccessorsEnd();
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++)
splitCost[range].loads += doLog10(successorsPtr->getTarget().loopDepth);
}
}
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
live.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
live.set(name2range[usePtr->getRegisterName()]);
}
}
NameLinkedList** splitAround = new(pool) NameLinkedList*[rangeCount];
memset(splitAround, '\0', rangeCount * sizeof(NameLinkedList*));
registerAllocator.splitAround = splitAround;
registerAllocator.splitCost = splitCost;
registerAllocator.splitFound = false;
}
#endif // _SPLITS_H_

View File

@@ -0,0 +1,186 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "HashTable.h"
#include "Timer.h"
#include "Pool.h"
static Pool pool; // Pool for the Timer class.
static HashTable<TimerEntry*> timerEntries(pool); // Timers hashtable.
const nTimersInABlock = 128; // Number of timers in a block.
static PRTime *timers = new(pool) PRTime[nTimersInABlock]; // A block of timers.
static Uint8 nextTimer = 0; // nextAvailableTimer.
//
// Calibrate the call to PR_Now().
//
static PRTime calibrate()
{
PRTime t = PR_Now();
PRTime& a = *new(pool) PRTime();
// Call 10 times the PR_Now() function.
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
t = (PR_Now() - t + 9) / 10;
return t;
}
static PRTime adjust = calibrate();
//
// Return the named timer..
//
TimerEntry& Timer::getTimerEntry(const char* name)
{
if (!timerEntries.exists(name)) {
TimerEntry* newEntry = new(pool) TimerEntry();
newEntry->accumulator = 0;
newEntry->running = false;
timerEntries.add(name, newEntry);
}
return *timerEntries[name];
}
//
// Return a reference to a new timer.
//
PRTime& Timer::getNewTimer()
{
if (nextTimer >= nTimersInABlock) {
timers = new(pool) PRTime[nTimersInABlock];
nextTimer = 0;
}
return timers[nextTimer++];
}
static Uint32 timersAreFrozen = 0;
//
// Start the named timer.
//
void Timer::start(const char* name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(!timer.running);
timer.accumulator = 0;
timer.running = true;
timer.done = false;
unfreezeTimers();
}
//
// Stop the named timer.
//
void Timer::stop(const char* name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(timer.running);
timer.running = false;
timer.done = true;
unfreezeTimers();
}
//
// Freeze all the running timers.
//
void Timer::freezeTimers()
{
PRTime when = PR_Now() - adjust;
if (timersAreFrozen == 0) {
Vector<TimerEntry*> entries = timerEntries;
Uint32 count = entries.size();
for (Uint32 i = 0; i < count; i++) {
TimerEntry& entry = *entries[i];
if (entry.running) {
entry.accumulator += (when - *entry.startTime);
}
}
}
timersAreFrozen++;
}
//
// Unfreeze all the running timers.
//
void Timer::unfreezeTimers()
{
PR_ASSERT(timersAreFrozen != 0);
timersAreFrozen--;
if (timersAreFrozen == 0) {
Vector<TimerEntry *> entries = timerEntries;
Uint32 count = entries.size();
PRTime& newStart = getNewTimer();
for (Uint32 i = 0; i < count; i++) {
TimerEntry& entry = *entries[i];
if (entry.running) {
entry.startTime = &newStart;
}
}
newStart = PR_Now();
}
}
//
// Print the named timer in the file f.
//
void Timer::print(FILE* f, const char *name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(timer.done);
PRTime elapsed = timer.accumulator;
if (elapsed >> 32) {
fprintf(f, "[timer %s out of range]\n", name);
} else {
fprintf(f, "[%dus in %s]\n", Uint32(elapsed), name);
}
fflush(f);
unfreezeTimers();
}

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _TIMER_H_
#define _TIMER_H_
#include "Fundamentals.h"
#include "HashTable.h"
#include "prtime.h"
//
// Naming convention:
// As the class Timer contains only static methods, the timer's name should start with the
// module name. Otherwise starting 2 timers with the same name will assert.
//
#ifndef NO_TIMER
struct TimerEntry
{
PRTime *startTime; // Current time when we start the timer.
PRTime accumulator; // Time spent in this timer.
bool running; // True if the timer is running.
bool done; // True if the timer was running and was stopped.
};
class Timer
{
private:
// Return the named timer.
static TimerEntry& getTimerEntry(const char* name);
// Return a reference to a new Timer.
static PRTime& getNewTimer();
public:
// Start the timer.
static void start(const char* name);
// Stop the timer.
static void stop(const char* name);
// Freeze all the running timers.
static void freezeTimers();
// Unfreeze all the running timers.
static void unfreezeTimers();
// Print the timer.
static void print(FILE* f, const char *name);
};
inline void startTimer(const char* name) {Timer::start(name);}
inline void stopTimer(const char* name) {Timer::stop(name); Timer::print(stdout, name);}
#define START_TIMER_SAFE Timer::freezeTimers();
#define END_TIMER_SAFE Timer::unfreezeTimers();
#define TIMER_SAFE(x) START_TIMER_SAFE x; END_TIMER_SAFE
#else /* NO_TIMER */
inline void startTimer(const char* /*name*/) {}
inline void stopTimer(const char* /*name*/) {}
#define START_TIMER_SAFE
#define END_TIMER_SAFE
#define TIMER_SAFE(x) x;
#endif /* NO_TIMER */
#endif /* _TIMER_H_ */

View File

@@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "VirtualRegister.h"
#include "Instruction.h"
//------------------------------------------------------------------------------
// VirtualRegister -
#ifdef MANUAL_TEMPLATES
template class IndexedPool<VirtualRegister>;
#endif
// Set the defining instruction.
//
void VirtualRegister::setDefiningInstruction(Instruction& instruction)
{
if (definingInstruction != NULL) {
if ((instruction.getFlags() & ifCopy) && (definingInstruction->getFlags() & ifPhiNode))
return;
}
definingInstruction = &instruction;
}

View File

@@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _VIRTUAL_REGISTER_H_
#define _VIRTUAL_REGISTER_H_
#include "Fundamentals.h"
#include "IndexedPool.h"
#include <string.h>
#include "RegisterTypes.h"
#include "RegisterClass.h"
//------------------------------------------------------------------------------
// VirtualRegister - 24b
class Instruction;
class VirtualRegister : public IndexedObject<VirtualRegister>
{
public:
Instruction* definingInstruction; // Instruction defining this VR.
// Initialize a VR of the given classKind.
VirtualRegister(RegisterClassKind /*classKind*/) : definingInstruction(NULL) {}
// Return the defining instruction for this VR.
Instruction* getDefiningInstruction() const {return definingInstruction;}
// Set the defining instruction.
void setDefiningInstruction(Instruction& insn);
};
// Return true if the VirtualRegisters are equals. The only way 2 VRs can be equal is if
// they have the same index. If they have the same index then they are at the same
// address in the indexed pool.
//
inline bool operator == (const VirtualRegister& regA, const VirtualRegister& regB) {return &regA == &regB;}
//------------------------------------------------------------------------------
// VirtualRegisterManager -
struct PreColoredRegister
{
RegisterID id;
RegisterName color;
};
class VirtualRegisterManager
{
private:
IndexedPool<VirtualRegister> registerPool;
PreColoredRegister machineRegister[6];
public:
VirtualRegisterManager()
{
for (Uint32 i = 0; i < 6; i++)
machineRegister[i].id = invalidID;
}
// Return the VirtualRegister at the given index.
VirtualRegister& getVirtualRegister(RegisterName name) const {return registerPool.get(name);}
// Return a new VirtualRegister.
RegisterID newVirtualRegister(RegisterClassKind classKind)
{
VirtualRegister& vReg = *new(registerPool) VirtualRegister(classKind);
RegisterID rid;
setName(rid, RegisterName(vReg.getIndex()));
setClass(rid, classKind);
return rid;
}
RegisterID newMachineRegister(RegisterName name, RegisterClassKind classKind)
{
RegisterID rid = machineRegister[name].id;
if (rid == invalidID) {
rid = newVirtualRegister(classKind);
DEBUG_ONLY(setMachineRegister(rid));
machineRegister[name].id = rid;
machineRegister[name].color = name;
}
return rid;
}
PreColoredRegister* getMachineRegistersBegin() const {return (PreColoredRegister*) machineRegister;} // FIX
PreColoredRegister* getMachineRegistersEnd() const {return (PreColoredRegister*) &machineRegister[6];} // FIX
// Return the VirtualRegister universe size.
Uint32 getSize() {return registerPool.getSize();}
void setSize(Uint32 size) {registerPool.setSize(size);}
};
#endif // _VIRTUAL_REGISTER_H_

View File

@@ -1,432 +0,0 @@
#################################################################################
# 12/03/01, ChatZilla 0.8.5, <rginda@netscape.com>
Shipped with 0.9.7. Again, thanks to Samuel Sieb <samuel@sieb.net> for
contributing many of the fixes (the most obvious of which is mIRC color code
support), reviews, and driving the release candidate process. Thanks to Casey
Hutchinson <nnooiissee@yahoo.com> for mac accelerator cleanup, help and edit
menus, xul refactoring work, statusbar, and motivation. Thanks to
KOIKE Kazuhiko, Katsuhiko Momoi, Shoji Matsumoto, and others who helped out in
bug 41564 to get charsets working.
* strict warning cleanup.
* add input/output charset support. use /charset <charsetname> to
change the current charset, settings will be saved.
* add "open at startup" item to view menus.
* implement urls for /query views (isnick urls.)
* make nicknames in output window isnick urls.
* add mozilla statusbar.
* add chatzilla icon to mozilla statusbar.
* move "statusbar" to top of message window, rename to "header".
* add mirc color code handling.
* show long topics in multiple lines in header, instead of cropping.
* add bugzilla munger rule, links "bug 12345" and "bug #12345" to appropriate
bugzilla bugs.
* add channel munger rule to link #channelname to the channel.
* add edit and help menus.
* make /attach accept urls and url "fragments",
/attach moznet, /attach moznet/chatzilla, and /attach irc://moznet/chatzilla
are now all valid commands.
* add prefs for when to make noise; new msg, msg in existing query view, and/or
/stalk matches.
* allow for space separated list of sounds to play, like "beep beep", or
"file:/foo.wav"
* fix bogus "connection refused" error when disconnecting.
* add editable topic in header area.
* implement server passowrds (they were way broke.)
* add ctrl-tab and ctrl-shift-tab handlers to switch views.
* fix tab complete behavior, so it works for words in the middle of the line.
* add /about command to get version info.
* add "collapse consecutive messages" option, useful for motifs with faces.
* mac s/ctrl/meta/ fixes.
* add default completions per view, as described in bug 63621.
* add whowas help info.
* format responses from WHO queries.
* add network view maxlines pref.
* only print "attampting to connect" message once per network.
* add target in Kick item of message pane context menu.
* remove timestamp tooltips, use status text instead.
* show message source in status bar, after timestamp.
* remove usage warning from /quit command.
* change max connect attempts from 20 to 5.
* remove unused listbox.js file from chatzilla.jar.
* add help menu.
* allow params in /ctcp commands.
=================================================================================
= Bugs fixed
41564,63621,71549,86032,88438,91399,92080,95913,97288,98244,99612,100159,100704,101942,102377,103104,103598,104114,105343,105604,105881,105882,106349,107148,108061,110006,111546,111565
http://bugzilla.mozilla.org/buglist.cgi?bug_id=41564%2C63621%2C71549%2C86032%2C88438%2C91399%2C92080%2C95913%2C97288%2C98244%2C99612%2C100159%2C100704%2C101942%2C102377%2C103104%2C103598%2C104114%2C105343%2C105604%2C105881%2C105882%2C106349%2C107148%2C108061%2C110006%2C111546%2C111565
28 bugs found.
ID Opened Summary
63621 2000-12-22 [RFE] Shortcut to reply to the last IRC message
98244 2001-09-04 Add "Leave this channel" to channel popup menu
101942 2001-09-27 whowas command said unknown even though it exists
92080 2001-07-24 Enter key to navigate menus also sends commmand
105604 2001-10-18 chatzilla should have a status bar (and component bar)
99612 2001-09-14 Chatzilla window id should not be "main-window"
102377 2001-09-29 Chatzilla does not handle server passwords
103104 2001-10-04 implement isnick urls
103598 2001-10-07 JavaScript strict mode patch for Chatzilla
91399 2001-07-18 Missing "screen buffer length" pref setting in prefs.js
104114 2001-10-10 Can't localize some strings in Chatzilla.
100704 2001-09-20 chatzilla needs an easy way to edit the topic
105882 2001-10-21 Chatzilla keyboard shortcuts use wrong modifier key
100159 2001-09-17 hiding a minimized userlist expands it instead
105343 2001-10-17 chatzilla should have /about command
106349 2001-10-23 [rfe]show a check beside selected motif in the view menu.
107148 2001-10-27 chatzilla menus should move to an overlay
105881 2001-10-21 `Edit' menu is missing in Chatzilla
88438 2001-06-29 2xAlt-Tab will bring up unexpected "user-match"-message
110006 2001-11-13 view/hide status bar is not saved
71549 2001-03-09 [RFE] add mIRC and IrcII color code support
86032 2001-06-14 [RFE] Ctrl+[shift]+tab and [shift]+F6 to switch channel view
95913 2001-08-18 Include Chatzilla icon in Component Bar
111565 2001-11-23 /query command no longer sends second argument
111546 2001-11-22 User list doesn't repopulate correctly after rejoining chann
108061 2001-11-01 /stalk won't stalk nicknames
41564 2000-06-05 Internationalize ChatZilla to handle different language scri
97288 2001-08-28 Chatzilla gets disconnected w/o indicating anything is wrong
#################################################################################
# 8/23/01, ChatZilla 0.8.4, <rginda@netscape.com>
Shipped with Mozilla 0.9.4, 0.9.5, and 0.9.6, introduced motifs, channel and
mailto links, and other things that were only availble in the 0.8.1a/b releases,
which were not checked in. Thanks to Samuel Sieb <samuel@sieb.net> for
contributing many of the fixes, and reviewing the rest.
=================================================================================
= Bugs fixed
superbug: 103386
41337,44447,69296,72272,72702,73652,73767,74408,79322,85573,89692,89717,92327,92403,95781,96567
http://bugzilla.mozilla.org/buglist.cgi?bugidtype=include&bug_id=41337%2C44447%2C69296%2C72272%2C72702%2C73652%2C73767%2C74408%2C79322%2C85573%2C89692%2C89717%2C92327%2C92403%2C95781%2C96567
SuperBug: http://bugzilla.mozilla.org/show_bug.cgi?id=89713
16 bugs found.
ID Opened Summary
92403 2001-07-26 mozilla -help displays >>>>>>>>>>>> chatzilla-service loaded
96567 2001-08-22 long nicks cause extra-high lines
95781 2001-08-17 Chatzilla text is black-on-black
74408 2001-04-02 Typing in Chatzilla should give Textbox at bottom focus
automatically.
89692 2001-07-06 /away command only uses first word for reason
85573 2001-06-12 [RFE] support for mailto:
72272 2001-03-16 irc urls don't detect server/network names correctly
72702 2001-03-20 need UI for adding irc:// bookmarks
89717 2001-07-06 header text not visible for op and voice
73652 2001-03-27 Missing support for !-Channels
41337 2000-06-02 /join should join the current window if it is a channel and you
are not currently in it
79322 2001-05-07 [RFE] Make chatzilla user scriptable
73767 2001-03-28 Confusing behaviour if nick already in use
44447 2000-07-02 no ctcp ping results
69296 2001-02-18 irc URL with # doesn't work
92327 2001-07-25 [RFE] Have ops' names in red
#################################################################################
# 07/01/01, ChatZilla 0.8.3, <rginda@netscape.com>
Revision 0.8.3 removed hardcoded strings, in favor of the Mozilla i18n/l10n api.
RTL languages may still have some issues. Many thanks to Chiaki Koufugata
<chiaki@mozilla.gr.jp> for doing the heavy lifting.
=================================================================================
= Bugs fixed
http://bugzilla.mozilla.org/show_bug.cgi?id=27805
Bug 27805, "ChatZilla needs i18n"
#################################################################################
# 06/03/01, ChatZilla 0.8.2, <rginda@netscape.com>
=================================================================================
= Bugs fixed
79311, 75226, 80993
=================================================================================
= Changes by file name...
chatzilla-service.js:
- Add stub allowPort method.
- Fix signature for handleContent method, bug 80993
connection-xpcom.js:
- factor chatzilla specific code out of this file. Callbacks into chatzilla specific code are now used, making this file more generic.
- according to darinf (the current necko guy), using openOutputStream with asyncRead is a bad thing. Most of the changes in this file involve migrating from usage of openOutputStream to asyncWrite.
- Changes also include fixing the function declaration syntax to match the rest of the code (two lines, named functions.)
irc-debug.js:
- check nextLine before using it.
irc.js:
- changes to work with new socket interface.
- correct isOp detection in setTopic
- remove checks for undefined exceptions
- route data-available immediatley. inserting a data-available event to be routed later caused disconnect events to be recieved out of order.
utils.js:
- fix HAS_XPCOM test (XPCDOM broke it.)
- add jsenv.HAS_NSPR_EVENTQ
mybot.js:
- not built -
- add dummy escape/unescape if it isn't there
handlers.js:
- return false the first time through onClose(), and disconnect from all servers. This makes sure we keep the window around long enough to send the QUIT messages.
- close window if client.userClose is set and we disconnected from the last server.
chatzilla.xul:
- hook up onclose event.
- apply patch from 75226, fixes initial splitter position.
static.js:
- copy client.userAgent code from chatzilla 0.8.1x
- implement getConnectionCount()
#################################################################################
# ChatZilla 0.8.1a and 0.8.1b released only in XPI format, changes to be merged
# in later.
#################################################################################
#################################################################################
# 03/08/01, ChatZilla 0.8, <rginda@netscape.com>
=================================================================================
= Bugs fixed
The superbug for ChatZilla 0.8 is 71468, which fixes the following bugs:
22890, 40959, 41798, 42905, 43850, 44077, 54143, 56312, 59036, 59374, 65633, 65634, 65861, 66040, 71310, and 71378.
Also, a workaround for bug 70335 is included, and bug 45576 *may* be fixed, we'll have to wait and see
Link to superbug: http://bugzilla.mozilla.org/show_bug.cgi?id=71468
Link to list of bugs fixed: http://bugzilla.mozilla.org/buglist.cgi?bug_id=22890%2C+40959%2C+41798%2C+42905%2C+43850%2C+44077%2C+54143%2C+56312%2C+59036%2C+59374%2C+65633%2C+65634%2C+65861%2C+66040%2C+71310%2C+71378
=================================================================================
= Changes by file name...
These changes are listed as they appear, when reading a diff between what's in cvs now, and what's in my local tree. Before checking in, I'll tag the current chatzilla code as chatzilla0.7, and after, chatzilla0.8. Just diff those two tags to get something to look at alongside this ChangeLog. Or see the superbug for ChatZilla 0.8, 71468, which has a copy of the diff attached to it.
---------------------------------------------------------------------------------
- NEW FILES:
outputwindow.html:
- used as the base html for the output window, allowed bug 41798, bug 54143, and bug 59374 to be fixed.
ChangeLog:
- this file, tracks changes between ChatZilla versions. I added the comments from the previous large checkin (retro-branded as ChatZilla 0.7) as well.
TODO:
- List of things to do in the future.
---------------------------------------------------------------------------------
- MODIFIED FILES:
README:
- Started user guide, only the TOC at the moment.
connection-xpcom.js:
- Don't call close on output streams, it throws a NS_ERROR_NOT_IMPLEMENTED. dougt says just let the refcount go to 0 and it'll be fine.
- Tell the IRCServer object it has lost it's connection when the stream gets an onStopRequest (bug 22890 and 42905)
events.js:
- dump exception on error (to get the filename and linenumber info, if it's there)
irc-debug.js:
- show data for new "info" type of event.
irc.js:
- add a servers collection to the IRCNetwork. I'm not exactly sure why I didn't do this from the beginning. It allows us to recover and reuse server objects in the event of a disconnect/reconnect. (bug 22890 and 66040)
- set default number of reconnect attempts to something more tolerable. (bug 22890 and 66040)
- move connection attempt/ next host to attempt information from the event object onto the actual network object. The new reconnect logic needs it in places where the event is not available. (bug 22890 and 66040)
- spew out info event when max connect attempts are exhausted. (bug 22890 and 66040)
- spew out info event when a connection attempt starts. (bug 22890 and 66040)
- add try/catch around server creation, to be safe.
- spew info event when moving on to the next connection attempt. (bug 22890 and 66040)
- modify CIRCServer connection to check for a dupe server in it's parent.servers collection, re-init/return that object if it exists, otherwise make a new one.
- try to reconnect if the connection was broken before we got a 001 message from the server, regardless of wether ot not the parent IRCNetwork has it's "stayingPower" flag set.
- forward the disconnect event from the server to the network, to keep the network properly informed.
- if an unknown message arrives at the server, send it to the server's onUnknown handler if it exists. If the server has no onUnknown handler, send it to the parent network's handler for that type of message, if it has one. If the parent network has no handler for this message, send it to the network's onUnknown handler as a last ditch. (the event code will fail silently if the network has no onUnknown handler.)
- when we get an 001, reset connection attempt cound, and record the successful connection.
- if the channel's users collection is considered "stable" when a new names list begins to arrive, mark it as unstable before wiping it out. the list will be marked stable again when the end of names (code 366) message arrives.
- refer to this.foo instead of e.server.foo. they are the same object, but this.foo is one less lookup. this change should happen to the rest of this file eventually.
- Tell the network when the user changes their nick. This is so nick changes that occur when you're not on any channel don't go unnoticed.
- round off excess decimals in the server lag.
- add opCount and voiceCount vars to the IRCChannel during a channel.getUsersCount() call.
utils.js:
- make keys() return an array instead of a string. this function was not called by anything before this change.
- add formatDateOffset() function to the result of a Date subtraction into english.
- add arraySpeak() function to join an array into an english list.
- add arrayContains() function to search an array for an element.
- add arrayIndexOf() function to get the index of an element within the array.
- modify hyphenateWord() function to search for a goo place to break the word with a -/+ 5 character fuzz factor.
- add splitLongWord() function, similar to hyphenateWord, except returns an array.
- fix stoopid paren bug in roundTo() function.
chatzilla.xul:
- add broadcasters for the file menu items.
- add keys for the file menu items.
- add file menu. (bug 43850)
- move options menu under file menu.
- remove old view toolbar.
- add crop="right" attribute to the userlist table to prevent horizontal scrollbars. (bug 56312)
- whitespace fixes.
- add input splitter for multiline-input mode.
- add multiline-input control for multiline-input mode.
- add crop="right" to statusbar elements (bug 59036 maybe 45576)
commands.js:
- alphabetize commands.
- add client, cancel, disconnect, infobar, list, networks, notify, query, and status commands. (bug 44077)
handlers.js:
- don't call setOutputStyle() onLoad (it's been deleted.)
- we can now call setClientOutput() and initStatic() onLoad, because the output window is a separate .html file. This means the the xul onLoad will not be called until the .html file is loaded, and so we can be sure that the content model for the output window will be stable.
- global change from 'quotes like this' to ``quotes like this''.
- set client.debugMode variable when debug messages are on. This flag is used to determine how we display irc message codes.
- remove onToggleToolbarIcons() because we don't have a toolbar anymore.
- don't allow the last view to be deleted.
- move to new sort-service, but leave the old one in for now. This keeps us from breaking 0.8 users.
- add keyUp handler for the multiline-input control.
- clear the input control's value in the singleline input control's keyUp handler, instead of onInputCompleteLine(), because we don't want to clear the multiline control.
- switch to multiline mode if the singleline control hears a ctl+up.
- don't spew an error message if autocomplete can't locate a match on [tab]
- remove old (and broken) multiline code.
- add onNotifyTimeout() handler to take care of sending ISON messages. ISON is used to ask the server if certain users are on, used for the /notify command.
- add onInputCancel() handler (for the /cancel command) to cancel and pending /attach command.
- send unknown / commands directly to the server, (after warning the user that the command was unknown.)
- add onInputSimpleCommand(). Any / commands that can be sent directly to the server can use this function, instead of creating a new one for every "simple" command.
- add onInputStatus() (for the /status command.) Prints connection status, including connection duration, lag, and channels joined.
- revamp onInputTestdisplay(). It now tests all types of messages, and all munger rules, from multiple sources, to multiple targets. Much more useful than it used to be.
- add onInputNetworks() (for /networks.) Lists all networks as a set of irc:// links.
- show an error message if you attempt to /attach to a network you are already attached to.
- fail a /delete if the user provided a parameter. /delete deletes the *current* view, failing if a param is given prevents accidental deletion.
- Change onInputNames() from a function that toggles the infobar (userlist) visibility to a function that sends a NAMES command to the server.
- add onInputInfobar() to do what onInputName() used to do.
- add extra help message to onInputCommands().
- add status messages to onInputAttach().
- fix onInputMe() so it works on /query views as well as channels.
- add onInputQuery() function (for /query.)
- fix onInputMsg() so it does not force a new query window to open.
- change parameter of temporary doEval() function form s to __s, so as not to interfere with eval'd expressions.
- split EVAL message types into EVAL-IN and EVAL-OUT, so you can see was was eval()d, in the event of an error.
- change onInputTopic() from a function that would consult the irc library for topic information to a function send asks the server to update the topic information in the irc library. the code that handles TOPIC replies now tales care of printing this information out.
- add onInputNotify() function (for /notify.)
- add onInfo handler to networks.
- add onUnknown handler to networks.
- add 005 to the list of initial server messages that are *always* displayed on the network view.
- force handlers attached to the my_showtonet() function to display on the network view (ignoring the client.SLOPPY_NETWORKS setting.)
- allow NOTICE messages to be affected by client.SPLOPPY_NETWORKS.
- add an on303 (ISON reply) handler to networks.
- add an on322 (LIST reply) handler to networks.
- use the new arraySpeak() and formatDateOffset() functions when printing WHOIS information.
- print error message when a network gets disconnected. (bug 42905)
- show nick change information on the network if it is the current view.
- display "end of NAMES" message if the channel's pendingNamesReply flag is set, then clear pendingNamesReply. channel.pendingNamesReply is set by the /names command (and cleared in on366) to control wether or not NAMES information (353 and 366 messages) should actually be displayed. (the irc library will request this information when a new channels is joined, and we don't want to display it in that case.) (bug 40959)
- print topic information on a 332.
- print topic setter information on a 333.
- print NAMES information on 353 if the channel's pendingNamesReply flag is set. (bug 40959)
- global fixes to .display callsites. new syntax is obj.display (<msg>, <type>, <source>, <dest>);
- beep when a message from a user is received.
readprefs.js:
- remove toolbar.icons pref, we don't have a toolbar anymore.
- set client.debugMode based on debug messages pref.
static.js:
- removed some unused client.PREFERENCE type variables.
- added client.SLOPPY_NETWORKS switch (see comment.)
- added client.HIDE_CODES switch (see comment.)
- added a message code -> display glyph map for use when client.HIDE_CODES is true.
- remove the isPermanent flag from the client view, allows users to delete the client view.
- set client.IGNORE_MOTD to false.
- bump MAX_MESSAGES up a few notches for various view types.
- set onresize handler for the window. (bug 41798)
- create an nsISound in the client object, so we can beep for /msgs.
- hook up multiline-input control keyUp handler.
- remove icons-in-toolbar related code.
- remove network list from the hello message, but...
- call onInputNetworks() during init.
- start the notify interval.
- global change from 'quotes like this' to ``quotes like this''.
- remove dead servers from the efnet server list.
- add opennet network. (bug 65633)
- removed the "you-talking-to-me" munger rule, this is now done in display().
- made bold, underline, teletype, italic regexps more better.
- remove matchMyNick function, this is now done in display().
- add a "chatzilla-link" class to all links.
- style rheet matches as chatzilla-rheet and chatzilla-link.
- keep smileys that start with the number 8 from matching. (bug 65861)
- fix insertHyphenatedWord() to use splitLongWord() and empty <img> tags, instead of using hyphenateWord() to insert spaces in long words. the empty <img> lets the layout engine break long words, without adding spaces.
- added skin switching voodoo to mainStep, it's a dumb ass hack, read the comment. (bug 59374)
- removed setOutputStyle() function, we can't do this now that we load the basic output document as a .html file.
- simplified setClientOutput() function. all the extra work is not needed now that we load the basic output document as a .html file.
- global fixes to .display callsites. new syntax is obj.display (<msg>, <type>, <source>, <dest>);
- added multilineLineInputMode() function, to set the input mode state.
- added stringToMsg() function. takes a string and converts it into munged DOM nodes ready to be added to the message window.
- set the "selected" attribute on the current view tab button.
- add scrollDown() function, it's now used from addHistory and onresize.
- put a <tbody> in the <table> before adding content. (bug 70335)
- create <xul:tab>s instead of <xul:menubutton>s for the views.
- add client.load() function to load js subscripts (won't work until bug 48974 is fixed.)
- combined client, network, channel, and user.display() implementations into a single function.
munger.js:
- rename third parameter to .munge() method.
- break long words found inside text that matched other munger rules.
chatzilla.css:
- remove unused ids and classes.
- made the status data color darker. (bug 65634)
output-default.css:
- removed unused classes.
- added huge comment (read it.)
- changed color scheme.
face-*.gif:
- made the smiley faces smaller so they fit better with the small font.
#################################################################################
# 10/23/00, ChatZilla 0.7, <rginda@netscape.com>
=================================================================================
= Bugs fixed
The superbug for ChatZilla 0.7 is 57633, which fixes the following bugs:
40636, 41343, 51352, 54145, 56708, 57104, and 57138
Link to superbug: http://bugzilla.mozilla.org/show_bug.cgi?id=57633
List of bugs dependent on the superbug: http://bugzilla.mozilla.org/buglist.cgi?field0-0-0=dependson&type0-0-0=equals&value0-0-0=57633&cmdtype=doit
=================================================================================
= Changes ...
= fixed 41343, tab complete still works after part.
= fixed 56708, link to rheet.wav when someone says rheet.
= fixed 40636, delete text when simleys are matched
= fixed 57138, toolbars not collapsing correctly.
= fixed 57104, link regex was kinda lame.
= fixed 54145, link completion char should be a pref.
= fixed 51352, chatzilla should remember your nick.
= cleaned up strict mode warnings.
= adjusted menu layout to make it easier to grok (i hope.)
= added "save settings now" and "save settings on exit" menu items.
= fixed invalid xul tags (<label/>) to avoid nasty warnings.
= implemented save settings functions.
= added prefs for default network, startup urls, nickname autocomplete suffix,
= delete view after part, save settings on exit, stalk list, smiley text deletion.
= removed pref fot startup network/channel (replaced by startup urls.)
= added graphic for scc's ear emoticon (*
= made ui state (toolbar, userlist, statusbar visiblity) persist.

View File

@@ -1,97 +0,0 @@
ChatZilla: Did You Know?
The basics...
+ The networks listed in the *client* view on startup are clickable links.
Instead of typing /attach <network-name>, you can just click on one of the
links.
+ The view tabs are color coded, green means that something has happened in that
view since you last looked at it. Red means that someone has said something
to you.
+ ChatZilla will automatically highlight phrases that contain your nickname.
+ You can add to the list of words that cause messages to be highlighted with
the /stalk command. You can remove words from the list with the /unstalk
command.
+ You can quickly switch to another view using the function keys. F1 will
switch to the first view, F2 to the second, etc.
+ You can turn off the userlist, statusbar, and/or view tabs using the
File->Options menu.
+ You can see a list of commands by typing /commands.
+ You can get help on any command by typing /help <command-name>.
+ You can delete any view with the /delete command. Once deleted, the text from
that view will be lost. Deleteing a channel view is not the same as leaving
the channel. You will still be a member of the channel if you only /delete it.
It will reappear (without the previous contents) the next time activity occurs.
+ You can remove a channel or query view from the tab list without dropping its
contents. The /hide command will remove the view's tab, but keep the contents.
The next time something happens on that view, it will re-appear with the
previous text still intact.
+ You can recover deleted or hidden views. To recover a deleted *client* view,
use /client. To recover a network view use the /attach command, to recover
channel view use /join, and to recover a query view use /query.
The cool commands...
+ /networks will display the list of networks as a list of clickable links.
+ /status will show your connection status. If you use /status from a channel,
you'll get information about the network and server you are connected to,
including connection duration, and last ping and lag (if available.) You will
also get status on the channel you are viewing, including number of operators,
number voiced, and topic.
Using /status from a network view will give you information on every channel
you are connected to.
Using /status from the *client* view will give you information on every network
you are connected to, as well as every channel on that network.
+ /disconnect can be used to disconnect from a network without quitting
ChatZilla. This can be useful if you are attached to more than one network
but want to leave only one of them.
The more advanced stuff...
+ The input area can be switched to multiline mode by pressing [CTRL]+[UP].
Press [CTRL]+[ENTER] to sent the text to the server. In multiline mode,
the text you type not scanned for commands, so stray / characters will not
affect your post. To return to single line mode, press [CRTL]+[DOWN].
+ The place where messages appear can be styled to your own taste, if you
know a little css <http://www.htmlhelp.org/reference/css/>. See the comment
at the top of <http://lxr.mozilla.org/mozilla/source/extensions/irc/xul/skin/output-default.css>
for details.
+ You can manually bookmark an irc channel by creating a new irc:// bookmark.
From the "Manage bookmarks" window, create a new bookmark and enter
"irc://moznet/chatzilla", to bookmark the #chatzilla channel, for example.
You can also use a server name, as in "irc://irc.mcs.com/javascript".
+ irc:// urls work from normal web pages as well. You can link to your
irc channel from you home page. See
<http://www.w3.org/Addressing/draft-mirashi-url-irc-01.txt> for a description
of irc:// urls.
+ Turning off File->Options->Enable Smileys actually turns off all of the text
matching rules, including link detection, and bold/underline/italic. It will
also disable the part of ChatZilla that makes it possible to break long words
(ie, you'll end up with a horizontal scrollbar eventually.) This
option was added back when a few bugs in the JavaScript engine caused the
text matching rules to do Bad Things. You probably don't really want to turn
this off.

View File

@@ -1,40 +0,0 @@
#
# The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla IRC Extentions, including Basic Socket Library,
# and JSIRC Library.
#
# The Initial Developer of the Original Code is New Dimensions Consulting,
# Inc. Portions created by New Dimensions Consulting, Inc. Copyright (C) 1999
# New Dimenstions Consulting, Inc. All Rights Reserved.
#
# Contributor(s):
# Robert Ginda, rginda@ndcico.com, original author
#
# Large LED icons (green-*, red-*, yellow-*) and Marble background (xtal.jpg)
# Copyright (C) 1996, 1997 Jim Evins.
# http://www.clark.net/pub/evins/Icons/
#
# Other Icons came from "Anthony's WWW Images"
# http://www.cit.gu.edu.au/images/Images.html
#
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
EXTRA_COMPONENTS = js/lib/chatzilla-service.js
include $(topsrcdir)/config/rules.mk

View File

@@ -1,70 +0,0 @@
Using ChatZilla
Table Of Contents
Part 1: Introduction to ChatZilla.
1.1: Introduction
1.1.1: What is IRC?
1.1.2: What is ChatZilla?
1.1.3: Where do I get more information on IRC?
1.2: The User Interface.
1.2.1: Menu structure.
1.2.2: User list.
1.2.3: Output area.
1.2.4: View tabs.
1.2.5: Status bar.
1.3: Features of the input area.
1.3.1: Responding to the last person who spoke to you.
1.3.2: Autocompleting nicknames.
1.3.3: Autocompleting commands.
1.3.4: Multiline input.
Part 2: Navigating IRC with ChatZilla.
2.1: Connecting to an IRC network.
2.1.1: Listing available networks.
2.1.2: Attaching to a network.
2.1.3: Canceling an attach that isn't going well.
2.1.4: Connecting to a specific server.
2.1.5: Disconnecting when you're finished.
2.2: Channels.
2.2.1: Finding a channel.
2.2.2: Joining.
2.2.3: Modes, Topics, and Kicks.
2.2.4: Parting.
2.3: Private messages.
2.3.1: Receiving messages.
2.3.2: Sending messages.
2.3.3: Query windows.
Part 3: Scripting ChatZilla.
3.1: Scripting basics.
3.1.1: The /eval command.
3.1.2: Writing text to the output window.
3.1.3: Writing DOM nodes to the output window.
3.1.1: Exploring objects with dumpObjectTree();
3.2: More Scripting.
3.2.1: External scripts.
3.2.2: Hooking into IRC events.
Appendix A:
A: Styling the output window.
(copy of the comment in output-window.css)

View File

@@ -1,8 +0,0 @@
ChatZilla 0.8.1
smarter [tab] code (tab on empty line responds to last /msg or yournick:)
flubbed /msg detection.
optional time stamps
isnick irc:// urls
ChatZilla 0.9
Lots of prefs work, including a pref panel (finally!)

View File

@@ -1,86 +0,0 @@
THIS BRANCH IS DEAD, PLEASE STOP USING IT, HAVE A NICE DAY.
chatzilla.jar:
content/chatzilla/contents.rdf (xul/content/contents.rdf)
locale/en-US/chatzilla/contents.rdf (xul/locale/en-US/contents.rdf)
skin/modern/chatzilla/contents.rdf (xul/skin/contents.rdf)
content/chatzilla/lib/js/utils.js (js/lib/utils.js)
content/chatzilla/lib/js/events.js (js/lib/events.js)
content/chatzilla/lib/js/connection-xpcom.js (js/lib/connection-xpcom.js)
content/chatzilla/lib/js/command-manager.js (js/lib/command-manager.js)
content/chatzilla/lib/js/command-manager.js (js/lib/command-manager.js)
content/chatzilla/lib/js/pref-manager.js (js/lib/pref-manager.js)
content/chatzilla/lib/js/message-manager.js (js/lib/message-manager.js)
content/chatzilla/lib/js/menu-manager.js (js/lib/menu-manager.js)
content/chatzilla/lib/js/irc.js (js/lib/irc.js)
content/chatzilla/lib/js/irc-debug.js (js/lib/irc-debug.js)
content/chatzilla/lib/js/file-utils.js (js/lib/file-utils.js)
content/chatzilla/lib/xul/munger.js (xul/lib/munger.js)
content/chatzilla/chatzilla.xul (xul/content/chatzilla.xul)
content/chatzilla/scripts.xul (xul/content/scripts.xul)
content/chatzilla/menus.xul (xul/content/menus.xul)
content/chatzilla/popups.xul (xul/content/popups.xul)
content/chatzilla/output-window.html (xul/content/output-window.html)
content/chatzilla/output-window.js (xul/content/output-window.js)
content/chatzilla/commands.js (xul/content/commands.js)
content/chatzilla/handlers.js (xul/content/handlers.js)
content/chatzilla/prefs.js (xul/content/prefs.js)
content/chatzilla/messages.js (xul/content/messages.js)
content/chatzilla/menus.js (xul/content/menus.js)
content/chatzilla/static.js (xul/content/static.js)
content/chatzilla/rdf.js (xul/content/rdf.js)
content/chatzilla/dynamic.css (xul/content/dynamic.css)
content/chatzilla/output-base.css (xul/content/output-base.css)
content/chatzilla/chatzillaOverlay.xul (xul/content/chatzillaOverlay.xul)
content/chatzilla/chatzillaOverlay.js (xul/content/chatzillaOverlay.js)
content/chatzilla/prefsOverlay.xul (xul/content/prefsOverlay.xul)
content/chatzilla/prefpanel/pref-irc.xul (xul/content/prefpanel/pref-irc.xul)
content/chatzilla/prefpanel/pref-irc.js (xul/content/prefpanel/pref-irc.js)
content/chatzilla/prefpanel/appearance.js (xul/content/prefpanel/appearance.js)
content/chatzilla/prefpanel/appearance.css (xul/content/prefpanel/appearance.css)
content/chatzilla/prefpanel/appearance.xul (xul/content/prefpanel/appearance.xul)
content/chatzilla/prefpanel/interface.js (xul/content/prefpanel/interface.js)
content/chatzilla/prefpanel/interface.xul (xul/content/prefpanel/interface.xul)
content/chatzilla/prefpanel/sound.js (xul/content/prefpanel/sound.js)
content/chatzilla/prefpanel/sound.xul (xul/content/prefpanel/sound.xul)
content/chatzilla/prefpanel/stalk.js (xul/content/prefpanel/stalk.js)
content/chatzilla/prefpanel/stalk.xul (xul/content/prefpanel/stalk.xul)
content/chatzilla/prefpanel/startup.js (xul/content/prefpanel/startup.js)
content/chatzilla/prefpanel/startup.xul (xul/content/prefpanel/startup.xul)
content/chatzilla/prefpanel/startup-newScript.js (xul/content/prefpanel/startup-newScript.js)
content/chatzilla/prefpanel/startup-newScript.xul (xul/content/prefpanel/startup-newScript.xul)
content/chatzilla/prefpanel/startup-newURL.js (xul/content/prefpanel/startup-newURL.js)
content/chatzilla/prefpanel/startup-newURL.xul (xul/content/prefpanel/startup-newURL.xul)
content/chatzilla/prefpanel/appearance-previewCSS.html (xul/content/prefpanel/appearance-previewCSS.html)
content/chatzilla/prefpanel/appearance-previewCSS.js (xul/content/prefpanel/appearance-previewCSS.js)
content/chatzilla/prefpanel/appearance-previewCSS.xul (xul/content/prefpanel/appearance-previewCSS.xul)
content/chatzilla/prefpanel/tabs.xul (xul/content/prefpanel/tabs.xul)
content/chatzilla/prefpanel/text.xul (xul/content/prefpanel/text.xul)
skin/modern/chatzilla/chatzilla.css (xul/skin/chatzilla.css)
skin/modern/chatzilla/chatzillaOverlay.css (xul/skin/chatzillaOverlay.css)
skin/modern/chatzilla/output-default.css (xul/skin/output-default.css)
skin/modern/chatzilla/output-light.css (xul/skin/output-light.css)
skin/modern/chatzilla/output-dark.css (xul/skin/output-dark.css)
skin/modern/chatzilla/images/face-ear.gif (xul/skin/images/face-ear.gif)
skin/modern/chatzilla/images/face-frown.gif (xul/skin/images/face-frown.gif)
skin/modern/chatzilla/images/face-tongue.gif (xul/skin/images/face-tongue.gif)
skin/modern/chatzilla/images/face-angry.gif (xul/skin/images/face-angry.gif)
skin/modern/chatzilla/images/face-screw.gif (xul/skin/images/face-screw.gif)
skin/modern/chatzilla/images/face-wink.gif (xul/skin/images/face-wink.gif)
skin/modern/chatzilla/images/face-cry.gif (xul/skin/images/face-cry.gif)
skin/modern/chatzilla/images/face-smile.gif (xul/skin/images/face-smile.gif)
skin/modern/chatzilla/images/face-dunno.gif (xul/skin/images/face-dunno.gif)
skin/modern/chatzilla/images/face-surprise.gif (xul/skin/images/face-surprise.gif)
skin/modern/chatzilla/images/is-op.gif (xul/skin/images/is-op.gif)
skin/modern/chatzilla/images/isnt-op.gif (xul/skin/images/isnt-op.gif)
skin/modern/chatzilla/images/is-voice.gif (xul/skin/images/is-voice.gif)
skin/modern/chatzilla/images/isnt-voice.gif (xul/skin/images/isnt-voice.gif)
skin/modern/chatzilla/images/taskbar-irc.gif (xul/skin/images/taskbar-irc.gif)
skin/modern/chatzilla/images/chatzilla-16.gif (xul/skin/images/chatzilla-16.gif)
skin/modern/chatzilla/images/multiline-expand.png (xul/skin/images/multiline-expand.png)
skin/modern/chatzilla/images/multiline-contract.png (xul/skin/images/multiline-contract.png)
skin/modern/chatzilla/images/input-send.png (xul/skin/images/input-send.png)
locale/en-US/chatzilla/chatzillaOverlay.dtd (xul/locale/en-US/chatzillaOverlay.dtd)
locale/en-US/chatzilla/chatzilla.dtd (xul/locale/en-US/chatzilla.dtd)
locale/en-US/chatzilla/chatzilla.properties (xul/locale/en-US/chatzilla.properties)
locale/en-US/chatzilla/pref-irc.dtd (xul/locale/en-US/pref-irc.dtd)

View File

@@ -1,363 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Seth Spitzer <sspitzer@netscape.com>
* Robert Ginda <rginda@netscape.com>
*/
/*
* This file contains the following chatzilla related components:
* 1. Command line handler service, for responding to the -chat command line
* option. (CLineHandler)
* 2. Content handler for responding to content of type x-application-irc
* (IRCContentHandler)
* 3. Protocol handler for supplying a channel to the browser when an irc://
* link is clicked. (IRCProtocolHandler)
* 4. A (nearly empty) imeplementation of nsIChannel for telling the browser
* that irc:// links have the content type x-application-irc (BogusChannel)
*/
/* components defined in this file */
const CLINE_SERVICE_CONTRACTID =
"@mozilla.org/commandlinehandler/general-startup;1?type=chat";
const CLINE_SERVICE_CID =
Components.ID("{38a95514-1dd2-11b2-97e7-9da958640f2c}");
const IRCCNT_HANDLER_CONTRACTID =
"@mozilla.org/uriloader/content-handler;1?type=x-application-irc";
const IRCCNT_HANDLER_CID =
Components.ID("{98919a14-1dd1-11b2-be1a-b84344307f0a}");
const IRCPROT_HANDLER_CONTRACTID =
"@mozilla.org/network/protocol;1?name=irc";
const IRCPROT_HANDLER_CID =
Components.ID("{f21c35f4-1dd1-11b2-a503-9bf8a539ea39}");
/* components used in this file */
const MEDIATOR_CONTRACTID =
"@mozilla.org/appshell/window-mediator;1";
const STANDARDURL_CONTRACTID =
"@mozilla.org/network/standard-url;1";
const IOSERVICE_CONTRACTID =
"@mozilla.org/network/io-service;1";
const ASS_CONTRACTID =
"@mozilla.org/appshell/appShellService;1";
/* interafces used in this file */
const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
const nsICmdLineHandler = Components.interfaces.nsICmdLineHandler;
const nsICategoryManager = Components.interfaces.nsICategoryManager;
const nsIContentHandler = Components.interfaces.nsIContentHandler;
const nsIProtocolHandler = Components.interfaces.nsIProtocolHandler;
const nsIURI = Components.interfaces.nsIURI;
const nsIStandardURL = Components.interfaces.nsIStandardURL;
const nsIChannel = Components.interfaces.nsIChannel;
const nsIRequest = Components.interfaces.nsIRequest;
const nsIIOService = Components.interfaces.nsIIOService;
const nsIAppShellService = Components.interfaces.nsIAppShellService;
const nsISupports = Components.interfaces.nsISupports;
/* Command Line handler service */
function CLineService()
{}
CLineService.prototype.commandLineArgument = "-chat";
CLineService.prototype.prefNameForStartup = "general.startup.chat";
CLineService.prototype.chromeUrlForTask = "chrome://chatzilla/content";
CLineService.prototype.helpText = "Start with an IRC chat client";
CLineService.prototype.handlesArgs = false;
CLineService.prototype.defaultArgs = "";
CLineService.prototype.openWindowWithArgs = false;
/* factory for command line handler service (CLineService) */
var CLineFactory = new Object();
CLineFactory.createInstance =
function (outer, iid)
{
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (!iid.equals(nsICmdLineHandler) && !iid.equals(nsISupports))
throw Components.results.NS_ERROR_INVALID_ARG;
return new CLineService();
}
/* x-application-irc content handler */
function IRCContentHandler ()
{}
IRCContentHandler.prototype.QueryInterface =
function (iid)
{
if (!iid.equals(nsIContentHandler))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
IRCContentHandler.prototype.handleContent =
function (contentType, command, windowTarget, request)
{
var e;
var channel = request.QueryInterface(nsIChannel);
var windowManager =
Components.classes[MEDIATOR_CONTRACTID].getService(nsIWindowMediator);
var w = windowManager.getMostRecentWindow("irc:chatzilla");
if (w)
{
w.focus();
w.gotoIRCURL(channel.URI.spec);
}
else
{
var ass =
Components.classes[ASS_CONTRACTID].getService(nsIAppShellService);
w = ass.hiddenDOMWindow;
var args = new Object ();
args.url = channel.URI.spec;
w.openDialog("chrome://chatzilla/content/chatzilla.xul", "_blank",
"chrome,menubar,toolbar,status,resizable,dialog=no",
args);
}
}
/* content handler factory object (IRCContentHandler) */
var IRCContentHandlerFactory = new Object();
IRCContentHandlerFactory.createInstance =
function (outer, iid)
{
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (!iid.equals(nsIContentHandler) && !iid.equals(nsISupports))
throw Components.results.NS_ERROR_INVALID_ARG;
return new IRCContentHandler();
}
/* irc protocol handler component */
function IRCProtocolHandler()
{
}
IRCProtocolHandler.prototype.scheme = "irc";
IRCProtocolHandler.prototype.defaultPort = 6667;
IRCProtocolHandler.prototype.protocolFlags =
nsIProtocolHandler.URI_NORELATIVE |
nsIProtocolHandler.ALLOWS_PROXY;
IRCProtocolHandler.prototype.allowPort =
function (port, scheme)
{
return false;
}
IRCProtocolHandler.prototype.newURI =
function (spec, charset, baseURI)
{
var cls = Components.classes[STANDARDURL_CONTRACTID];
var url = cls.createInstance(nsIStandardURL);
url.init(nsIStandardURL.URLTYPE_STANDARD, 6667, spec, charset, baseURI);
return url.QueryInterface(nsIURI);
}
IRCProtocolHandler.prototype.newChannel =
function (URI)
{
ios = Components.classes[IOSERVICE_CONTRACTID].getService(nsIIOService);
if (!ios.allowPort(URI.port, URI.scheme))
throw Components.results.NS_ERROR_FAILURE;
return new BogusChannel (URI);
}
/* protocol handler factory object (IRCProtocolHandler) */
var IRCProtocolHandlerFactory = new Object();
IRCProtocolHandlerFactory.createInstance =
function (outer, iid)
{
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (!iid.equals(nsIProtocolHandler) && !iid.equals(nsISupports))
throw Components.results.NS_ERROR_INVALID_ARG;
return new IRCProtocolHandler();
}
/* bogus IRC channel used by the IRCProtocolHandler */
function BogusChannel (URI)
{
this.URI = URI;
this.originalURI = URI;
}
BogusChannel.prototype.QueryInterface =
function (iid)
{
if (!iid.equals(nsIChannel) && !iid.equals(nsIRequest) &&
!iid.equals(nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
/* nsIChannel */
BogusChannel.prototype.loadAttributes = null;
BogusChannel.prototype.contentType = "x-application-irc";
BogusChannel.prototype.contentLength = 0;
BogusChannel.prototype.owner = null;
BogusChannel.prototype.loadGroup = null;
BogusChannel.prototype.notificationCallbacks = null;
BogusChannel.prototype.securityInfo = null;
BogusChannel.prototype.open =
BogusChannel.prototype.asyncOpen =
function ()
{
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
}
BogusChannel.prototype.asyncOpen =
function (observer, ctxt)
{
observer.onStartRequest (this, ctxt);
}
BogusChannel.prototype.asyncRead =
function (listener, ctxt)
{
return listener.onStartRequest (this, ctxt);
}
/* nsIRequest */
BogusChannel.prototype.isPending =
function ()
{
return true;
}
BogusChannel.prototype.status = Components.results.NS_OK;
BogusChannel.prototype.cancel =
function (status)
{
this.status = status;
}
BogusChannel.prototype.suspend =
BogusChannel.prototype.resume =
function ()
{
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
}
var ChatzillaModule = new Object();
ChatzillaModule.registerSelf =
function (compMgr, fileSpec, location, type)
{
debug("*** Registering -chat handler.\n");
compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
compMgr.registerFactoryLocation(CLINE_SERVICE_CID,
"Chatzilla CommandLine Service",
CLINE_SERVICE_CONTRACTID,
fileSpec,
location,
type);
catman = Components.classes["@mozilla.org/categorymanager;1"]
.getService(nsICategoryManager);
catman.addCategoryEntry("command-line-argument-handlers",
"chatzilla command line handler",
CLINE_SERVICE_CONTRACTID, true, true);
debug("*** Registering x-application-irc handler.\n");
compMgr.registerFactoryLocation(IRCCNT_HANDLER_CID,
"IRC Content Handler",
IRCCNT_HANDLER_CONTRACTID,
fileSpec,
location,
type);
debug("*** Registering irc protocol handler.\n");
compMgr.registerFactoryLocation(IRCPROT_HANDLER_CID,
"IRC protocol handler",
IRCPROT_HANDLER_CONTRACTID,
fileSpec,
location,
type);
}
ChatzillaModule.unregisterSelf =
function(compMgr, fileSpec, location)
{
compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
compMgr.unregisterFactoryLocation(CLINE_SERVICE_CID,
fileSpec);
catman = Components.classes["@mozilla.org/categorymanager;1"]
.getService(nsICategoryManager);
catman.deleteCategoryEntry("command-line-argument-handlers",
CLINE_SERVICE_CONTRACTID, true);
}
ChatzillaModule.getClassObject =
function (compMgr, cid, iid)
{
if (cid.equals(CLINE_SERVICE_CID))
return CLineFactory;
if (cid.equals(IRCCNT_HANDLER_CID))
return IRCContentHandlerFactory;
if (cid.equals(IRCPROT_HANDLER_CID))
return IRCProtocolHandlerFactory;
if (!iid.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
ChatzillaModule.canUnload =
function(compMgr)
{
return true;
}
/* entrypoint */
function NSGetModule(compMgr, fileSpec)
{
return ChatzillaModule;
}

View File

@@ -1,842 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*/
function getAccessKey (str)
{
var i = str.indexOf("&");
if (i == -1)
return "";
return str[i + 1];
}
function CommandRecord (name, func, usage, help, label, flags, keystr, tip,
format)
{
this.name = name;
this.func = func;
this._usage = usage;
this.scanUsage();
this.help = help;
this.label = label ? label : name;
this.format = format;
this.labelstr = label.replace ("&", "");
this.tip = tip;
this.flags = flags;
this._enabled = true;
this.keyNodes = new Array();
this.keystr = keystr;
this.uiElements = new Array();
}
CommandRecord.prototype.__defineGetter__ ("enabled", cr_getenable);
function cr_getenable ()
{
return this._enabled;
}
CommandRecord.prototype.__defineSetter__ ("enabled", cr_setenable);
function cr_setenable (state)
{
for (var i = 0; i < this.uiElements.length; ++i)
{
if (state)
this.uiElements[i].removeAttribute ("disabled");
else
this.uiElements[i].setAttribute ("disabled", "true");
}
return (this._enabled = state);
}
CommandRecord.prototype.__defineSetter__ ("usage", cr_setusage);
function cr_setusage (usage)
{
this._usage = usage;
this.scanUsage();
}
CommandRecord.prototype.__defineGetter__ ("usage", cr_getusage);
function cr_getusage()
{
return this._usage;
}
/**
* Internal use only.
*
* Scans the argument spec, in the format "<a1> <a2> [<o1> <o2>]", into an
* array of strings.
*/
CommandRecord.prototype.scanUsage =
function cr_scanusage()
{
var spec = this._usage;
var currentName = "";
var inName = false;
var len = spec.length;
var capNext = false;
this._usage = spec;
this.argNames = new Array();
for (var i = 0; i < len; ++i)
{
switch (spec[i])
{
case '[':
this.argNames.push (":");
break;
case '<':
inName = true;
break;
case '-':
capNext = true;
break;
case '>':
inName = false;
this.argNames.push (currentName);
currentName = "";
capNext = false;
break;
default:
if (inName)
currentName += capNext ? spec[i].toUpperCase() : spec[i];
capNext = false;
break;
}
}
}
/**
* Returns the command formatted for presentation as part of online
* documentation.
*/
CommandRecord.prototype.getDocumentation =
function cr_getdocs(flagFormatter)
{
var str;
str = getMsg(MSG_DOC_COMMANDLABEL,
[this.label.replace("&", ""), this.name]) + "\n";
str += getMsg(MSG_DOC_KEY, this.keystr ? this.keystr : MSG_VAL_NA) + "\n";
str += getMsg(MSG_DOC_SYNTAX, [this.name, this.usage]) + "\n";
str += MSG_DOC_NOTES + "\n";
str += (flagFormatter ? flagFormatter(this.flags) : this.flags) + "\n\n";
str += MSG_DOC_DESCRIPTION + "\n";
str += wrapText(this.help, 75) + "\n";
return str;
}
CommandRecord.prototype.argNames = new Array();
function CommandManager (defaultBundle)
{
this.commands = new Object();
this.defaultBundle = defaultBundle;
}
CommandManager.prototype.defaultFlags = 0;
CommandManager.prototype.defineCommands =
function cmgr_defcmds (cmdary)
{
var len = cmdary.length;
var commands = new Object();
var bundle = "stringBundle" in cmdary ? cmdary.stringBundle : null;
for (var i = 0; i < len; ++i)
{
var name = cmdary[i][0];
var func = cmdary[i][1];
var flags = cmdary[i][2];
var usage;
if (3 in cmdary[i])
usage = cmdary[i][3];
var command = this.defineCommand(name, func, flags, usage, bundle);
commands[name] = command;
}
return commands;
}
CommandManager.prototype.defineCommand =
function cmdmgr_defcmd (name, func, flags, usage, bundle)
{
if (!bundle)
bundle = this.defaultBundle;
var helpDefault;
var labelDefault = name;
var aliasFor;
if (typeof flags != "number")
flags = this.defaultFlags;
if (flags & CMD_NO_HELP)
helpDefault = MSG_NO_HELP;
if (typeof usage != "string")
usage = getMsgFrom(bundle, "cmd." + name + ".params", null, "");
if (typeof func == "string")
{
var ary = func.match(/(\S+)/);
if (ary)
aliasFor = ary[1];
else
aliasFor = null;
helpDefault = getMsg (MSG_DEFAULT_ALIAS_HELP, func);
if (aliasFor)
labelDefault = getMsgFrom (bundle, "cmd." + aliasFor + ".label",
null, name);
}
var label = getMsgFrom(bundle, "cmd." + name + ".label", null,
labelDefault);
var help = getMsgFrom(bundle, "cmd." + name + ".help", null,
helpDefault);
var keystr = getMsgFrom (bundle, "cmd." + name + ".key", null, "");
var format = getMsgFrom (bundle, "cmd." + name + ".format", null, null);
var tip = getMsgFrom (bundle, "cmd." + name + ".tip", null, "");
var command = new CommandRecord (name, func, usage, help, label, flags,
keystr, tip, format);
this.addCommand(command);
if (aliasFor)
command.aliasFor = aliasFor;
return command;
}
CommandManager.prototype.installKeys =
function cmgr_instkeys (document, commands)
{
var parentElem = document.getElementById("dynamic-keys");
if (!parentElem)
{
parentElem = document.createElement("keyset");
parentElem.setAttribute ("id", "dynamic-keys");
document.firstChild.appendChild (parentElem);
}
if (!commands)
commands = this.commands;
for (var c in commands)
this.installKey (parentElem, commands[c]);
}
/**
* Create a <key> node relative to a DOM node. Usually called once per command,
* per document, so that accelerator keys work in all application windows.
*
* @param parentElem A reference to the DOM node which should contain the new
* <key> node.
* @param command reference to the CommandRecord to install.
*/
CommandManager.prototype.installKey =
function cmgr_instkey (parentElem, command)
{
if (!command.keystr)
return;
var ary = command.keystr.match (/(.*\s)?([\S]+)$/);
if (!ASSERT(ary, "couldn't parse key string ``" + command.keystr +
"'' for command ``" + command.name + "''"))
{
return;
}
var key = document.createElement ("key");
key.setAttribute ("id", "key:" + command.name);
key.setAttribute ("oncommand", "dispatch('" + command.name +
"', {isInteractive: true});");
key.setAttribute ("modifiers", ary[1]);
if (ary[2].indexOf("VK_") == 0)
key.setAttribute ("keycode", ary[2]);
else
key.setAttribute ("key", ary[2]);
parentElem.appendChild(key);
command.keyNodes.push(key);
}
CommandManager.prototype.uninstallKeys =
function cmgr_uninstkeys (commands)
{
if (!commands)
commands = this.commands;
for (var c in commands)
this.uninstallKey (commands[c]);
}
CommandManager.prototype.uninstallKey =
function cmgr_uninstkey (command)
{
for (var i in command.keyNodes)
{
try
{
/* document may no longer exist in a useful state. */
command.keyNodes[i].parentNode.removeChild(command.keyNodes[i]);
}
catch (ex)
{
dd ("*** caught exception uninstalling key node: " + ex);
}
}
}
/**
* Register a new command with the manager.
*/
CommandManager.prototype.addCommand =
function cmgr_add (command)
{
this.commands[command.name] = command;
}
CommandManager.prototype.removeCommands =
function cmgr_removes (commands)
{
for (var c in commands)
this.removeCommand(commands[c]);
}
CommandManager.prototype.removeCommand =
function cmgr_remove (command)
{
delete this.commands[command.name];
}
/**
* Register a hook for a particular command name. |id| is a human readable
* identifier for the hook, and can be used to unregister the hook. If you
* re-use a hook id, the previous hook function will be replaced.
* If |before| is |true|, the hook will be called *before* the command executes,
* if |before| is |false|, or not specified, the hook will be called *after*
* the command executes.
*/
CommandManager.prototype.addHook =
function cmgr_hook (commandName, func, id, before)
{
if (!ASSERT(commandName in this.commands,
"Unknown command '" + commandName + "'"))
{
return;
}
var command = this.commands[commandName];
if (before)
{
if (!("beforeHooks" in command))
command.beforeHooks = new Object();
command.beforeHooks[id] = func;
}
else
{
if (!("afterHooks" in command))
command.afterHooks = new Object();
command.afterHooks[id] = func;
}
}
CommandManager.prototype.addHooks =
function cmgr_hooks (hooks, prefix)
{
if (!prefix)
prefix = "";
for (var h in hooks)
{
this.addHook(h, hooks[h], prefix + ":" + h,
("_before" in hooks[h]) ? hooks[h]._before : false);
}
}
CommandManager.prototype.removeHooks =
function cmgr_remhooks (hooks, prefix)
{
if (!prefix)
prefix = "";
for (var h in hooks)
{
this.removeHook(h, prefix + ":" + h,
("before" in hooks[h]) ? hooks[h].before : false);
}
}
CommandManager.prototype.removeHook =
function cmgr_unhook (commandName, id, before)
{
var command = this.commands[commandName];
if (before)
delete command.beforeHooks[id];
else
delete command.afterHooks[id];
}
/**
* Return an array of all CommandRecords which start with the string
* |partialName|, sorted by |label| property.
*
* @param partialName Prefix to search for.
* @param flags logical ANDed with command flags.
* @returns array Array of matching commands, sorted by |label| property.
*/
CommandManager.prototype.list =
function cmgr_list (partialName, flags)
{
/* returns array of command objects which look like |partialName|, or
* all commands if |partialName| is not specified */
function compare (a, b)
{
a = a.labelstr.toLowerCase();
b = b.labelstr.toLowerCase();
if (a == b)
return 0;
if (a > b)
return 1;
return -1;
}
var ary = new Array();
var commandNames = keys(this.commands);
/* a command named "eval" wouldn't show up in the result of keys() because
* eval is not-enumerable, even if overwritten. */
if ("eval" in this.commands && typeof this.commands.eval == "object")
commandNames.push ("eval");
for (var i in commandNames)
{
var name = commandNames[i];
if (!flags || (this.commands[name].flags & flags))
{
if (!partialName ||
this.commands[name].name.indexOf(partialName) == 0)
{
if (partialName &&
partialName.length == this.commands[name].name.length)
{
/* exact match */
return [this.commands[name]];
}
else
{
ary.push (this.commands[name]);
}
}
}
}
ary.sort(compare);
return ary;
}
/**
* Return a sorted array of the command names which start with the string
* |partialName|.
*
* @param partialName Prefix to search for.
* @param flags logical ANDed with command flags.
* @returns array Sorted Array of matching command names.
*/
CommandManager.prototype.listNames =
function cmgr_listnames (partialName, flags)
{
var cmds = this.list(partialName, flags);
var cmdNames = new Array();
for (var c in cmds)
cmdNames.push (cmds[c].name);
cmdNames.sort();
return cmdNames;
}
/**
* Internal use only.
*
* Called to parse the arguments stored in |e.inputData|, as properties of |e|,
* for the CommandRecord stored on |e.command|.
*
* @params e Event object to be processed.
*/
CommandManager.prototype.parseArguments =
function cmgr_parseargs (e)
{
var rv = this.parseArgumentsRaw(e);
//dd("parseArguments '" + e.command.usage + "' " +
// (rv ? "passed" : "failed") + "\n" + dumpObjectTree(e));
delete e.currentArgIndex;
return rv;
}
/**
* Internal use only.
*
* Don't call parseArgumentsRaw directly, use parseArguments instead.
*
* Parses the arguments stored in the |inputData| property of the event object,
* according to the format specified by the |command| property.
*
* On success this method returns true, and propery names corresponding to the
* argument names used in the format spec will be created on the event object.
* All optional parameters will be initialized to |null| if not already present
* on the event.
*
* On failure this method returns false and a description of the problem
* will be stored in the |parseError| property of the event.
*
* For example...
* Given the argument spec "<int> <word> [ <word2> <word3> ]", and given the
* input string "411 foo", stored as |e.command.usage| and |e.inputData|
* respectively, this method would add the following propertys to the event
* object...
* -name---value--notes-
* e.int 411 Parsed as an integer
* e.word foo Parsed as a string
* e.word2 null Optional parameters not specified will be set to null.
* e.word3 null If word2 had been provided, word3 would be required too.
*
* Each parameter is parsed by calling the function with the same name, located
* in this.argTypes. The first parameter is parsed by calling the function
* this.argTypes["int"], for example. This function is expected to act on
* e.unparsedData, taking it's chunk, and leaving the rest of the string.
* The default parse functions are...
* <word> parses contiguous non-space characters.
* <int> parses as an int.
* <rest> parses to the end of input data.
* <state> parses yes, on, true, 1, 0, false, off, no as a boolean.
* <toggle> parses like a <state>, except allows "toggle" as well.
* <...> parses according to the parameter type before it, until the end
* of the input data. Results are stored in an array named
* paramnameList, where paramname is the name of the parameter
* before <...>. The value of the parameter before this will be
* paramnameList[0].
*
* If there is no parse function for an argument type, "word" will be used by
* default. You can alias argument types with code like...
* commandManager.argTypes["my-integer-name"] = commandManager.argTypes["int"];
*/
CommandManager.prototype.parseArgumentsRaw =
function parse_parseargsraw (e)
{
var argc = e.command.argNames.length;
function initOptionals()
{
for (var i = 0; i < argc; ++i)
{
if (e.command.argNames[i] != ":" &&
e.command.argNames[i] != "..." &&
!(e.command.argNames[i] in e))
{
e[e.command.argNames[i]] = null;
}
if (e.command.argNames[i] == "...")
{
var paramName = e.command.argNames[i - 1];
if (paramName == ":")
paramName = e.command.argNames[i - 2];
var listName = paramName + "List";
if (!(listName in e))
e[listName] = [ e[paramName] ];
}
}
}
if ("inputData" in e && e.inputData)
{
/* if data has been provided, parse it */
e.unparsedData = e.inputData;
var parseResult;
var currentArg;
e.currentArgIndex = 0;
if (argc)
{
currentArg = e.command.argNames[e.currentArgIndex];
while (e.unparsedData)
{
if (currentArg != ":")
{
if (!this.parseArgument (e, currentArg))
return false;
}
if (++e.currentArgIndex < argc)
currentArg = e.command.argNames[e.currentArgIndex];
else
break;
}
if (e.currentArgIndex < argc && currentArg != ":")
{
/* parse loop completed because it ran out of data. We haven't
* parsed all of the declared arguments, and we're not stopped
* at an optional marker, so we must be missing something
* required... */
e.parseError = getMsg(MSG_ERR_REQUIRED_PARAM,
e.command.argNames[e.currentArgIndex]);
return false;
}
}
if (e.unparsedData)
{
/* parse loop completed with unparsed data, which means we've
* successfully parsed all arguments declared. Whine about the
* extra data... */
display (getMsg(MSG_EXTRA_PARAMS, e.unparsedData), MT_WARN);
}
}
var rv = this.isCommandSatisfied(e);
if (rv)
initOptionals();
return rv;
}
/**
* Returns true if |e| has the properties required to call the command
* |command|.
*
* If |command| is not provided, |e.command| is used instead.
*
* @param e Event object to test against the command.
* @param command Command to test.
*/
CommandManager.prototype.isCommandSatisfied =
function cmgr_isok (e, command)
{
if (typeof command == "undefined")
command = e.command;
else if (typeof command == "string")
command = this.commands[command];
if (!command.enabled)
return false;
for (var i = 0; i < command.argNames.length; ++i)
{
if (command.argNames[i] == ":")
return true;
if (!(command.argNames[i] in e))
{
e.parseError = getMsg(MSG_ERR_REQUIRED_PARAM, command.argNames[i]);
//dd("command '" + command.name + "' unsatisfied: " + e.parseError);
return false;
}
}
//dd ("command '" + command.name + "' satisfied.");
return true;
}
/**
* Internal use only.
* See parseArguments above and the |argTypes| object below.
*
* Parses the next argument by calling an appropriate parser function, or the
* generic "word" parser if none other is found.
*
* @param e event object.
* @param name property name to use for the parse result.
*/
CommandManager.prototype.parseArgument =
function cmgr_parsearg (e, name)
{
var parseResult;
if (name in this.argTypes)
parseResult = this.argTypes[name](e, name, this);
else
parseResult = this.argTypes["word"](e, name, this);
if (!parseResult)
e.parseError = getMsg(MSG_ERR_INVALID_PARAM,
[name, e.unparsedData]);
return parseResult;
}
CommandManager.prototype.argTypes = new Object();
/**
* Convenience function used to map a list of new types to an existing parse
* function.
*/
CommandManager.prototype.argTypes.__aliasTypes__ =
function at_alias (list, type)
{
for (var i in list)
{
this[list[i]] = this[type];
}
}
/**
* Internal use only.
*
* Parses an integer, stores result in |e[name]|.
*/
CommandManager.prototype.argTypes["int"] =
function parse_int (e, name)
{
var ary = e.unparsedData.match (/(\d+)(?:\s+(.*))?$/);
if (!ary)
return false;
e[name] = Number(ary[1]);
e.unparsedData = (2 in ary) ? ary[2] : "";
return true;
}
/**
* Internal use only.
*
* Parses a word, which is defined as a list of nonspace characters.
*
* Stores result in |e[name]|.
*/
CommandManager.prototype.argTypes["word"] =
function parse_word (e, name)
{
var ary = e.unparsedData.match (/(\S+)(?:\s+(.*))?$/);
if (!ary)
return false;
e[name] = ary[1];
e.unparsedData = (2 in ary) ? ary[2] : "";
return true;
}
/**
* Internal use only.
*
* Parses a "state" which can be "true", "on", "yes", or 1 to indicate |true|,
* or "false", "off", "no", or 0 to indicate |false|.
*
* Stores result in |e[name]|.
*/
CommandManager.prototype.argTypes["state"] =
function parse_state (e, name)
{
var ary =
e.unparsedData.match (/(true|on|yes|1|false|off|no|0)(?:\s+(.*))?$/i);
if (!ary)
return false;
if (ary[1].search(/true|on|yes|1/i) != -1)
e[name] = true;
else
e[name] = false;
e.unparsedData = (2 in ary) ? ary[2] : "";
return true;
}
/**
* Internal use only.
*
* Parses a "toggle" which can be "true", "on", "yes", or 1 to indicate |true|,
* or "false", "off", "no", or 0 to indicate |false|. In addition, the string
* "toggle" is accepted, in which case |e[name]| will be the string "toggle".
*
* Stores result in |e[name]|.
*/
CommandManager.prototype.argTypes["toggle"] =
function parse_toggle (e, name)
{
var ary = e.unparsedData.match
(/(toggle|true|on|yes|1|false|off|no|0)(?:\s+(.*))?$/i);
if (!ary)
return false;
if (ary[1].search(/toggle/i) != -1)
e[name] = "toggle";
else if (ary[1].search(/true|on|yes|1/i) != -1)
e[name] = true;
else
e[name] = false;
e.unparsedData = (2 in ary) ? ary[2] : "";
return true;
}
/**
* Internal use only.
*
* Returns all unparsed data to the end of the line.
*
* Stores result in |e[name]|.
*/
CommandManager.prototype.argTypes["rest"] =
function parse_rest (e, name)
{
e[name] = e.unparsedData;
e.unparsedData = "";
return true;
}
/**
* Internal use only.
*
* Parses the rest of the unparsed data the same way the previous argument was
* parsed. Can't be used as the first parameter. if |name| is "..." then the
* name of the previous argument, plus the suffix "List" will be used instead.
*
* Stores result in |e[name]| or |e[lastName + "List"]|.
*/
CommandManager.prototype.argTypes["..."] =
function parse_repeat (e, name, cm)
{
ASSERT (e.currentArgIndex > 0, "<...> can't be the first argument.");
var lastArg = e.command.argNames[e.currentArgIndex - 1];
if (lastArg == ":")
lastArg = e.command.argNames[e.currentArgIndex - 2];
var listName = lastArg + "List";
e[listName] = [ e[lastArg] ];
while (e.unparsedData)
{
if (!cm.parseArgument(e, lastArg))
return false;
e[listName].push(e[lastArg]);
}
e[lastArg] = e[listName][0];
return true;
}

View File

@@ -1,136 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
* Patrick C. Beard <beard@netscape.com,
*
* wrapper for Rhino that uses Java networking.
*
*/
function CBSConnection ()
{
this._socket = null;
}
CBSConnection.prototype.connect = function(host, port, bind, tcp_flag)
{
if (typeof tcp_flag == "undefined")
tcp_flag = false;
this.host = host;
this.port = port;
this.bind = bind;
this.tcp_flag = tcp_flag;
this._socket = new java.net.Socket(host, port);
this._inputStream = this._socket.getInputStream();
this._outputStream = new java.io.PrintStream(this._socket.getOutputStream());
// create a 512 byte buffer for reading into.
this._buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 512);
dd("connected to " + host);
this.isConnected = true;
return this.isConnected;
}
CBSConnection.prototype.disconnect = function()
{
if (this.isConnected) {
this.isConnected = false;
this._socket.close();
delete this._socket;
delete this._inputStream;
delete this._outputStream;
}
}
CBSConnection.prototype.sendData = function(str)
{
// dd ("sendData: str=" + str);
if (!this.isConnected)
throw "Not Connected.";
var rv = false;
try
{
/* var s = new java.lang.String (str);
b = s.getBytes();
this._outputStream.write(b, 0, b.length); */
this._outputStream.print(str);
rv = true;
}
catch (ex)
{
dd ("write caught exception " + ex + ".");
if (typeof ex != "undefined")
{
this.isConnected = false;
throw (ex);
}
else
rv = false;
}
return rv;
}
CBSConnection.prototype.readData = function(timeout)
{
if (!this.isConnected)
throw "Not Connected.";
var rv;
// dd ("readData: timeout " + timeout);
try {
this._socket.setSoTimeout(Number(timeout));
var len = this._inputStream.read(this._buffer);
// dd ("read done, len = " + len + ", buffer = " + this._buffer);
rv = String(new java.lang.String(this._buffer, 0, 0, len));
} catch (ex) {
// dd ("read caught exception " + ex + ".");
if ((typeof ex != "undefined") &&
(!(ex instanceof java.io.InterruptedIOException)))
{
dd ("@@@ throwing " + ex);
this.isConnected = false;
throw (ex);
} else {
// dd ("int");
rv = "";
}
}
// dd ("readData: rv = '" + rv + "'");
return rv;
}

View File

@@ -1,373 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
* Peter Van der Beken, peter.vanderbeken@pandora.be, necko-only version
*
* depends on utils.js, and XPCOM/XPConnect in the JS environment
*
*/
const NS_ERROR_MODULE_NETWORK = 2152398848;
const NS_ERROR_UNKNOWN_HOST = NS_ERROR_MODULE_NETWORK + 30;
const NS_ERROR_CONNECTION_REFUSED = NS_ERROR_MODULE_NETWORK + 13;
const NS_ERROR_NET_TIMEOUT = NS_ERROR_MODULE_NETWORK + 14;
const NS_NET_STATUS_RESOLVING_HOST = NS_ERROR_MODULE_NETWORK + 3;
const NS_NET_STATUS_CONNECTED_TO = NS_ERROR_MODULE_NETWORK + 4;
const NS_NET_STATUS_SENDING_TO = NS_ERROR_MODULE_NETWORK + 5;
const NS_NET_STATUS_RECEIVING_FROM = NS_ERROR_MODULE_NETWORK + 6;
const NS_NET_STATUS_CONNECTING_TO = NS_ERROR_MODULE_NETWORK + 7;
function toScriptableInputStream (i)
{
var si = Components.classes["@mozilla.org/scriptableinputstream;1"];
si = si.createInstance();
si = si.QueryInterface(Components.interfaces.nsIScriptableInputStream);
si.init(i);
return si;
}
function CBSConnection ()
{
var sockServiceClass =
Components.classesByID["{c07e81e0-ef12-11d2-92b6-00105a1b0d64}"];
if (!sockServiceClass)
throw ("Couldn't get socket service class.");
var sockService = sockServiceClass.getService();
if (!sockService)
throw ("Couldn't get socket service.");
this._sockService = sockService.QueryInterface
(Components.interfaces.nsISocketTransportService);
this.wrappedJSObject = this;
}
CBSConnection.prototype.connect =
function bc_connect(host, port, bind, tcp_flag, observer)
{
if (typeof tcp_flag == "undefined")
tcp_flag = false;
this.host = host.toLowerCase();
this.port = port;
this.bind = bind;
this.tcp_flag = tcp_flag;
// Lets get a transportInfo for this
var cls =
Components.classes["@mozilla.org/network/protocol-proxy-service;1"];
var pps = cls.getService(Components.interfaces.nsIProtocolProxyService);
if (!pps)
throw ("Couldn't get protocol proxy service");
var ios = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
var spec = "irc://" + host + ':' + port;
var uri = ios.newURI(spec,null,null);
var info = pps.examineForProxy(uri);
if (jsenv.HAS_STREAM_PROVIDER)
{
this._transport = this._sockService.createTransport (host, port, info,
0, 0);
if (!this._transport)
throw ("Error creating transport.");
if (jsenv.HAS_NSPR_EVENTQ)
{ /* we've got an event queue, so start up an async write */
this._streamProvider = new StreamProvider (observer);
this._write_req =
this._transport.asyncWrite (this._streamProvider, this,
0, -1, 0);
}
else
{
/* no nspr event queues in this environment, we can't use async
* calls, so set up the streams. */
this._outputStream = this._transport.openOutputStream(0, -1, 0);
if (!this._outputStream)
throw "Error getting output stream.";
this._inputStream =
toScriptableInputStream(this._transport.openInputStream(0,
-1, 0));
if (!this._inputStream)
throw "Error getting input stream.";
}
}
else
{
/* use new necko interfaces */
this._transport = this._sockService.createTransport(null, 0, host, port,
info);
if (!this._transport)
throw ("Error creating transport.");
/* if we don't have an event queue, then all i/o must be blocking */
var openFlags;
if (jsenv.HAS_NSPR_EVENTQ)
openFlags = 0;
else
openFlags = Components.interfaces.nsITransport.OPEN_BLOCKING;
/* no limit on the output stream buffer */
this._outputStream =
this._transport.openOutputStream(openFlags, 4096, -1);
if (!this._outputStream)
throw "Error getting output stream.";
this._inputStream = this._transport.openInputStream(openFlags, 0, 0);
if (!this._inputStream)
throw "Error getting input stream.";
}
this.connectDate = new Date();
this.isConnected = true;
return this.isConnected;
}
CBSConnection.prototype.disconnect =
function bc_disconnect()
{
if ("_inputStream" in this && this._inputStream)
this._inputStream.close();
if ("_outputStream" in this && this._outputStream)
this._outputStream.close();
this.isConnected = false;
/*
this._streamProvider.close();
if (this._streamProvider.isBlocked)
this._write_req.resume();
*/
}
CBSConnection.prototype.sendData =
function bc_senddata(str)
{
if (!this.isConnected)
throw "Not Connected.";
if (jsenv.HAS_NSPR_EVENTQ && jsenv.HAS_STREAM_PROVIDER)
this.asyncWrite (str);
else
this.sendDataNow (str);
}
CBSConnection.prototype.readData =
function bc_readdata(timeout, count)
{
if (!this.isConnected)
throw "Not Connected.";
var rv;
try
{
rv = this._scriptableInputStream.read (count);
}
catch (ex)
{
dd ("*** Caught " + ex + " while reading.");
this.disconnect();
throw (ex);
}
return rv;
}
CBSConnection.prototype.startAsyncRead =
function bc_saread (observer)
{
if (jsenv.HAS_STREAM_PROVIDER)
{
this._transport.asyncRead (new StreamListener (observer),
this, 0, -1, 0);
}
else
{
var cls = Components.classes["@mozilla.org/network/input-stream-pump;1"];
var pump = cls.createInstance(Components.interfaces.nsIInputStreamPump);
pump.init(this._inputStream, -1, -1, 0, 0, false);
pump.asyncRead(new StreamListener(observer), this);
}
}
CBSConnection.prototype.asyncWrite =
function bc_awrite (str)
{
this._streamProvider.pendingData += str;
if (this._streamProvider.isBlocked)
{
this._write_req.resume();
this._streamProvider.isBlocked = false;
}
}
CBSConnection.prototype.hasPendingWrite =
function bc_haspwrite ()
{
if (jsenv.HAS_STREAM_PROVIDER)
return (this._streamProvider.pendingData != "");
else
return false; /* data already pushed to necko */
}
CBSConnection.prototype.sendDataNow =
function bc_senddatanow(str)
{
var rv = false;
try
{
this._outputStream.write(str, str.length);
rv = true;
}
catch (ex)
{
dd ("*** Caught " + ex + " while sending.");
this.disconnect();
throw (ex);
}
return rv;
}
function _notimpl ()
{
throw "Not Implemented.";
}
if (!jsenv.HAS_NSPR_EVENTQ)
{
CBSConnection.prototype.startAsyncRead = _notimpl;
CBSConnection.prototype.asyncWrite = _notimpl;
}
else if (jsenv.HAS_STREAM_PROVIDER)
{
CBSConnection.prototype.sendDataNow = _notimpl;
}
else
{
CBSConnection.prototype.asyncWrite = _notimpl;
}
delete _notimpl;
function StreamProvider(observer)
{
this._observer = observer;
}
StreamProvider.prototype.pendingData = "";
StreamProvider.prototype.isBlocked = true;
StreamProvider.prototype.close =
function sp_close ()
{
this.isClosed = true;
}
StreamProvider.prototype.onDataWritable =
function sp_datawrite (request, ctxt, ostream, offset, count)
{
//dd ("StreamProvider.prototype.onDataWritable");
if ("isClosed" in this && this.isClosed)
throw Components.results.NS_BASE_STREAM_CLOSED;
if (!this.pendingData)
{
this.isBlocked = true;
/* this is here to support pre-XPCDOM builds (0.9.0 era), which
* don't have this result code mapped. */
if (!Components.results.NS_BASE_STREAM_WOULD_BLOCK)
throw 2152136711;
throw Components.results.NS_BASE_STREAM_WOULD_BLOCK;
}
var len = ostream.write (this.pendingData, this.pendingData.length);
this.pendingData = this.pendingData.substr (len);
}
StreamProvider.prototype.onStartRequest =
function sp_startreq (request, ctxt)
{
//dd ("StreamProvider::onStartRequest: " + request + ", " + ctxt);
}
StreamProvider.prototype.onStopRequest =
function sp_stopreq (request, ctxt, status)
{
//dd ("StreamProvider::onStopRequest: " + request + ", " + ctxt + ", " +
// status);
if (this._observer)
this._observer.onStreamClose(status);
}
function StreamListener(observer)
{
this._observer = observer;
}
StreamListener.prototype.onStartRequest =
function sl_startreq (request, ctxt)
{
//dd ("StreamListener::onStartRequest: " + request + ", " + ctxt);
}
StreamListener.prototype.onStopRequest =
function sl_stopreq (request, ctxt, status)
{
//dd ("StreamListener::onStopRequest: " + request + ", " + ctxt + ", " +
//status);
if (this._observer)
this._observer.onStreamClose(status);
}
StreamListener.prototype.onDataAvailable =
function sl_dataavail (request, ctxt, inStr, sourceOffset, count)
{
ctxt = ctxt.wrappedJSObject;
if (!ctxt)
{
dd ("*** Can't get wrappedJSObject from ctxt in " +
"StreamListener.onDataAvailable ***");
return;
}
if (!("_scriptableInputStream" in ctxt))
ctxt._scriptableInputStream = toScriptableInputStream (inStr);
if (this._observer)
this._observer.onStreamDataAvailable(request, inStr, sourceOffset,
count);
}

View File

@@ -1,36 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
**HERE
*
* The contents of this file are Copyright 1999 Robert G. Ginda,
* rginda@ndcico.com. This program may be freely copied and modified for
* non-commercial use, provided everything between HERE and THERE appears
* in the copy.
* If you have questions, comments or suggestions direct them to
* rginda@ndcico.com.
*
**THERE
*
* depends on utils.js, and the connection-*.js implementations.
*
* loads an appropriate connection implementation, or dies trying.
*
*/
function connection_init(libPath)
{
if (jsenv.HAS_XPCOM)
load (libPath + "connection-xpcom.js");
else if (jsenv.HAS_RHINO)
load (libPath + "connection-rhino.js");
else
{
dd ("No connection object for this platform.");
return false;
}
return true;
}

View File

@@ -1,117 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
* JavaScript utility functions.
*
* 1999-08-15 rginda@ndcico.com v1.0
*/
function CDCCChat (ep, host, port)
{
this.READ_TIMEOUT = 50;
this.eventPump = ep;
this.host = host;
this.port = port;
this.connection = new CBSConnection();
this.savedLine = "";
}
CDCCChat.prototype.connect =
function dchat_connect (host, port)
{
if (typeof host != "undefined") this.host = host;
if (typeof port != "undefined") this.port = port;
if (!this.connection.connect (this.host, this.port, (void 0), true))
return false;
this.eventPump.addEvent (new CEvent ("dcc-chat", "poll", this, "onPoll"));
return true;
}
CDCCChat.prototype.onPoll =
function dchat_poll (e)
{
var line = "";
try
{
line = this.connection.readData (this.READ_TIMEOUT);
}
catch (ex)
{
if (typeof (ex) != "undefined")
{
this.connection.disconnect();
var e = new CEvent ("dcc-chat", "close", this, "onClose");
e.reason = "read-error";
e.exception = ex;
this.eventPump.addEvent (e);
return false;
}
else
line = "";
}
this.eventPump.addEvent (new CEvent ("dcc-chat", "poll", this, "onPoll"));
if (line == "")
return false;
var incomplete = (line[line.length] != '\n');
var lines = line.split("\n");
if (this.savedLine)
{
lines[0] = this.savedLine + lines[0];
this.savedLine = "";
}
if (incomplete)
this.savedLine = lines.pop();
for (i in lines)
{
var ev = new CEvent("dcc-chat", "rawdata", this, "onRawData");
ev.data = lines[i];
ev.replyTo = this;
this.eventPump.addEvent (ev);
}
return true;
}
CDCCChat.prototype.say =
function dchat_say (msg)
{
this.connection.sendData (msg + "\n");
}

View File

@@ -1,262 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
* depends on utils.js
*
* Event and EventPump classes. The EventPump maintains a queue of event
* objects. To inject an event into this queue, use |EventPump.addEvent|.
* |EventQueue.routeEvents| steps at most |EventPump.eventsPerStep|
* events, and then returns control.
*
* 1999-08-15 rginda@ndcico.com v1.0
*
*/
/*
* event class
*/
function CEvent (set, type, destObject, destMethod)
{
this.set = set;
this.type = type;
this.destObject = destObject;
this.destMethod = destMethod;
this.hooks = new Array();
}
/*
* event pump
*/
function CEventPump (eventsPerStep)
{
/* event routing stops after this many levels, safety valve */
this.MAX_EVENT_DEPTH = 50;
this.eventsPerStep = eventsPerStep;
this.queue = new Array();
this.hooks = new Array();
}
CEventPump.prototype.onHook =
function ep_hook(e, hooks)
{
var h;
if (typeof hooks == "undefined")
hooks = this.hooks;
hook_loop:
for (h = hooks.length - 1; h >= 0; h--)
{
if (!hooks[h].enabled ||
!matchObject (e, hooks[h].pattern, hooks[h].neg))
continue hook_loop;
e.hooks.push (hooks[h]);
var rv = hooks[h].f(e);
if ((typeof rv == "boolean") &&
(rv == false))
{
dd ("hook #" + h + " '" +
((typeof hooks[h].name != "undefined") ? hooks[h].name :
"") + "' stopped hook processing.");
return true;
}
}
return false;
}
CEventPump.prototype.addHook =
function ep_addhook(pattern, f, name, neg, enabled, hooks)
{
if (typeof hooks == "undefined")
hooks = this.hooks;
if (typeof f != "function")
return false;
if (typeof enabled == "undefined")
enabled = true;
else
enabled = Boolean(enabled);
neg = Boolean(neg);
var hook = {
pattern: pattern,
f: f,
name: name,
neg: neg,
enabled: enabled
};
hooks.push(hook);
return hook;
}
CEventPump.prototype.getHook =
function ep_gethook(name, hooks)
{
if (typeof hooks == "undefined")
hooks = this.hooks;
for (var h in hooks)
if (hooks[h].name.toLowerCase() == name.toLowerCase())
return hooks[h];
return null;
}
CEventPump.prototype.removeHookByName =
function ep_remhookname(name, hooks)
{
if (typeof hooks == "undefined")
hooks = this.hooks;
for (var h in hooks)
if (hooks[h].name.toLowerCase() == name.toLowerCase())
{
arrayRemoveAt (hooks, h);
return true;
}
return false;
}
CEventPump.prototype.removeHookByIndex =
function ep_remhooki(idx, hooks)
{
if (typeof hooks == "undefined")
hooks = this.hooks;
return arrayRemoveAt (hooks, idx);
}
CEventPump.prototype.addEvent =
function ep_addevent (e)
{
e.queuedAt = new Date();
arrayInsertAt(this.queue, 0, e);
return true;
}
CEventPump.prototype.routeEvent =
function ep_routeevent (e)
{
var count = 0;
this.currentEvent = e;
e.level = 0;
while (e.destObject)
{
e.level++;
this.onHook (e);
var destObject = e.destObject;
e.destObject = (void 0);
switch (typeof destObject[e.destMethod])
{
case "function":
if (1)
try
{
destObject[e.destMethod] (e);
}
catch (ex)
{
if (typeof ex == "string")
{
dd ("Error routing event " + e.set + "." +
e.type + ": " + ex);
}
else
{
dd ("Error routing event " + e.set + "." +
e.type + ": " + dumpObjectTree(ex) +
" in " + e.destMethod + "\n" + ex);
if ("stack" in ex)
dd(ex.stack);
}
}
else
destObject[e.destMethod] (e);
if (count++ > this.MAX_EVENT_DEPTH)
throw "Too many events in chain";
break;
case "undefined":
//dd ("** " + e.destMethod + " does not exist.");
break;
default:
dd ("** " + e.destMethod + " is not a function.");
}
if ((e.type != "event-end") && (!e.destObject))
{
e.lastSet = e.set;
e.set = "eventpump";
e.lastType = e.type;
e.type = "event-end";
e.destMethod = "onEventEnd";
e.destObject = this;
}
}
delete this.currentEvent;
return true;
}
CEventPump.prototype.stepEvents =
function ep_stepevents()
{
var i = 0;
while (i < this.eventsPerStep)
{
var e = this.queue.pop();
if (!e || e.type == "yield")
break;
this.routeEvent (e);
i++;
}
return true;
}

View File

@@ -1,356 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, <rginda@netscape.com>, original author
*
*/
/* notice that these valuse are octal. */
const PERM_IRWXU = 00700; /* read, write, execute/search by owner */
const PERM_IRUSR = 00400; /* read permission, owner */
const PERM_IWUSR = 00200; /* write permission, owner */
const PERM_IXUSR = 00100; /* execute/search permission, owner */
const PERM_IRWXG = 00070; /* read, write, execute/search by group */
const PERM_IRGRP = 00040; /* read permission, group */
const PERM_IWGRP = 00020; /* write permission, group */
const PERM_IXGRP = 00010; /* execute/search permission, group */
const PERM_IRWXO = 00007; /* read, write, execute/search by others */
const PERM_IROTH = 00004; /* read permission, others */
const PERM_IWOTH = 00002; /* write permission, others */
const PERM_IXOTH = 00001; /* execute/search permission, others */
const MODE_RDONLY = 0x01;
const MODE_WRONLY = 0x02;
const MODE_RDWR = 0x04;
const MODE_CREATE = 0x08;
const MODE_APPEND = 0x10;
const MODE_TRUNCATE = 0x20;
const MODE_SYNC = 0x40;
const MODE_EXCL = 0x80;
const PICK_OK = Components.interfaces.nsIFilePicker.returnOK;
const PICK_CANCEL = Components.interfaces.nsIFilePicker.returnCancel;
const PICK_REPLACE = Components.interfaces.nsIFilePicker.returnReplace;
const FILTER_ALL = Components.interfaces.nsIFilePicker.filterAll;
const FILTER_HTML = Components.interfaces.nsIFilePicker.filterHTML;
const FILTER_TEXT = Components.interfaces.nsIFilePicker.filterText;
const FILTER_IMAGES = Components.interfaces.nsIFilePicker.filterImages;
const FILTER_XML = Components.interfaces.nsIFilePicker.filterXML;
const FILTER_XUL = Components.interfaces.nsIFilePicker.filterXUL;
const FTYPE_DIR = Components.interfaces.nsIFile.DIRECTORY_TYPE;
const FTYPE_FILE = Components.interfaces.nsIFile.NORMAL_FILE_TYPE;
// evald f = fopen("/home/rginda/foo.txt", MODE_WRONLY | MODE_CREATE)
// evald f = fopen("/home/rginda/vnk.txt", MODE_RDONLY)
var futils = new Object();
futils.umask = PERM_IWOTH | PERM_IWGRP;
futils.MSG_SAVE_AS = "Save As";
futils.MSG_OPEN = "Open";
futils.getPicker =
function futils_nosepicker(initialPath, typeList, attribs)
{
const classes = Components.classes;
const interfaces = Components.interfaces;
const PICKER_CTRID = "@mozilla.org/filepicker;1";
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
const nsIFilePicker = interfaces.nsIFilePicker;
const nsILocalFile = interfaces.nsILocalFile;
var picker = classes[PICKER_CTRID].createInstance(nsIFilePicker);
if (typeof attribs == "object")
{
for (var a in attribs)
picker[a] = attribs[a];
}
else
throw "bad type for param |attribs|";
if (initialPath)
{
var localFile;
if (typeof initialPath == "string")
{
localFile =
classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
localFile.initWithPath(initialPath);
}
else
{
if (!(initialPath instanceof nsILocalFile))
throw "bad type for argument |initialPath|";
localFile = initialPath;
}
picker.displayDirectory = localFile
}
if (typeof typeList == "string")
typeList = typeList.split(" ");
if (typeList instanceof Array)
{
for (var i in typeList)
{
switch (typeList[i])
{
case "$all":
picker.appendFilters(FILTER_ALL);
break;
case "$html":
picker.appendFilters(FILTER_HTML);
break;
case "$text":
picker.appendFilters(FILTER_TEXT);
break;
case "$images":
picker.appendFilters(FILTER_IMAGES);
break;
case "$xml":
picker.appendFilters(FILTER_XML);
break;
case "$xul":
picker.appendFilters(FILTER_XUL);
break;
default:
picker.appendFilter(typeList[i], typeList[i]);
break;
}
}
}
return picker;
}
function pickSaveAs (title, typeList, defaultFile, defaultDir)
{
if (!defaultDir && "lastSaveAsDir" in futils)
defaultDir = futils.lastSaveAsDir;
var picker = futils.getPicker (defaultDir, typeList,
{defaultString: defaultFile});
picker.init (window, title ? title : futils.MSG_SAVE_AS,
Components.interfaces.nsIFilePicker.modeSave);
var reason;
try
{
reason = picker.show();
}
catch (ex)
{
dd ("caught exception from file picker: " + ex);
}
var obj = new Object();
obj.reason = reason;
obj.picker = picker;
if (reason != PICK_CANCEL)
{
obj.file = picker.file;
futils.lastSaveAsDir = picker.file.parent;
}
else
{
obj.file = null;
}
return obj;
}
function pickOpen (title, typeList, defaultFile, defaultDir)
{
if (!defaultDir && "lastOpenDir" in futils)
defaultDir = futils.lastOpenDir;
var picker = futils.getPicker (defaultDir, typeList,
{defaultString: defaultFile});
picker.init (window, title ? title : futils.MSG_OPEN,
Components.interfaces.nsIFilePicker.modeOpen);
var rv = picker.show();
if (rv != PICK_CANCEL)
futils.lastOpenDir = picker.file.parent;
return {reason: rv, file: picker.file, picker: picker};
}
function mkdir (localFile, perms)
{
if (typeof perms == "undefined")
perms = 0766 & ~futils.umask;
localFile.create(FTYPE_DIR, perms);
}
function nsLocalFile(path)
{
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
const nsILocalFile = Components.interfaces.nsILocalFile;
var localFile =
Components.classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
localFile.initWithPath(path);
return localFile;
}
function fopen (path, mode, perms, tmp)
{
return new LocalFile(path, mode, perms, tmp);
}
function LocalFile(file, mode, perms, tmp)
{
const classes = Components.classes;
const interfaces = Components.interfaces;
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
const FILEIN_CTRID = "@mozilla.org/network/file-input-stream;1";
const FILEOUT_CTRID = "@mozilla.org/network/file-output-stream;1";
const SCRIPTSTREAM_CTRID = "@mozilla.org/scriptableinputstream;1";
const nsIFile = interfaces.nsIFile;
const nsILocalFile = interfaces.nsILocalFile;
const nsIFileOutputStream = interfaces.nsIFileOutputStream;
const nsIFileInputStream = interfaces.nsIFileInputStream;
const nsIScriptableInputStream = interfaces.nsIScriptableInputStream;
if (typeof perms == "undefined")
perms = 0666 & ~futils.umask;
if (typeof mode == "string")
{
switch (mode)
{
case ">":
mode = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
break;
case ">>":
mode = MODE_WRONLY | MODE_CREATE | MODE_APPEND;
break;
case "<":
mode = MODE_RDONLY;
break;
default:
throw "Invalid mode ``" + mode + "''";
}
}
if (typeof file == "string")
{
this.localFile = new nsLocalFile(file);
}
else if (file instanceof nsILocalFile)
{
this.localFile = file;
}
else
{
throw "bad type for argument |file|.";
}
this.path = this.localFile.path;
if (mode & (MODE_WRONLY | MODE_RDWR))
{
this.outputStream =
classes[FILEOUT_CTRID].createInstance(nsIFileOutputStream);
this.outputStream.init(this.localFile, mode, perms, 0);
}
if (mode & (MODE_RDONLY | MODE_RDWR))
{
var is = classes[FILEIN_CTRID].createInstance(nsIFileInputStream);
is.init(this.localFile, mode, perms, tmp);
this.inputStream =
classes[SCRIPTSTREAM_CTRID].createInstance(nsIScriptableInputStream);
this.inputStream.init(is);
}
}
LocalFile.prototype.write =
function fo_write(buf)
{
if (!("outputStream" in this))
throw "file not open for writing.";
return this.outputStream.write(buf, buf.length);
}
LocalFile.prototype.read =
function fo_read(max)
{
if (!("inputStream" in this))
throw "file not open for reading.";
var av = this.inputStream.available();
if (typeof max == "undefined")
max = av;
if (!av)
return null;
var rv = this.inputStream.read(max);
return rv;
}
LocalFile.prototype.close =
function fo_close()
{
if ("outputStream" in this)
this.outputStream.close();
if ("inputStream" in this)
this.inputStream.close();
}
LocalFile.prototype.flush =
function fo_close()
{
return this.outputStream.flush();
}

View File

@@ -1,202 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
*
* depends on utils.js, events.js, and connection.js
*
* HTTP document class. Asynchronous retrieval of documents via HTTP.
*
* 1999-08-15 rginda@ndcico.com v1.0
*
*/
function CHTTPDoc (server, path)
{
this.GET_TIMEOUT = 2 * 60; /* 2 minute timeout on gets */
this.state = "new";
this.server = server;
this.path = path;
}
CHTTPDoc.prototype.get =
function http_get (ep)
{
this.connection = new CBSConnection();
if (!this.connection.connect (this.server, 80, (void 0), true))
{
this.state = "connect-error";
var e = new CEvent ("httpdoc", "complete", this, "onComplete");
this.eventPump.addEvent (e);
return false;
}
this.eventPump = ep;
this.state = "opened";
this.data = "";
this.duration = 0;
var e = new CEvent ("httpdoc", "poll", this, "onPoll");
this.eventPump.addEvent (e);
this.connection.sendData ("GET " + this.path + "\n");
this.startDate = new Date();
return true;
}
CHTTPDoc.prototype.onPoll =
function http_poll (e)
{
var line = "";
var ex, c;
var need_more = false;
if (this.duration < this.GET_TIMEOUT)
try
{
line = this.connection.readData (50);
need_more = true;
}
catch (ex)
{
if (typeof (ex) == "undefined")
{
line = "";
need_more = true;
}
else
{
dd ("** Caught exception: '" + ex + "' while receiving " +
this.server + this.path);
this.state = "read-error";
}
}
else
this.state = "receive-timeout";
switch (this.state)
{
case "opened":
case "receive-header":
if (this.state == "opened")
this.headers = "";
c = line.search(/\<html\>/i);
if (c != -1)
{
this.data = line.substr (c, line.length);
this.state = "receive-data";
line = line.substr (0, c);
c = this.data.search(/\<\/html\>/i);
if (c != -1)
{
this.docType = stringTrim(this.docType);
this.state = "complete";
need_more = false;
}
}
this.headers += line;
c = this.headers.search (/\<\!doctype/i);
if (c != -1)
{
this.docType = this.headers.substr (c, line.length);
if (this.state == "opened")
this.state = "receive-doctype";
this.headers = this.headers.substr (0, c);
}
if (this.state == "opened")
this.state = "receive-header";
break;
case "receive-doctype":
var c = line.search (/\<html\>/i);
if (c != -1)
{
this.docType = stringTrim(this.docType);
this.data = line.substr (c, line.length);
this.state = "receive-data";
line = line.substr (0, c);
}
this.docType += line;
break;
case "receive-data":
this.data += line;
var c = this.data.search(/\<\/html\>/i);
if (c != -1)
this.state = "complete";
break;
case "read-error":
case "receive-timeout":
break;
default:
dd ("** INVALID STATE in HTTPDoc object (" + this.state + ") **");
need_more = false;
this.state = "error";
break;
}
if ((this.state != "complete") && (need_more))
var e = new CEvent ("httpdoc", "poll", this, "onPoll");
else
{
this.connection.disconnect();
if (this.data)
{
var m = this.data.match(/\<title\>(.*)\<\/title\>/i);
if (m != null)
this.title = m[1];
else
this.title = "";
}
var e = new CEvent ("httpdoc", "complete", this, "onComplete");
}
this.eventPump.addEvent (e);
this.duration = (new Date() - this.startDate) / 1000;
return true;
}
CHTTPDoc.prototype.onComplete =
function http_complete(e)
{
return true;
}

View File

@@ -1,103 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*/
/*
* Hook used to trace events.
*/
function event_tracer (e)
{
var name = "";
var data = ("debug" in e) ? e.debug : "";
switch (e.set)
{
case "server":
name = e.destObject.connection.host;
if (e.type == "rawdata")
data = "'" + e.data + "'";
if (e.type == "senddata")
{
var nextLine =
e.destObject.sendQueue[e.destObject.sendQueue.length - 1];
if ("logged" in nextLine)
return true; /* don't print again */
if (nextLine) {
data = "'" + nextLine.replace ("\n", "\\n") + "'";
nextLine.logged = true;
}
else
data = "!!! Nothing to send !!!";
}
break;
case "network":
case "channel":
name = e.destObject.name;
break;
case "user":
name = e.destObject.nick;
break;
case "httpdoc":
name = e.destObject.server + e.destObject.path;
if (e.destObject.state != "complete")
data = "state: '" + e.destObject.state + "', received " +
e.destObject.data.length;
else
dd ("document done:\n" + dumpObjectTree (this));
break;
case "dcc-chat":
name = e.destObject.host + ":" + e.destObject.port;
if (e.type == "rawdata")
data = "'" + e.data + "'";
break;
case "client":
if (e.type == "do-connect")
data = "attempt: " + e.attempt + "/" +
e.destObject.MAX_CONNECT_ATTEMPTS;
break;
default:
break;
}
if (name)
name = "[" + name + "]";
if (e.type == "info")
data = "'" + e.msg + "'";
var str = "Level " + e.level + ": '" + e.type + "', " +
e.set + name + "." + e.destMethod;
if (data)
str += "\ndata : " + data;
dd (str);
return true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,582 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, <rginda@netscape.com>, original author
*
*/
function MenuManager (commandManager, menuSpecs, contextFunction, commandStr)
{
var menuManager = this;
this.commandManager = commandManager;
this.menuSpecs = menuSpecs;
this.contextFunction = contextFunction;
this.commandStr = commandStr;
this.onPopupShowing =
function mmgr_onshow (event) { return menuManager.showPopup (event); };
this.onPopupHiding =
function mmgr_onhide (event) { return menuManager.hidePopup (event); };
}
MenuManager.prototype.appendMenuItems =
function mmgr_append(menuId, items)
{
for (var i = 0; i < items.length; ++i)
client.menuSpecs[menuId].items.push(items[i]);
}
MenuManager.prototype.createContextMenus =
function mmgr_initcxs (document)
{
for (var id in this.menuSpecs)
{
if (id.indexOf("context:") == 0)
this.createContextMenu(document, id);
}
}
MenuManager.prototype.createContextMenu =
function mmgr_initcx (document, id)
{
if (!document.getElementById(id))
{
if (!ASSERT(id in this.menuSpecs, "unknown context menu " + id))
return;
var dp = document.getElementById("dynamic-popups");
var popup = this.appendPopupMenu (dp, null, id, id);
var items = this.menuSpecs[id].items;
this.createMenuItems (popup, null, items);
}
}
MenuManager.prototype.createMenus =
function mmgr_createtb(document, menuid)
{
var menu = document.getElementById(menuid);
for (id in this.menuSpecs)
{
var domID;
if ("domID" in this.menuSpecs[id])
domID = this.menuSpecs[id].domID;
else
domID = id;
if (id.indexOf(menuid + ":") == 0)
this.createMenu(menu, null, id, domID);
}
}
MenuManager.prototype.createMainToolbar =
function mmgr_createtb(document, id)
{
var toolbar = document.getElementById(id);
var spec = client.menuSpecs[id];
for (var i in spec.items)
{
this.appendToolbarItem (toolbar, null, spec.items[i]);
}
toolbar.className = "toolbar-primary chromeclass-toolbar";
}
/**
* Internal use only.
*
* Registers event handlers on a given menu.
*/
MenuManager.prototype.hookPopup =
function mmgr_hookpop (node)
{
node.addEventListener ("popupshowing", this.onPopupShowing, false);
node.addEventListener ("popuphiding", this.onPopupHiding, false);
}
/**
* Internal use only.
*
* |showPopup| is called from the "onpopupshowing" event of menus
* managed by the CommandManager. If a command is disabled, represents a command
* that cannot be "satisfied" by the current command context |cx|, or has an
* "enabledif" attribute that eval()s to false, then the menuitem is disabled.
* In addition "checkedif" and "visibleif" attributes are eval()d and
* acted upon accordingly.
*/
MenuManager.prototype.showPopup =
function mmgr_showpop (event)
{
//dd ("showPopup {");
/* returns true if the command context has the properties required to
* execute the command associated with |menuitem|.
*/
function satisfied()
{
if (menuitem.hasAttribute("isSeparator") ||
!menuitem.hasAttribute("commandname"))
{
return true;
}
if (!("menuManager" in cx))
{
dd ("no menuManager in cx");
return false;
}
var name = menuitem.getAttribute("commandname");
var commandManager = cx.menuManager.commandManager;
var commands = commandManager.commands;
if (!ASSERT (name in commands,
"menu contains unknown command '" + name + "'"))
{
return false;
}
var rv = commandManager.isCommandSatisfied(cx, commands[name]);
delete cx.parseError;
return rv;
};
/* Convenience function for "enabledif", etc, attributes. */
function has (prop)
{
return (prop in cx);
};
/* evals the attribute named |attr| on the node |node|. */
function evalIfAttribute (node, attr)
{
var ex;
var expr = node.getAttribute(attr);
if (!expr)
return true;
expr = expr.replace (/\Wand\W/gi, " && ");
try
{
return eval("(" + expr + ")");
}
catch (ex)
{
dd ("caught exception evaling '" + node.getAttribute("id") + "'.'" +
attr + "'\n" + ex);
}
return true;
};
var cx;
var popup = event.originalTarget;
var menuitem = popup.firstChild;
/* If the host provided a |contextFunction|, use it now. Remember the
* return result as this.cx for use if something from this menu is actually
* dispatched. this.cx is deleted in |hidePopup|. */
if (typeof this.contextFunction == "function")
{
cx = this.cx = this.contextFunction (popup.getAttribute("menuName"),
event);
}
else
{
cx = this.cx = { menuManager: this, originalEvent: event };
}
do
{
/* should it be visible? */
if (menuitem.hasAttribute("visibleif"))
{
if (evalIfAttribute(menuitem, "visibleif"))
menuitem.removeAttribute ("hidden");
else
{
menuitem.setAttribute ("hidden", "true");
continue;
}
}
/* it's visible, maybe it has a dynamic label? */
if (menuitem.hasAttribute("format"))
{
var label = replaceVars(menuitem.getAttribute("format"), cx);
if (label.indexOf("\$") != -1)
label = menuitem.getAttribute("backupLabel");
menuitem.setAttribute("label", label);
}
/* ok, it's visible, maybe it should be disabled? */
if (satisfied())
{
if (menuitem.hasAttribute("enabledif"))
{
if (evalIfAttribute(menuitem, "enabledif"))
menuitem.removeAttribute ("disabled");
else
menuitem.setAttribute ("disabled", "true");
}
else
menuitem.removeAttribute ("disabled");
}
else
{
menuitem.setAttribute ("disabled", "true");
}
/* should it have a check? */
if (menuitem.hasAttribute("checkedif"))
{
if (evalIfAttribute(menuitem, "checkedif"))
menuitem.setAttribute ("checked", "true");
else
menuitem.removeAttribute ("checked");
}
} while ((menuitem = menuitem.nextSibling));
//dd ("}");
return true;
}
/**
* Internal use only.
*
* |hidePopup| is called from the "onpopuphiding" event of menus
* managed by the CommandManager. Nothing to do here anymore.
* We used to just clean up this.cx, but that's a problem for nested
* menus.
*/
MenuManager.prototype.hidePopup =
function mmgr_hidepop (id)
{
return true;
}
/**
* Appends a sub-menu to an existing menu.
* @param parentNode DOM Node to insert into
* @param beforeNode DOM Node already contained by parentNode, to insert before
* @param id ID of the sub-menu to add.
* @param label Text to use for this sub-menu. The & character can be
* used to indicate the accesskey.
* @param attribs Object containing CSS attributes to set on the element.
*/
MenuManager.prototype.appendSubMenu =
function mmgr_addsmenu (parentNode, beforeNode, menuName, domId, label, attribs)
{
var document = parentNode.ownerDocument;
/* sometimes the menu is already there, for overlay purposes. */
var menu = document.getElementById(domId);
if (!menu)
{
menu = document.createElement ("menu");
menu.setAttribute ("id", domId);
parentNode.insertBefore(menu, beforeNode);
}
var menupopup = menu.firstChild;
if (!menupopup)
{
menupopup = document.createElement ("menupopup");
menupopup.setAttribute ("id", domId + "-popup");
menu.appendChild(menupopup);
menupopup = menu.firstChild;
}
menupopup.setAttribute ("menuName", menuName);
menu.setAttribute ("accesskey", getAccessKey(label));
label = label.replace("&", "");
menu.setAttribute ("label", label);
menu.setAttribute ("isSeparator", true);
if (typeof attribs == "object")
{
for (var p in attribs)
menu.setAttribute (p, attribs[p]);
}
this.hookPopup (menupopup);
return menupopup;
}
/**
* Appends a popup to an existing popupset.
* @param parentNode DOM Node to insert into
* @param beforeNode DOM Node already contained by parentNode, to insert before
* @param id ID of the popup to add.
* @param label Text to use for this popup. Popup menus don't normally have
* labels, but we set a "label" attribute anyway, in case
* the host wants it for some reason. Any "&" characters will
* be stripped.
* @param attribs Object containing CSS attributes to set on the element.
*/
MenuManager.prototype.appendPopupMenu =
function mmgr_addpmenu (parentNode, beforeNode, menuName, id, label, attribs)
{
var document = parentNode.ownerDocument;
var popup = document.createElement ("popup");
popup.setAttribute ("id", id);
if (label)
popup.setAttribute ("label", label.replace("&", ""));
if (typeof attribs == "object")
{
for (var p in attribs)
popup.setAttribute (p, attribs[p]);
}
popup.setAttribute ("menuName", menuName);
parentNode.insertBefore(popup, beforeNode);
this.hookPopup (popup);
return popup;
}
/**
* Appends a menuitem to an existing menu or popup.
* @param parentNode DOM Node to insert into
* @param beforeNode DOM Node already contained by parentNode, to insert before
* @param command A reference to the CommandRecord this menu item will represent.
* @param attribs Object containing CSS attributes to set on the element.
*/
MenuManager.prototype.appendMenuItem =
function mmgr_addmenu (parentNode, beforeNode, commandName, attribs)
{
var menuManager = this;
var document = parentNode.ownerDocument;
if (commandName == "-")
return this.appendMenuSeparator(parentNode, beforeNode, attribs);
var parentId = parentNode.getAttribute("id");
if (!ASSERT(commandName in this.commandManager.commands,
"unknown command " + commandName + " targeted for " +
parentId))
{
return null;
}
var command = this.commandManager.commands[commandName];
var menuitem = document.createElement ("menuitem");
menuitem.setAttribute ("id", parentId + ":" + commandName);
menuitem.setAttribute ("commandname", command.name);
menuitem.setAttribute ("key", "key:" + command.name);
menuitem.setAttribute ("accesskey", getAccessKey(command.label));
var label = command.label.replace("&", "");
menuitem.setAttribute ("label", label);
if (command.format)
{
menuitem.setAttribute("format", command.format);
menuitem.setAttribute("backupLabel", label);
}
menuitem.setAttribute ("oncommand", this.commandStr);
if (typeof attribs == "object")
{
for (var p in attribs)
menuitem.setAttribute (p, attribs[p]);
}
command.uiElements.push(menuitem);
parentNode.insertBefore (menuitem, beforeNode);
return menuitem;
}
/**
* Appends a menuseparator to an existing menu or popup.
* @param parentNode DOM Node to insert into
* @param beforeNode DOM Node already contained by parentNode, to insert before
* @param attribs Object containing CSS attributes to set on the element.
*/
MenuManager.prototype.appendMenuSeparator =
function mmgr_addsep (parentNode, beforeNode, attribs)
{
var document = parentNode.ownerDocument;
var menuitem = document.createElement ("menuseparator");
menuitem.setAttribute ("isSeparator", true);
if (typeof attribs == "object")
{
for (var p in attribs)
menuitem.setAttribute (p, attribs[p]);
}
parentNode.insertBefore (menuitem, beforeNode);
return menuitem;
}
/**
* Appends a toolbaritem to an existing box element.
* @param parentNode DOM Node to insert into
* @param beforeNode DOM Node already contained by parentNode, to insert before
* @param command A reference to the CommandRecord this toolbaritem will
* represent.
* @param attribs Object containing CSS attributes to set on the element.
*/
MenuManager.prototype.appendToolbarItem =
function mmgr_addtb (parentNode, beforeNode, commandName, attribs)
{
if (commandName == "-")
return this.appendToolbarSeparator(parentNode, beforeNode, attribs);
var parentId = parentNode.getAttribute("id");
if (!ASSERT(commandName in this.commandManager.commands,
"unknown command " + commandName + " targeted for " +
parentId))
{
return null;
}
var command = this.commandManager.commands[commandName];
var document = parentNode.ownerDocument;
var tbitem = document.createElement ("toolbarbutton");
var id = parentNode.getAttribute("id") + ":" + commandName;
tbitem.setAttribute ("id", id);
tbitem.setAttribute ("class", "toolbarbutton-1");
if (command.tip)
tbitem.setAttribute ("tooltiptext", command.tip);
tbitem.setAttribute ("label", command.label.replace("&", ""));
tbitem.setAttribute ("oncommand",
"dispatch('" + commandName + "');");
if (typeof attribs == "object")
{
for (var p in attribs)
tbitem.setAttribute (p, attribs[p]);
}
command.uiElements.push(tbitem);
parentNode.insertBefore (tbitem, beforeNode);
return tbitem;
}
/**
* Appends a toolbarseparator to an existing box.
* @param parentNode DOM Node to insert into
* @param beforeNode DOM Node already contained by parentNode, to insert before
* @param attribs Object containing CSS attributes to set on the element.
*/
MenuManager.prototype.appendToolbarSeparator =
function mmgr_addmenu (parentNode, beforeNode, attribs)
{
var document = parentNode.ownerDocument;
var tbitem = document.createElement ("toolbarseparator");
tbitem.setAttribute ("isSeparator", true);
if (typeof attribs == "object")
{
for (var p in attribs)
tbitem.setAttribute (p, attribs[p]);
}
parentNode.appendChild (tbitem);
return tbitem;
}
/**
* Creates menu DOM nodes from a menu specification.
* @param parentNode DOM Node to insert into
* @param beforeNode DOM Node already contained by parentNode, to insert before
* @param menuSpec array of menu items
*/
MenuManager.prototype.createMenu =
function mmgr_newmenu (parentNode, beforeNode, menuName, domId, attribs)
{
if (typeof domId == "undefined")
domId = menuName;
if (!ASSERT(menuName in this.menuSpecs, "unknown menu name " + menuName))
return null;
var menuSpec = this.menuSpecs[menuName];
var subMenu = this.appendSubMenu (parentNode, beforeNode, menuName, domId,
menuSpec.label, attribs);
this.createMenuItems (subMenu, null, menuSpec.items);
return subMenu;
}
MenuManager.prototype.createMenuItems =
function mmgr_newitems (parentNode, beforeNode, menuItems)
{
function itemAttribs()
{
return (1 in menuItems[i]) ? menuItems[i][1] : null;
};
var parentId = parentNode.getAttribute("id");
for (var i in menuItems)
{
var itemName = menuItems[i][0];
if (itemName[0] == ">")
{
itemName = itemName.substr(1);
if (!ASSERT(itemName in this.menuSpecs,
"unknown submenu " + itemName + " referenced in " +
parentId))
{
continue;
}
this.createMenu (parentNode, beforeNode, itemName,
parentId + ":" + itemName, itemAttribs());
}
else if (itemName in this.commandManager.commands)
{
this.appendMenuItem (parentNode, beforeNode, itemName,
itemAttribs());
}
else if (itemName == "-")
{
this.appendMenuSeparator (parentNode, beforeNode, itemAttribs());
}
else
{
dd ("unknown command " + itemName + " referenced in " + parentId);
}
}
}

View File

@@ -1,222 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, <rginda@netscape.com>, original author
*
*/
function MessageManager()
{
const UC_CTRID = "@mozilla.org/intl/scriptableunicodeconverter";
const nsIUnicodeConverter =
Components.interfaces.nsIScriptableUnicodeConverter;
this.ucConverter =
Components.classes[UC_CTRID].getService(nsIUnicodeConverter);
this.defaultBundle = null;
this.bundleList = new Array();
}
MessageManager.prototype.addBundle =
function mm_addbundle(bundlePath, targetWindow)
{
var bundle = srGetStrBundle(bundlePath);
this.bundleList.push(bundle);
this.importBundle(bundle, targetWindow, this.bundleList.length - 1);
return bundle;
}
MessageManager.prototype.importBundle =
function mm_importbundle(bundle, targetWindow, index)
{
const nsIPropertyElement = Components.interfaces.nsIPropertyElement;
if (!targetWindow)
targetWindow = window;
if (typeof index == "undefined")
index = arrayIndexOf(this.bundleList, bundle);
var pfx;
if (index == 0)
pfx = "";
else
pfx = index + ":";
var enumer = bundle.getSimpleEnumeration();
while (enumer.hasMoreElements())
{
var prop = enumer.getNext().QueryInterface(nsIPropertyElement);
var ary = prop.key.match (/^(msg|msn)/);
if (ary)
{
var constValue;
var constName = prop.key.toUpperCase().replace (/\./g, "_");
if (ary[1] == "msn" || prop.value.search(/%(\d+\$)?s/i) != -1)
constValue = pfx + prop.key;
else
constValue = prop.value.replace (/^\"/, "").replace (/\"$/, "");
targetWindow[constName] = constValue;
}
}
if (this.bundleList.length == 1)
this.defaultBundle = bundle;
}
MessageManager.prototype.checkCharset =
function mm_checkset(charset)
{
try
{
this.ucConverter.charset = charset;
}
catch (ex)
{
return false;
}
return true;
}
MessageManager.prototype.toUnicode =
function mm_tounicode(msg, charset)
{
if (!charset)
return msg;
try
{
this.ucConverter.charset = charset;
msg = this.ucConverter.ConvertToUnicode(msg);
}
catch (ex)
{
//dd ("caught exception " + ex + " converting " + msg + " to charset " +
// charset);
}
return msg;
}
MessageManager.prototype.fromUnicode =
function mm_fromunicode(msg, charset)
{
if (!charset)
return msg;
if (charset != this.ucConverter.charset)
this.ucConverter.charset = charset;
try
{
if ("Finish" in this.ucConverter)
{
msg = this.ucConverter.ConvertFromUnicode(msg);
this.ucConverter.Finish();
}
else
{
msg = this.ucConverter.ConvertFromUnicode(msg + " ");
msg = msg.substr(0, msg.length - 1);
}
}
catch (ex)
{
//dd ("caught exception " + ex + " converting " + msg + " to charset " +
// charset);
}
return msg;
}
MessageManager.prototype.getMsg =
function mm_getmsg (msgName, params, deflt)
{
try
{
var bundle;
var ary = msgName.match (/(\d+):(.+)/);
if (ary)
{
return (this.getMsgFrom(this.bundleList[ary[1]], ary[2], params,
deflt));
}
return this.getMsgFrom(this.bundleList[0], msgName, params, deflt);
}
catch (ex)
{
ASSERT (0, "Caught exception getting message: " + msgName + "/" +
params);
return deflt ? deflt : msgName;
}
}
MessageManager.prototype.getMsgFrom =
function mm_getfrom (bundle, msgName, params, deflt)
{
try
{
var rv;
if (params && params instanceof Array)
rv = bundle.formatStringFromName (msgName, params, params.length);
else if (params || params == 0)
rv = bundle.formatStringFromName (msgName, [params], 1);
else
rv = bundle.GetStringFromName (msgName);
/* strip leading and trailing quote characters, see comment at the
* top of venkman.properties.
*/
rv = rv.replace (/^\"/, "");
rv = rv.replace (/\"$/, "");
return rv;
}
catch (ex)
{
if (typeof deflt == "undefined")
{
ASSERT (0, "caught exception getting value for ``" + msgName +
"''\n" + ex + "\n");
return msgName;
}
return deflt;
}
return null;
}

View File

@@ -1,383 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, <rginda@netscape.com>, original author
*
*/
const PREF_RELOAD = true;
const PREF_WRITETHROUGH = true;
function PrefManager (branchName)
{
var prefManager = this;
function pm_observe (prefService, topic, prefName)
{
var r = prefManager.prefRecords[prefName];
if (!r)
return;
var oldValue = (r.realValue != null) ? r.realValue : r.defaultValue;
r.realValue = prefManager.getPref(prefName, PREF_RELOAD);
prefManager.onPrefChanged(prefName, r.realValue, oldValue);
};
const PREF_CTRID = "@mozilla.org/preferences-service;1";
const nsIPrefService = Components.interfaces.nsIPrefService;
const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
const nsIPrefBranchInternal = Components.interfaces.nsIPrefBranchInternal;
this.prefService =
Components.classes[PREF_CTRID].getService(nsIPrefService);
this.prefBranch = this.prefService.getBranch(branchName);
this.defaultValues = new Object();
this.prefs = new Object();
this.prefNames = new Array();
this.prefRecords = new Object();
this.observer = { observe: pm_observe };
this.prefBranchInternal =
this.prefBranch.QueryInterface(nsIPrefBranchInternal);
this.prefBranchInternal.addObserver("", this.observer, false);
this.valid = true;
}
PrefManager.prototype.destroy =
function pm_destroy()
{
if (this.valid)
{
this.prefBranchInternal.removeObserver("", this.observer);
this.valid = false;
}
}
PrefManager.prototype.getBranch =
function pm_getbranch(suffix)
{
return this.prefService.getBranch(this.prefBranch.root + suffix);
}
PrefManager.prototype.getBranchManager =
function pm_getbranchmgr(suffix)
{
return new PrefManager(this.prefBranch.root + suffix);
}
PrefManager.prototype.onPrefChanged =
function pm_changed(prefName, prefManager, topic)
{
/* clients can override this to hear about pref changes */
}
PrefManager.prototype.listPrefs =
function pm_listprefs (prefix)
{
var list = new Array();
var names = this.prefNames;
for (var i = 0; i < names.length; ++i)
{
if (!prefix || names[i].indexOf(prefix) == 0)
list.push (names[i]);
}
return list;
}
PrefManager.prototype.readPrefs =
function pm_readprefs ()
{
const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
var list = this.prefBranch.getChildList("", {});
for (var i = 0; i < list.length; ++i)
{
if (!(list[i] in this))
{
var type = this.prefBranch.getPrefType (list[i]);
var defaultValue;
switch (type)
{
case nsIPrefBranch.PREF_INT:
defaultValue = 0;
break;
case nsIPrefBranch.PREF_BOOL:
defaultValue = false;
break;
default:
defaultValue = "";
}
this.addPref(list[i], defaultValue);
}
}
}
PrefManager.prototype.isKnownPref =
function pm_ispref(prefName)
{
return (prefName in this.prefRecords);
}
PrefManager.prototype.addPrefs =
function pm_addprefs(prefSpecs)
{
for (var i = 0; i < prefSpecs.length; ++i)
{
this.addPref(prefSpecs[i][0], prefSpecs[i][1],
2 in prefSpecs[i] ? prefSpecs[i][2] : null);
}
}
PrefManager.prototype.addDeferredPrefs =
function pm_addprefsd(targetManager, writeThrough)
{
function deferGet(prefName)
{
return targetManager.getPref(prefName);
};
function deferSet(prefName, value)
{
return targetManager.setPref(prefName, value);
};
var setter = null;
if (writeThrough)
setter = deferSet;
var prefs = targetManager.prefs;
for (var i = 0; i < prefs.length; ++i)
this.addPref(prefs[i], deferGet, setter);
}
PrefManager.prototype.updateArrayPref =
function pm_arrayupdate(prefName)
{
var record = this.prefRecords[prefName];
if (!ASSERT(record, "Unknown pref: " + prefName))
return;
if (record.realValue == null)
record.realValue = record.defaultValue;
if (!ASSERT(record.realValue instanceof Array, "Pref is not an array"))
return;
this.prefBranch.setCharPref(prefName, this.arrayToString(record.realValue));
this.prefService.savePrefFile(null);
}
PrefManager.prototype.stringToArray =
function pm_s2a(string)
{
if (string.search(/\S/) == -1)
return [];
var ary = string.split(/\s*;\s*/);
for (var i = 0; i < ary.length; ++i)
ary[i] = unescape(ary[i]);
return ary;
}
PrefManager.prototype.arrayToString =
function pm_a2s(ary)
{
var escapedAry = new Array()
for (var i = 0; i < ary.length; ++i)
escapedAry[i] = escape(ary[i]);
return escapedAry.join("; ");
}
PrefManager.prototype.getPref =
function pm_getpref(prefName, reload)
{
var prefManager = this;
function updateArrayPref() { prefManager.updateArrayPref(prefName); };
var record = this.prefRecords[prefName];
if (!ASSERT(record, "Unknown pref: " + prefName))
return null;
var defaultValue;
if (typeof record.defaultValue == "function")
{
// deferred pref, call the getter, and don't cache the result.
defaultValue = record.defaultValue(prefName);
}
else
{
if (!reload && record.realValue != null)
return record.realValue;
defaultValue = record.defaultValue;
}
var realValue = null;
try
{
if (typeof defaultValue == "boolean")
{
realValue = this.prefBranch.getBoolPref(prefName);
}
else if (typeof defaultValue == "number")
{
realValue = this.prefBranch.getIntPref(prefName);
}
else if (defaultValue instanceof Array)
{
realValue = this.prefBranch.getCharPref(prefName);
realValue = this.stringToArray(realValue);
realValue.update = updateArrayPref;
}
else if (typeof defaultValue == "string" ||
defaultValue == null)
{
realValue = this.prefBranch.getCharPref(prefName);
}
}
catch (ex)
{
// if the pref doesn't exist, ignore the exception.
}
if (realValue == null)
return defaultValue;
record.realValue = realValue;
return realValue;
}
PrefManager.prototype.setPref =
function pm_setpref(prefName, value)
{
var prefManager = this;
function updateArrayPref() { prefManager.updateArrayPref(prefName); };
var record = this.prefRecords[prefName];
if (!ASSERT(record, "Unknown pref: " + prefName))
return null;
if ((record.realValue == null && value == record.defaultValue) ||
record.realValue == value)
{
// no realvalue, and value is the same as default value ... OR ...
// no change at all. just bail.
return record.realValue;
}
if (value == record.defaultValue)
{
this.clearPref(prefName);
return value;
}
var defaultValue = record.defaultValue;
if (typeof defaultValue == "function")
defaultValue = defaultValue(prefName);
if (typeof defaultValue == "boolean")
{
this.prefBranch.setBoolPref(prefName, value);
}
else if (typeof defaultValue == "number")
{
this.prefBranch.setIntPref(prefName, value);
}
else if (defaultValue instanceof Array)
{
var str = this.arrayToString(value);
this.prefBranch.setCharPref(prefName, str);
value.update = updateArrayPref;
}
else
{
this.prefBranch.setCharPref(prefName, value);
}
this.prefService.savePrefFile(null);
record.realValue = value;
return value;
}
PrefManager.prototype.clearPref =
function pm_reset(prefName)
{
this.prefRecords[prefName].realValue = null;
this.prefBranch.clearUserPref(prefName);
this.prefService.savePrefFile(null);
}
PrefManager.prototype.addPref =
function pm_addpref(prefName, defaultValue, setter)
{
var prefManager = this;
function updateArrayPref() { prefManager.updateArrayPref(prefName); };
function prefGetter() { return prefManager.getPref(prefName); };
function prefSetter(value) { return prefManager.setPref(prefName, value); };
if (!ASSERT(!(prefName in this.defaultValues),
"Preference already exists: " + prefName))
{
return;
}
if (!setter)
setter = prefSetter;
if (defaultValue instanceof Array)
defaultValue.update = updateArrayPref;
this.prefRecords[prefName] = {defaultValue: defaultValue, realValue: null};
this.prefNames.push(prefName);
this.prefNames.sort();
this.prefs.__defineGetter__(prefName, prefGetter);
this.prefs.__defineSetter__(prefName, setter);
}

View File

@@ -1,820 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
*
* JavaScript utility functions.
*
* 1999-08-15 rginda@ndcico.com v1.0
*/
var utils = new Object();
var DEBUG = true;
var dd;
if (DEBUG) {
var _dd_pfx = "";
var _dd_singleIndent = " ";
var _dd_indentLength = _dd_singleIndent.length;
var _dd_currentIndent = "";
var _dd_lastDumpWasOpen = false;
var _dd_timeStack = new Array();
var _dd_disableDepth = Number.MAX_VALUE;
var _dd_currentDepth = 0;
dd = function _dd(str) {
if (typeof str != "string") {
dump (str + "\n");
} else if (str[str.length - 1] == "{") {
++_dd_currentDepth;
if (_dd_currentDepth >= _dd_disableDepth)
return;
if (str.indexOf("OFF") == 0)
_dd_disableDepth = _dd_currentDepth;
_dd_timeStack.push (new Date());
if (_dd_lastDumpWasOpen)
dump("\n");
dump (_dd_pfx + _dd_currentIndent + str);
_dd_currentIndent += _dd_singleIndent;
_dd_lastDumpWasOpen = true;
} else if (str[0] == "}") {
if (--_dd_currentDepth >= _dd_disableDepth)
return;
_dd_disableDepth = Number.MAX_VALUE;
var sufx = (new Date() - _dd_timeStack.pop()) / 1000 + " sec";
_dd_currentIndent =
_dd_currentIndent.substr(0, _dd_currentIndent.length -
_dd_indentLength);
if (_dd_lastDumpWasOpen)
dump(str + " " + sufx + "\n");
else
dump(_dd_pfx + _dd_currentIndent + str + " " +
sufx + "\n");
_dd_lastDumpWasOpen = false;
} else {
if (_dd_currentDepth >= _dd_disableDepth)
return;
if (_dd_lastDumpWasOpen)
dump("\n");
dump(_dd_pfx + _dd_currentIndent + str + "\n");
_dd_lastDumpWasOpen = false;
}
}
} else {
dd = function (){};
}
var jsenv = new Object();
jsenv.HAS_SECURITYMANAGER = ((typeof netscape == "object") &&
(typeof netscape.security == "object"));
jsenv.HAS_XPCOM = ((typeof Components == "object") &&
(typeof Components.classes == "object"));
jsenv.HAS_JAVA = (typeof java == "object");
jsenv.HAS_RHINO = (typeof defineClass == "function");
jsenv.HAS_DOCUMENT = (typeof document == "object");
jsenv.HAS_NSPR_EVENTQ = jsenv.HAS_DOCUMENT;
jsenv.HAS_STREAM_PROVIDER = ("nsIStreamProvider" in Components.interfaces);
function dumpObject (o, pfx, sep)
{
var p;
var s = "";
sep = (typeof sep == "undefined") ? " = " : sep;
pfx = (typeof pfx == "undefined") ? "" : pfx;
for (p in o)
{
if (typeof (o[p]) != "function")
s += pfx + p + sep + o[p] + "\n";
else
s += pfx + p + sep + "function\n";
}
return s;
}
/* Dumps an object in tree format, recurse specifiec the the number of objects
* to recurse, compress is a boolean that can uncompress (true) the output
* format, and level is the number of levels to intitialy indent (only useful
* internally.) A sample dumpObjectTree (o, 1) is shown below.
*
* + parent (object)
* + users (object)
* | + jsbot (object)
* | + mrjs (object)
* | + nakkezzzz (object)
* | *
* + bans (object)
* | *
* + topic (string) 'ircclient.js:59: nothing is not defined'
* + getUsersLength (function) 9 lines
* *
*/
function dumpObjectTree (o, recurse, compress, level)
{
var s = "";
var pfx = "";
if (typeof recurse == "undefined")
recurse = 0;
if (typeof level == "undefined")
level = 0;
if (typeof compress == "undefined")
compress = true;
for (var i = 0; i < level; i++)
pfx += (compress) ? "| " : "| ";
var tee = (compress) ? "+ " : "+- ";
for (i in o)
{
var t, ex;
try
{
t = typeof o[i];
}
catch (ex)
{
t = "ERROR";
}
switch (t)
{
case "function":
var sfunc = String(o[i]).split("\n");
if (sfunc[2] == " [native code]")
sfunc = "[native code]";
else
if (sfunc.length == 1)
sfunc = String(sfunc);
else
sfunc = sfunc.length + " lines";
s += pfx + tee + i + " (function) " + sfunc + "\n";
break;
case "object":
s += pfx + tee + i + " (object)\n";
if (!compress)
s += pfx + "|\n";
if ((i != "parent") && (recurse))
s += dumpObjectTree (o[i], recurse - 1,
compress, level + 1);
break;
case "string":
if (o[i].length > 200)
s += pfx + tee + i + " (" + t + ") " +
o[i].length + " chars\n";
else
s += pfx + tee + i + " (" + t + ") '" + o[i] + "'\n";
break;
case "ERROR":
s += pfx + tee + i + " (" + t + ") ?\n";
break;
default:
s += pfx + tee + i + " (" + t + ") " + o[i] + "\n";
}
if (!compress)
s += pfx + "|\n";
}
s += pfx + "*\n";
return s;
}
function replaceVars(str, vars)
{
// replace "string $with a $variable", with
// "string " + vars["with"] + " with a " + vars["variable"]
function doReplace(symbol)
{
var name = symbol.substr(1);
if (name in vars)
return vars[name];
return "$" + name;
};
return str.replace(/(\$\w[\w\d\-]+)/g, doReplace);
}
function formatException (ex)
{
if (ex instanceof Error)
return getMsg (MSG_FMT_JSEXCEPTION, [ex.name, ex.message, ex.fileName,
ex.lineNumber]);
return String(ex);
}
/*
* Clones an existing object (Only the enumerable properties
* of course.) use as a function..
* var c = Clone (obj);
* or a constructor...
* var c = new Clone (obj);
*/
function Clone (obj)
{
var robj = new Object();
for (var p in obj)
robj[p] = obj[p];
return robj;
}
function Copy(source, dest, overwrite)
{
if (!dest)
dest = new Object();
for (var p in source)
{
if (overwrite || !(p in dest))
dest[p] = source[p];
}
return dest;
}
/*
* matches a real object against one or more pattern objects.
* if you pass an array of pattern objects, |negate| controls wether to check
* if the object matches ANY of the patterns, or NONE of the patterns.
*/
function matchObject (o, pattern, negate)
{
negate = Boolean(negate);
function _match (o, pattern)
{
if (pattern instanceof Function)
return pattern(o);
for (p in pattern)
{
var val;
/* nice to have, but slow as molases, allows you to match
* properties of objects with obj$prop: "foo" syntax */
/*
if (p[0] == "$")
val = eval ("o." +
p.substr(1,p.length).replace (/\$/g, "."));
else
*/
val = o[p];
if (pattern[p] instanceof Function)
{
if (!pattern[p](val))
return false;
}
else
{
var ary = (new String(val)).match(pattern[p]);
if (ary == null)
return false;
else
o.matchresult = ary;
}
}
return true;
}
if (!(pattern instanceof Array))
return Boolean (negate ^ _match(o, pattern));
for (var i in pattern)
if (_match (o, pattern[i]))
return !negate;
return negate;
}
function matchEntry (partialName, list)
{
if ((typeof partialName == "undefined") ||
(String(partialName) == ""))
return list;
var ary = new Array();
for (var i in list)
{
if (list[i].indexOf(partialName) == 0)
ary.push (list[i]);
}
return ary;
}
function encodeChar(ch)
{
return "%" + ch.charCodeAt(0).toString(16);
}
function escapeFileName(fileName)
{
return fileName.replace(/[^\w\d.,#-_]/g, encodeChar);
}
function getCommonPfx (list)
{
var pfx = list[0];
var l = list.length;
for (var i = 0; i < l; i++)
{
for (var c = 0; c < pfx.length; ++c)
{
if (c >= list[i].length)
{
pfx = pfx.substr (0, c);
break;
}
else
{
if (pfx[c] != list[i][c])
pfx = pfx.substr (0, c);
}
}
}
return pfx;
}
function openTopWin (url)
{
return openDialog (getBrowserURL(), "_blank", "chrome,all,dialog=no", url);
}
function getWindowByType (windowType)
{
const MEDIATOR_CONTRACTID =
"@mozilla.org/appshell/window-mediator;1";
const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
var windowManager =
Components.classes[MEDIATOR_CONTRACTID].getService(nsIWindowMediator);
return windowManager.getMostRecentWindow(windowType);
}
function renameProperty (obj, oldname, newname)
{
if (oldname == newname)
return;
obj[newname] = obj[oldname];
delete obj[oldname];
}
function newObject(contractID, iface)
{
if (!jsenv.HAS_XPCOM)
return null;
var obj = Components.classes[contractID].createInstance();
var rv;
switch (typeof iface)
{
case "string":
rv = obj.QueryInterface(Components.interfaces[iface]);
break;
case "object":
rv = obj.QueryInterface[iface];
break;
default:
rv = null;
break;
}
return rv;
}
function getContentWindow(frame)
{
try
{
if (!frame || !("contentWindow" in frame))
return false;
return frame.contentWindow;
}
catch (ex)
{
// throws exception is contentWindow is gone
return null;
}
}
function getPriv (priv)
{
if (!jsenv.HAS_SECURITYMANAGER)
return true;
var rv = true;
try
{
netscape.security.PrivilegeManager.enablePrivilege(priv);
}
catch (e)
{
dd ("getPriv: unable to get privlege '" + priv + "': " + e);
rv = false;
}
return rv;
}
function len(o)
{
var l = 0;
for (var p in o)
++l;
return l;
}
function keys (o)
{
var rv = new Array();
for (var p in o)
rv.push(p);
return rv;
}
function stringTrim (s)
{
if (!s)
return "";
s = s.replace (/^\s+/, "");
return s.replace (/\s+$/, "");
}
/* the offset should be in seconds, it will be rounded to 2 decimal places */
function formatDateOffset (offset, format)
{
var seconds = roundTo(offset % 60, 2);
var minutes = Math.floor(offset / 60);
var hours = Math.floor(minutes / 60);
minutes = minutes % 60;
var days = Math.floor(hours / 24);
hours = hours % 24;
if (!format)
{
var ary = new Array();
if (days > 0)
ary.push (getMsg(MSG_DAYS, days));
if (hours > 0)
ary.push (getMsg(MSG_HOURS, hours));
if (minutes > 0)
ary.push (getMsg(MSG_MINUTES, minutes));
if (seconds > 0 || offset == 0)
ary.push (getMsg(MSG_SECONDS, seconds));
format = ary.join(", ");
}
else
{
format = format.replace ("%d", days);
format = format.replace ("%h", hours);
format = format.replace ("%m", minutes);
format = format.replace ("%s", seconds);
}
return format;
}
function arrayContains (ary, elem)
{
return (arrayIndexOf (ary, elem) != -1);
}
function arrayIndexOf (ary, elem)
{
for (var i in ary)
if (ary[i] == elem)
return i;
return -1;
}
function arrayInsertAt (ary, i, o)
{
ary.splice (i, 0, o);
/* doh, forgot about that 'splice' thing
if (ary.length < i)
{
this[i] = o;
return;
}
for (var j = ary.length; j > i; j--)
ary[j] = ary[j - 1];
ary[i] = o;
*/
}
function arrayRemoveAt (ary, i)
{
ary.splice (i, 1);
/* doh, forgot about that 'splice' thing
if (ary.length < i)
return false;
for (var j = i; j < ary.length; j++)
ary[j] = ary[j + 1];
ary.length--;
*/
}
/* length should be an even number >= 6 */
function abbreviateWord (str, length)
{
if (str.length <= length || length < 6)
return str;
var left = str.substr (0, (length / 2) - 1);
var right = str.substr (str.length - (length / 2) + 1);
return left + "..." + right;
}
/*
* Inserts the string |hyphen| into string |str| every |pos| characters.
* If there are any wordbreaking characters in |str| within -/+5 characters of
* of a |pos| then the hyphen is inserted there instead, in order to produce a
* "cleaner" break.
*/
function hyphenateWord (str, pos, hyphen)
{
if (str.length <= pos)
return str;
if (typeof hyphen == "undefined")
hyphen = " ";
/* search for a nice place to break the word, fuzzfactor of +/-5, centered
* around |pos| */
var splitPos =
str.substring(pos - 5, pos + 5).search(/[^A-Za-z0-9]/);
splitPos = (splitPos != -1) ? pos - 4 + splitPos : pos;
var left = str.substr (0, splitPos);
var right = hyphenateWord(str.substr (splitPos), pos, hyphen);
return left + hyphen + right;
}
/*
* Like hyphenateWord, except individual chunks of the word are returned as
* elements of an array.
*/
function splitLongWord (str, pos)
{
if (str.length <= pos)
return [str];
var ary = new Array();
var right = str;
while (right.length > pos)
{
/* search for a nice place to break the word, fuzzfactor of +/-5,
* centered around |pos| */
var splitPos =
right.substring(pos - 5, pos + 5).search(/[^A-Za-z0-9]/);
splitPos = (splitPos != -1) ? pos - 4 + splitPos : pos;
ary.push(right.substr (0, splitPos));
right = right.substr (splitPos);
}
ary.push (right);
return ary;
}
function getRandomElement (ary)
{
return ary[Math.floor(Math.random() * ary.length)];
}
function roundTo (num, prec)
{
return Math.round(num * Math.pow (10, prec)) / Math.pow (10, prec);
}
function randomRange (min, max)
{
if (typeof min == "undefined")
min = 0;
if (typeof max == "undefined")
max = 1;
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getStackTrace ()
{
if (!jsenv.HAS_XPCOM)
return "No stack trace available.";
var frame = Components.stack.caller;
var str = "<top>";
while (frame)
{
var name = frame.name ? frame.name : "[anonymous]";
str += "\n" + name + "@" + frame.lineNumber;
frame = frame.caller;
}
return str;
}
function getInterfaces (cls)
{
if (!jsenv.HAS_XPCOM)
return null;
var rv = new Object();
var e;
for (var i in Components.interfaces)
{
try
{
var ifc = Components.interfaces[i];
cls.QueryInterface(ifc);
rv[i] = ifc;
}
catch (e)
{
/* nada */
}
}
return rv;
}
/**
* Calls a named function for each element in an array, sending
* the same parameter each call.
*
* @param ary an array of objects
* @param func_name string name of function to call.
* @param data data object to pass to each object.
*/
function mapObjFunc(ary, func_name, data)
{
/*
* WARNING: Caller assumes resonsibility to verify ary
* and func_name
*/
for (var i in ary)
ary[i][func_name](data);
}
/**
* Passes each element of an array to a given function object.
*
* @param func a function object.
* @param ary an array of values.
*/
function map(func, ary) {
/*
* WARNING: Caller assumnes responsibility to verify
* func and ary.
*/
for (var i in ary)
func(ary[i]);
}
function getSpecialDirectory(name)
{
if (!("directoryService" in utils))
{
const DS_CTR = "@mozilla.org/file/directory_service;1";
const nsIProperties = Components.interfaces.nsIProperties;
utils.directoryService =
Components.classes[DS_CTR].getService(nsIProperties);
}
return utils.directoryService.get(name, Components.interfaces.nsIFile);
}
function getFileFromURLSpec(url)
{
const FILE_CTRID = "@mozilla.org/network/protocol;1?name=file";
const nsIFileProtocolHandler = Components.interfaces.nsIFileProtocolHandler;
var handler = Components.classes[FILE_CTRID].createInstance();
handler = handler.QueryInterface(nsIFileProtocolHandler);
return handler.getFileFromURLSpec(url);
}
function getURLSpecFromFile (file)
{
if (!file)
return null;
const IOS_CTRID = "@mozilla.org/network/io-service;1";
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
const nsIIOService = Components.interfaces.nsIIOService;
const nsILocalFile = Components.interfaces.nsILocalFile;
if (typeof file == "string")
{
var fileObj =
Components.classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
fileObj.initWithPath(file);
file = fileObj;
}
var service = Components.classes[IOS_CTRID].getService(nsIIOService);
/* In sept 2002, bug 166792 moved this method to the nsIFileProtocolHandler
* interface, but we need to support older versions too. */
if ("getURLSpecFromFile" in service)
return service.getURLSpecFromFile(file);
var nsIFileProtocolHandler = Components.interfaces.nsIFileProtocolHandler;
var fileHandler = service.getProtocolHandler("file");
fileHandler = fileHandler.QueryInterface(nsIFileProtocolHandler);
return fileHandler.getURLSpecFromFile(file);
}

View File

@@ -1,630 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
*/
/*
* Dissociated Press javascript for the jsbot
* see: http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?query=dissociated%20press
*/
DP_DEBUG = false;
if (DP_DEBUG)
dpprint = dd;
else
dpprint = (function () {});
function CDPressMachine()
{
this.wordPivots = new Object();
this.cleanCounter = 0;
this.cleanCount = 0;
}
CDPressMachine.CLEAN_CYCLE = 1000; // list will be trimmed after this many
// or never if < 1 addPhrase()s
CDPressMachine.CLEAN_THRESHOLD = 2; // anything <= this will be trimmed
CDPressMachine.RANDOMIZE_DEPTH = 10; // not used yet
CDPressMachine.MIN_PHRASE_LENGTH = 3; // requested minimum phrase length
CDPressMachine.MAX_PHRASE_LENGTH = 8; // requested maximum phrase length
CDPressMachine.LENGTH_RETRIES = 3 // number of retries per word
// (to reach maxlen)
CDPressMachine.WORD_PATTERN = /[\x21-\x7e]+/; // pattern for words
/**
* Adds a phrase to the engine
*/
CDPressMachine.prototype.addPhrase =
function DPM_addPhrase (strPhrase, weight)
{
if (strPhrase == "")
return;
this.cleanCounter++;
if ((CDPressMachine.CLEAN_CYCLE >= 1) &&
(this.cleanCounter >= CDPressMachine.CLEAN_CYCLE))
{
dpprint ("** cleaning list");
this.cleanCounter = 0;
this.trimList (CDPressMachine.CLEAN_THRESHOLD);
this.cleancount++;
}
strPhrase = strPhrase.toLowerCase();
/* split the phrase */
var aryWordMatches = strPhrase.split (" ");
var previousWord = aryWordMatches[aryWordMatches.length - 1];
previousWord = previousWord.match(CDPressMachine.WORD_PATTERN);
var nextWord = "";
/* loop through each word */
for (var i=-1; i < aryWordMatches.length; i++)
{
var currentWord = nextWord;
var currentWordPivot = this.wordPivots[currentWord];
if (typeof currentWordPivot == "undefined")
currentWordPivot =
(this.wordPivots[currentWord] = new CWordPivot (currentWord));
currentWordPivot.previousList.addLink (previousWord, weight);
if (i < aryWordMatches.length - 1)
{
nextWord = aryWordMatches[i + 1];
if (nextWord == (String.fromCharCode(1) + "action"))
nextWord = escape(nextWord.toUpperCase());
else
nextWord = nextWord.match(CDPressMachine.WORD_PATTERN);
if (nextWord == null)
nextWord = ""; //this is weak
currentWordPivot.nextList.addLink (nextWord, weight);
}
else
currentWordPivot.nextList.addLink ("");
previousWord = currentWord;
}
}
CDPressMachine.prototype.addPhrases =
function DPM_addPhrases(phrases)
{
for (var i in phrases)
this.addPhrase (phrases[i]);
}
/**
* Gets a phrase from the engine, starting from seedWord.
* if dir is greater than 0, then seedWord will be the first in
* the phrase, otherwise it will be the last
*/
CDPressMachine.prototype.getPhraseDirected =
function DPM_getPhraseDirected(seedWord, dir)
{
var word = (typeof seedWord != "undefined") ? seedWord : "";
var tempword = word;
var rval = "";
var c = 0, retry = 0;
dpprint ("DPM_getPhraseDirected: '" + word + "' " + dir);
if (typeof this.wordPivots[word] == "undefined")
return;
do
{
if (typeof this.wordPivots[word] == "undefined")
{
dd ("** DP Error: Word '" + word + "' is not a pivot **");
return;
}
if (dir > 0) // pick a word
word= this.wordPivots[word].nextList.getRandomLink().link;
else
word= this.wordPivots[word].previousList.getRandomLink().link;
if (word != "") // if it isnt blank
{
dpprint ("DPM_getPhraseDirected: got word '" + word + "'");
if (c < CDPressMachine.MIN_PHRASE_LENGTH)
retry = 0;
if (c > CDPressMachine.MAX_PHRASE_LENGTH)
if (((dir > 0) && (this.wordPivots[word].nextList.list[""])) ||
((dir <= 0) &&
(this.wordPivots[word].previousList.list[""])))
{
dpprint ("DPM_getPhraseDirected: forcing last word");
word="";
rval = rval.substring (0, rval.length - 1);
break;
}
if (dir > 0)
rval += word + " "; // put it in the rslt
else
rval = word + " " + rval;
c++; // count the word
}
else // otherwise
{
dpprint ("DPM_getPhraseDirected: last word");
// if it's too short
// and were not out of retrys
if ((c < CDPressMachine.MIN_PHRASE_LENGTH) &&
(retry++ < CDPressMachine.LENGTH_RETRIES))
word = tempword; // try again
else
// otherwise, we're done
rval = rval.substring (0, rval.length - 1);
}
tempword = word;
} while (word != "");
rval = unescape (rval);
return rval;
}
CDPressMachine.prototype.getPhraseForward =
function DPM_getPhraseForward(firstWord)
{
return this.getPhraseDirected (firstWord, 1)
}
CDPressMachine.prototype.getPhraseReverse =
function DPM_getPhraseReverse(lastWord)
{
return this.getPhraseDirected (lastWord, -1)
}
/**
* locates a random pivot by following CDPressMachine.RANDOMIZE_DEPTH
* links from |word|.
*/
CDPressMachine.prototype.getRandomPivot =
function DPM_getRandomPivot (word)
{
/**
* XXXrgg: erm, this is currently pointless, but could be neat later
* if max phrase length's were implemented.
*/
if (false)
{
var depth = parseInt (Math.round
(CDPressMachine.RANDOMIZE_DEPTH * Math.random()));
word = "";
for (var i = 0;
i < depth, word =
this.wordPivots[word].nextList.getRandomLink().link;
i++); /* empty loop */
}
}
CDPressMachine.prototype.getPhrase =
function DPM_getPhrase(word)
{
var rval = this.getPhraseContaining (word);
return rval;
}
/**
* Returns a phrase with |word| somewhere in it.
*/
CDPressMachine.prototype.getPhraseContaining =
function DPM_getPhraseContaining(word)
{
if (typeof word == "undefined")
word = "";
else
word = word.toString();
dpprint ("* DPM_getPhraseContaining: '" + word + "'");
var rval, spc;
var post, pre = this.getPhraseReverse (word);
if (word != "")
var post = this.getPhraseForward (word);
dpprint ("* DPM_getPhraseContaining: pre = '" + pre + "' post = '" +
post + "'");
dpprint ("* DPM_getPhraseContaining: " + (post == "" && pre == ""));
if (word)
{
word = unescape (word);
spc = " ";
}
else
spc = "";
if (pre)
{
if (post)
rval = pre + spc + word + spc + post;
else
rval = pre + spc + word;
}
else
{
if (post)
rval = word + spc + post;
else
if (post == "" && pre == "")
rval = word;
}
if (rval && (rval.charCodeAt(0) == 1))
rval += String.fromCharCode(1);
dpprint ("* DPM_getPhraseContaining: returning '" + rval + "'");
return rval;
}
CDPressMachine.prototype.getPhraseWeight =
function DPM_getPhraseWeight (phrase)
{
var ary = this.getPhraseWeights (phrase);
var w = 0;
while (ary.length > 0)
w += ary.pop();
return w;
}
CDPressMachine.prototype.getPhraseWeights =
function DPM_getPhraseWeights (phrase)
{
var words, ary = new Array();
var lastword = "";
var link, pivot;
if (!phrase)
return ary;
words = phrase.split (" ");
for (var i = 0; i < words.length; i++)
{
if (i == 0)
{
lastWord = "";
nextWord = words[i + 1];
}
else if (i == words.length - 1)
{
lastWord = words[i - 1];
nextWord = "";
}
else
{
lastWord = words[i - 1];
nextWord = words[i + 1];
}
pivot = this.wordPivots[words[i]];
if (pivot)
{
link = pivot.previousList.list[lastWord];
if (link)
ary.push(link.weight);
else
ary.push(0);
link = pivot.nextList.list[nextWord];
if (link)
ary.push(link.weight);
else
ary.push(0);
}
else
{
ary.push(0);
ary.push(0);
}
}
return ary;
}
CDPressMachine.prototype.getPivot =
function DPM_getPivot(word)
{
return this.wordPivots[word];
}
CDPressMachine.prototype.trimList =
function DPM_trimList(threshold)
{
var el;
var c;
for (el in this.wordPivots)
{
c = this.wordPivots[el].nextList.trimList (threshold);
if (c == 0)
delete this.wordPivots[el];
else
{
c = this.wordPivots[el].previousList.trimList (threshold);
if (c == 0)
delete this.wordPivots[el];
}
}
}
CDPressMachine.prototype.getMachineStatus =
function DPM_getMachineStatus()
{
var o = new Object();
o.pivotcount = 0;
o.linkcount = 0;
o.linksperpivot = 0;
o.maxweight = 0;
o.minweight = Number.MAX_VALUE;
o.averageweight = 0;
o.cleancounter = this.cleanCounter;
o.cleancount = this.cleanCount;
for (var pivot in this.wordPivots)
{
o.pivotcount++;
for (var link in this.wordPivots[pivot].previousList.list)
{
var l = this.wordPivots[pivot].previousList.list[link];
o.linkcount++;
o.maxweight = Math.max (o.maxweight, l.weight);
o.minweight = Math.min (o.minweight, l.weight);
(o.averageweight == 0) ?
o.averageweight = l.weight :
o.averageweight = (l.weight + o.averageweight) / 2;
}
}
o.linksperpivot = o.linkcount / o.pivotcount;
return o;
}
////////////////////////
function CWordPivot (word)
{
dpprint ("* new pivot : '" + word + "'");
this.word = word;
this.nextList = new CPhraseLinkList(word, "next");
this.previousList = new CPhraseLinkList(word, "prevoius");
}
///////////////////////
function CPhraseLinkList (parentWord, listID)
{
if (DP_DEBUG)
{
this.parentWord = parentWord;
this.listID = listID;
}
this.list = new Object();
}
CPhraseLinkList.prototype.addLink =
function PLL_addLink (link, weight)
{
var existingLink = this.list[link];
dpprint ("* adding link to '" + link + "' from '" + this.parentWord +
"' in list '" + this.listID + "'");
if (typeof weight == "undefined")
weight = 1;
if (typeof existingLink == "undefined")
this.list[link] = new CPhraseLink (link, weight);
else
if (!(typeof existingLink.adjust == "function"))
dd("existingLink.adjust is a '" + existingLink.adjust + "' " +
"not a function! link is '" + link +"'");
else
existingLink.adjust (weight);
}
CPhraseLinkList.prototype.getRandomLink =
function PLL_getRandomLink ()
{
var tot = 0;
var lastMatch = "";
var aryChoices = new Array();
var fDone = false;
dpprint ("* PLL_getRandomLink: from '" + this.parentWord + "'");
for (el in this.list)
{
tot += this.list[el].weight;
for (var i = 0; i< aryChoices.length; i++)
if (this.list[el].weight <= aryChoices[i].weight)
break;
arrayInsertAt (aryChoices, i, this.list[el]);
}
if (DP_DEBUG)
for (var i = 0; i < aryChoices.length; i++)
dpprint ("** potential word '" + aryChoices[i].link + "', weight " +
aryChoices[i].weight);
var choice = parseInt (Math.round(((tot - 1) * Math.random()) + 1));
dpprint ("* PLL_getRandomLink: tot = " + tot + ", choice = " + choice);
tot = 0;
for (i = 0; i < aryChoices.length; i++)
{
if ((tot += aryChoices[i].weight) >= choice)
{
lastMatch = aryChoices[i];
break;
}
}
if (lastMatch == "")
lastMatch = aryChoices[aryChoices.length - 1];
if (!lastMatch)
lastMatch = {link: ""}
dpprint ("* PLL_getRandomLink: returning: " + lastMatch);
return lastMatch;
}
CPhraseLinkList.prototype.getListWeights =
function PLL_getListWeights ()
{
var ary = new Array();
for (var el in this.list)
ary.push (this.list[el].weight);
return ary;
}
CPhraseLinkList.prototype.getListLinks =
function PLL_getListLinks ()
{
var ary = new Array();
for (var el in this.list)
ary.push (this.list[el].link);
return ary;
}
CPhraseLinkList.prototype.trimList =
function PLL_trimList (threshold)
{
var el;
var c;
dpprint ("trimming '" + this.parentWord + "'s list to " + threshold);
for (el in this.list)
{
c++;
if (this.list[el].weight <= threshold)
{
dpprint ("removing '" + el + "' from '" + this.parentWord + "'s '" +
this.listID + "' list, because it's weight is " +
this.list[el].weight);
delete this.list[el];
c--;
}
}
return c;
}
////////////////////////
function CPhraseLink (link, weight)
{
if (typeof weight == "undefined")
this.weight = 1;
else
this.weight = weight;
this.link = link;
}
CPhraseLink.prototype.adjust =
function PL_adjust(weight)
{
if ((this.weight += weight) < 1)
this.weight = 1;
}
CPhraseLink.prototype.weight =
function PL_weight ()
{
return this.weight;
}

View File

@@ -1,397 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Sample bot
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
* depends on utils.js, events.js, connection.js, http.js, and irc.js
*
* Sample client for the irc library.
*/
var LIB_PATH = "../lib/";
bot = new Object();
bot.ownerPatterns = new Array();
bot.personality = new Object();
bot.personality.hooks = new Array();
bot.prefix = "!js ";
function loadDeps()
{
load (LIB_PATH + "utils.js");
load (LIB_PATH + "events.js");
load (LIB_PATH + "connection.js");
load (LIB_PATH + "http.js");
load (LIB_PATH + "dcc.js");
load (LIB_PATH + "irc.js");
load (LIB_PATH + "irc-debug.js");
if (!connection_init(LIB_PATH))
return false;
return true;
}
function initStatic()
{
if (jsenv.HAS_RHINO)
gc = java.lang.System.gc;
CIRCNetwork.prototype.INITIAL_NICK = "jsbot";
CIRCNetwork.prototype.INITIAL_NAME = "XPJSBot";
CIRCNetwork.prototype.INITIAL_DESC = "XPCOM Javascript bot";
CIRCNetwork.prototype.INITIAL_CHANNEL = "#jsbot";
CIRCNetwork.prototype.stayingPower = true;
CIRCNetwork.prototype.on433 = my_433;
CIRCChannel.prototype.onPrivmsg = my_chan_privmsg;
CIRCUser.prototype.onDCCChat = my_user_dccchat;
CDCCChat.prototype.onRawData = my_dccchat_rawdata;
}
/*
* One time initilization stuff
*/
function init(obj)
{
obj.eventPump = new CEventPump (100);
obj.networks = new Object();
obj.networks["hybridnet"] =
new CIRCNetwork ("hybridnet", [{name: "irc.ssc.net", port: 6667}],
obj.eventPump);
obj.networks["moznet"] =
new CIRCNetwork ("moznet", [{name: "irc.mozilla.org", port: 6667}],
obj.eventPump);
obj.networks["efnet"] =
new CIRCNetwork ("efnet", [
{name: "irc.mcs.net", port: 6667},
{name: "irc.cs.cmu.edu", port: 6667}],
obj.eventPump);
obj.primNet = obj.networks["efnet"];
}
/*
* Kick off the mainloop for the first time
*/
function go()
{
if (!loadDeps())
return false;
initStatic();
init(bot);
if (DEBUG)
/* hook all events EXCEPT server.poll and *.event-end types
* (the 4th param inverts the match) */
bot.eventPump.addHook ([{type: "poll", set: /^(server|dcc-chat)$/},
{type: "event-end"}], event_tracer,
"event-tracer", true /* negate */);
if (typeof initPersonality == "function")
initPersonality();
bot.primNet.connect();
rego();
return true;
}
/*
* If you didnt compile libjs with JS_HAS_ERROR_EXCEPTIONS, any error the
* bot encounters will exit the mainloop and drop you back to a shell ("js>")
* prompt. You can continue the mainloop by executing this function.
*/
function rego()
{
/* mainloop */
while (bot.eventPump.queue.length > 0)
{
bot.eventPump.stepEvents();
if (typeof gc == "function")
{
if ((typeof bot.lastGc == "undefined") ||
(Number(new Date()) - bot.lastGc > 60000))
{
gc();
bot.lastGc = Number(new Date());
}
}
}
dd ("No events to process.");
return true;
}
function addOwner (pattern)
{
bot.ownerPatterns.push (pattern);
}
function userIsOwner (user)
{
if (!user.host)
{
/* we havn't got any information on this user yet. They havn't spoken
* yet, and we havn't /whoi's them yet. Say no for now, but do the
* /whois so we'll know for sure next time.
*/
if (user.TYPE == "IRCChanUser")
user.parent.parent.sendData ("WHOIS " + user.nick + "\n");
else
user.parent.sendData ("WHOIS " + user.nick + "\n");
return false;
}
var userString = user.nick + "!" + user.name + "@" + user.host;
dd ("userIsOwner: checking userString `" + userString + "' against:");
for (var p in bot.ownerPatterns)
if (userString.search(bot.ownerPatterns[p]) != -1)
{
dd (String(bot.ownerPatterns[p]) + " passed.");
return true;
}
else
dd (String(bot.ownerPatterns[p]) + " fails.");
return false;
}
function psn_isAddressedToMe (e)
{
if (!e.server)
return false;
if ((e.type.search(/privmsg|ctcp-action/)) || (e.set != "channel") ||
(e.meat.indexOf(bot.prefix) == 0))
return false;
/*
dd ("-*- checking to see if message '" + e.meat + "' is addressed to me.");
*/
var regex = new RegExp ("^\\s*" + e.server.me.nick + "\\W+(.*)", "i");
var ary = e.meat.match(regex);
//dd ("address match: " + ary);
if (ary != null)
{
e.statement = ary[1];
return true;
}
bot.personality.dp.addPhrase (e.meat);
return false;
}
function psn_onAddressedMsg (e)
{
bot.eventPump.onHook (e, bot.personality.hooks);
return false;
}
bot.personality.addHook =
function psn_addhook (pattern, f, name, neg, enabled)
{
if (pattern instanceof RegExp)
pattern = {statement: pattern};
return bot.eventPump.addHook (pattern, f, name, neg, enabled,
bot.personality.hooks);
}
function bot_eval(e, script)
{
try
{
var v = eval(script);
}
catch (ex)
{
e.replyTo.say(e.user.nick + ": " + String(ex));
return false;
}
if (typeof (v) != "undefined")
{
if (v != null)
v = String(v);
else
v = "null";
var rsp = e.user.nick + ", your result is,";
if (v.indexOf ("\n") != -1)
rsp += "\n";
else
rsp += " ";
e.replyTo.say (rsp + v);
}
}
/*
* The following my_* are attached to their proper objects in the init()
* function. This is because the CIRC* objects are not defined at load time
* (they get defined when loadDeps() loads the irc library) and so connecting
* them here would cause an error.
*/
/*
* What to do when a privmsg is recieved on a channel
*/
function my_chan_privmsg (e)
{
var user = e.user;
var meat = e.meat;
if (meat.indexOf(bot.prefix) == 0 && userIsOwner(user))
{
/* if last char is a continuation character, then... */
if (meat[meat.length - 1] == '\\') {
user.accumulatedScript = meat.substring(bot.prefix.length,
meat.length - 1);
return false; // prevent other hooks from processing this...
}
else
{
return bot_eval(e, meat.substring(bot.prefix.length,
meat.length));
}
}
else if ((typeof(user.accumulatedScript) != "undefined") &&
userIsOwner(user))
/* if we were accumulating a message, add here,
* and finish if not ends with '\'. */
{
var lastLine = (meat[meat.length - 1] != '\\');
var line = meat.substring(0, meat.length - (lastLine ? 0 : 1));
user.accumulatedScript += line;
if (lastLine)
{
var script = user.accumulatedScript;
delete user.accumulatedScript;
return bot_eval(e, script);
}
}
}
/*
* What to do when a dcc chat request reaches a user object
*/
function my_user_dccchat (e)
{
if (!e.user.canDCC)
{
e.user.notice ("\01DCC REJECT CHAT chat\01");
return false;
}
var c = new CDCCChat (bot.eventPump);
if (!c.connect (e.user.host, e.port))
{
e.user.notice ("\01DCC REJECT CHAT chat\01");
return false;
}
return true;
}
/*
* What to do when our requested nickname is in use
*/
function my_433 (e)
{
if (e.params[2] != CIRCNetwork.prototype.INITIAL_NICK)
{
/* server didn't like the last nick we tried, probably too long.
* not much more we can do, bail out. */
e.server.disconnect();
}
CIRCNetwork.prototype.INITIAL_NICK += "_";
e.server.sendData ("nick " + CIRCNetwork.prototype.INITIAL_NICK + "\n");
}
/*
* What to do when raw data is recieved on a dcc chat connection
*/
function my_dccchat_rawdata (e)
{
try
{
var v = eval(e.data);
}
catch (ex)
{
this.say (String(ex));
return false;
}
if (typeof (v) != "undefined")
{
if (v != null)
v = String(v);
else
v = "null";
this.say (v);
}
}
/*
* Wrapper around CHTTPDoc to make is simpler to use
*/
function loadHTTP (host, path, onComplete)
{
var htdoc = new CHTTPDoc (host, path);
htdoc.onComplete = onComplete;
htdoc.get (bot.eventPump);
return htdoc;
}

View File

@@ -1,381 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
*/
bot.personality.guessPrefixes = ["I guess ", "maybe ", "probably ", "I think ",
"could be that ", "", ""];
bot.personality.guessActionPrefixes = ["guesses ", "postulates ", "figures ",
"tries ","pretends ", "", ""];
function initMingus ()
{
addOwner (/rginda.*!.*@adsl-63-198-63-20\.dsl\.snfc21\.pacbell\.net$/i);
addOwner (/rginda.*!.*@.*netscape\.com$/i);
addOwner (/ssieb.*!.*@.*pyr\.ec\.gc\.ca$/i);
addOwner (/ssieb.*!.*@.*wave\.home\.com$/i);
addOwner (/garyc.*!.*@.*ihug\.co\.nz$/i);
bot.primNet = bot.networks["moznet"];
load ("DP.js");
CIRCNetwork.prototype.INITIAL_NICK = "mingus";
CIRCNetwork.prototype.INITIAL_NAME = "mingus";
CIRCNetwork.prototype.INITIAL_DESC = "real men do it with prototypes";
CIRCNetwork.prototype.INITIAL_CHANNEL = "#chatzilla";
CIRCChannel.prototype.onJoin =
function my_chan_join (e) {
if (userIsOwner(e.user))
e.user.setOp(true);
}
bot.eventPump.addHook (psn_isAddressedToMe, psn_onAddressedMsg,
"addressed-to-me-hook");
bot.personality.dp = new CDPressMachine();
/*
bot.personality.dp.addPhrase ("I am " +
CIRCNetwork.prototype.INITIAL_NICK +
", hear me roar.");
*/
bot.personality.dp.addPhrase ("\01ACTION is back.");
/* dp hooks start */
var f = function (e)
{
var catchall = (e.hooks[e.hooks.length - 1].name == "catchall");
var answer = "";
if (catchall)
{
var ary = e.statement.split(" ");
for (var i = 0; i < 3; i++)
{
answer =
bot.personality.dp.getPhraseContaining(getRandomElement(ary));
if (answer)
break;
}
}
if (!answer)
answer = bot.personality.dp.getPhrase();
if (answer[answer.length - 1] == "\01")
{
if (answer[0] != "\01")
if (catchall)
answer = "\01ACTION " +
getRandomElement(bot.personality.guessActionPrefes) +
answer;
else
answer = "\01ACTION " + answer;
}
else
{
if (!answer)
answer = "I don't know anything";
if (catchall)
answer = getRandomElement(bot.personality.guessPrefixes) +
answer;
}
if (answer[0] != "\01")
e.replyTo.say (e.user.properNick + ", " + answer);
else
e.replyTo.say (answer);
return false;
}
/* first hook added is last checked */
bot.personality.addHook (/.*/i, f, "catchall");
bot.personality.addHook (/speak$/i, f, "speak");
bot.personality.addHook (/talk$/i, f, "hook");
bot.personality.addHook (/say something$/i, f, "say-something");
f = function (e)
{
var subject = e.matchresult[1].match(CDPressMachine.WORD_PATTERN);
if (subject == null)
subject = "";
else
subject = subject.toString();
var answer =
bot.personality.dp.getPhraseContaining (escape(subject.toLowerCase()));
if (!answer)
answer = "I dont know anything about " + e.matchresult[1];
if (answer.charCodeAt (0) != 1)
e.replyTo.say (e.user.properNick + ", " + answer);
else
e.replyTo.say (answer);
return false;
}
bot.personality.addHook (/speak about (\S+)/i, f);
bot.personality.addHook (/talk about (\S+)/i, f);
bot.personality.addHook (/say something about (\S+)/i, f);
f = function (e)
{
var answer = bot.personality.dp.getPhraseContaining ("%01ACTION");
if (!answer)
answer = "I can't do a thing.";
e.replyTo.say (answer);
return false;
}
bot.personality.addHook (/do something/i, f);
f = function (e)
{
var ary = bot.personality.dp.getPhraseWeights (e.matchresult[1]);
var c = bot.personality.dp.getPhraseWeight (e.matchresult[1]);
e.replyTo.say (e.user.properNick + ", that phrase weighs " + c + ": " + ary);
return false;
}
bot.personality.addHook (/weigh (.+)/i, f);
f = function (e)
{
var word = e.matchresult[1].toLowerCase();
var pivot = bot.personality.dp.getPivot(word);
var result = "";
if (pivot)
{
var list, w, l;
list = pivot.previousList;
w = list.getListWeights();
l = list.getListLinks();
if (w.length != l.length)
e.replyTo.say ("warning: previous list mismatched.");
for (var i = 0; i < (Math.max(w.length, l.length)); i++)
result += ( "`" + l[i] + "'" + w[i] + " " );
if (result.length > 250)
result += "\n";
result += ( "[" + word + "]" );
if (result.length > 250)
result += "\n";
list = pivot.nextList;
w = list.getListWeights();
l = list.getListLinks();
if (w.length != l.length)
e.replyTo.say ("warning: next list mismatched.");
for (var i = 0; i < (Math.max(w.length, l.length)); i++)
result += ( " `" + l[i] + "'" + w[i] );
}
else
result = "- [" + word + "] -";
e.replyTo.say (result);
return false;
}
bot.personality.addHook(/pivot (.*)/i, f);
/* dp hooks end */
f = function (e)
{
print ("I can hear you.");
e.replyTo.say (e.user.properNick + ", yes, I am.");
return false;
}
bot.personality.addHook (/are you alive(\?)?/i, f);
f = function (e)
{
if (!userIsOwner(e.user))
{
e.replyTo.say ("nope.");
return;
}
chan = e.matchresult[1];
if (chan.charAt (0) != "#")
chan = "#" + chan;
e.server.sendData ("join " + chan + "\n");
return false;
}
bot.personality.addHook (/join\s+(\S+)\.*/i, f);
f = function (e)
{
if (!userIsOwner (e.user))
{
e.channel.say ("nope.");
return false;
}
chan = e.matchresult[1];
if (chan.charAt (0) != "#")
chan = "#" + chan;
e.server.sendData ("part " + chan + "\n");
return false;
}
bot.personality.addHook (/part\s+(\S+)\.*/i, f);
bot.personality.addHook (/leave\s+(\S+)\.*/i, f);
f = function (e)
{
e.replyTo.say ("mmmmmmm. Thanks " + e.user.properNick + ".");
return false;
}
bot.personality.addHook (/botsnack/i, f);
f = function (e)
{
e.replyTo.act ("blushes");
return false;
}
bot.personality.addHook (/you rock/i, f);
f = function (e)
{
if (e.matchresult[1] == "me")
e.replyTo.act ("hugs " + e.user.properNick);
else
e.replyTo.act ("hugs " + e.matchresult[1]);
return false;
}
bot.personality.addHook (/hug (.*)/i, f);
f = function (e)
{
if (e.matchresult[1] == "me")
e.replyTo.say (e.user.properNick + ", :*");
else
e.replyTo.say (e.matchresult[1] + ", :*");
return false;
}
bot.personality.addHook (/kiss (\w+)/, f);
f = function (e)
{
e.replyTo.say (e.user.properNick + ", I'll try :(");
return false;
}
bot.personality.addHook
(/(shut up)|(shaddup)|(be quiet)|(keep quiet)|(sssh)|(stfu)/i, f);
f = function (e)
{
if (!userIsOwner (e.user))
e.replyTo.say ("No.");
else
{
for (var n in bot.networks)
bot.networks[n].quit("Goodnight.");
}
return false;
}
bot.personality.addHook (/(go to bed)|(go to sleep)|(sleep)/i, f);
f = function (e)
{
e.replyTo.say (":)");
return false;
}
bot.personality.addHook
(/(smile)|(rotfl)|(lmao)|(rotflmao)|(look happy)|(you(.)?re smart)/i, f);
/* (/(smile)|(rotfl)|(lmao)|(rotflmao)|(you(.)?re funny)|(look happy)|(you(.)?re smart)/i, f); */
f = function (e)
{
e.replyTo.say (":(");
return false;
}
bot.personality.addHook (/(frown)|(don(.)?t like you)|(look sad)/i, f);
f = function (e)
{
e.replyTo.say (">:|");
return false;
}
bot.personality.addHook (/(look mad)|(beat you up)/i, f);
f = function (e)
{
e.replyTo.say (":/");
return false;
}
bot.personality.addHook (/(look confused)|(i like windows)/i, f);
}

View File

@@ -1,39 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Library
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
*/
if (typeof escape == "undefined")
escape = unescape = function (s) {return s;}
function runMyBot()
{
load ("ircbot.js");
go();
}
function initPersonality()
{
load ("mingus.js");
initMingus();
}

View File

@@ -1,41 +0,0 @@
function test_matchObject()
{
var f = true;
obj1 = {foo:"hey", bar:"ho"}
obj2 = {a:"1", b:"2"}
p1 = {foo:"hey"}
p2 = {bar:"ho"}
p3 = {a:"1"}
p4 = {b:"2"}
/* true, single pattern, and it matches */
f &= matchObject (obj1, p1);
/* false, single pattern matches, negated */
f &= !matchObject (obj1, p1, true);
/* false, single pattern doesnt match*/
f &= !matchObject (obj1, p3);
/* true, single pattern doesnt match, negated */
f &= matchObject (obj1, p3, true);
/* true, p1 matches */
f &= matchObject (obj1, [p1, p3]);
/* false, p1 matches, negated */
f &= !matchObject (obj1, [p1, p3], true);
/* true, both paterns match */
f &= matchObject (obj2, [p3, p4]);
/* false, both patterns match, negated */
f &= !matchObject (obj2, [p3, p4], true);
/* false, neither pattern matches */
f &= !matchObject (obj1, [p3, p4]);
/* true, neither pattern matches, negated */
f &= matchObject (obj1, [p3, p4], true);
return Boolean(f); /* you've got to find any problems by hand :) */
}

View File

@@ -1,35 +0,0 @@
function rainbow(str)
{
str = String(str);
var c = str.length;
var rv = "";
for (var i = 0; i < c; i++)
{
var color = randomRange (2, 6);
rv += unescape ("%03" + color + str[i]);
}
return rv;
}
function fade(str)
{
var colors = new Array(1, 14, 10, 15, 0);
var cIndex = 0;
var msg = "";
for (i = 0; i < str.length; i++)
{
msg += "%03" + colors[cIndex] + str[i];
if ((++cIndex) == 5)
{
cIndex = 0;
}
}
return unescape(msg);
}

View File

@@ -1,156 +0,0 @@
<?xml version="1.0"?>
<!--
- The contents of this file are subject to the Mozilla Public
- 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS
- IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- implied. See the License for the specific language governing
- rights and limitations under the License.
-
- The Original Code is JSIRC Test Client #3
-
- The Initial Developer of the Original Code is New Dimensions Consulting,
- Inc. Portions created by New Dimensions Consulting, Inc. are
- Copyright (C) 1999 New Dimenstions Consulting, Inc. All
- Rights Reserved.
-
- Contributor(s):
- Robert Ginda, rginda@ndcico.com, original author
- Josh Soref, timeless@mac.com, international support
- Chiaki Koufugata chiaki@mozilla.gr.jp UI i18n
-->
<!DOCTYPE window SYSTEM "chrome://chatzilla/locale/chatzilla.dtd">
<?xml-stylesheet href="chrome://chatzilla/skin/chatzilla.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
<?xul-overlay href="chrome://chatzilla/content/scripts.xul"?>
<?xul-overlay href="chrome://chatzilla/content/menus.xul"?>
<window id="chatzilla-window"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
orient="vertical" onload="onLoad();" onunload="onUnload();"
onclose="return onClose();" onmouseover="onMouseOver(event);"
persist="width height screenX screenY sizemode" windowtype="irc:chatzilla">
<overlaytarget id="scripts-overlay-target"/>
<overlaytarget id="menu-overlay-target"/>
<vbox id="outer-box" flex="1">
<vbox id="upper-box" flex="1">
<hbox id="tabpanels-contents-box" flex="1">
<vbox id="user-list-box" width="20%" persist="collapsed width">
<tree id="user-list" container="true" datasources="rdf:null" flex="1"
containment="http://home.netscape.com/NC-irc#chanuser"
context="context:userlist">
<template>
<rule>
<conditions>
<content uri="?container"/>
<member container="?container" child="?member"/>
</conditions>
<bindings>
<binding subject="?member" predicate="http://home.netscape.com/NC-irc#op" object="?op"/>
<binding subject="?member" predicate="http://home.netscape.com/NC-irc#voice" object="?voice"/>
<binding subject="?member" predicate="http://home.netscape.com/NC-irc#nick" object="?nick"/>
</bindings>
<action>
<treechildren>
<treeitem uri="?member" flex="1" properties="op-?op voice-?voice">
<treerow>
<treecell properties="state-?op"/>
<treecell properties="state-?voice"/>
<treecell label="?nick"/>
</treerow>
</treeitem>
</treechildren>
</action>
</rule>
</template>
<treecols>
<treecol id="usercol-op" label="O"
persist="hidden sortDirection"
onclick="return onSortCol('usercol-op')"
resource="http://home.netscape.com/NC-irc#op" width="25"/>
<splitter class="tree-splitter"/>
<treecol id="usercol-voice" label="V"
persist="hidden sortDirection"
onclick="return onSortCol('usercol-voice')"
resource="http://home.netscape.com/NC-irc#voice" width="25"/>
<splitter class="tree-splitter"/>
<treecol id="usercol-nick" label="Nick" flex="1"
persist="sortDirection" ignoreincolumnpicker="true"
onclick="return onSortCol('usercol-nick')"
resource="http://home.netscape.com/NC-irc#nick"/>
</treecols>
</tree>
</vbox> <!-- user-list-box -->
<splitter id="main-splitter" collapse="before" persist="collapsed left">
<grippy/>
</splitter>
<vbox flex="1">
<deck id="output-deck" flex="1"/>
</vbox>
</hbox> <!-- tabpanels-contents-box -->
<hbox id="tabstrip-box" flex="0" crop="right">
<scrollbox id="view-tabs" persist="collapsed" orient="horizontal"
flex="1">
<hbox>
<tabs class="tabs-bottom" id="views-tbar-inner" flex="1" crop="right">
<tab collapsed="true"/> <!-- dummy tab to keep the freaking xbl from
causing an exception -->
</tabs>
</hbox>
</scrollbox>
</hbox>
</vbox> <!-- upper-box -->
<splitter id="input-splitter" orient="vertical" collapse="after"
collapsed="true"/>
<hbox id="input-widgets">
<text id="server-nick" value=""/>
<hbox id="multiline-box" flex="1" collapsed="true">
<textbox id="multiline-input" multiline="true" flex="1" height="100px"
class="multiline-input-widget" onfocus="onInputFocus();"/>
<vbox>
<toolbarbutton id="button-input" flex="1"
oncommand="onMultilineSend(event);"
tooltiptext="&multiline-send.tooltip;" />
<toolbarbutton id="button-multiline-contract"
oncommand="dispatch('pref multiline false');"
tooltiptext="&multiline-contract.tooltip;" />
</vbox>
</hbox>
<hbox id="singleline-box" flex="1" collapsed="true">
<textbox id="input" class="input-widget" flex="1" autostretch="true"
onfocus="onInputFocus();"/>
<toolbarbutton id="button-multiline-expand"
oncommand="dispatch('pref multiline true');"
tooltiptext="&multiline-expand.tooltip;"/>
</hbox>
</hbox>
</vbox> <!-- outer-box -->
<overlaytarget id="statusbar-overlay-target"/>
</window>

View File

@@ -1,7 +0,0 @@
function toIRC()
{
toOpenWindowByType("irc:chatzilla", "chrome://chatzilla/content/chatzilla.xul");
}

View File

@@ -1,38 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE overlay SYSTEM "chrome://chatzilla/locale/chatzillaOverlay.dtd" >
<!-- This is the overlay that addes "Chatzilla" to the (global) task menu. -->
<?xml-stylesheet href="chrome://chatzilla/skin/chatzillaOverlay.css" type="text/css"?>
<overlay id="ChatzillaTaskMenuID"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://chatzilla/content/chatzillaOverlay.js"/>
<keyset id="tasksKeys">
<key id="key_irc" key="&ircCmd.commandkey;" command="Tasks:IRC" modifiers="accel"/>
</keyset>
<commandset id="tasksCommands">
<command id="Tasks:IRC" oncommand="toIRC();"/>
</commandset>
<menupopup id="windowPopup">
<menuitem
label="&ircCmd.label;"
accesskey="&ircCmd.accesskey;"
key="key_irc"
command="Tasks:IRC"
id="tasksMenuIRC"
class="menuitem-iconic"
insertafter="tasksMenuAddressBook"/>
</menupopup>
<statusbarpanel id="component-bar">
<toolbarbutton class="taskbutton" id="mini-irc" oncommand="toIRC()"
position="5" tooltiptext="&ircCmd.label;"/>
</statusbarpanel>
</overlay>

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +0,0 @@
<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
<!-- list all the packages being supplied by this jar -->
<RDF:Seq about="urn:mozilla:package:root">
<RDF:li resource="urn:mozilla:package:chatzilla"/>
</RDF:Seq>
<!-- package information -->
<RDF:Description about="urn:mozilla:package:chatzilla"
chrome:displayName="Chatzilla"
chrome:author="mozilla.org"
chrome:localeVersion="1.5b"
chrome:name="chatzilla">
</RDF:Description>
<!-- overlay information -->
<RDF:Seq about="urn:mozilla:overlays">
<RDF:li resource="chrome://editor/content/editorTasksOverlay.xul"/>
<RDF:li resource="chrome://communicator/content/pref/preftree.xul"/>
</RDF:Seq>
<RDF:Seq about="chrome://editor/content/editorTasksOverlay.xul">
<RDF:li>chrome://chatzilla/content/chatzillaOverlay.xul</RDF:li>
</RDF:Seq>
<RDF:Seq about="chrome://communicator/content/pref/preftree.xul">
<RDF:li>chrome://chatzilla/content/prefsOverlay.xul</RDF:li>
</RDF:Seq>
</RDF:RDF>

View File

@@ -1,3 +0,0 @@
/* empty css file. rules are appended to this dynamically */

File diff suppressed because it is too large Load Diff

View File

@@ -1,277 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, <rginda@netscape.com>, original author
*
*/
function initMenus()
{
function isMotif(name)
{
return "client.prefs['motif.current'] == " +
"client.prefs['motif." + name + "']";
};
function onMenuCommand (event, window)
{
var params;
var commandName = event.originalTarget.getAttribute("commandname");
if ("cx" in client.menuManager && client.menuManager.cx)
{
client.menuManager.cx.sourceWindow = window;
params = client.menuManager.cx;
}
else
{
params = { sourceWindow: window };
}
dispatch (commandName, params);
delete client.menuManager.cx;
};
client.onMenuCommand = onMenuCommand;
client.menuSpecs = new Object();
var menuManager = new MenuManager(client.commandManager,
client.menuSpecs,
getCommandContext,
"client.onMenuCommand(event, window);");
client.menuManager = menuManager;
client.menuSpecs["maintoolbar"] = {
items:
[
["disconnect"],
["quit"],
["part"]
]
};
client.menuSpecs["mainmenu:file"] = {
label: MSG_MNU_FILE,
getContext: getDefaultContext,
items:
[
["delete-view", {enabledif: "client.viewsArray.length > 1"}],
["quit"],
["disconnect"],
["-"],
[navigator.platform.search(/win/i) == -1 ?
"quit-mozilla" : "exit-mozilla"]
]
};
client.menuSpecs["popup:motifs"] = {
label: MSG_MNU_MOTIFS,
items:
[
["motif-default",
{type: "checkbox",
checkedif: isMotif("default")}],
["motif-dark",
{type: "checkbox",
checkedif: isMotif("dark")}],
["motif-light",
{type: "checkbox",
checkedif: isMotif("light")}],
]
};
client.menuSpecs["mainmenu:view"] = {
label: MSG_MNU_VIEW,
getContext: getDefaultContext,
items:
[
[">popup:showhide"],
["-"],
["toggle-oas",
{type: "checkbox",
checkedif: "isStartupURL(cx.sourceObject.getURL())"}],
["clear-view"],
["delete-view",
{visibleif: "!cx.channel || !cx.channel.active",
enabledif: "client.viewsArray.length > 1"}],
["leave", {visibleif: "cx.channel && cx.channel.active"}],
["-"],
[">popup:motifs"],
["toggle-ccm",
{type: "checkbox",
checkedif: "client.prefs['collapseMsgs']"}],
["toggle-copy",
{type: "checkbox",
checkedif: "client.prefs['copyMessages']"}]
]
};
/* Mac expects a help menu with this ID, and there is nothing we can do
* about it. */
client.menuSpecs["mainmenu:help"] = {
label: MSG_MNU_HELP,
domID: "menu_Help",
items:
[
["about"],
]
};
client.menuSpecs["popup:showhide"] = {
label: MSG_MNU_SHOWHIDE,
items:
[
["tabstrip",
{type: "checkbox",
checkedif: "isVisible('view-tabs')"}],
["header",
{type: "checkbox",
checkedif: "cx.sourceObject.prefs['displayHeader']"}],
["userlist",
{type: "checkbox",
checkedif: "isVisible('user-list-box')"}],
["statusbar",
{type: "checkbox",
checkedif: "isVisible('status-bar')"}],
]
};
client.menuSpecs["popup:opcommands"] = {
label: MSG_MNU_OPCOMMANDS,
items:
[
["op", {enabledif: "cx.channel.iAmOp() && !cx.user.isOp"}],
["deop", {enabledif: "cx.channel.iAmOp() && cx.user.isOp"}],
["voice", {enabledif: "cx.channel.iAmOp() && !cx.user.isVoice"}],
["devoice", {enabledif: "cx.channel.iAmOp() && cx.user.isVoice"}],
["-"],
["kick", {enabledif: "cx.channel.iAmOp()"}],
["kick-ban", {enabledif: "cx.channel.iAmOp()"}]
]
};
client.menuSpecs["context:userlist"] = {
getContext: getUserlistContext,
items:
[
[">popup:opcommands"],
["whois"],
["query"],
["version"],
]
};
var urlenabled = "has('url') && cx.url.search(/^irc:/i) == -1";
client.menuSpecs["context:messages"] = {
getContext: getMessagesContext,
items:
[
["goto-url", {enabledif: urlenabled}],
["goto-url-newwin", {enabledif: urlenabled}],
["goto-url-newtab", {enabledif: urlenabled}],
["-"],
["leave",
{enabledif: "cx.TYPE == 'IRCChannel'"}],
["delete-view", {enabledif: "client.viewsArray.length > 1"}],
["disconnect"],
["-"],
[">popup:opcommands"],
["whois"],
["query"],
["version"],
["-"],
[">popup:motifs"],
["toggle-oas",
{type: "checkbox",
checkedif: "isStartupURL(cx.sourceObject.getURL())"}],
]
};
client.menuSpecs["context:tab"] = {
getContext: getTabContext,
items:
[
["leave",
{enabledif: "cx.TYPE == 'IRCChannel'"}],
["delete-view", {enabledif: "client.viewsArray.length > 1"}],
["disconnect"],
["-"],
["toggle-oas",
{type: "checkbox",
checkedif: "isStartupURL(cx.sourceObject.getURL())"}],
]
};
}
function createMenus()
{
client.menuManager.createMenus(document, "mainmenu");
client.menuManager.createContextMenus(document);
}
function getCommandContext (id, event)
{
var cx = { originalEvent: event };
if (id in client.menuSpecs)
{
if ("getContext" in client.menuSpecs[id])
cx = client.menuSpecs[id].getContext(cx);
else if ("cx" in client.menuManager)
{
//dd ("using existing context");
cx = client.menuManager.cx;
}
else
{
//no context.
}
}
else
{
dd ("getCommandContext: unknown menu id " + id);
}
if (typeof cx == "object")
{
if (!("menuManager" in cx))
cx.menuManager = client.menuManager;
if (!("contextSource" in cx))
cx.contextSource = id;
if ("dbgContexts" in client && client.dbgContexts)
dd ("context '" + id + "'\n" + dumpObjectTree(cx));
}
return cx;
}

View File

@@ -1,154 +0,0 @@
<?xml version="1.0"?>
<!--
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is The JavaScript Debugger
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation
- Portions created by Netscape are
- Copyright (C) 1998 Netscape Communications Corporation.
- All Rights Reserved.
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- Robert Ginda, <rginda@netscape.com>, original author
-
-->
<!DOCTYPE overlay SYSTEM "chrome://chatzilla/locale/chatzilla.dtd" >
<?xul-overlay href="chrome://communicator/content/tasksOverlay.xul"?>
<overlay id="chatzilla-menu-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<overlaytarget id="menu-overlay-target">
<!-- parents for the command manager-managed objects -->
<keyset id="dynamic-keys"/>
<popupset id="dynamic-popups"/>
<!-- tooltip thingy -->
<tooltip id="html-tooltip-node" onpopupshowing="return onTooltip(event);"/>
<tooltip id="xul-tooltip-node" onpopupshowing="return onTooltip(event);"/>
<!-- Commands -->
<commandset id="chatzilla-commands">
<!-- Edit commands -->
<commandset id="selectEditMenuItems"/>
<commandset id="globalEditMenuItems"/>
<commandset id="undoEditMenuItems"/>
<commandset id="clipboardEditMenuItems"/>
<command id="cmd_undo"/>
<command id="cmd_redo"/>
<command id="cmd_cut"/>
<command id="cmd_copy"/>
<command id="cmd_paste"/>
<command id="cmd_delete"/>
<command id="cmd_selectAll"/>
<!-- Tasks commands, from overlay -->
<commandset id="tasksCommands"/>
</commandset>
<!-- Keys -->
<keyset id="chatzillaKeys">
<key id="key:reloadui" modifiers="accel alt" key="R"
oncommand="if (typeof cmdReloadUI =='function') cmdReloadUI(); else window.location.href = window.location.href;"/>
<!-- Edit keys -->
<key id="key_undo"/>
<key id="key_redo"/>
<key id="key_cut"/>
<key id="key_copy"/>
<key id="key_paste"/>
<key id="key_delete"/>
<key id="key_selectAll"/>
<!-- Tasks keys, from overlay -->
<keyset id="tasksKeys"/>
</keyset>
<!-- Main menu bar -->
<toolbox flex="1" id="main-toolbox">
<menubar id="mainmenu" persist="collapsed"
grippytooltiptext="&Menubar.tooltip;">
<!-- File menu placeholder, see menus.js -->
<menu id="mainmenu:file"/>
<!-- Edit menu -->
<menu id="menu_Edit">
<menupopup id="menu_Edit_Popup">
<menuitem id="menu_undo"/>
<menuitem id="menu_redo"/>
<menuseparator/>
<menuitem id="menu_cut"/>
<menuitem id="menu_copy"/>
<menuitem id="menu_paste"/>
<menuitem id="menu_delete"/>
<menuseparator/>
<menuitem id="menu_selectAll"/>
<menuseparator/>
<menuitem id="menu_preferences"
oncommand="goPreferences('chatzillaItem', 'chrome://chatzilla/content/prefpanel/pref-irc.xul', 'chatzillaItem');"/>
</menupopup>
</menu>
<!-- View menu placeholder, see venkman-menus.js -->
<menu id="mainmenu:view"/>
<!-- Tasks menu -->
<menu id="tasksMenu"/>
<!-- Tasks menu -->
<menu id="windowMenu"/>
<!-- Help menu -->
<!-- Mac expects a help menu with this ID, and there is nothing we can
do about it. -->
<menu id="menu_Help"/>
</menubar>
</toolbox>
</overlaytarget>
<!-- Statusbar (hey, it's /almost/ a menu) -->
<overlaytarget id="statusbar-overlay-target">
<statusbar class="chromeclass-status" id="status-bar" flex="1">
<statusbarpanel id="component-bar"/>
<statusbarpanel id="status-text" label="" flex="1"
crop="right"/>
<!--
<statusbarpanel class="statusbarpanel-iconic" id="offline-status"
hidden="true" offline="true"/>
-->
</statusbar>
</overlaytarget>
</overlay>

View File

@@ -1,128 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, <rginda@netscape.com>, original author
*
*/
function initMessages()
{
var path = "chrome://chatzilla/locale/chatzilla.properties";
client.messageManager = new MessageManager();
client.defaultBundle = client.messageManager.addBundle(path);
client.name = MSG_CLIENT_NAME;
client.responseCodeMap =
{
"HELLO": MSG_RSP_HELLO,
"HELP" : MSG_RSP_HELP,
"USAGE": MSG_RSP_USAGE,
"ERROR": MSG_RSP_ERROR,
"WARNING": MSG_RSP_WARN,
"INFO": MSG_RSP_INFO,
"EVAL-IN": MSG_RSP_EVIN,
"EVAL_-OUT": MSG_RSP_EVOUT,
"JOIN": "-->|",
"PART": "<--|",
"QUIT": "|<--",
"NICK": "=-=",
"TOPIC": "=-=",
"KICK": "=-=",
"MODE": "=-=",
"END_STATUS": "---",
"315": "---", /* end of WHO */
"318": "---", /* end of WHOIS */
"366": "---", /* end of NAMES */
"376": "---" /* end of MOTD */
};
}
function checkCharset(charset)
{
return client.messageManager.checkCharset(charset);
}
function toUnicode (msg, charsetOrView)
{
if (!msg)
return msg;
var charset;
if (typeof charsetOrView == "object")
charset = charsetOrView.prefs["charset"];
else if (typeof charsetOrView == "string")
charset = charsetOrView;
else
charset = client.currentObject.prefs["charset"];
return client.messageManager.toUnicode(msg, charset);
}
function fromUnicode (msg, charsetOrView)
{
if (!msg)
return msg;
var charset;
if (typeof charsetOrView == "object")
charset = charsetOrView.prefs["charset"];
else if (typeof charsetOrView == "string")
charset = charsetOrView;
else
charset = client.currentObject.prefs["charset"];
return client.messageManager.fromUnicode(msg, charset);
}
function getMsg(msgName, params, deflt)
{
return client.messageManager.getMsg(msgName, params, deflt);
}
function getMsgFrom(bundle, msgName, params, deflt)
{
return client.messageManager.getMsgFrom(bundle, msgName, params, deflt);
}
/* message types, don't localize */
const MT_ATTENTION = "ATTENTION";
const MT_ERROR = "ERROR";
const MT_HELLO = "HELLO";
const MT_HELP = "HELP";
const MT_MODE = "MODE";
const MT_WARN = "WARN";
const MT_INFO = "INFO";
const MT_USAGE = "USAGE";
const MT_STATUS = "STATUS";
const MT_EVALIN = "EVAL-IN";
const MT_EVALOUT = "EVAL-OUT";

View File

@@ -1,518 +0,0 @@
/* -*- Mode: Text; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Mozilla Public
* 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Chatzilla.
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
* Styles for output window
*
*/
/*
* This file contains the CSS rules for the output window in ChatZilla.
* The output window is layed out as a table with two columns. The first
* column holds a message type or a nickname, depending on what view the
* message is contained by, and what kind of message it is. The second column
* contains the text of the message. For most message types, ChatZilla displays
* ascii-art instead of the actual code. For example, messages of type "JOIN"
* are displayed as "-->|", and most unclassified message types are displayed
* as "===". If you turn on debug messages (using the options->debug messages
* menuitem) ChatZilla will always show the actual message type. This can be
* helpful when styling a particular response from the IRC server. See the
* description of the msg-type attribute below.
*
* You can modify these styles on your local system by placing your desired
* styles in a file called chatzilla.css in your <profile>/chrome directory.
* (the file won't be there already, you have to create it.) Add the line
*
* @import url(chatzilla.css);
*
* to the to your userContent.css (also in your <profile>/chrome directory, and
* also not there unless you created it already.) End all CSS rules in your
* new chatzilla.css with !important to override any styles declared here.
* For example, on a Linux system, you would create a file called
* /home/<username>/.mozilla/<username>/chrome/userContent.css (if it
* doesn't already exist), and add the line @import url(chatzilla.css) to it.
* Next, create /home/<username>/.mozilla/<username>/chrome/chatzilla.css, and
* add the text:
*
* .msg {
* font-size: 14pt !important;
* }
*
* body.chatzilla-body {
* background: green !important;
* }
*
* Close your browser and restart. When you bring up ChatZilla, it should have
* a 14pt font and a green background.
*
* To learn how to make more useful changes to the ChatZilla output style, read
* on.
*
* All of the output in the message window is contained in an html <TABLE>.
* New messages are composed of <TR> and <TD> elements inside this <TABLE>.
* The message table and it's children have the following CSS classes assigned
* to them:
*
* + .msg-table is used as the class for the surrounding <TABLE>.
* Styles applied to this class will affect all parts of all messages.
*
* + .msg-nested-table is used as the class for the surrounding <TABLE> for
* messages sent from users with long nicknames. A new table is created, and
* nested inside a <TR colspan="2"> of the .msg-table. The rows of this
* table have their classes set as if they were direct children of the
* .msg-table. Placing messages from users with long nicknames in a nested
* table keeps the nickname column from getting too wide.
*
* + .msg is used as the class for the surrounding <TR>. This means that
* any styles applied here will affect the entire message.
*
* + .msg-type is used as the class for the <TD> surrounding the message type
* portion of messages. Styles applied here will only affect message
* types. ie. "-->|", or "[HELP]".
*
* + .msg-user is used as the class for the <TD> surrounding the nickname
* portion of messages. ChatZilla makes use of the :before and :after
* pseudoclasses to decorate nicknames with different characters depending
* on their message type. For example, when a user performs a /me, their
* nickname may be surrounded by asterisks.
*
* + .msg-data is used as the class for the <TD> surrounding the actual text
* of the message.
*
* In addition to CSS class properties, portions of a message may have one
* or mode of the following attributes set:
*
* + view-type is the type of view the message is contained in. The types
* are:
* "IRCClient" for the *client* view
* "IRCNetwork" for network and server views
* "IRCChannel" for channel views
* "IRCUser" for query views
*
* + msg-type is the message type described above. There are too many types
* to list here. Turn on debug messages to force message types to print
* in the left column of the output.
*
* + msg-user is the nickname (in lowercase) of the nickname who sent the
* message. If you sent the message, msg-user will be set to "ME!", so
* that you can style your messages regardless of your nickname.
*
* + msg-dest is the name of the object that the message is directed to. It
* could be a channel name, or a nickname (both in lowercase.)
*
* + dest-type is the type of object the message is directed to. The types
* are:
* "IRCChannel" for messages sent to a channel.
* "IRCUser" for messages sent directly to another user, including
* private messages that appear in a network or channel view (when
* a dedicated query view does not exist.)
*
* + mark is either the text "even" or "odd". When the first user speaks on
* a channel, that message is marked as "even". Messages will continue to
* be marked "even" until a different user speaks, when the mark switches
* to "odd". Each view maintains it's own mark state. An example of how
* ChatZilla marks messages would be:
*
* EVEN: <moe> this deep fat fry-o-later is great.
* EVEN: <moe> It'll deep fat fry a whole buffalo in 30 seconds.
* ODD: <homer> but I'm hungry *now*!
*
* + important is either the text "true", or it is not set at all. If
* important is true, then the message triggered ChatZilla /stalk function.
* This occurs when someone with a nickname matching a pattern in your
* /stalk list speaks, when someone says a word that matches a pattern in
* your /stalk list, or when someone says your nickname.
*
*
*/
/******************************************************************************
* basic classes *
******************************************************************************/
body.chatzilla-body { /* The topmost container in the ChatZilla */
margin: 0px 0px 0px 0px; /* output window. */
font: 10pt lucida, sans-serif;
}
/* links */
a.chatzilla-link {
text-decoration: none;
}
/* link hover effect */
a.chatzilla-link:hover {
text-decoration: underline;
}
/* basic styles */
.chatzilla-highlight[name="Large"] {
font-size: 12pt;
}
.chatzilla-highlight[name="Small"] {
font-size: 8pt;
}
.chatzilla-highlight[name="Bold text"],
.chatzilla-bold {
font-weight: bold;
}
.chatzilla-italic {
font-style: italic;
}
.chatzilla-underline {
text-decoration: underline;
}
.chatzilla-strikethrough {
text-decoration: line-through;
}
.chatzilla-teletype {
font-family: monospace;
}
.chatzilla-rheet {
font-weight: bold;
}
/* mirc colors */
.chatzilla-fg00 {
color: #000000;
}
.chatzilla-fg01 {
color: #c8c8c8;
}
.chatzilla-fg02 {
color: #0000c8;
}
.chatzilla-fg03 {
color: #00c800;
}
.chatzilla-fg04 {
color: #c80000;
}
.chatzilla-fg05 {
color: #c8c800;
}
.chatzilla-fg06 {
color: #c800c8;
}
.chatzilla-fg07 {
color: #ffb000;
}
.chatzilla-fg08 {
color: #ffff00;
}
.chatzilla-fg09 {
color: #00ff00;
}
.chatzilla-fg10 {
color: #00c8c8;
}
.chatzilla-fg11 {
color: #00ffff;
}
.chatzilla-fg12 {
color: #0000ff;
}
.chatzilla-fg13 {
color: #ff00ff;
}
.chatzilla-fg14 {
color: #808080;
}
.chatzilla-fg15 {
color: #989898;
}
.chatzilla-bg00 {
background: #000000;
}
.chatzilla-bg01 {
background: #c8c8c8;
}
.chatzilla-bg02 {
background: #0000c8;
}
.chatzilla-bg03 {
background: #00c800;
}
.chatzilla-bg04 {
background: #c80000;
}
.chatzilla-bg05 {
background: #c8c800;
}
.chatzilla-bg06 {
background: #c800c8;
}
.chatzilla-bg07 {
background: #ffb000;
}
.chatzilla-bg08 {
background: #ffff00;
}
.chatzilla-bg09 {
background: #00ff00;
}
.chatzilla-bg10 {
background: #00c8c8;
}
.chatzilla-bg11 {
background: #00ffff;
}
.chatzilla-bg12 {
background: #0000ff;
}
.chatzilla-bg13 {
background: #ff00ff;
}
.chatzilla-bg14 {
background: #808080;
}
.chatzilla-bg15 {
background: #989898;
}
.chatzilla-control-char:before {
content: "[\\";
}
.chatzilla-control-char:after {
content: "]";
}
/* smiley faces */
.chatzilla-emote-txt { /* emoticon text inside */
display: none;
}
.chatzilla-emote:after { /* empty span to attach :after images to */
margin-left: 3px;
margin-right: 3px;
content: url(chrome://chatzilla/skin/images/face-dunno.gif);
}
.chatzilla-emote[type="face-angry"]:after {
content: url(chrome://chatzilla/skin/images/face-angry.gif);
}
.chatzilla-emote[type="face-cry"]:after {
content: url(chrome://chatzilla/skin/images/face-cry.gif);
}
.chatzilla-emote[type="face-frown"]:after {
content: url(chrome://chatzilla/skin/images/face-frown.gif);
}
.chatzilla-emote[type="face-screw"]:after {
content: url(chrome://chatzilla/skin/images/face-screw.gif);
}
.chatzilla-emote[type="face-smile"]:after {
content: url(chrome://chatzilla/skin/images/face-smile.gif);
}
.chatzilla-emote[type="face-surprise"]:after {
content: url(chrome://chatzilla/skin/images/face-surprise.gif);
}
.chatzilla-emote[type="face-tongue"]:after {
content: url(chrome://chatzilla/skin/images/face-tongue.gif);
}
.chatzilla-emote[type="face-wink"]:after {
content: url(chrome://chatzilla/skin/images/face-wink.gif);
}
/******************************************************************************
* message class base definitions *
******************************************************************************/
.msg-table { /* <TABLE> containing all of the */
width: 100%; /* messages. */
}
.msg-nested-table { /* <TABLE> nested inside */
width: 100%; /* .msg-table for users with long */
margin: 0px; /* nicknames. */
border: 0px;
border-spacing: 0px;
padding: 0px;
}
.msg { /* .msg = a single message in the */
width: 100%; /* output window */
font-size: 10pt;
}
.msg-type { /* .msg-type = message type */
font-variant: small-caps; /* indicator */
font-size: 9pt;
padding-right: 10px;
text-align: right;
vertical-align: top;
white-space: nowrap;
}
.msg-user { /* msg-user = nickname portion of */
text-align: right; /* a message (channel and query */
vertical-align: top; /* views) */
}
.msg-data { /* .msg-data = the text portion */
padding: 1px 1px 1px 3px; /* of a message */
width: 100%;
white-space: -moz-pre-wrap;
}
/******************************************************************************
* message class specific definitions *
******************************************************************************/
/* msg-user is the nickname of the person who spoke, or "ME!" if you said it.
* msg-type is the type of the message, taken from the irc message. If you
* turn on debug messages (options->debug messages), the msg-types will be
* displayed to the left of the messages for all messages except:
* PRIVMSG: when a user sends you, or a channel you are on a message.
* ACTION: when a user performs a /me.
* NOTIFY: when a server or user sends you a notification.
*/
.msg-data[msg-user="|"], /* messages from common "bulk */
.msg-data[msg-user="||"], /* paste" nicks */
.msg-data[msg-user="|||"],
.msg-data[msg-user="]"],
.msg-data[msg-user="["],
.msg-data[msg-type="372"], /* MOTD */
.msg-data[msg-type="EVAL-IN"], /* /eval results */
.msg-data[msg-type="EVAL-OUT"] {
font-size: 9pt;
font-family: monospace;
}
.msg-data[msg-type="USAGE"] {
font-style: italic;
}
.msg-data[msg-type="HELP"] {
font-weight: normal;
}
.msg-user[msg-type="ACTION"] {
font-style: italic;
}
.msg-user[important="true"] {
font-weight: bold;
}
/******************************************************************************
* nickname decorations *
******************************************************************************/
/* :before and :after pseudoclasses form the decorations around nicknames */
.msg-user:before {
content: "<";
}
.msg-user:after {
content: ">";
}
.msg-user[important="true"]:before {
font-weight: bold;
}
.msg-user[important="true"]:after {
font-weight: bold;
}
.msg-user[msg-user$="ME!"]:before {
content: "<";
}
.msg-user[msg-user$="ME!"]:after {
content: ">";
}
.msg-user[msg-type="ACTION"]:before,
.msg-user[msg-type="ACTION"]:after {
content: "";
}
.msg-user[msg-type="NOTICE"]:before {
content: "[";
}
.msg-user[msg-type="NOTICE"]:after {
content: "]";
}
/* private messages *not* in a query window */
.msg-user[dest-type="IRCUser"]:before {
content: "to(";
}
.msg-user[msg-dest$="ME!"]:before {
content: "from(";
}
.msg-user[dest-type="IRCUser"]:after {
content: ")";
}
/* private messages in a query window */
.msg-user[view-type="IRCUser"]:before {
content: "{";
}
.msg-user[view-type="IRCUser"]:after {
content: "}";
}
.msg-user[view-type="IRCUser"][msg-user$="ME!"]:before {
content: "{";
}
.msg-user[view-type="IRCUser"][msg-user$="ME!"]:after {
content: "}";
}

View File

@@ -1,170 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<style>
[hidden="true"] {
display: none;
}
.header-outer {
position: fixed;
}
.header {
background-color: white;
color: black;
margin: 2px;
border: 1px black solid;
}
#h-table,
#net-url,
#ch-url {
width: 100%;
}
#splash {
padding-top: 55%;
padding-bottom: 20%;
font-size: 24pt;
font-weight: bold;
text-align: center;
}
#cli-version-container {
text-align: center;
width: 100%;
}
#usr-descnodes,
#ch-topicnodes {
line-height: 110%;
}
#ch-usercount,
#ch-modestr,
#net-lag {
white-space: nowrap;
}
.label {
font-weight: bold;
text-align: right;
vertical-align: top;
white-space: nowrap;
padding-right: 0.5em;
}
.value {
vertical-align: top;
padding-right: 1em;
}
#usr-title,
#usr-descnodes {
text-align: center;
}
</style>
<link id="pre-effect-css" rel="stylesheet" type="text/css"
href="about-blank">
<link id="main-css" rel="stylesheet" type="text/css"
href="about:blank">
<link id="post-effect-css" rel="stylesheet" type="text/css"
href="about:blank">
<head>
<script src="chrome://chatzilla/content/output-window.js"></script>
<!-- <script src="file:///home/rginda/.chatzilla/scripts/goodies/output-window.js"></script> -->
</head>
<body class="chatzilla-body">
<div class="header-outer">
<div class="header" id="cli-container" hidden="true">
<table id="h-table">
<tbody>
<tr>
<td class="label">Known Networks</td>
<td class="value" id="cli-netcount">&lt;none&gt;</td>
<td class="label" id="cli-version-container"
condition="yellow">ChatZilla <span id="cli-version">0.9.8</span></td>
<td class="label">Connected Networks</td>
<td class="value" id="cli-connectcount">&lt;none&gt;</td>
</tr>
</tbody>
</table>
</div>
<div class="header" id="net-container" hidden="true">
<table id="h-table">
<tbody>
<tr>
<td class="label" id="net-url-l">URL</td>
<td class="value" id="net-url">
<a id="net-url-anchor" class="chatzilla-link"
href="irc://foo/bar">irc://foo/bar</a>
</td>
<td class="value" id="net-status"
condition="red">Not Connected</td>
<td class="label" id="net-lag-l">Lag</td>
<td class="value" id="net-lag">&lt;unknown&gt;</td>
</td>
</tr>
</tbody>
</table>
</div>
<div class="header" id="ch-container" hidden="true">
<table id="h-table">
<tbody>
<tr>
<td class="label" id="ch-url-l">URL</td>
<td class="value" id="ch-url">
<a id="ch-url-anchor" class="chatzilla-link"
href="irc://foo/bar">irc://foo/bar</a>
</td>
<td class="label" id="ch-modestr-l">Mode</td>
<td class="value" id="ch-modestr">&lt;none&gt;</td>
<td class="label" id="ch-usercount-l">Users</td>
<td class="value" id="ch-usercount">&lt;none&gt;</td>
</tr>
<tr>
<td class="label" id="ch-topicnodes-l">Topic</td>
<td class="value" id="ch-topicnodes"
colspan="6">&lt;none&gt;</td>
</tr>
</tbody>
</table>
</div>
<div class="header" id="usr-container" hidden="true">
<table id="h-table">
<tbody>
<tr>
<td class="label">URL</td>
<td class="value" width="100%">
<a id="usr-url-anchor" class="chatzilla-link"
href="irc://foo/bar">irc://foo/bar</a>
</td>
<td class="label" id="usr-serverstr-l">Connected via</td>
<td class="value" id="usr-serverstr">&lt;none&gt;</td>
</tr>
<tr>
<td id="usr-title" colspan="4">&lt;none&gt;</td>
</tr>
<tr>
<td id="usr-descnodes" colspan="4">&lt;none&gt;</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="messages-outer" hidden="true">
<div id="splash"></div>
<div id="output"></div>
</div>
</body>
</html>

View File

@@ -1,355 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, <rginda@netscape.com>, original author
*
*/
var initialized = false;
var view;
var client;
var mainWindow;
var dd;
var getMsg;
var getObjectDetails;
var header = null;
var headers = {
IRCClient: {
prefix: "cli-",
fields: ["container", "netcount", "version-container", "version",
"connectcount"],
update: updateClient
},
IRCNetwork: {
prefix: "net-",
fields: ["container", "url-anchor", "status", "lag"],
update: updateNetwork
},
IRCChannel: {
prefix: "ch-",
fields: ["container", "url-anchor", "modestr", "usercount",
"topicnodes"],
update: updateChannel
},
IRCUser: {
prefix: "usr-",
fields: ["container", "url-anchor", "serverstr", "title",
"descnodes"],
update: updateUser
}
};
var initOutputWindow = stock_initOutputWindow;
function stock_initOutputWindow(newClient, newView)
{
function initHeader()
{
/* it's better if we wait a half a second before poking at these
* dom nodes. */
setHeaderState(view.prefs["displayHeader"]);
updateHeader();
var div = document.getElementById("messages-outer");
div.removeAttribute("hidden");
window.scrollTo(0, window.document.height);
};
client = newClient;
view = newView;
mainWindow = client.mainWindow;
client.messageManager.importBundle(client.defaultBundle, window);
getMsg = mainWindow.getMsg;
getObjectDetails = mainWindow.getObjectDetails;
dd = mainWindow.dd;
changeCSS(view.prefs["motif.current"]);
var output = document.getElementById("output");
output.appendChild(view.messages);
if (view.TYPE in headers)
{
header = cacheNodes(headers[view.TYPE].prefix,
headers[view.TYPE].fields);
header.update = headers[view.TYPE].update;
}
var splash = document.getElementById("splash");
var name;
if ("unicodeName" in view)
name = view.unicodeName;
else if ("properNick" in view)
name = view.properNick;
else
name = view.name;
splash.appendChild(document.createTextNode(name));
setTimeout(initHeader, 500);
initialized = true;
}
function cacheNodes(pfx, ary, nodes)
{
if (!nodes)
nodes = new Object();
for (var i = 0; i < ary.length; ++i)
nodes[ary[i]] = document.getElementById(pfx + ary[i]);
return nodes;
}
function changeCSS(url, id)
{
if (!id)
id = "main-css";
node = document.getElementById(id);
if (!node)
{
node = document.createElement("link");
node.setAttribute("id", "main-css");
node.setAttribute("rel", "stylesheet");
node.setAttribute("type", "text/css");
var head = document.getElementsByTagName("head")[0];
head.appendChild(node);
}
else
{
if (node.getAttribute("href") == url)
return;
}
node.setAttribute("href", url);
window.scrollTo(0, window.document.height);
}
function setText(field, text, checkCondition)
{
if (!header[field].firstChild)
header[field].appendChild(document.createTextNode(""));
if (typeof text != "string")
{
text = MSG_UNKNOWN;
if (checkCondition)
setAttribute(field, "condition", "red");
}
else if (checkCondition)
{
setAttribute(field, "condition", "green");
}
header[field].firstChild.data = text;
}
function setAttribute(field, name, value)
{
if (!value)
value = "true";
header[field].setAttribute(name, value);
}
function removeAttribute(field, name)
{
header[field].removeAttribute(name);
}
function hasAttribute(field, name)
{
header[field].hasAttribute(name);
}
function setHeaderState(state)
{
if (header)
{
if (state)
{
updateHeader();
removeAttribute("container", "hidden");
}
else
{
setAttribute("container", "hidden");
}
}
}
function updateHeader()
{
if (!header || hasAttribute("container", "hidden"))
return;
for (var id in header)
{
var value;
if (id == "url-anchor")
{
value = view.getURL();
setAttribute("url-anchor", "href", value);
setText("url-anchor", value);
}
else if (id in view)
{
setText(id, view[id]);
}
}
if (header.update)
header.update();
}
function updateClient()
{
var n = 0, c = 0;
for (name in client.networks)
{
++n;
if (client.networks[name].isConnected())
++c;
}
setAttribute("version-container", "title", client.userAgent);
setAttribute("version-container", "condition", mainWindow.__cz_condition);
setText("version", mainWindow.__cz_version);
setText("netcount", String(n));
setText("connectcount", String(c));
}
function updateNetwork()
{
if (view.connecting)
{
setText("status", MSG_CONNECTING);
setAttribute("status","condition", "yellow");
removeAttribute("status", "title");
setText("lag", MSG_UNKNOWN);
}
else if (view.isConnected())
{
setText("status", MSG_CONNECTED);
setAttribute("status","condition", "green");
setAttribute("status", "title",
getMsg(MSG_CONNECT_VIA, view.primServ.name));
if (view.primServ.lag != -1)
setText("lag", getMsg(MSG_FMT_SECONDS, view.primServ.lag));
else
setText("lag", MSG_UNKNOWN);
}
else
{
setText("status", MSG_DISCONNECTED);
setAttribute("status","condition", "red");
removeAttribute("status", "title");
setText("lag", MSG_UNKNOWN);
}
}
function updateChannel()
{
header["topicnodes"].removeChild(header["topicnodes"].firstChild);
if (view.active)
{
var str = view.mode.getModeStr();
if (!str)
str = MSG_NO_MODE;
setText("modestr", str);
setAttribute("modestr", "condition", "green");
setText("usercount", getMsg(MSG_FMT_USERCOUNT,
[view.getUsersLength(), view.opCount,
view.voiceCount]));
setAttribute("usercount", "condition", "green");
if (view.topic)
{
var nodes = client.munger.munge(view.topic, null,
getObjectDetails(view));
header["topicnodes"].appendChild(nodes);
}
else
{
setText("topicnodes", MSG_NONE);
}
}
else
{
setText("modestr", MSG_UNKNOWN);
setAttribute("modestr", "condition", "red");
setText("usercount", MSG_UNKNOWN);
setAttribute("usercount", "condition", "red");
setText("topicnodes", MSG_UNKNOWN);
}
}
function updateUser()
{
var source;
if (view.name)
source = "<" + view.name + "@" + view.host + ">";
else
source = MSG_UNKNOWN;
if (view.parent.isConnected)
setText("serverstr", view.connectionHost, true);
else
setText("serverstr", null, true);
setText("title", getMsg(MSG_TITLE_USER, [view.properNick, source]));
header["descnodes"].removeChild(header["descnodes"].firstChild);
if (typeof view.desc != "undefined")
{
var nodes = client.munger.munge(view.desc, null,
getObjectDetails(view));
header["descnodes"].appendChild(nodes);
}
else
{
setText("descnodes", "");
}
}

View File

@@ -1,173 +0,0 @@
<?xml version="1.0"?>
<!--
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation
- Portions created by Netscape are
- Copyright (C) 1998 Netscape Communications Corporation.
- All Rights Reserved.
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- Robert Ginda, <rginda@netscape.com>, original author
-
-->
<!DOCTYPE overlay SYSTEM "chrome://chatzilla/locale/chatzilla.dtd" >
<overlay id="chatzilla-popup-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<overlaytarget id="popup-overlay-target">
<commandset id="chatzillaPopupCommands">
<!-- Context menu commands -->
<command id="cmd_leaveview" oncommand="dispatch('part');"/>
<command id="cmd_clearview" oncommand="dispatch('clear-view');"/>
<command id="cmd_deleteview" oncommand="dispatch('delete-view');"/>
<command id="cmd_status" oncommand="dispatch('status')"/>
<command id="cmd_popup_query"
oncommand="onPopupSimulateCommand('/query $nick');"/>
<command id="cmd_popup_whois"
oncommand="onPopupSimulateCommand('/whois $nick');"/>
<command id="cmd_popup_ping"
oncommand="onPopupSimulateCommand('/ctcp $nick PING');"/>
<command id="cmd_popup_version"
oncommand="onPopupSimulateCommand('/ctcp $nick VERSION');"/>
<command id="cmd_popup_highlight"
oncommand="onPopupHighlight(true);"/>
<command id="cmd_popup_nohighlight"
oncommand="onPopupHighlight(false);"/>
<command id="cmd_popup_giveop"
oncommand="onPopupSimulateCommand('/op $nick');"/>
<command id="cmd_popup_takeop"
oncommand="onPopupSimulateCommand('/deop $nick');"/>
<command id="cmd_popup_givevoice"
oncommand="onPopupSimulateCommand('/voice $nick');"/>
<command id="cmd_popup_takevoice"
oncommand="onPopupSimulateCommand('/devoice $nick');"/>
<command id="cmd_popup_kick"
oncommand="onPopupSimulateCommand('/kick $nick');"/>
</commandset>
<!-- html tooltips -->
<tooltip id="aHTMLTooltip"
onpopupshowing="return fillInTooltip(document.tooltipNode,'aHTMLTooltip');"/>
<!--
tab tooltips, always show above the tab, so we don't draw over the input box
-->
<tooltip id="tabTT" position="end_after"
onpopupshowing="return fillInTooltip(document.tooltipNode,'tabTT');"/>
<popupset id="contextMenus">
<popup id="userlistPopup" oncommand="onUserListPopupClick(event)">
<menuitem label="&op.value;" accesskey="&op.accesskey;" code="/op" />
<menuitem label="&deop.value;" accesskey="&deop.accesskey;"
code="/deop" />
<menuitem label="&voice.value;" accesskey="&voice.accesskey;"
code="/voice" />
<menuitem label="&devoice.value;" accesskey="&devoice.accesskey;"
code="/devoice" />
<menuitem label="&kick.value;" accesskey="&kick.accesskey;"
code="/kick" />
<menuitem label="&whois.value;" accesskey="&whois.accesskey;"
code="/whois" />
</popup>
<popup id="outputContext"
onpopupshowing="if (event.originalTarget == this) return onOutputContextMenuCreate(event); else return true;"
onpopuphiding="if (event.originalTarget == this) delete client._popupContext;">
<menuitem format="&PopupQueryCmd.label;" accesskey="&PopupQueryCmd.aKey;"
observes="cmd_popup_query"
visibleif="targetUser"/>
<menuitem format="&PopupWhoisCmd.label;" accesskey="&PopupWhoisCmd.aKey;"
observes="cmd_popup_whois"
visibleif="targetUser"/>
<menuitem format="&PopupPingCmd.label;" accesskey="&PopupPingCmd.aKey;"
observes="cmd_popup_ping"
visibleif="targetUser"/>
<menuitem format="&PopupVersionCmd.label;"
accesskey="&PopupVersionCmd.aKey;"
observes="cmd_popup_version"
visibleif="targetUser"/>
<!--
<menu format="&PopupHighlightStyle.label;"
accesskey="&PopupHighlightStyle.aKey;"
visibleif="targetUser">
<menupopup id="highlightMenu">
<menuitem/>
</menupopup>
</menu>
-->
<menuseparator
visibleif="targetUser"/>
<menuitem label="&PopupGiveOp.label;" accesskey="&PopupGiveOp.aKey;"
observes="cmd_popup_giveop"
visibleif="iAmOp == 'yes' and targetIsOp == 'no'"/>
<menuitem label="&PopupTakeOp.label;" accesskey="&PopupTakeOp.aKey;"
observes="cmd_popup_takeop"
visibleif="iAmOp == 'yes' and targetIsOp == 'yes'"/>
<menuitem label="&PopupGiveVoice.label;"
accesskey="&PopupGiveVoice.aKey;"
observes="cmd_popup_givevoice"
visibleif="iAmOp == 'yes' and targetIsVoice == 'no'"/>
<menuitem label="&PopupTakeVoice.label;"
accesskey="&PopupTakeVoice.aKey;"
observes="cmd_popup_takevoice"
visibleif="iAmOp == 'yes' and targetIsVoice == 'yes'"/>
<menuitem format="&PopupKick.label;" accesskey="&PopupKick.aKey;"
observes="cmd_popup_kick"
visibleif="iAmOp == 'yes' and targetUser != 'undefined'"/>
<menuseparator
visibleif="targetUser != 'undefined' and iAmOp == 'yes'"/>
<menuitem label="&StartupVisitCmd.label;" type="checkbox"
accesskey="&StartupVisitCmd.aKey;" observes="cmd_toggle_startup_visit"
checkedif="isStartupURL(client.currentObject.getURL())"/>
<menuitem format="&LeaveViewCmd.label;" accesskey="&LeaveViewCmd.aKey;"
observes="cmd_leaveview" key="key_deleteview"
visibleif="client.currentObject.TYPE == 'IRCChannel'"/>
<menuitem label="&DeleteViewCmd.label;" accesskey="&DeleteViewCmd.aKey;"
observes="cmd_deleteview" key="key_deleteview"
visibleif="client.currentObject.TYPE != 'IRCChannel'"/>
<menuitem label="&ClearViewCmd.label;" accesskey="&ClearViewCmd.aKey;"
observes="cmd_clearview" key="key_clearview"/>
<menuseparator/>
<menuitem label="&StatusCmd.label;" accesskey="&StatusCmd.aKey;"
observes="cmd_status"/>
</popup>
</popupset>
</overlaytarget>
</overlay>

View File

@@ -1,76 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<script>
var css = "chrome://chatzilla/skin/output-default.css";
if (document.location.search)
css = document.location.search.substr(1);
document.write ("<LINK REL=StyleSheet HREF='" + css +
"' TYPE='text/css' MEDIA='screen'>");
</script>
<!--<LINK REL=StyleSheet id='dynamic-styles' TYPE='text/css' MEDIA='screen'
href='chrome://chatzilla/content/dynamic.css'>-->
</head>
<body class="chatzilla-body">
<div id="output">
</div>
<table class="msg-table" view-type="IRCChannel">
<tbody>
<tr class="msg" msg-type="INFO" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 14:10" class="msg-type" msg-type="INFO" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">[INFO]</span></td><td class="msg-data" msg-type="INFO" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span>Channel view for ``#mozilla'' opened.</span></td></tr>
<tr class="msg" msg-type="NOTICE" msg-user="moznet" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 14:10" class="msg-type" msg-type="NOTICE" msg-user="moznet" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">===</span></td><td class="msg-data" msg-type="NOTICE" msg-user="moznet" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span>*** Your host is irc.mozilla.org[irc.mozilla.org/6667], running version 2.8/hybrid-6.0</span></td></tr>
<tr class="msg" msg-type="250" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 14:10" class="msg-type" msg-type="250" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">===</span></td><td class="msg-data" msg-type="250" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span>: Highest connection count: 417 (417 clients) (269041 since server was (re)started)</span></td></tr>
<tr class="msg" msg-type="JOIN" msg-user="ME!" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 14:10" class="msg-type" msg-type="JOIN" msg-user="ME!" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">--&gt;|</span></td><td class="msg-data" msg-type="JOIN" msg-user="ME!" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span>YOU have joined #mozilla</span></td></tr>
<tr class="msg" msg-type="TOPIC" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 14:10" class="msg-type" msg-type="TOPIC" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">=-=</span></td><td class="msg-data" msg-type="TOPIC" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span>Topic for #mozilla is ``&lt;pinkerton&gt; something crude''</span></td></tr>
<tr class="msg" msg-type="TOPIC" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 14:10" class="msg-type" msg-type="TOPIC" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">=-=</span></td><td class="msg-data" msg-type="TOPIC" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span>Topic for #mozilla was set by dmose on Thu Jul 12 12:03:59 GMT-0700 (PDT) 2001</span></td></tr>
<tr class="msg" msg-type="JOIN" msg-user="illsleydc" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 14:10" class="msg-type" msg-type="JOIN" msg-user="illsleydc" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">--&gt;|</span></td><td class="msg-data" msg-type="JOIN" msg-user="illsleydc" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span>illsleydc (<a href="mailto:illsleydc@usr2574-kno.cableinet.co.uk" class="chatzilla-link">illsleydc@usr2574-kno.cableinet.co.uk</a>) has joined #mozilla</span></td></tr>
<tr class="msg" msg-type="JOIN" msg-user="fantasai" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 14:11" class="msg-type" msg-type="JOIN" msg-user="fantasai" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">--&gt;|</span></td><td class="msg-data" msg-type="JOIN" msg-user="fantasai" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span>fantasai (<a href="mailto:fantasai@escape.com" class="chatzilla-link">fantasai@escape.com</a>) has joined #mozilla</span></td></tr>
<tr class="msg" msg-type="JOIN" msg-user="walk84_" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 14:11" class="msg-type" msg-type="JOIN" msg-user="walk84_" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">--&gt;|</span></td><td class="msg-data" msg-type="JOIN" msg-user="walk84_" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span>walk84_ (<a href="mailto:walk84@tc0-193.stn.bluemarble.net" class="chatzilla-link">walk84@tc0-193.stn.bluemarble.net</a>) has joined #mozilla</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="fantasai" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 14:12" class="msg-user" msg-type="PRIVMSG" msg-user="fantasai" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">fantasai</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="fantasai" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel" mark="even"><span>Hixie: ping</span></td></tr>
<tr class="msg" msg-type="NICK" msg-user="akkpit" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:13" class="msg-type" msg-type="NICK" msg-user="akkpit" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">=-=</span></td><td class="msg-data" msg-type="NICK" msg-user="akkpit" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel" mark="even"><span>akk is now known as akkPit</span></td></tr>
<tr class="msg" msg-type="ACTION" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:14" class="msg-user" msg-type="ACTION" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">pinkerton</span></td><td class="msg-data" msg-type="ACTION" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel" mark="even"><span>notices the tipic</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:14" class="msg-user" msg-type="PRIVMSG" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">pinkerton</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel" mark="even"><span>er, topic</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:14" class="msg-user" msg-type="PRIVMSG" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">pinkerton</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel" mark="even"><span>hey ben</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="bengoodger" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:14" class="msg-user" msg-type="PRIVMSG" msg-user="bengoodger" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">BenGoodger</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="bengoodger" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>pink!</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="smfr2" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:14" class="msg-user" msg-type="PRIVMSG" msg-user="smfr2" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">smfr2</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="smfr2" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel" mark="even"><span>pink: bug 87112</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:14" class="msg-user" msg-type="PRIVMSG" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">pinkerton</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="pinkerton" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>gracias</span></td></tr>
<tr class="msg" msg-type="JOIN" msg-user="mang" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:14" class="msg-type" msg-type="JOIN" msg-user="mang" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">--&gt;|</span></td><td class="msg-data" msg-type="JOIN" msg-user="mang" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>mang (<a href="mailto:mang@h-208-12-41-197.netscape.com" class="chatzilla-link">mang@h-208-12-41-197.netscape.com</a>) has joined #mozilla</span></td></tr>
<tr class="msg" msg-type="QUIT" msg-user="kowalski" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:15" class="msg-type" msg-type="QUIT" msg-user="kowalski" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">|&lt;--</span></td><td class="msg-data" msg-type="QUIT" msg-user="kowalski" msg-dest="#mozilla" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>Kowalski has left moznet (How did you manage to get your face caught in the door?)</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ME!" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ME!" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">rgindaFOO</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ME!" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>foo</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ME!" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ME!" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">rgindaFOO</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ME!" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>foo</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ME!" msg-dest="blablabalabl" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ME!" msg-dest="blablabalabl" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">blablabalabl</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ME!" msg-dest="blablabalabl" dest-type="IRCUser" view-type="IRCChannel" mark="odd"><span>bnla</span></td></tr>
<tr class="msg" msg-type="401" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="401" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">===</span></td><td class="msg-data" msg-type="401" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel" mark="odd"><span>blablabalabl: No such nick/channel</span></td></tr>
<tr class="msg" msg-type="HELLO" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="HELLO" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">[HELLO]</span></td><td class="msg-data" msg-type="HELLO" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel" mark="odd"><span>Sample HELLO message.</span></td></tr>
<tr class="msg" msg-type="INFO" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="INFO" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">[INFO]</span></td><td class="msg-data" msg-type="INFO" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel" mark="odd"><span>Sample INFO message.</span></td></tr>
<tr class="msg" msg-type="ERROR" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="ERROR" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">[ERROR]</span></td><td class="msg-data" msg-type="ERROR" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel" mark="odd"><span>Sample ERROR message.</span></td></tr>
<tr class="msg" msg-type="HELP" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="HELP" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">[HELP]</span></td><td class="msg-data" msg-type="HELP" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel" mark="odd"><span>Sample HELP message.</span></td></tr>
<tr class="msg" msg-type="USAGE" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="USAGE" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">[USAGE]</span></td><td class="msg-data" msg-type="USAGE" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel" mark="odd"><span>Sample USAGE message.</span></td></tr>
<tr class="msg" msg-type="STATUS" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="STATUS" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel"><span class="undefined">===</span></td><td class="msg-data" msg-type="STATUS" msg-user="undefined" msg-dest="undefined" dest-type="unk" view-type="IRCChannel" mark="odd"><span>Sample STATUS message.</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>Normal message from IRCUser ``IRCMonkey'' to you</span></td></tr>
<tr class="msg" msg-type="ACTION" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="ACTION" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="ACTION" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>Action message from IRCUser ``IRCMonkey'' to you</span></td></tr>
<tr class="msg" msg-type="NOTICE" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="NOTICE" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="NOTICE" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>Notice message from IRCUser ``IRCMonkey'' to you</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ME!" msg-dest="ircmonkey" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ME!" msg-dest="ircmonkey" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ME!" msg-dest="ircmonkey" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>Normal message from you to IRCUser ``IRCMonkey''</span></td></tr>
<tr class="msg" msg-type="ACTION" msg-user="ME!" msg-dest="ircmonkey" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="ACTION" msg-user="ME!" msg-dest="ircmonkey" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="ACTION" msg-user="ME!" msg-dest="ircmonkey" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>Action message from you to IRCUser ``IRCMonkey''</span></td></tr>
<tr class="msg" msg-type="NOTICE" msg-user="ME!" msg-dest="ircmonkey" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="NOTICE" msg-user="ME!" msg-dest="ircmonkey" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="NOTICE" msg-user="ME!" msg-dest="ircmonkey" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>Notice message from you to IRCUser ``IRCMonkey''</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>Sample URL &lt;<a href="http://www.mozilla.org" class="chatzilla-link" target="_content">http://www.mozilla.org</a>&gt; message.</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>Sample text styles <span class="chatzilla-bold">*bold*<img></span>, <span class="chatzilla-underline">_underline_<img></span>, <span class="chatzilla-italic">/italic/<img></span>, <span class="chatzilla-teletype">|teletype|<img></span> message.</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>Sample emoticon<span class="chatzilla-emote-txt" type="face-smile"> :) </span><span class="chatzilla-emote" type="face-smile"></span><span class="chatzilla-emote-txt" type="face-frown">:( </span><span class="chatzilla-emote" type="face-frown"></span><span class="chatzilla-emote-txt" type="face-cry">:~( </span><span class="chatzilla-emote" type="face-cry"></span><span class="chatzilla-emote-txt" type="face-surprise">:0 </span><span class="chatzilla-emote" type="face-surprise"></span><span class="chatzilla-emote-txt" type="face-screw">:/ </span><span class="chatzilla-emote" type="face-screw"></span><span class="chatzilla-emote-txt" type="face-tongue">:P </span><span class="chatzilla-emote" type="face-tongue"></span><span class="chatzilla-emote-txt" type="face-angry">:| </span><span class="chatzilla-emote" type="face-angry"></span><img src="chrome://chatzilla/skin/images/face-ear.gif"> message.</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="ME!" dest-type="IRCUser" view-type="IRCChannel" mark="even"><span>Sample <a href="ftp://ftp.mozilla.org/pub/mozilla/libraries/bonus-tracks/rheet.wav" class="chatzilla-rheet chatzilla-link">Rheeeeeeeeeet!</a> message.</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="even"><span>Normal message from IRCUser ``IRCMonkey'' to IRCChannel ``<a href="irc://moznet/#mojo" class="chatzilla-link">#mojo</a>''</span></td></tr>
<tr class="msg" msg-type="ACTION" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="ACTION" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="ACTION" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="even"><span>Action message from IRCUser ``IRCMonkey'' to IRCChannel ``<a href="irc://moznet/#mojo" class="chatzilla-link">#mojo</a>''</span></td></tr>
<tr class="msg" msg-type="NOTICE" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="NOTICE" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="NOTICE" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="even"><span>Notice message from IRCUser ``IRCMonkey'' to IRCChannel ``<a href="irc://moznet/#mojo" class="chatzilla-link">#mojo</a>''</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">rgindaFOO</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>Normal message from you to IRCChannel ``<a href="irc://moznet/#mojo" class="chatzilla-link">#mojo</a>''</span></td></tr>
<tr class="msg" msg-type="ACTION" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="ACTION" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">rgindaFOO</span></td><td class="msg-data" msg-type="ACTION" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>Action message from you to IRCChannel ``<a href="irc://moznet/#mojo" class="chatzilla-link">#mojo</a>''</span></td></tr>
<tr class="msg" msg-type="NOTICE" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="NOTICE" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">rgindaFOO</span></td><td class="msg-data" msg-type="NOTICE" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>Notice message from you to IRCChannel ``<a href="irc://moznet/#mojo" class="chatzilla-link">#mojo</a>''</span></td></tr>
<tr class="msg" msg-type="TOPIC" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="TOPIC" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">=-=</span></td><td class="msg-data" msg-type="TOPIC" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>Sample Topic message</span></td></tr>
<tr class="msg" msg-type="JOIN" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="JOIN" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">--&gt;|</span></td><td class="msg-data" msg-type="JOIN" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>Sample Join message</span></td></tr>
<tr class="msg" msg-type="PART" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="PART" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">&lt;--|</span></td><td class="msg-data" msg-type="PART" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>Sample Part message</span></td></tr>
<tr class="msg" msg-type="KICK" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="KICK" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">=-=</span></td><td class="msg-data" msg-type="KICK" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>Sample Kick message</span></td></tr>
<tr class="msg" msg-type="QUIT" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-type" msg-type="QUIT" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">|&lt;--</span></td><td class="msg-data" msg-type="QUIT" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>Sample Quit message</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" important="true"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" important="true"><span class="undefined">IRCMonkey</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ircmonkey" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" important="true" mark="even"><span>rgindafoo : Sample /stalk match.</span></td></tr>
<tr class="msg" msg-type="PRIVMSG" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><td title="7/12 15:17" class="msg-user" msg-type="PRIVMSG" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel"><span class="undefined">rgindaFOO</span></td><td class="msg-data" msg-type="PRIVMSG" msg-user="ME!" msg-dest="#mojo" dest-type="IRCChannel" view-type="IRCChannel" mark="odd"><span>Sample text styles <span class="chatzilla-bold">*bold*<img></span>, <span class="chatzilla-underline">_underline_<img></span>, <span class="chatzilla-italic">/italic/<img></span>, <span class="chatzilla-teletype">|teletype|<img></span>, message.</span></td></tr>
</tbody>
</table>
</body>
</html>

View File

@@ -1,54 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla.
*
* The Initial Developer of the Original Code is
* ____________________________________________.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Ross, <twpol@aol.com>, original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the LGPL or the GPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var gData;
var gPage;
function Init()
{
gPage = document.getElementById('czPreviewPage');
if ("arguments" in window && window.arguments[0])
gData = window.arguments[0];
if (! gData)
gData = new Object();
gPage.contentDocument.location.href =
"chrome://chatzilla/content/prefpanel/appearance-previewCSS.html"
+ (gData.style ? "?" + gData.style : '');
}

View File

@@ -1,53 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="Init();" buttons="accept" style=" width: 50em; height: 40em; "
title="&appearance-previewCSS.window.title;">
<script src="chrome://chatzilla/content/prefpanel/appearance-previewCSS.js"/>
<keyset id="dialogKeys"/>
<hbox flex="1">
<iframe id="czPreviewPage" flex="1" src="about:blank"/>
</hbox>
<separator/>
</dialog>

View File

@@ -1,17 +0,0 @@
#czMungerBold {
font-weight: bold;
}
#czMungerItalic {
font-style: italic;
}
/* FIXME: This doesn't work in XUL due to bug 68841. */
#czMungerUnderline {
text-decoration: underline;
}
#czMungerTeletype {
font-family: monospace;
}

View File

@@ -1,115 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla.
*
* The Initial Developer of the Original Code is
* ____________________________________________.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Ross, <twpol@aol.com>, original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the LGPL or the GPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const nsIFilePicker = Components.interfaces.nsIFilePicker;
const czStyleDefault = "chrome://chatzilla/skin/output-default.css";
const czStyleLight = "chrome://chatzilla/skin/output-light.css";
const czStyleDark = "chrome://chatzilla/skin/output-dark.css";
const czStyleFacesDefault = "http://www.hacksrus.com/~ginda/chatzilla/motifs/output-default-faces.css";
const czStyleFacesLight = "http://www.hacksrus.com/~ginda/chatzilla/motifs/output-light-faces.css";
const czStyleFacesDark = "http://www.hacksrus.com/~ginda/chatzilla/motifs/output-dark-faces.css";
function Init()
{
parent.initPanel("chrome://chatzilla/content/prefpanel/appearance.xul");
var edit = document.getElementById("czStyleCSS");
selectStyle(edit.getAttribute("prefvalue"));
}
function onChooseFile()
{
try
{
var edit = document.getElementById("czStyleCSS");
var oldStyle = edit.getAttribute("prefvalue");
var fpClass = Components.classes["@mozilla.org/filepicker;1"];
var fp = fpClass.createInstance(nsIFilePicker);
fp.init(window, getMsg("file_browse_CSS"), nsIFilePicker.modeOpen);
fp.appendFilter(getMsg("file_browse_CSS_spec"), "*.css");
fp.appendFilters(nsIFilePicker.filterAll);
if (fp.show() == nsIFilePicker.returnOK && fp.fileURL.spec
&& fp.fileURL.spec.length > 0)
selectStyle(fp.fileURL.spec);
else
selectStyle(oldStyle);
}
catch(ex)
{
dump ("caught exception in `onChooseFile`\n" + ex);
}
}
function selectStyle(file)
{
var edit = document.getElementById("czStyleCSS");
var option = document.getElementById("czStyleCustomCSS");
edit.setAttribute("prefvalue", file);
var opts = edit.childNodes[0].childNodes;
for (var i = 0; i < opts.length; i++)
{
if (opts[i].getAttribute("url") == file)
{
edit.selectedIndex = i;
return true;
}
}
option.hidden = false;
option.label = file;
option.setAttribute("url", file);
edit.selectedIndex = 7;
return true;
}
function previewStyle()
{
var edit = document.getElementById("czStyleCSS");
var gData = new Object();
gData.style = edit.getAttribute("prefvalue");
window.openDialog("chrome://chatzilla/content/prefpanel/appearance-previewCSS.xul",
"czPreviewCSS", "chrome,modal,resizable=yes", gData);
}

View File

@@ -1,171 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://chatzilla/content/prefpanel/appearance.css" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="Init();"
headertitle="&appearance.window.title;">
<script src="chrome://global/content/strres.js"/>
<script src="chrome://chatzilla/content/prefpanel/pref-irc.js"/>
<script src="chrome://chatzilla/content/prefpanel/appearance.js"/>
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["czMungerBold", "czMungerItalic", "czMungerUnderline",
"czMungerTeletype", "czMungerWeb", "czMungerMail", "czMungerChannels",
"czMungerBugzilla", "czMungerEmoti", "czMungerColors", "czMungerWrap",
"czMungerBugzillaURL", "czStyleCSS"];
]]>
</script>
<groupbox>
<caption label="&prePro.title;"/>
<label>&prePro.desc;</label>
<grid>
<columns>
<column/>
<column flex="1"/><column flex="1"/><column flex="1"/><column flex="1"/>
</columns>
<rows>
<row align="center">
<label value="&prePro.styles;" hidden="true"/>
<checkbox id="czMungerBold" label="&prePro.styles.bold.label;"
tooltiptext="&prePro.styles.bold.tooltip;"
accesskey="&prePro.styles.bold.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.bold"/>
<checkbox id="czMungerItalic" label="&prePro.styles.italic.label;"
tooltiptext="&prePro.styles.italic.tooltip;"
accesskey="&prePro.styles.italic.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.italic"/>
<checkbox id="czMungerUnderline" label="&prePro.styles.underline.label;"
tooltiptext="&prePro.styles.underline.tooltip;"
accesskey="&prePro.styles.underline.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.underline"/>
<checkbox id="czMungerTeletype" label="&prePro.styles.teletype.label;"
tooltiptext="&prePro.styles.teletype.tooltip;"
accesskey="&prePro.styles.teletype.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.teletype"/>
</row>
<row align="center">
<label value="&prePro.links;" hidden="true"/>
<checkbox id="czMungerWeb" label="&prePro.styles.web.label;"
tooltiptext="&prePro.styles.web.tooltip;"
accesskey="&prePro.styles.web.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.link"/>
<checkbox id="czMungerMail" label="&prePro.styles.mail.label;"
tooltiptext="&prePro.styles.mail.tooltip;"
accesskey="&prePro.styles.mail.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.mailto"/>
<checkbox id="czMungerChannels" label="&prePro.styles.channel.label;"
tooltiptext="&prePro.styles.channel.tooltip;"
accesskey="&prePro.styles.channel.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.channel-link"/>
<checkbox id="czMungerBugzilla" label="&prePro.styles.bug.label;"
tooltiptext="&prePro.styles.bug.tooltip;"
accesskey="&prePro.styles.bug.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.bugzilla-link"/>
</row>
<row>
<checkbox id="czMungerEmoti" label="&prePro.emoti.label;"
tooltiptext="&prePro.emoti.tooltip;"
accesskey="&prePro.emoti.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.face"/>
<checkbox id="czMungerColors" label="&prePro.colors.label;"
tooltiptext="&prePro.colors.tooltip;"
accesskey="&prePro.colors.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.colorCodes"/>
<checkbox id="czMungerWrap" label="&prePro.wrap.label;"
tooltiptext="&prePro.wrap.tooltip;"
accesskey="&prePro.wrap.accesskey;" prefdefval="true"
prefstring="extensions.irc.munger.word-hyphenator"/>
</row>
</rows>
</grid>
<hbox align="center">
<label value="&prePro.bugURL.label;" control="czMungerBugzillaURL"
accesskey="&prePro.bugURL.accesskey;"/>
<textbox id="czMungerBugzillaURL" flex="1"
prefdefval="http://bugzilla.mozilla.org/show_bug.cgi?id=%s"
prefstring="extensions.irc.bugURL"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&style.title;"/>
<vbox>
<label>&style.desc;</label>
<hbox align="center">
<label value="&style.css.label;" control="czStyleCSS"
accesskey="&style.css.accesskey;"/>
<!-- FIXME: Shows blank when switching to this pref page. -->
<menulist flex="1" id="czStyleCSS" crop="center"
prefvalue="" prefattribute="prefvalue" wsm_attributes="prefvalue"
prefdefval="chrome://chatzilla/skin/output-default.css"
preftype="string" prefstring="extensions.irc.motif.current">
<menupopup>
<menuitem label="&style.default.label;"
oncommand="selectStyle(this.getAttribute('url'));"
url="chrome://chatzilla/skin/output-default.css"/>
<menuitem label="&style.dark.label;"
oncommand="selectStyle(this.getAttribute('url'));"
url="chrome://chatzilla/skin/output-dark.css"/>
<menuitem label="&style.light.label;"
oncommand="selectStyle(this.getAttribute('url'));"
url="chrome://chatzilla/skin/output-light.css"/>
<menuitem label="&style.faces.default.label;"
oncommand="selectStyle(this.getAttribute('url'));"
url="http://www.hacksrus.com/~ginda/chatzilla/motifs/output-default-faces.css"/>
<menuitem label="&style.faces.dark.label;"
oncommand="selectStyle(this.getAttribute('url'));"
url="http://www.hacksrus.com/~ginda/chatzilla/motifs/output-dark-faces.css"/>
<menuitem label="&style.faces.light.label;"
oncommand="selectStyle(this.getAttribute('url'));"
url="http://www.hacksrus.com/~ginda/chatzilla/motifs/output-light-faces.css"/>
<menuseparator/>
<menuitem id="czStyleCustomCSS" label="" hidden="true" url="" crop="center"
oncommand="selectStyle(this.getAttribute('url'));"/>
<menuitem label="&style.custom.label;" oncommand="onChooseFile();"/>
</menupopup>
</menulist>
<button label="&style.preview.label;" accesskey="&style.preview.accesskey;"
oncommand="previewStyle();"/>
</hbox>
</vbox>
</groupbox>
</page>

View File

@@ -1,95 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla.
*
* The Initial Developer of the Original Code is
* ____________________________________________.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Ross, <twpol@aol.com>, original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the LGPL or the GPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
function Init() {
parent.initPanel("chrome://chatzilla/content/prefpanel/interface.xul");
initPMTabsPref();
}
function initPMTabsPref()
{
var allowTabs = document.getElementById("czCreateTabsForPMs");
var limitTabs = document.getElementById("czLimitPMTabs");
var userTabs = document.getElementById("csPMTabLimitUser");
var prefBox = document.getElementById("czPMTabLimit");
if (prefBox.value == 0)
{
allowTabs.checked = true;
limitTabs.checked = false;
userTabs.value = "15";
}
else if (prefBox.value == 1)
{
allowTabs.checked = false;
limitTabs.checked = false;
userTabs.value = "15";
}
else
{
allowTabs.checked = true;
limitTabs.checked = true;
userTabs.value = prefBox.value;
}
limitTabs.disabled = ! allowTabs.checked;
userTabs.disabled = ! (allowTabs.checked && limitTabs.checked);
}
function updatePMTabPref()
{
var allowTabs = document.getElementById("czCreateTabsForPMs");
var limitTabs = document.getElementById("czLimitPMTabs");
var userTabs = document.getElementById("csPMTabLimitUser");
var prefBox = document.getElementById("czPMTabLimit");
if (allowTabs.checked)
{
if (limitTabs.checked)
prefBox.value = userTabs.value;
else
prefBox.value = "0";
}
else
{
prefBox.value = "1";
}
limitTabs.disabled = ! allowTabs.checked;
userTabs.disabled = ! (allowTabs.checked && limitTabs.checked);
if (! userTabs.disabled)
userTabs.focus();
}

View File

@@ -1,117 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE page SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="Init();"
headertitle="&interface.window.title;">
<script src="chrome://chatzilla/content/prefpanel/interface.js"/>
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["czPMTabLimit", "czFocusPMs", "czConL",
"czScrollback1", "czScrollback2", "czScrollback3",
"czScrollback4"];
]]>
</script>
<groupbox align="start">
<caption label="&tabs.title;"/>
<vbox>
<checkbox id="czCreateTabsForPMs" label="&tabs.createForPMs.label;"
accesskey="&tabs.createForPMs.accesskey;" oncommand="updatePMTabPref();"/>
<hbox class="indent">
<checkbox id="czLimitPMTabs" label="&tabs.limitPMTabs.label;"
accesskey="&tabs.limitPMTabs.accesskey;" oncommand="updatePMTabPref();"/>
<textbox id="csPMTabLimitUser" size="5" oninput="updatePMTabPref();"/>
<textbox id="czPMTabLimit" hidden="true" prefdefval="15"
preftype="int" prefattribute="value"
prefstring="extensions.irc.newTabLimit"/>
<!-- Set to 0 for unlimited tabs, and 1 for no PM tabs. -->
</hbox>
</vbox>
<checkbox id="czFocusPMs" label="&tabs.focusPMs.label;"
accesskey="&tabs.focusPMs.accesskey;" prefdefval="false"
prefstring="extensions.irc.raiseNewTab"/>
<checkbox id="czConL" label="&tabs.closeOnLeave.label;"
accesskey="&tabs.closeOnLeave.accesskey;" prefdefval="true"
prefstring="extensions.irc.deleteOnPart"/>
</groupbox>
<groupbox>
<caption label="&scrollback.title;"/>
<vbox>
<label>&scrollback.label;</label>
<grid>
<columns>
<column/><column flex="1"/>
</columns>
<rows>
<row align="center">
<label value="&scrollback.1.label;" control="czScrollback1"
accesskey="&scrollback.1.accesskey;"/><hbox>
<textbox id="czScrollback1" size="5" preftype="int"
prefattribute="value" prefdefval="200"
prefstring="extensions.irc.views.client.maxlines"
/><spacer/></hbox>
</row>
<row align="center">
<label value="&scrollback.2.label;" control="czScrollback2"
accesskey="&scrollback.2.accesskey;"/><hbox>
<textbox id="czScrollback2" size="5" preftype="int"
prefattribute="value" prefdefval="100"
prefstring="extensions.irc.views.network.maxlines"/><spacer/></hbox>
</row>
<row align="center">
<label value="&scrollback.3.label;" control="czScrollback3"
accesskey="&scrollback.3.accesskey;"/><hbox>
<textbox id="czScrollback3" size="5" preftype="int"
prefattribute="value" prefdefval="300"
prefstring="extensions.irc.views.channel.maxlines"/><spacer/></hbox>
</row>
<row align="center">
<label value="&scrollback.4.label;" control="czScrollback4"
accesskey="&scrollback.4.accesskey;"/><hbox>
<textbox id="czScrollback4" size="5" preftype="int"
prefattribute="value" prefdefval="200"
prefstring="extensions.irc.views.chanuser.maxlines"/><spacer/></hbox>
</row>
</rows>
</grid>
</vbox>
</groupbox>
</page>

View File

@@ -1,73 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla.
*
* The Initial Developer of the Original Code is
* ____________________________________________.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Ross, <twpol@aol.com>, original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the LGPL or the GPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var strBundle;
function getMsg (msgName)
{
var restCount = arguments.length - 1;
if (!strBundle)
{
strBundle =
srGetStrBundle("chrome://chatzilla/locale/chatzilla.properties");
}
try
{
if (restCount == 1 && arguments[1] instanceof Array)
{
return strBundle.formatStringFromName (msgName, arguments[1],
arguments[1].length);
}
else if (restCount > 0)
{
var subPhrases = new Array();
for (var i = 1; i < arguments.length; ++i)
subPhrases.push(arguments[i]);
return strBundle.formatStringFromName (msgName, subPhrases,
subPhrases.length);
}
return strBundle.GetStringFromName (msgName);
}
catch (ex)
{
dump ("caught exception getting value for ``" + msgName + "''\n" + ex);
return msgName;
}
}

View File

@@ -1,136 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="parent.initPanel('chrome://chatzilla/content/prefpanel/pref-irc.xul');"
headertitle="&pref-irc.window.title;">
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["czNickname", "czUsername", "czDesc",
"czNotify", "czDisplayCollapse", "czDisplayCopyMsgs",
"czReconnect", "czColorCodes", "czNickCompleteStr", "czCharset"];
const OSBS_CTRID = "@mozilla.org/observer-service;1";
const nsIObserverService = Components.interfaces.nsIObserverService;
var observerService =
Components.classes[OSBS_CTRID].getService(nsIObserverService);
observerService.notifyObservers(null, "charsetmenu-selected", "other");
]]>
</script>
<groupbox>
<caption label="&userDetails.title;"/>
<grid flex="1">
<columns>
<column/><column flex="1"/>
</columns>
<rows>
<row align="center">
<label value="&userDetails.nick.label;" control="czNickname"
accesskey="&userDetails.nick.accesskey;"/><hbox>
<textbox id="czNickname" size="20" prefdefval="IRCMonkey"
prefstring="extensions.irc.nickname"/><spacer/></hbox>
</row><row align="center">
<label value="&userDetails.name.label;" control="czUsername"
accesskey="&userDetails.name.accesskey;"/><hbox>
<textbox id="czUsername" size="20" prefdefval="chatzilla"
prefstring="extensions.irc.username"/><spacer/></hbox>
</row><row align="center">
<label value="&userDetails.desc.label;" control="czDesc"
accesskey="&userDetails.desc.accesskey;"/>
<textbox id="czDesc" prefdefval="New Now Know How"
prefstring="extensions.irc.desc"/>
</row>
</rows>
</grid>
<hbox id="czUserHelpButton">
<button label="&userDetails.help.label;"
accesskey="&userDetails.help.accesskey;"
oncommand="
document.getElementById('czUserHelpButton').hidden = true;
document.getElementById('czUserHelpBox').hidden = false;
"/>
<spacer flex="1"/>
</hbox>
<label id="czUserHelpBox" hidden="true">&userDetails.help.desc;</label>
</groupbox>
<groupbox align="start">
<caption label="&global.title;"/>
<checkbox id="czNotify" label="&global.notify.label;"
accesskey="&global.notify.accesskey;" prefdefval="true"
prefstring="extensions.irc.notify.aggressive"/>
<checkbox id="czDisplayCollapse" label="&global.collapse.label;"
accesskey="&global.collapse.accesskey;" prefdefval="false"
prefstring="extensions.irc.collapseMsgs"/>
<checkbox id="czDisplayCopyMsgs" label="&global.copyMsgs.label;"
accesskey="&global.copyMsgs.accesskey;" prefdefval="true"
prefstring="extensions.irc.copyMessages"/>
<checkbox id="czReconnect" label="&global.reconnect.label;"
accesskey="&global.reconnect.accesskey;" prefdefval="true"
prefstring="extensions.irc.reconnect"/>
<checkbox id="czColorCodes" label="&global.colorcodes.label;"
accesskey="&global.colorcodes.accesskey;" prefdefval="false"
prefstring="extensions.irc.outgoing.colorCodes"/>
<separator/>
<hbox align="center">
<label value="&global.nickCompleteStr.label;" control="czNickCompleteStr"
accesskey="&global.nickCompleteStr.accesskey;"/>
<textbox id="czNickCompleteStr" size="5" prefdefval=","
prefstring="extensions.irc.nickCompleteStr"/>
</hbox>
<label>&global.nickCompleteStr.desc;</label>
</groupbox>
<groupbox align="start">
<caption label="&global.Charset.grouplabel;"/>
<hbox align="center">
<label value="&global.DefaultCharset.label;" accesskey="&global.DefaultCharset.accesskey;" control="DefaultCharsetList"/>
<menulist id="czCharset" ref="NC:DecodersRoot" datasources="rdf:charset-menu"
prefstring="extensions.irc.charset" preftype="localizedstring"
wsm_attributes="value">
<template>
<menupopup>
<menuitem label="rdf:http://home.netscape.com/NC-rdf#Name" value="..." uri="..."/>
</menupopup>
</template>
</menulist>
</hbox>
</groupbox>
</page>

View File

@@ -1,101 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla.
*
* The Initial Developer of the Original Code is
* ____________________________________________.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Ross, <twpol@aol.com>, original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the LGPL or the GPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const nsIFilePicker = Components.interfaces.nsIFilePicker;
function Init()
{
parent.initPanel("chrome://chatzilla/content/prefpanel/sound.xul");
var edit = document.getElementById("czSound1");
selectSound(1, edit.getAttribute("prefvalue"));
edit = document.getElementById("czSound2");
selectSound(2, edit.getAttribute("prefvalue"));
edit = document.getElementById("czSound3");
selectSound(3, edit.getAttribute("prefvalue"));
}
function onChooseFile(index)
{
try
{
var edit = document.getElementById("czSound" + index);
var oldValue = edit.getAttribute("prefvalue");
var fpClass = Components.classes["@mozilla.org/filepicker;1"];
var fp = fpClass.createInstance(nsIFilePicker);
fp.init(window, getMsg("file_browse_Wave"), nsIFilePicker.modeOpen);
fp.appendFilter(getMsg("file_browse_Wave_spec"), "*.wav");
fp.appendFilters(nsIFilePicker.filterAll);
if ((fp.show() == nsIFilePicker.returnOK) && fp.fileURL.spec
&& fp.fileURL.spec.length > 0)
selectSound(index, fp.fileURL.spec);
else
selectSound(index, oldValue);
}
catch(ex)
{
dump ("caught exception in `onChooseFile`\n" + ex);
}
}
function selectSound(index, value)
{
var edit = document.getElementById("czSound" + index);
var custom = document.getElementById("czSound" + index + "Custom");
edit.setAttribute("prefvalue", value);
var opts = edit.childNodes[0].childNodes;
for (var i = 0; i < opts.length; i++)
{
if (opts[i].getAttribute("url") == value)
{
edit.selectedIndex = i;
return true;
}
}
custom.hidden = false;
custom.label = value;
custom.setAttribute("url", value);
edit.selectedIndex = 4;
return true;
}

View File

@@ -1,120 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE page SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
headertitle="&sound.window.title;" onload="Init();">
<script src="chrome://global/content/strres.js"/>
<script src="chrome://chatzilla/content/prefpanel/pref-irc.js"/>
<script src="chrome://chatzilla/content/prefpanel/sound.js"/>
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["czSound1", "czSound2", "czSound3"];
]]>
</script>
<groupbox>
<caption><label value="&sndSimpleMsg.title;" control="czSound1"
accesskey="&sndSimpleMsg.accesskey;"/></caption>
<hbox flex="1" align="center">
<label value="&sndFile.label;"/>
<menulist id="czSound1" flex="1" crop="center" preftype="string"
prefvalue="" prefattribute="prefvalue" wsm_attributes="prefvalue"
prefstring="extensions.irc.msgBeep" prefdefval="beep beep">
<menupopup>
<menuitem label="&sndPreset1.label;" url=""
oncommand="selectSound(1, this.getAttribute('url'));"/>
<menuitem label="&sndPreset2.label;" url="beep"
oncommand="selectSound(1, this.getAttribute('url'));"/>
<menuitem label="&sndPreset3.label;" url="beep beep"
oncommand="selectSound(1, this.getAttribute('url'));"/>
<menuseparator/>
<menuitem id="czSound1Custom" label="" crop="center" hidden="true"/>
<menuitem label="&sndChoose.label;" oncommand="onChooseFile(1);"/>
</menupopup>
</menulist>
</hbox>
</groupbox>
<groupbox>
<caption><label value="&sndPrivateMsg.title;" control="czSound2"
accesskey="&sndPrivateMsg.accesskey;"/></caption>
<hbox flex="1" align="center">
<label value="&sndFile.label;"/>
<menulist id="czSound2" flex="1" crop="center" preftype="string"
prefvalue="" prefattribute="prefvalue" wsm_attributes="prefvalue"
prefstring="extensions.irc.queryBeep" prefdefval="beep">
<menupopup>
<menuitem label="&sndPreset1.label;" url=""
oncommand="selectSound(2, this.getAttribute('url'));"/>
<menuitem label="&sndPreset2.label;" url="beep"
oncommand="selectSound(2, this.getAttribute('url'));"/>
<menuitem label="&sndPreset3.label;" url="beep beep"
oncommand="selectSound(2, this.getAttribute('url'));"/>
<menuseparator/>
<menuitem id="czSound2Custom" label="" crop="center" hidden="true"/>
<menuitem label="&sndChoose.label;" oncommand="onChooseFile(2);"/>
</menupopup>
</menulist>
</hbox>
</groupbox>
<groupbox>
<caption><label value="&sndStalkMsg.title;" control="czSound3"
accesskey="&sndStalkMsg.accesskey;"/></caption>
<hbox flex="1" align="center">
<label value="&sndFile.label;"/>
<menulist id="czSound3" flex="1" crop="center" preftype="string"
prefvalue="" prefattribute="prefvalue" wsm_attributes="prefvalue"
prefstring="extensions.irc.stalkBeep" prefdefval="beep">
<menupopup>
<menuitem label="&sndPreset1.label;" url=""
oncommand="selectSound(3, this.getAttribute('url'));"/>
<menuitem label="&sndPreset2.label;" url="beep"
oncommand="selectSound(3, this.getAttribute('url'));"/>
<menuitem label="&sndPreset3.label;" url="beep beep"
oncommand="selectSound(3, this.getAttribute('url'));"/>
<menuseparator/>
<menuitem id="czSound3Custom" label="" crop="center" hidden="true"/>
<menuitem label="&sndChoose.label;" oncommand="onChooseFile(3);"/>
</menupopup>
</menulist>
</hbox>
</groupbox>
</page>

View File

@@ -1,158 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla.
*
* The Initial Developer of the Original Code is
* ____________________________________________.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Ross, <twpol@aol.com>, original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the LGPL or the GPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
function Init()
{
parent.initPanel("chrome://chatzilla/content/prefpanel/stalk.xul");
loadList("StalkWords");
}
function loadList(list)
{
var gList = document.getElementById("cz" + list);
var prefList = gList.getAttribute("prefvalue");
if (prefList)
{
var items = prefList.split(/\s*;\s*/);
for (i in items)
listAddItem(list, items[i]);
}
listUpdateButtons(list);
}
function addStalkWord()
{
var word = prompt(getMsg("stalk_add_msg"));
if (word)
listAddItem("StalkWords", word);
}
function listUpdateButtons(list)
{
var gList = document.getElementById("cz" + list);
var gButtonAdd = document.getElementById("czAdd" + list);
var gButtonDel = document.getElementById("czDel" + list);
if (gList.selectedItems && gList.selectedItems.length)
gButtonDel.removeAttribute("disabled");
else
gButtonDel.setAttribute("disabled", "true");
}
function listUpdate(list) {
var gList = document.getElementById("cz" + list);
listUpdateButtons(list);
var prefList = "";
for (var item = gList.firstChild; item; item = item.nextSibling)
{
var url = item.getAttribute("url");
if (prefList)
prefList = prefList + "; " + url;
else
prefList = url;
}
gList.setAttribute("prefvalue", prefList);
}
function listAdd(list) {
if (list == "StalkWords")
addStalkWord();
listUpdate(list);
}
function listDelete(list)
{
var gList = document.getElementById("cz" + list);
var selected = gList.selectedItems[0];
gList.removeChild(selected);
listUpdate(list);
}
function listAddItem(list, url)
{
var gList = document.getElementById("cz" + list);
var newItem = document.createElement("listitem");
var label = url;
newItem.setAttribute("label", label);
newItem.setAttribute("url", url);
gList.appendChild(newItem);
}
function listMoveUp(list)
{
var gList = document.getElementById("cz" + list);
var selected = gList.selectedItems[0];
var before = selected.previousSibling;
if (before)
{
before.parentNode.insertBefore(selected, before);
gList.selectItem(selected);
gList.ensureElementIsVisible(selected);
}
listUpdate(list);
}
function listMoveDown(list)
{
var gList = document.getElementById("cz" + list);
var selected = gList.selectedItems[0];
if (selected.nextSibling)
{
if (selected.nextSibling.nextSibling)
gList.insertBefore(selected, selected.nextSibling.nextSibling);
else
gList.appendChild(selected);
gList.selectItem(selected);
}
listUpdate(list);
}

View File

@@ -1,81 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE page SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="Init();"
headertitle="&stalk.window.title;">
<script src="chrome://global/content/strres.js"/>
<script src="chrome://chatzilla/content/prefpanel/pref-irc.js"/>
<script src="chrome://chatzilla/content/prefpanel/stalk.js"/>
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["czStalkWords", "czStalkWholeWords"];
]]>
</script>
<vbox flex="1">
<groupbox flex="1">
<caption><label value="&stalkWords.title;" control="czStalkWords"
accesskey="&stalkWords.accesskey;"/></caption>
<label>&stalkWords.label1;</label>
<label>&stalkWords.label2;</label>
<hbox flex="1">
<listbox id="czStalkWords" flex="1"
style="width: 0px; height: 0px;" crop="center"
prefstring="extensions.irc.stalkWords" preftype="string"
prefvalue="" prefattribute="prefvalue" wsm_attributes="prefvalue"
onselect="listUpdateButtons('StalkWords');"/>
</hbox>
<hbox>
<button id="czAddStalkWords" label="&list.add.label;"
accesskey="&list.add.stalk.accesskey;"
oncommand="listAdd('StalkWords');"/>
<button id="czDelStalkWords" label="&list.del.label;"
accesskey="&list.del.stalk.accesskey;"
oncommand="listDelete('StalkWords');"/>
</hbox>
</groupbox>
<checkbox id="czStalkWholeWords" label="&stalkWholeWords.label;"
tooltiptext="&stalkWholeWords.tooltip;"
accesskey="&stalkWholeWords.accesskey;" prefdefval="true"
prefstring="extensions.irc.stalkWholeWords"/>
</vbox>
</page>

View File

@@ -1,40 +0,0 @@
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var gFileBox;
var gData;
function Init() {
doSetOKCancel(onOK);
gFileBox = document.getElementById("czFileBox");
if ("arguments" in window && window.arguments[0]) {
gData = window.arguments[0];
}
gFileBox.focus();
}
function onChooseFile() {
try {
var flClass = Components.classes["@mozilla.org/filepicker;1"];
var fp = flClass.createInstance(nsIFilePicker);
fp.init(window, getMsg("file_browse_Script"),
nsIFilePicker.modeOpen);
fp.appendFilter(getMsg("file_browse_Script_spec"), "*.js");
fp.appendFilters(nsIFilePicker.filterAll);
if (fp.show() == nsIFilePicker.returnOK && fp.fileURL.spec
&& fp.fileURL.spec.length > 0)
gFileBox.value = fp.fileURL.spec;
}
catch(ex) {
}
}
function onOK() {
gData.url = gFileBox.value;
gData.ok = true;
return true;
}

View File

@@ -1,60 +0,0 @@
<?xml version="1.0"?>
<!--
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
-->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="Init();"
class="dialog" style="width: 40em;"
title="&startup-newScript.window.title;">
<script type="application/x-javascript"
src="chrome://chatzilla/content/prefpanel/startup-newScript.js"/>
<keyset id="dialogKeys"/>
<label value="&text.desc;"/>
<hbox align="center">
<textbox id="czFileBox" type="autocomplete" searchSessions="history"
timeout="50" maxrows="6"
disablehistory="true" flex="1"/>
<button label="Choose File.." onclick="onChooseFile();"/>
</hbox>
<separator/>
<hbox id="okCancelButtonsRight"/>
</window>

View File

@@ -1,168 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla.
*
* The Initial Developer of the Original Code is
* ____________________________________________.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Ross, <twpol@aol.com>, original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the LGPL or the GPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var gFileBox;
var gData;
var gType;
var gServer;
var gServerNeedPass;
var gServerAlso;
var gChannel;
var gChannelIsNick;
var gChannelNeedKey;
function Init()
{
doSetOKCancel(onOK);
gType = document.getElementById("czURLType");
gServer = document.getElementById("czServer");
gServerNeedPass = document.getElementById("czServerNeedPass");
gServerAlso = document.getElementById("czServerAlso");
gChannel = document.getElementById("czChannel");
gChannelIsNick = document.getElementById("czChannelIsNick");
gChannelNeedKey = document.getElementById("czChannelNeedKey");
if ("arguments" in window && window.arguments[0])
gData = window.arguments[0];
if (! gData)
gData = new Object();
if (!("url" in gData) || !gData.url)
gData.url = "irc:///";
if (gData.url == "irc:" || gData.url == "irc:/" || gData.url == "irc://")
{
gType.selectedItem = gType.mRadioChildren[1];
}
else
{
gType.selectedItem = gType.mRadioChildren[0];
gChannelIsNick.selectedItem = gChannelIsNick.mRadioChildren[0];
// Split it up into server/channel parts...
var params = gData.url.match(/^irc:\/\/(.*)\/([^,]*)(.*)?$/);
gServer.value = params[1];
gChannel.value = params[2];
gServerAlso.checked = (gChannel.value != '');
if (params.length >= 4)
{
var modifiers = params[3].split(/,/);
for (m in modifiers)
{
if (modifiers[m] == 'needpass')
gServerNeedPass.checked = true;
if (modifiers[m] == 'isnick')
gChannelIsNick.selectedItem = gChannelIsNick.mRadioChildren[1];
if (modifiers[m] == 'needkey')
gChannelNeedKey.checked = true;
}
}
}
updateType();
gData.ok = false;
}
function updateType()
{
if (gType.value == "normal")
{
gServer.removeAttribute("disabled");
gServerNeedPass.removeAttribute("disabled");
gServerAlso.removeAttribute("disabled");
}
else
{
gServer.setAttribute("disabled", "true");
gServerNeedPass.setAttribute("disabled", "true");
gServerAlso.setAttribute("disabled", "true");
}
if ((gType.value == "normal") && gServerAlso.checked)
{
gChannel.removeAttribute("disabled");
gChannelIsNick.childNodes[1].removeAttribute("disabled");
gChannelIsNick.childNodes[5].removeAttribute("disabled");
if (gChannelIsNick.value == "channel")
gChannelNeedKey.removeAttribute("disabled");
else
gChannelNeedKey.setAttribute("disabled", "true");
gServer.focus();
}
else
{
gChannel.setAttribute("disabled", "true");
gChannelIsNick.childNodes[1].setAttribute("disabled", "true");
gChannelIsNick.childNodes[5].setAttribute("disabled", "true");
gChannelNeedKey.setAttribute("disabled", "true");
}
}
function onOK()
{
if (gType.value == "normal")
{
gData.url = "irc://" + gServer.value + "/";
if (gServerAlso.checked)
{
gData.url += gChannel.value;
if ((gChannelIsNick.value == "channel") &&
(gChannelNeedKey.checked))
gData.url += ",needkey";
if (gChannelIsNick.value == "nickname")
gData.url += ",isnick";
}
if (gServerNeedPass.checked)
gData.url += ",needpass";
}
else
{
gData.url = "irc://";
}
gData.ok = true;
return true;
}

View File

@@ -1,85 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl"
onload="Init();"
class="dialog" style=" width: 25em; "
title="&startup-newURL.window.title;">
<script src="chrome://chatzilla/content/prefpanel/startup-newURL.js"/>
<keyset id="dialogKeys"/>
<radiogroup id="czURLType" onselect="updateType();">
<radio value="normal" label="&normal.label;"/>
<vbox class="indent">
<vbox style=" x-width: 22em; ">
<label>&normal.server;</label>
<textbox id="czServer" size="5"/>
<checkbox id="czServerNeedPass" label="&normal.needpass.label;"/>
</vbox>
<groupbox>
<caption><checkbox id="czServerAlso" label="&normal.channel.label;"
oncommand="updateType();"/></caption>
<radiogroup id="czChannelIsNick" orient="horizontal"
onselect="updateType();" align="center">
<spacer flex="1"/>
<radio value="channel" label="&normal.ischan.label;"/>
<spacer flex="1"/>
<label value="&normal.isor.label;"/>
<spacer flex="1"/>
<radio value="nickname" label="&normal.isnick.label;" flex="1"/>
<spacer flex="1"/>
</radiogroup>
<textbox id="czChannel"/>
<checkbox id="czChannelNeedKey" label="&normal.needkey.label;"/>
</groupbox>
</vbox>
<radio value="client" label="&client.label;"/>
<vbox class="indent">
<label>&client.desc;</label>
</vbox>
</radiogroup>
<separator/>
<hbox id="okCancelButtonsRight"/>
</window>

View File

@@ -1,284 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla.
*
* The Initial Developer of the Original Code is
* ____________________________________________.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Ross, <twpol@aol.com>, original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the LGPL or the GPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const nsIFilePicker = Components.interfaces.nsIFilePicker;
function Init()
{
parent.initPanel("chrome://chatzilla/content/prefpanel/startup.xul");
loadList("Scripts");
loadList("URLs");
}
function loadList(list)
{
var gList = document.getElementById("czInitial" + list);
var prefList = gList.getAttribute("prefvalue");
if (prefList.search(/\S/) != -1)
{
var items = prefList.split(/\s*;\s*/);
for (var i = 0; i < items.length; i++)
listAddItem(list, items[i]);
}
listUpdateButtons(list);
}
function getIRCDisplayText(url)
{
var params;
// NOTE: This code (by design) ignores all the irc:// modifiers except
// 'isnick'. Showing the others can be added later, if needed.
// FIXME: Localization support here (getMsg).
if ((url == "irc:" || url == "irc:/" || url == "irc://"))
return "Client view";
if ((url == "irc:///"))
return "Default network";
if ((params = url.match(/^irc:\/\/\/([^,]*)(.*),isnick(,.*)?$/)))
return params[2] + " nickname on default network";
if ((params = url.match(/^irc:\/\/\/([^,]+)/)))
return params[1] + " channel on default network";
if ((params = url.match(/^irc:\/\/(.*)\/(,.*)?$/)))
return params[1] + " network";
if ((params = url.match(/^irc:\/\/(.*)\/([^,]*)(.*),isnick(,.*)?$/)))
return params[2] + " nickname on " + params[1];
if ((params = url.match(/^irc:\/\/(.*)\/([^,]+)/)))
return params[2] + " channel on " + params[1];
return url;
}
function addScript()
{
try
{
var fpClass = Components.classes["@mozilla.org/filepicker;1"];
var fp = fpClass.createInstance(nsIFilePicker);
fp.init(window, getMsg("file_browse_Script"), nsIFilePicker.modeOpen);
fp.appendFilter(getMsg("file_browse_Script_spec"), "*.js");
fp.appendFilters(nsIFilePicker.filterAll);
if (fp.show() == nsIFilePicker.returnOK && fp.fileURL.spec &&
fp.fileURL.spec.length > 0)
listAddItem("Scripts", fp.fileURL.spec);
}
catch(ex)
{
dump ("caught exception in `addScript`\n" + ex);
}
}
function addURL()
{
var gData = new Object();
window.openDialog("chrome://chatzilla/content/prefpanel/startup-newURL.xul",
"czAddURL", "chrome,modal,resizable=no", gData);
if (gData.ok)
listAddItem("URLs", gData.url);
}
function editURL()
{
var gData = new Object();
var gList = document.getElementById("czInitialURLs");
if (gList.selectedItems.length == 0)
return;
var selected = gList.selectedItems[0];
gData.url = selected.getAttribute("url");
window.openDialog("chrome://chatzilla/content/prefpanel/startup-newURL.xul",
"czEditURL", "chrome,modal,resizable=no", gData);
if (gData.ok)
{
selected.setAttribute("label", getIRCDisplayText(gData.url));
selected.setAttribute("url", gData.url);
}
}
function listUpdateButtons(list)
{
var gList = document.getElementById("czInitial" + list);
var gButtonUp = document.getElementById("czUp" + list);
var gButtonDn = document.getElementById("czDn" + list);
var gButtonAdd = document.getElementById("czAdd" + list);
var gButtonEdit = document.getElementById("czEdit" + list);
var gButtonDel = document.getElementById("czDel" + list);
if (gList.selectedItems && gList.selectedItems.length)
{
if (gButtonEdit) gButtonEdit.removeAttribute("disabled");
gButtonDel.removeAttribute("disabled");
}
else
{
if (gButtonEdit) gButtonEdit.setAttribute("disabled", "true");
gButtonDel.setAttribute("disabled", "true");
}
if (gList.selectedItems.length == 0 || gList.selectedIndex == 0)
{
gButtonUp.setAttribute("disabled", "true");
}
else
{
gButtonUp.removeAttribute("disabled");
}
if (gList.selectedItems.length == 0 ||
gList.selectedIndex == gList.childNodes.length - 1)
{
gButtonDn.setAttribute("disabled", "true");
}
else
{
gButtonDn.removeAttribute("disabled");
}
}
function listUpdate(list)
{
var gList = document.getElementById("czInitial" + list);
listUpdateButtons(list);
var prefList = "";
for (var item = gList.firstChild; item; item = item.nextSibling)
{
var url = escape(item.getAttribute("url"));
if (prefList)
prefList = prefList + "; " + url;
else
prefList = url;
}
gList.setAttribute("prefvalue", prefList);
}
function listAdd(list)
{
if (list == "Scripts")
addScript();
else if (list == "URLs")
addURL();
listUpdate(list);
}
function listEdit(list)
{
if (list == "URLs")
editURL();
listUpdate(list);
}
function listDelete(list)
{
var gList = document.getElementById("czInitial" + list);
var selected = gList.selectedItems[0];
gList.removeChild(selected);
listUpdate(list);
}
function listAddItem(list, url)
{
var gList = document.getElementById("czInitial" + list);
var newItem = document.createElement("listitem");
url = unescape(url);
var label = url;
if (list == "URLs")
label = getIRCDisplayText(url);
if (list == "Scripts")
newItem.setAttribute("crop", "center");
newItem.setAttribute("label", label);
newItem.setAttribute("url", url);
gList.appendChild(newItem);
}
function listMoveUp(list)
{
var gList = document.getElementById("czInitial" + list);
var selected = gList.selectedItems[0];
var before = selected.previousSibling;
if (before)
{
before.parentNode.insertBefore(selected, before);
gList.selectItem(selected);
gList.ensureElementIsVisible(selected);
}
listUpdate(list);
}
function listMoveDown(list)
{
var gList = document.getElementById("czInitial" + list);
var selected = gList.selectedItems[0];
if (selected.nextSibling)
{
if (selected.nextSibling.nextSibling)
gList.insertBefore(selected, selected.nextSibling.nextSibling);
else
gList.appendChild(selected);
gList.selectItem(selected);
}
listUpdate(list);
}

View File

@@ -1,111 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE page SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="Init();"
headertitle="&startup.window.title;">
<script src="chrome://global/content/strres.js"/>
<script src="chrome://chatzilla/content/prefpanel/pref-irc.js"/>
<script src="chrome://chatzilla/content/prefpanel/startup.js"/>
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["czInitialScripts", "czInitialURLs"];
]]>
</script>
<label>&startupOrder.label;</label>
<groupbox flex="1">
<caption><label value="&autoScripts.title;" control="czInitialScripts"
accesskey="&autoScripts.accesskey;"/></caption>
<hbox flex="1">
<listbox id="czInitialScripts" flex="1" prefdefval=""
style="width: 0px; height: 0px;" crop="center"
prefstring="extensions.irc.initialScripts" preftype="string"
prefvalue="" prefattribute="prefvalue" wsm_attributes="prefvalue"
onselect="listUpdateButtons('Scripts');"/>
<vbox>
<button id="czUpScripts" label="&list.up.label;" class="up"
accesskey="&list.up.script.accesskey;"
oncommand="listMoveUp('Scripts');"/>
<button id="czDnScripts" label="&list.dn.label;" class="down"
accesskey="&list.dn.script.accesskey;"
oncommand="listMoveDown('Scripts');"/>
</vbox>
</hbox>
<hbox>
<button id="czAddScripts" label="&list.add.label;"
accesskey="&list.add.script.accesskey;"
oncommand="listAdd('Scripts');"/>
<button id="czDelScripts" label="&list.del.label;"
accesskey="&list.del.script.accesskey;"
oncommand="listDelete('Scripts');"/>
</hbox>
</groupbox>
<groupbox flex="1">
<caption><label value="&autoURLs.title;" control="czInitialURLs"
accesskey="&autoURLs.accesskey;"/></caption>
<hbox flex="1">
<listbox id="czInitialURLs" flex="1" prefdefval="irc:///"
style="width: 0px; height: 0px;"
prefstring="extensions.irc.initialURLs" preftype="string"
prefvalue="" prefattribute="prefvalue" wsm_attributes="prefvalue"
onselect="listUpdateButtons('URLs');" ondblclick="listEdit('URLs');"/>
<vbox>
<button id="czUpURLs" label="&list.up.label;" class="up"
accesskey="&list.up.server.accesskey;"
oncommand="listMoveUp('URLs');"/>
<button id="czDnURLs" label="&list.dn.label;" class="down"
accesskey="&list.dn.server.accesskey;"
oncommand="listMoveDown('URLs');"/>
</vbox>
</hbox>
<hbox>
<button id="czAddURLs" label="&list.add.label;"
accesskey="&list.add.server.accesskey;"
oncommand="listAdd('URLs');"/>
<button id="czEditURLs" label="&list.edit.label;"
accesskey="&list.edit.accesskey;"
oncommand="listEdit('URLs');"/>
<button id="czDelURLs" label="&list.del.label;"
accesskey="&list.del.server.accesskey;"
oncommand="listDelete('URLs');"/>
</hbox>
</groupbox>
</page>

View File

@@ -1,114 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is ChatZilla.
-
- The Initial Developer of the Original Code is
- ____________________________________________.
- Portions created by the Initial Developer are Copyright (C) 2002
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE page SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="parent.initPanel('chrome://chatzilla/content/prefpanel/tabs.xul');"
headertitle="&tabs.window.title;">
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["czPMTabLimit", "czFocusPMs", "czConL",
"czScrollback1", "czScrollback2", "czScrollback3",
"czScrollback4"];
]]>
</script>
<groupbox align="start">
<caption label="&tabs.title;"/>
<vbox>
<checkbox id="czCreateTabsForPMs" label="&tabs.createForPMs.label;"
accesskey="&tabs.createForPMs.accesskey;"/>
<hbox class="indent">
<checkbox id="czLimitPMTabs" label="&tabs.limitPMTabs.label;"
accesskey="&tabs.limitPMTabs.accesskey;"/>
<textbox id="czPMTabLimit" size="5"
preftype="int" prefattribute="value"
prefstring="extensions.irc.newTabLimit"/>
</hbox>
</vbox>
<checkbox id="czFocusPMs" label="&tabs.focusPMs.label;"
accesskey="&tabs.focusPMs.accesskey;"
prefstring="extensions.irc.raiseNewTab"/>
<checkbox id="czConL" label="&tabs.closeOnLeave.label;"
accesskey="&tabs.closeOnLeave.accesskey;"
prefstring="extensions.irc.deleteOnPart"/>
</groupbox>
<groupbox>
<caption label="&scrollback.title;"/>
<vbox>
<label>&scrollback.label;</label>
<grid>
<columns>
<column/><column flex="1"/>
</columns>
<rows>
<row align="center">
<label value="&scrollback.1.label;"
accesskey="&scrollback.1.accesskey;"/><hbox>
<textbox id="czScrollback1" size="5" preftype="int" prefattribute="value"
prefstring="extensions.irc.views.client.maxlines"/><spacer/></hbox>
</row>
<row align="center">
<label value="&scrollback.2.label;"
accesskey="&scrollback.2.accesskey;"/><hbox>
<textbox id="czScrollback2" size="5" preftype="int" prefattribute="value"
prefstring="extensions.irc.views.network.maxlines"/><spacer/></hbox>
</row>
<row align="center">
<label value="&scrollback.3.label;"
accesskey="&scrollback.3.accesskey;"/><hbox>
<textbox id="czScrollback3" size="5" preftype="int" prefattribute="value"
prefstring="extensions.irc.views.channel.maxlines"/><spacer/></hbox>
</row>
<row align="center">
<label value="&scrollback.4.label;"
accesskey="&scrollback.4.accesskey;"/><hbox>
<textbox id="czScrollback4" size="5" preftype="int" prefattribute="value"
prefstring="extensions.irc.views.chanuser.maxlines"/><spacer/></hbox>
</row>
</rows>
</grid>
</vbox>
</groupbox>
</page>

View File

@@ -1,111 +0,0 @@
<?xml version="1.0"?>
<!--
-
- The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Chatzilla
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU Public License (the "GPL"), in which case the
- provisions of the GPL are applicable instead of those above.
- If you wish to allow use of your version of this file only
- under the terms of the GPL and not to allow others to use your
- version of this file under the MPL, indicate your decision by
- deleting the provisions above and replace them with the notice
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- Contributor(s):
- James Ross, <twpol@aol.com>, original author
-
-->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE page SYSTEM "chrome://chatzilla/locale/pref-irc.dtd">
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="parent.initPanel('chrome://chatzilla/content/prefpanel/text.xul');"
headertitle="&text.window.title;">
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["czMungerBold", "czMungerItalic", "czMungerUnderline",
"czMungerTeletype", "czMungerWeb", "czMungerMail", "czMungerChannels",
"czMungerBugzilla", "czMungerEmoti", "czMungerColors", "czMungerWrap",
"czDisplayCollapse", "czDisplayCopyMsgs"];
]]>
</script>
<groupbox>
<caption label="&prePro.title;"/>
<label>&prePro.desc;</label>
<grid>
<columns>
<column/>
<column flex="1"/><column flex="1"/><column flex="1"/><column flex="1"/>
</columns>
<rows>
<row align="center">
<label value="&prePro.styles;"/>
<checkbox id="czMungerBold" label="Bold" accesskey="B"
prefstring="extensions.irc.munger.bold"/>
<checkbox id="czMungerItalic" label="Italic" accesskey="I"
prefstring="extensions.irc.munger.italic"/>
<checkbox id="czMungerUnderline" label="Underline" accesskey="U"
prefstring="extensions.irc.munger.underline"/>
<checkbox id="czMungerTeletype" label="Teletype" accesskey="T"
prefstring="extensions.irc.munger.teletype"/>
</row>
<row align="center">
<label value="&prePro.links;"/>
<checkbox id="czMungerWeb" label="Web" accesskey="W"
prefstring="extensions.irc.munger.link"/>
<checkbox id="czMungerMail" label="Mail" accesskey="M"
prefstring="extensions.irc.munger.mailto"/>
<checkbox id="czMungerChannels" label="Channels" accesskey="C"
prefstring="extensions.irc.munger.channel-link"/>
<checkbox id="czMungerBugzilla" label="Bugzilla" accesskey="z"
prefstring="extensions.irc.munger.bugzilla-link"/>
</row>
</rows>
</grid>
<label value="&prePro.otherOptions;"/>
<vbox class="indent" align="start">
<checkbox id="czMungerEmoti" label="&prePro.emoti;" accesskey="e"
prefstring="extensions.irc.munger.face"/>
<checkbox id="czMungerColors" label="&prePro.colors;" accesskey="c"
prefstring="extensions.irc.munger.colorCodes"/>
<checkbox id="czMungerWrap" label="&prePro.wrap;" accesskey="W"
prefstring="extensions.irc.munger.word-hyphenator"/>
</vbox>
</groupbox>
<groupbox align="start">
<caption label="&text.title;"/>
<label>&text.desc;</label>
<checkbox id="czDisplayCollapse" label="&text.collapse;" accesskey="l"
prefstring="extensions.irc.views.collapseMsgs"/>
<checkbox id="czDisplayCopyMsgs" label="&text.copyMsgs;" accesskey="p"
prefstring="extensions.irc.views.copyMessages"/>
</groupbox>
<groupbox>
<caption label="&style.title;"/>
<label>&style.desc;</label>
<textbox/>
</groupbox>
</page>

View File

@@ -1,514 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ChatZilla
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, <rginda@netscape.com>, original author
*
*/
const DEFAULT_NICK = "IRCMonkey"
function initPrefs()
{
client.prefManager = new PrefManager("extensions.irc.");
client.prefManagers = [client.prefManager];
client.prefs = client.prefManager.prefs;
var profilePath = getSpecialDirectory("ProfD");
profilePath.append("chatzilla");
client.prefManager.addPref("profilePath", profilePath.path);
profilePath = new nsLocalFile(client.prefs["profilePath"]);
if (!profilePath.exists())
mkdir(profilePath);
client.prefManager.profilePath = profilePath;
var scriptPath = profilePath.clone();
scriptPath.append("scripts");
if (!scriptPath.exists())
mkdir(scriptPath);
client.prefManager.scriptPath = scriptPath;
var logPath = profilePath.clone();
logPath.append("logs");
if (!logPath.exists())
mkdir(logPath);
client.prefManager.logPath = logPath;
var logDefault = client.prefManager.logPath.clone();
logDefault.append(escapeFileName("client.log"));
var prefs =
[
["aliases", []],
["bugURL", "http://bugzilla.mozilla.org/show_bug.cgi?id=%s"],
["channelHeader", true],
["channelLog", false],
["channelMaxLines", 500],
["charset", "utf-8"],
["clientMaxLines", 200],
["collapseMsgs", false],
["copyMessages", true],
["debugMode", ""],
["desc", "New Now Know How"],
["deleteOnPart", true],
["displayHeader", true],
["guessCommands", true],
["focusChannelOnJoin", true],
["initialURLs", []],
["initialScripts", [getURLSpecFromFile(scriptPath.path)]],
["log", false],
["logFileName", logDefault.path],
["messages.click", "goto-url"],
["messages.ctrlClick", "goto-url-newwin"],
["messages.metaClick", "goto-url-newtab"],
["motif.dark", "chrome://chatzilla/skin/output-dark.css"],
["motif.light", "chrome://chatzilla/skin/output-light.css"],
["motif.default", "chrome://chatzilla/skin/output-default.css"],
["motif.current", "chrome://chatzilla/skin/output-default.css"],
["msgBeep", "beep beep"],
["multiline", false],
["munger.colorCodes", true],
["networkHeader", true],
["networkLog", false],
["networkMaxLines", 200],
["newTabLimit", 15],
["notify.aggressive", true],
["nickCompleteStr", ":"],
["nickname", DEFAULT_NICK],
["outgoing.colorCodes", false],
["outputWindowURL", "chrome://chatzilla/content/output-window.html"],
["queryBeep", "beep"],
["raiseNewTab", false],
["reconnect", true],
["stalkBeep", "beep"],
["stalkWholeWords", true],
["stalkWords", []],
["username", "chatzilla"],
["usermode", "+ix"],
["userHeader", true],
["userLog", false],
["userMaxLines", 200]
];
client.prefManager.addPrefs(prefs);
client.prefManager.onPrefChanged = onPrefChanged;
CIRCNetwork.prototype.stayingPower = client.prefs["reconnect"];
CIRCNetwork.prototype.INITIAL_NICK = client.prefs["nickname"];
CIRCNetwork.prototype.INITIAL_NAME = client.prefs["username"];
CIRCNetwork.prototype.INITIAL_DESC = client.prefs["desc"];
CIRCNetwork.prototype.INITIAL_UMODE = client.prefs["usermode"];
CIRCNetwork.prototype.MAX_MESSAGES = client.prefs["networkMaxLines"];
CIRCChannel.prototype.MAX_MESSAGES = client.prefs["channelMaxLines"];
CIRCChanUser.prototype.MAX_MESSAGES = client.prefs["userMaxLines"];
client.MAX_MESSAGES = client.prefs["clientMaxLines"];
client.charset = client.prefs["charset"];
initAliases();
}
function pref_mungeName(name)
{
return escape(name.replace(/\./g, "-").replace(/:/g, "_").toLowerCase());
}
function getNetworkPrefManager(network)
{
function defer(prefName)
{
return client.prefs[prefName];
};
function onPrefChanged(prefName, newValue, oldValue)
{
onNetworkPrefChanged (network, prefName, newValue, oldValue);
};
var logDefault = client.prefManager.logPath.clone();
logDefault.append(escapeFileName(pref_mungeName(network.name)) + ".log");
var prefs =
[
["charset", defer],
["collapseMsgs", defer],
["desc", defer],
["displayHeader", client.prefs["networkHeader"]],
["log", client.prefs["networkLog"]],
["logFileName", logDefault.path],
["motif.current", defer],
["nickname", defer],
["outputWindowURL", defer],
["reconnect", defer],
["username", defer],
["usermode", defer]
];
var branch = "extensions.irc.networks." + pref_mungeName(network.name) +
".";
var prefManager = new PrefManager(branch);
prefManager.addPrefs(prefs);
prefManager.onPrefChanged = onPrefChanged;
network.INITIAL_NICK = prefManager.prefs["nickname"];
network.INITIAL_NAME = prefManager.prefs["username"];
network.INITIAL_DESC = prefManager.prefs["desc"];
network.INITIAL_UMODE = prefManager.prefs["usermode"];
network.stayingPower = prefManager.prefs["reconnect"];
client.prefManagers.push(prefManager);
return prefManager;
}
function getChannelPrefManager(channel)
{
var network = channel.parent.parent;
function defer(prefName)
{
return network.prefs[prefName];
};
function onPrefChanged(prefName, newValue, oldValue)
{
onChannelPrefChanged (channel, prefName, newValue, oldValue);
};
var logDefault = client.prefManager.logPath.clone();
var filename = pref_mungeName(network.name) + "," +
pref_mungeName(channel.name);
logDefault.append(escapeFileName(filename) + ".log");
var prefs =
[
["charset", defer],
["collapseMsgs", defer],
["displayHeader", client.prefs["channelHeader"]],
["log", client.prefs["channelLog"]],
["logFileName", logDefault.path],
["motif.current", defer],
["outputWindowURL", defer]
];
var branch = "extensions.irc.networks." + pref_mungeName(network.name) +
".channels." + pref_mungeName(channel.normalizedName) + "."
var prefManager = new PrefManager(branch);
prefManager.addPrefs(prefs);
prefManager.onPrefChanged = onPrefChanged;
client.prefManagers.push(prefManager);
return prefManager;
}
function getUserPrefManager(user)
{
var network = user.parent.parent;
function defer(prefName)
{
return network.prefs[prefName];
};
function onPrefChanged(prefName, newValue, oldValue)
{
onUserPrefChanged (user, prefName, newValue, oldValue);
};
var logDefault = client.prefManager.logPath.clone();
var filename = pref_mungeName(network.name);
filename += "," + pref_mungeName(user.nick);
logDefault.append(escapeFileName(filename) + ".log");
var prefs =
[
["charset", defer],
["collapseMsgs", defer],
["displayHeader", client.prefs["userHeader"]],
["motif.current", defer],
["outputWindowURL", defer],
["log", client.prefs["userLog"]],
["logFileName", logDefault.path]
];
var branch = "extensions.irc.networks." + pref_mungeName(network.name) +
".users." + pref_mungeName(user.nick) + ".";
var prefManager = new PrefManager(branch);
prefManager.addPrefs(prefs);
prefManager.onPrefChanged = onPrefChanged;
client.prefManagers.push(prefManager);
return prefManager;
}
function destroyPrefs()
{
if ("prefManagers" in client)
{
for (var i = 0; i < client.prefManagers.length; ++i)
client.prefManagers[i].destroy();
}
}
function onPrefChanged(prefName, newValue, oldValue)
{
switch (prefName)
{
case "channelMaxLines":
CIRCChannel.prototype.MAX_MESSAGES = newValue;
break;
case "charset":
client.charset = newValue;
break;
case "clientMaxLines":
client.MAX_MESSAGES = newValue;
case "nickname":
CIRCNetwork.prototype.INITIAL_NICK = newValue;
break;
case "username":
CIRCNetwork.prototype.INITIAL_NAME = newValue;
break;
case "usermode":
CIRCNetwork.prototype.INITIAL_UMODE = newValue;
break;
case "userMaxLines":
CIRCChanUser.prototype.MAX_MESSAGES = newValue;
break;
case "debugMode":
if (newValue.indexOf("e") != -1)
client.debugHook.enabled = true;
else
client.debugHook.enabled = false;
if (newValue.indexOf("c") != -1)
client.dbgContexts = true;
else
delete client.dbgContexts;
if (newValue.indexOf("d") != -1)
client.dbgDispatch = true;
else
delete client.dbgDispatch;
break;
case "desc":
CIRCNetwork.prototype.INITIAL_DESC = newValue;
break;
case "stalkWholeWords":
case "stalkWords":
updateAllStalkExpressions();
break;
case "motif.current":
dispatch("sync-motifs");
break;
case "multiline":
multilineInputMode(newValue);
break;
case "munger.colorCodes":
client.enableColors = newValue;
break;
case "networkMaxLines":
CIRCNetwork.prototype.MAX_MESSAGES = newValue;
break;
case "outputWindowURL":
dispatch("sync-windows");
break;
case "displayHeader":
dispatch("sync-headers");
break;
case "log":
dispatch("sync-logs");
break;
case "aliases":
initAliases();
break;
}
}
function onNetworkPrefChanged(network, prefName, newValue, oldValue)
{
if (network != client.networks[network.name])
{
/* this is a stale observer, remove it */
network.prefManager.destroy();
return;
}
network.updateHeader();
switch (prefName)
{
case "nickname":
network.INITIAL_NICK = newValue;
break;
case "username":
network.INITIAL_NAME = newValue;
break;
case "usermode":
network.INITIAL_UMODE = newValue;
if (network.isConnected())
{
network.primServ.sendData("mode " + network.server.me + " :" +
newValue + "\n");
}
break;
case "desc":
network.INITIAL_DESC = newValue;
break;
case "reconnect":
network.stayingPower = newValue;
break;
case "motif.current":
dispatch("sync-motifs");
break;
case "outputWindowURL":
dispatch("sync-windows");
break;
case "displayHeader":
dispatch("sync-headers");
break;
case "log":
dispatch("sync-logs");
break;
}
}
function onChannelPrefChanged(channel, prefName, newValue, oldValue)
{
var network = channel.parent.parent;
if (network != client.networks[network.name] ||
channel.parent != network.primServ ||
channel != network.primServ.channels[channel.normalizedName])
{
/* this is a stale observer, remove it */
channel.prefManager.destroy();
return;
}
channel.updateHeader();
switch (prefName)
{
case "motif.current":
dispatch("sync-motifs");
case "outputWindowURL":
dispatch("sync-windows");
break;
case "displayHeader":
dispatch("sync-headers");
break;
case "log":
dispatch("sync-logs");
break;
}
}
function onUserPrefChanged(user, prefName, newValue, oldValue)
{
var network = user.parent.parent;
if (network != client.networks[network.name] ||
user.parent != network.primServ ||
user != network.primServ.users[user.name])
{
/* this is a stale observer, remove it */
user.prefManager.destroy();
return;
}
user.updateHeader();
switch (prefName)
{
case "motif.current":
dispatch("sync-motifs");
case "outputWindowURL":
dispatch("sync-windows");
break;
case "displayHeader":
dispatch("sync-headers");
break;
case "log":
dispatch("sync-logs");
break;
}
}
function initAliases()
{
var aliasDefs = client.prefs["aliases"];
for (var i = 0; i < aliasDefs.length; ++i)
{
var ary = aliasDefs[i].split(/\s*=\s*/);
var name = ary[0];
var list = ary[1];
client.commandManager.defineCommand(name, list);
}
}

Some files were not shown because too many files have changed in this diff Show More