/** * Default handler for any error conditions. This just sets the * condition information in the dispatch unit. * * @param c The condition information for the error. */ void ContextCommandHandlerDispatcher::handleError(DirectoryClass *c) { // this only gets added if there is a condition // NB: This is called by the native activation after re-entering the // kernel code, so this has full access to kernel calls. if (c != OREF_NULL) { // check to see if this is an error or failure situation RexxString *conditionName = (RexxString *)c->get(GlobalNames::CONDITION); // if this is not a syntax error, this is likely an error // or failure condition, and the return value is taken from // the condition object. if (!conditionName->strCompare(GlobalNames::SYNTAX)) { // just set the condition now...additional processing will be // done on return to the command issuer condition = c; } else { // raise this as a normal error by default activation->checkConditions(); } } }
/*------------------------------------------------------Routine::unsetTrapper-+ | | +----------------------------------------------------------------------------*/ void Routine::unsetTrapper(RexxString const & key, bool isSignalStmt) { unsigned short & condSide = isSignalStmt? m_signals : m_callons; switch (key.charAt(0)) { case 'E': condSide &= ~SIG_ERROR; break; case 'F': condSide &= ~SIG_FAILURE; break; case 'H': condSide &= ~SIG_HALT; break; case 'L': condSide &= ~SIG_LOSTDIGITS; break; case 'N': if (key.charAt(2)=='V') { condSide &= ~SIG_NOVALUE; }else { condSide &= ~SIG_NOTREADY; } break; case 'S': condSide &= ~SIG_SYNTAX; break; } }
/*---------------------------------DynamicCharConverter::DynamicCharConverter-+ | Build a cross table such that translated = m_x[translatee]; | +----------------------------------------------------------------------------*/ DynamicCharConverter::DynamicCharConverter( char pad, RexxString const & tableo ) { int len = tableo.length(); if (len > sizeof m_table) len = sizeof m_table; memcpy(m_table, tableo, len); memset(m_table+len, pad, sizeof m_table - len); }
/*--------------------------------------------------------Routine::setTrapper-+ | | +----------------------------------------------------------------------------*/ void Routine::setTrapper( RexxString const & key, RexxString & strName, bool isSignalStmt ) { Signaled sig; switch (key.charAt(0)) { case 'E': sig = SIG_ERROR; m_strError = strName; break; case 'F': sig = SIG_FAILURE; m_strFailure = strName; break; case 'H': sig = SIG_HALT; m_strHalt = strName; break; case 'L': sig = SIG_LOSTDIGITS; m_strLostDigits = strName; break; case 'N': if (key.charAt(2)=='V') { sig = SIG_NOVALUE; m_strNoValue = strName; } else { sig = SIG_NOTREADY; m_strNotReady = strName; } break; case 'S': sig = SIG_SYNTAX; m_strSyntax = strName; break; } if (isSignalStmt) { m_signals |= sig; m_callons &= ~sig; }else { m_callons |= sig; m_signals &= ~sig; } }
/*-------------------------------------------------------Arguments::Arguments-+ | Constructor for the main program | | | | IMPLEMENTATION: | | m_r(strArgs) e.g.: "m_r refers strArgs". This is just for convenience. | | The main program is not supposed to return anything? Hmmm... | | Consider using the top top top of the stack to return what | | the CT_PROGRAM returned (generally a numeric return code.) | | Also: why is this strArgs the blank-sep "char ** argv" | | Isn't CT_PROGRAM like anything else? | | For today (11/07/2001) PGR has too much on his plate for taking care. | +----------------------------------------------------------------------------*/ Arguments::Arguments(RexxString & strArgs) : m_r(strArgs) { memset(m_a, 0, sizeof m_a); if (strArgs.length() > 0) { m_a[0] = &strArgs; m_n = 1; }else { m_n = 0; } }
/*---------------------------------DynamicCharConverter::DynamicCharConverter-+ | Build a cross table such that translated = table[translatee]; | +----------------------------------------------------------------------------*/ DynamicCharConverter::DynamicCharConverter( RexxString const & tablei, char pad, RexxString const & tableo ) { for (int i=0; i < sizeof m_table; ++i) { m_table[i] = i; // aka identity, which is the default } // because of the duplicates rule, do it reverse unsigned char const * pIn = (unsigned char const *)((char const *)tablei); unsigned char const * pOut = (unsigned char const *)((char const *)tableo); unsigned char const * pOutCur = pOut + tableo.length(); unsigned char const * pInCur = pIn + tablei.length(); unsigned char const * pInPeg = pIn + tableo.length(); while (pInCur > pInPeg) { m_table[*(--pInCur)] = pad; } while (pInCur > pIn) { m_table[*(--pInCur)] = *(--pOutCur); } }
/*---------------------------------DynamicCharConverter::DynamicCharConverter-+ | Build a cross table such that translated = table[translatee]; | +----------------------------------------------------------------------------*/ DynamicCharConverter::DynamicCharConverter( RexxString const & tablei, char pad ) { for (int i=0; i < sizeof m_table; ++i) { m_table[i] = i; // aka identity, which is the default } unsigned char const * e_p = (unsigned char const *)(char const *)tablei; unsigned char const * c_p = e_p + tablei.length(); while (c_p > e_p) { m_table[*(--c_p)] = pad; } }
/*----------------------------------------------------Arguments::catenateArgs-+ | | +----------------------------------------------------------------------------*/ RexxString Arguments::catenateArgs( RexxString const & cmd, RexxString ** stack, PresenceBits presenceBits, int & base // initially: top of the stack ) { StringBuffer res(cmd, cmd.length()); int top = base; while (presenceBits != 0) { if (presenceBits & 1) --base; presenceBits >>= 1; } for (int i=base+1; i <= top; ++i) { // stack[base] is the result res.append(' '); res .append(*stack[i], stack[i]->length()); } return res; }
/*------------------------------------------------------------HashMap::remove-+ | | +----------------------------------------------------------------------------*/ void HashMap::remove(RexxString const & key) { MapItem ** ppItm = m_table + (key.hash() % m_capacity); for (;;) { RexxString::COMPARE_RESULT cond; if ( (!*ppItm) || (cond=(*ppItm)->m_key.strictCompare(key), cond == RexxString::IS_GT) ) { return; }else if (cond == RexxString::IS_EQ) { // success MapItem * pItm = *ppItm; *ppItm = (*ppItm)->m_next; delete pItm; return; } ppItm = &(*ppItm)->m_next; } }
// in behaviour RexxString *RexxString::bitAnd(RexxString *string2, RexxString *pad) { char PadChar; /* pad character */ const char *String1; /* string 1 pointer */ const char *PadString; /* padded string part */ const char *String2; /* string 2 pointer */ sizeB_t String1Len; /* string 1 length */ sizeB_t String2Len; /* string 2 length */ sizeB_t MinLength; /* length of shorter string */ sizeB_t PadLength; /* length to pad */ sizeB_t MaxLength; /* longest length */ RexxString *Retval; /* return value */ const char *Source; /* source string pointer */ char *Target; /* target string pointer */ /* get string we will be doing bit */ /* stuff to... */ string2 = optionalStringArgument(string2, OREF_NULLSTRING, ARG_ONE); ProtectedObject p(string2); String2Len = string2->getBLength(); /* get the string length */ String2 = string2->getStringData(); /* get the string data pointer */ /* get the pad character */ PadChar = optionalPadArgument(pad, (char)0xff, ARG_TWO); String1 = this->getStringData(); /* point to the first string */ String1Len = this->getBLength(); /* get the length */ if (String1Len <= String2Len) { /* string 1 shorter or equal? */ MinLength = String1Len; /* string 1 is the shorter */ MaxLength = String2Len; /* string 2 is the longer */ PadString = String2; /* padding is done on string2 */ Source = String1; /* operate from string 1 */ } else { MinLength = String2Len; /* string 2 is the shorter */ MaxLength = String1Len; /* string 1 is the longer */ PadString = String1; /* padding is done on string1 */ Source = String2; /* operate from string 2 */ } PadLength = MaxLength - MinLength; /* get the padding length */ /* Duplicate Longer */ Retval = raw_string(MaxLength); Target = Retval->getWritableData(); /* point to the tArget */ memcpy(Target, PadString, MaxLength);/* now copy in the longer one */ while (MinLength-- != 0) { /* while shorter has data */ /* and in each character */ *Target = *Target & *Source++; Target++; /* step the target */ } while (PadLength-- != 0) { /* while pad needed */ /* and in a pad character */ *Target = *Target & PadChar; Target++; /* step the target */ } return Retval; /* return result string */ }
/*-----------------------------------------------CIRexxApp::addRecordsToIndex-+ | | +----------------------------------------------------------------------------*/ void CIRexxApp::addRecordsToIndex(CArray<ScriptRecord *> & records, CDatabase * db, UInt16 cat, char * dbi) { UInt16 index = 0; UInt32 rowId; MemHandle hMem; Int16 recordPosition = 0; CHash<unsigned int, Int16> recordPositionBySegmentId; ScriptRecord * scriptRecord; if (db == 0) { return; } while ((hMem = db->QueryNextInCategory(index, cat))) { db->GetRecordUniqueID(index, rowId); UInt32 size = MemHandleSize(hMem); const char * pMem = (char *)MemHandleLock(hMem); /* | FORMAT: | %6s #segment.<no>#\ndate() time() <id>\nTitle: <tit>\nCategory: <cat> */ char * scanner; if ( // if it's segmented, combine the segments (scanner = StrStr(pMem, "#segment.")) && (scanner = StrChr(scanner + 1, '#')) ) { char segmentNoAsString[5]; memcpy(segmentNoAsString, scanner - 4, 4); segmentNoAsString[4] = '\0'; int segmentNo = StrAToI(segmentNoAsString); ++scanner; int peditHeaderSize = size - (scanner - pMem); if (peditHeaderSize > ScriptRecord::MAX_PEDITHEADERLEN) { peditHeaderSize = ScriptRecord::MAX_PEDITHEADERLEN; } RexxString header(scanner, peditHeaderSize); RexxString segmentIdAsString; segmentIdAsString.wordAt(header, 3); unsigned int segmentId = hex2uint( (char const *)segmentIdAsString, segmentIdAsString.length() ); int titWordNo = RexxString("Title:").wordpos(header, 1); int catWordNo = RexxString("Category:").wordpos(header, 1); RexxString title; title.subword(header, titWordNo + 1, catWordNo - (titWordNo + 1)); // create the script record Int16 * psegmentedRecordPosition = (Int16 *)recordPositionBySegmentId.Lookup(segmentId); // if this segment has already been encountered, then create a chain of segments if (psegmentedRecordPosition) { ScriptRecord * sr = records[*psegmentedRecordPosition]; sr->m_indexes.Insert(sr->m_indexes.GetCount(), index); sr->m_segments.Insert(sr->m_segments.GetCount(), segmentNo); // otherwise just add it }else { scriptRecord = new ScriptRecord(db, dbi, title, index, segmentNo); recordPositionBySegmentId.SetAt(segmentId, recordPosition); records.Insert(recordPosition++, scriptRecord); } }else { // otherwise just add it unsigned int i; for (i=0; pMem[i] && pMem[i] != linefeedChr && i < ScriptRecord::MAX_TITLELEN; ++i) { ; } char * t = new char[i + 1]; memcpy(t, pMem, i); t[i] = '\0'; RexxString title(t); scriptRecord = new ScriptRecord(db, dbi, title, index); delete [] t; records.Insert(recordPosition++, scriptRecord); } MemHandleUnlock(hMem); ++index; } }
/*----------------------------------------------------Routine::setEnvironment-+ | | +----------------------------------------------------------------------------*/ void Routine::setEnvironment(RexxString & value) { if (value.length() > 250) { m_erh << ECE__ERROR << _REX__29_1 << 250 << value << endm; } m_env = value; }
// in behaviour RexxString *RexxString::delWord(RexxInteger *position, RexxInteger *plength) { char *Current; /* current pointer position */ const char *Word; /* current word pointer */ const char *NextSite; /* next word */ sizeB_t WordPos; /* needed word position */ size_t Count; /* count of words */ sizeB_t Length; /* remaining length */ sizeB_t WordLength; /* word size */ sizeB_t FrontLength; /* front substring */ RexxString *Retval; /* return value */ /* convert position to binary */ WordPos = positionArgument(position, ARG_ONE); /* get num of words to delete, the */ /* default is "a very large number" */ Count = optionalLengthArgument(plength, Numerics::MAX_WHOLENUMBER, ARG_TWO); Length = this->getBLength(); /* get string length */ if (Length == 0) /* null string? */ { Retval = OREF_NULLSTRING; /* result is null also */ } else if (Count == 0) /* deleting zero words? */ { Retval = this; /* just use this string */ } else { Word = this->getStringData(); /* point to the string */ /* get the first word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); while (--WordPos != 0 && WordLength != 0) { /* loop until we reach tArget */ Word = NextSite; /* copy the start pointer */ /* get the next word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); } if (WordPos != 0) /* run out of words first */ { Retval = this; /* return entire string */ } else { /* count off number of words */ /* calculate front length */ FrontLength = (size_t)(Word - this->getStringData()); while (--Count != 0 && WordLength != 0) { /* loop until we reach tArget */ Word = NextSite; /* copy the start pointer */ /* get the next word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); } if (Length != 0) /* didn't use up the string */ { StringUtil::skipBlanks(&NextSite, &Length);/* skip over trailing blanks */ } /* allocate return string */ Retval = raw_string(FrontLength + Length); /* point to data portion */ Current = Retval->getWritableData(); if (FrontLength != 0) { /* have a leading portion? */ /* copy into the result */ memcpy(Current, this->getStringData(), FrontLength); Current += FrontLength; /* step output position */ } if (Length != 0) /* any string left? */ { /* copy what's left */ memcpy(Current, NextSite, Length); } } } return Retval; /* return deleted string */ }
// in behaviour RexxString *RexxString::space(RexxInteger *space_count, RexxString *pad) { sizeC_t Spaces; /* requested spacing */ codepoint_t PadChar; /* pad character */ char *Current; /* current pointer position */ const char *Word; /* current word pointer */ const char *NextSite; /* next word */ sizeB_t Count; /* count of words */ sizeB_t WordSize; /* size of words */ sizeB_t Length; /* remaining length */ sizeB_t WordLength; /* word size */ RexxString *Retval; /* return value */ /* get the spacing count */ Spaces = optionalLengthArgument(space_count, 1, ARG_ONE); /* get the pad character */ PadChar = optionalPadArgument(pad, ' ', ARG_TWO); Length = this->getBLength(); /* get the string length */ Count = 0; /* no words yet */ WordSize = 0; /* no characters either */ Word = this->getStringData(); /* point to the string */ /* get the first word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); while (WordLength != 0) { /* loop until we reach tArget */ Count++; /* count the word */ WordSize += WordLength; /* add in the word length */ Word = NextSite; /* copy the start pointer */ /* get the next word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); } if (Count == 0) /* no words? */ { Retval = OREF_NULLSTRING; /* this is a null string */ } else { /* real words */ Count--; /* step back one */ /* get space for output */ Retval = raw_string(WordSize + Count * size_v(Spaces)); // todo m17n : Spaces is a char count /* point to output area */ Current = Retval->getWritableData(); Length = this->getBLength(); /* recover the length */ Word = this->getStringData(); /* point to the string */ /* get the first word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); while (Count-- != 0) { /* loop for each word */ /* copy the word over */ memcpy(Current, Word, WordLength); Current += WordLength; /* step over the word */ if (Spaces != 0) { /* if have gaps... */ /* fill in the pad chars */ memset(Current, PadChar, size_v(Spaces)); // todo m17n Current += size_v(Spaces); /* step over the pad chars */ // todo m17n } Word = NextSite; /* copy the start pointer */ /* get the next word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); } /* copy the word over */ memcpy(Current, Word, WordLength); } return Retval; /* return spaced string */ }