/*********************************************************************** * * FUNCTION: PrvCreateTimeZoneArray * * DESCRIPTION: Create the array of time zone entries from our string * list, gtm offset list, and country list resources. Sort based on * time zone name. * * DOLATER kwk - we could save the time zone array we're creating here * in memory, to avoid the performance hit of creating the array. * On the other hand, then the list of names would need to stay * locked down, unless we also copy those into the memory buffer, * which means another 700+ bytes. * * PARAMETERS: * timeZoneNames <-> Ptr to returned handle to list of names. * numTimeZones <-> Ptr to count of number of time zones. * * RETURNED: * Ptr to allocated array of time zone entry records. * * HISTORY: * 07/31/00 kwk Created by Ken Krugler. * 08/23/00 kwk Fixed bug where release ROMs caused ErrNonFatalDisplayIf * to become a no-op, and thus the country and time zone * offset list ptrs weren't skipping the count word. * ***********************************************************************/ static TimeZoneEntryType* PrvCreateTimeZoneArray(MemHandle* timeZoneNames, UInt16* numTimeZones) { const Char* tzNamesP; TimeZoneEntryType* tzEntries; MemHandle offsetsH; MemHandle countriesH; UInt16* resP; Int16* gmtOffsetsP; UInt16* countriesP; UInt16 i; // Specify the number of items in the list, based on total # of items // in our time zone name list resource. *timeZoneNames = DmGetResource(strListRscType, TimeZoneNamesStringList); ErrNonFatalDisplayIf(*timeZoneNames == NULL, "No time zone names"); tzNamesP = (const Char*)MemHandleLock(*timeZoneNames); // Skip over prefix string, then get the entry count. tzNamesP += StrLen(tzNamesP) + 1; *numTimeZones = *tzNamesP++; *numTimeZones = (*numTimeZones << 8) + *tzNamesP++; // Allocate the array of time zone records. tzEntries = (TimeZoneEntryType*)MemPtrNew(*numTimeZones * sizeof(TimeZoneEntryType)); ErrFatalDisplayIf(tzEntries == NULL, "Out of memory"); // Find and lock down the gtm offset and country integer lists. offsetsH = DmGetResource(wrdListRscType, TimeZoneGMTOffsetsList); ErrNonFatalDisplayIf(offsetsH == NULL, "No time zone offsets"); resP = (UInt16*)MemHandleLock(offsetsH); ErrNonFatalDisplayIf(*resP != *numTimeZones, "GMT offset count != name count"); // Skip count at start of list. gmtOffsetsP = (Int16*)resP + 1; countriesH = DmGetResource(wrdListRscType, TimeZoneCountriesList); ErrNonFatalDisplayIf(countriesH == NULL, "No time zone countries"); resP = (UInt16*)MemHandleLock(countriesH); ErrNonFatalDisplayIf(*resP != *numTimeZones, "Time zone country count != name count"); // Skip count at start of list. countriesP = resP + 1; // Now loop to fill in all of the records. for (i = 0; i < *numTimeZones; i++) { tzEntries[i].tzName = tzNamesP; tzNamesP += StrLen(tzNamesP) + 1; tzEntries[i].tzOffset = gmtOffsetsP[i]; tzEntries[i].tzCountry = (CountryType)countriesP[i]; } MemHandleUnlock(offsetsH); MemHandleUnlock(countriesH); // Now sort the list, based on the time zone name. SysQSort(tzEntries, *numTimeZones, sizeof(TimeZoneEntryType), PrvCompareTimeZoneEntries, 0); return(tzEntries); } // PrvCreateTimeZoneArray
Boolean IntlSetStrictChecks(Boolean iStrictChecks) { Boolean oldSetting; UInt32 flags; Err result; // Global flags has precedence over feature value. oldSetting = (GIntlData->intlFlags & kStrictChecksFlag) != 0; result = FtrGet(sysFtrCreator, sysFtrNumIntlMgr, &flags); ErrNonFatalDisplayIf(result != errNone, "Can't get sysFtrNumIntlMgr feature"); if (iStrictChecks) { flags |= intlMgrStrict; GIntlData->intlFlags |= kStrictChecksFlag; } else { flags &= ~intlMgrStrict; GIntlData->intlFlags &= ~kStrictChecksFlag; } result = FtrSet(sysFtrCreator, sysFtrNumIntlMgr, flags); ErrNonFatalDisplayIf(result != errNone, "Can't set sysFtrNumIntlMgr feature"); return(oldSetting); } // IntlSetStrictChecks
/*********************************************************************** * * FUNCTION: StrAToI * * DESCRIPTION: This routine converts a string to an integer. It behaves * the same as the standard C library function atoi. Because * of a bug in the Metrowerks libraries however, we can't link * with the atoi() function in the library when compiling * for the device. * * PARAMETERS: str - string to convert * * RETURNED: converted integer * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * ron 8/18/95 Initial Revision * adamh 8/12/97 Added a for Max Int32 Int16 when Error Check Level == Full * art 9/15/97 Fix error checking code. * vmk 1/15/98 Disabled error checking code because it modified function's behavior * and interfered with normal user input testing on debug builds * (with agreement from Ron, Roger) * ***********************************************************************/ Int32 StrAToI (const Char* str) { Int32 result=0; Int16 sign = 1; Char c; // DOLATER... what is needed here, is a way to signal an overrun error to the caller. vmk 1/15/98 #if 0 // CASTRATION #if ERROR_CHECK_LEVEL == ERROR_CHECK_FULL Int32 MaxInt=0x7FFFFFFF; Int32 Divisor=1000000000; Boolean Risk=0; Int16 N=0; Int16 MaxDigits=10; #endif #endif // Check for err ErrNonFatalDisplayIf(str == NULL, "NULL string ptr passed"); // First character can be a sign c = *str++; if (!c) return 0; if (c == '+') {sign = 1; c = *str++;} else if (c == '-') {sign = -1; c = *str++;} // Accumulate digits will we reach the end of the string while(c) { if (c < '0' || c > '9') break; result = result * 10 + c -'0'; c = *str++; #if 0 // CASTRATION #if ERROR_CHECK_LEVEL == ERROR_CHECK_FULL if (N++ == MaxDigits) // ***THIS IS POOR ERROR-CHECKING CODE BECAUSE IT MODIFIES BEHAVIOR vmk 1/15/98 break; if(MaxInt / Divisor < result) //If the current number were brought out to maximum length Risk = true; //would it go over maximum size for a Int32 Int16. Divisor /= 10; #endif #endif } #if 0 // CASTRATION #if ERROR_CHECK_LEVEL == ERROR_CHECK_FULL ErrNonFatalDisplayIf((Risk && N >=MaxDigits) || result < 0,"Number exceeds maximum value for a long integer"); #endif #endif return result * sign; }
/************************************************************ * * FUNCTION: StrCat * * DESCRIPTION: Concatenates 1 string to another * * PARAMETERS: 2 string pointers * * RETURNS: pointer to dest string * * CREATED: 11/09/94 * * BY: Ron Marianetti * *************************************************************/ Char * StrCat(Char * dst, const Char* src) { Char * tmp = dst; // Check for err ErrNonFatalDisplayIf(dst == NULL || src == NULL, "NULL string passed"); ErrNonFatalDisplayIf(dst == src, "dest and source can't be the same"); tmp += StrLen(dst); while(*src) *tmp++ = *src++; *tmp = 0; return dst; }
static void SetComputers( Short num ) { FormPtr frm; ControlPtr cPtr; Word oIdx; if( num > (MaxPlayers - 1) || num < 0 ) { ErrNonFatalDisplayIf( true, "SetComputers: Out of Bounds"); return; } if( stor.tmpcomputers == num ) { return; } frm = FrmGetActiveForm(); /* Unset the old one */ oIdx = FrmGetObjectIndex( frm, cbtnVal[stor.tmpcomputers] ); cPtr = FrmGetObjectPtr( frm, oIdx ); CtlSetValue( cPtr, false ); /* Set new one */ oIdx = FrmGetObjectIndex( frm, cbtnVal[num] ); cPtr = FrmGetObjectPtr( frm, oIdx ); CtlSetValue( cPtr, true ); stor.tmpcomputers = num; if( stor.tmpcomputers + stor.tmpplayers > MaxPlayers ) { SetPlayers( MaxPlayers - stor.tmpcomputers ); } return; }
/************************************************************ * * FUNCTION: StrLocalizeNumber * * DESCRIPTION: Localize a number by converting from US number * notation to a localized version by replacing any thousand * or decimal separators. * * PARAMETERS: s - number asci string to localize * thousandSeparator - the localized thousand separator * decimalSeparator - the localized decimal separator * * RETURNS: s * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * roger 8/28/96 Initial version * roger 4/29/98 Fixed case when thousandSeparator is '.' * *************************************************************/ Char * StrLocalizeNumber(Char * s, Char thousandSeparator, Char decimalSeparator) { Char * str = s; // Check for err ErrNonFatalDisplayIf(s == NULL, "NULL string passed"); while (*str != '\0') { // Check for thousandSeparator if (*str == ',') *str = thousandSeparator; // Check for decimalSeparator else if (*str == '.') *str = decimalSeparator; // Look at the next char. str++; }; return s; }
/*********************************************************************** * * FUNCTION: PrvSetTimeField * * DESCRIPTION: Set the given field's text to show a time and day of week. * * PARAMETERS: frm - a pointer to the form containing the field to set * timeFieldID - the ID of the field to set * timeHandle - the handle used for storing the text for this field * time - a pointer to the date and time to show in the field * drawField - whether to draw field after setting its text * * RETURNED: nothing * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * peter 3/7/00 Initial Revision * ***********************************************************************/ static void PrvSetTimeField(FormType * frm, UInt16 timeFieldID, MemHandle timeHandle, DateTimeType *time, Boolean drawField) { FieldType * timeFieldP; Char * timeString, * timeZoneDOWFormatString, * currentDOWString; MemHandle resHandle; TimeFormatType timeFormat; // Format to display time in timeFormat = (TimeFormatType)PrefGetPreference(prefTimeFormat); timeString = MemHandleLock(timeHandle); TimeToAscii(time->hour, time->minute, timeFormat, timeString); currentDOWString = timeString + StrLen(timeString); currentDOWString[0] = ' '; currentDOWString++; resHandle = DmGetResource(strRsc, DOWformatString); ErrNonFatalDisplayIf(resHandle == NULL, "Missing string resource"); timeZoneDOWFormatString = MemHandleLock(resHandle); DateTemplateToAscii(timeZoneDOWFormatString, time->month, time->day, time->year, currentDOWString, dowLongDateStrLength); MemHandleUnlock(resHandle); MemHandleUnlock(timeHandle); timeFieldP = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, timeFieldID)); FldSetTextHandle(timeFieldP, timeHandle); if (drawField) FldDrawField(timeFieldP); }
/*********************************************************************** * * FUNCTION: FntSetFont * * DESCRIPTION: This routine set the current font. If the font is a valid * font but doesn't exist, the stdFont is used. * * PARAMETERS: fontID id of the font to make the active font * * RETURNED: ID of the current font prior to the change. * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * art 12/14/94 Initial Revision * roger 9/26/97 Now substitutes the stdFont for missing fonts * SCL 12/10/97 Rewrote to support new (separate) font tables * SCL 1/23/98 Now uses stdFont if passed an invalid font * bob 3/5/99 Update GState values with new font * ***********************************************************************/ FontID FntSetFont (FontID fontID) { FontID newFontID = fontID; FontID oldFontID; // See if fontID is a valid system font or app font ID if ( !FntIsAppDefined(newFontID) ? (newFontID >= UINumSysFonts) : (newFontID-fntAppFontCustomBase >= UINumAppFonts) ) { ErrNonFatalDisplay("Invalid font"); newFontID = stdFont; } oldFontID = UICurrentFontID; UICurrentFontID = newFontID; // Set the new font or a default one. if ( FntIsAppDefined(newFontID) ) { UICurrentFontPtr = UIAppFontPtr[newFontID-fntAppFontCustomBase]; } else { UICurrentFontPtr = UISysFontPtr[newFontID]; } if (UICurrentFontPtr == NULL) UICurrentFontPtr = UISysFontPtr[stdFont]; GState.drawStateP->fontId = UICurrentFontID; GState.drawStateP->font = UICurrentFontPtr; ErrNonFatalDisplayIf (UICurrentFontPtr == NULL, "Invalid font"); return oldFontID; }
/*********************************************************************** * * FUNCTION: StrStr * * DESCRIPTION: This routine looks for a substring within a string. It * behaves the same as the standard C library function strstr, except * that it correctly handles multi-byte character encodings. * * PARAMETERS: * str - string to search * token - the string to search for * * RETURNED: pointer to the first occurance of token in str, or null * if not found. * * HISTORY: * 08/18/95 ron Created by Ron Marianetti. * 05/13/00 kwk Made it work for all char encodings, not just Latin. * 11/30/00 kwk Cast token to unsigned before comparing to kTxtMaxNeverMultiByte. * ***********************************************************************/ Char* StrStr(const Char* str, const Char* token) { register Char * srcP = (Char *)str; const Char* tP; const Char* sP; // Check for err ErrNonFatalDisplayIf(str == NULL || token == NULL, "NULL string passed"); // Return null if token is null if (*token == '\0') { return(NULL); } while (*srcP != '\0') { tP = token; sP = srcP; do { if (*tP != *sP) { break; } tP++; sP++; } while (*tP != '\0'); // We think we have a match. Make sure we didn't start the match // in the middle of a character. We only need to do this check if // the first byte of token could be in the middle/end of a multi- // byte character. if (*tP == 0) { if (*(UInt8*)token > kTxtMaxNeverMultiByte) { UInt32 charStart, charEnd; TxtCharBounds(str, srcP - str, &charStart, &charEnd); if (str + charStart == srcP) { return(srcP); } } else { return(srcP); } } srcP++; } return(NULL); } // StrStr
/*********************************************************************** * * FUNCTION: FntLineWidth * * DESCRIPTION: This routine returns the width of the specified line * of text. It takes tab characters in to account. It is * assumed that the characters passed are left-align and * that the fisrt character of the string is the first * charater draw on a line. In other words, this routine * will not work for characters that start in a * position other than the start of a line. * * PARAMETERS: charsP pointer to a string of characters * length number of character in the string. * * RETURNED: nothing * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * art 10/20/95 Initial Revision * kcr 11/7/95 handles missing chars * art 5/6/98 Add support for double byte fonts. * ***********************************************************************/ Int16 FntLineWidth (Char const * charsP, UInt16 length) { FontCharInfoType * ptr; Int16 width = 0; Int16 firstChar; Int16 lastChar; Int16 charSize; UInt8 ch; ErrNonFatalDisplayIf(length > 0 && charsP == NULL, "Null charsP"); if (((UInt16)UICurrentFontPtr->fontType & fntFontMapMask) != fntFontMapMask) { firstChar = UICurrentFontPtr->firstChar; lastChar = UICurrentFontPtr->lastChar; ptr = (FontCharInfoType *) (&UICurrentFontPtr->owTLoc) + UICurrentFontPtr->owTLoc; while (length) { ch = *charsP; if (ch == tabChr) // DOLATER art - calculate tab width base on the size of the font width += fntTabChrWidth - (width % fntTabChrWidth); else if (ch >= firstChar && ch <= lastChar && ptr[ch - firstChar].width != fntMissingChar) // char exists in font width += ptr[ch - firstChar].width; else // Use width of Missing Char Symbol width += ptr[lastChar - firstChar +1].width; charsP++; length--; } } else { while (((Int16)length) > 0) { if (*charsP == tabChr) { width += fntTabChrWidth - (width % fntTabChrWidth); length--; charsP++; } else { width += GetCharsWidth (charsP, &charSize); length -= charSize; charsP += charSize; } } } return (width); }
/*********************************************************************** * * FUNCTION: StrChr * * DESCRIPTION: This routine looks for a character within a string. It * behaves the same as the standard C library function strchr, except * that it works correctly with multi-byte character encodings. * * PARAMETERS: * str - string to search * chr - the character to search for * * RETURNED: pointer to the first occurance of character in str, or NULL * if not found. * * HISTORY: * 08/18/95 ron Created by Ron Marianetti * 05/07/96 rsf Fixed to MemHandle searching for '\0' * 10/24/96 rsf Check chr * 08/12/97 ADH Revised Algorithm * 08/26/98 kwk Changed chr param from Int16 to WChar. Fixed up * sign extension problem. * 05/13/00 kwk Made it work for all char encodings, not just Latin. * ***********************************************************************/ Char* StrChr(const Char* str, WChar chr) { Char c = (Char)chr; register const Char* srcP = str; ErrNonFatalDisplayIf(str == NULL, "NULL string passed"); // Correct for sign extension. This will happen if the caller passes // a single byte >= 0x80, which the compiler will sign extend. if (chr >= 0xFF80) { ErrNonFatalDisplay("Sign extended character passed to StrChr"); chr = chr & 0x00FF; } // See if we need to do the slower (multi-byte) search case. if (chr > kTxtMaxAlwaysSingleByte) { Char buffer[maxCharBytes + 1]; UInt16 len = TxtSetNextChar(buffer, 0, chr); if (len > 1) { buffer[len] = '\0'; return(StrStr(str, buffer)); } } // Be sure to handle chr == '\0' correctly do { if (*srcP == c) { // If the character we're searching for could be part of a // multi-byte character, then we need to do an extra check // to make sure we didn't find part of a multi-byte character. // Since most people use StrChr to search for tabs, returns, // etc. this typically never gets executed. if (chr > kTxtMaxNeverMultiByte) { UInt32 charStart, charEnd; UInt32 charOffset = srcP - str; TxtCharBounds(str, charOffset, &charStart, &charEnd); if (charStart == charOffset) { return((Char*)srcP); } } else { return((Char*)srcP); } } } while (*srcP++ != 0); return(NULL); } // StrChr
void NextPlayer() { Int x; #ifdef DEBUG Int dd = 0; #endif x = stor.currplayer; while(1) { stor.currplayer = (stor.currplayer + 1) % stor.numplayers; if ( x == stor.currplayer ) { if ( stor.numplayers > 1 ) { // Only one guy hasn't lost //HaveWinner(); FrmCustomAlert( calertDEBUG, "We have a weiner, I mean a winner!", "No, I'm not telling you who.", "ToDo: Do this correctly." ); } break; } if ( ! stor.player[stor.currplayer].lost ) { break; } #ifdef DEBUG ErrNonFatalDisplayIf( ++dd > (MaxPlayers + 4), "NextPlayer: Had to rely on dd loop check!" ); #endif } DrawPlayerScore( x ); DrawPlayerScore( stor.currplayer ); // Clear scores stor.scorethisroll = stor.scorethisturn = 0; StayBit = false; // Clear cubes for( x = 0 ; x < NumCubes ; x++ ) { stor.cube[x].keep = false; stor.cube[x].value = 0; } stor.status = DS_NextPlayer; // Bypass StatusLine(); if ( stor.flags & flag_NextPlayerPopUp ) { FrmCustomAlert( calertNEXTPLAYER, stor.player[stor.currplayer].name, " ", " "); DrawState(); } else { DrawStatus(); } }
/************************************************************ * * FUNCTION: StrLen * * DESCRIPTION: Computes the length of a string * * PARAMETERS: string pointer * * RETURNS: length of string * * CREATED: 11/09/94 * * BY: Ron Marianetti * *************************************************************/ Int16 StrLen(const Char* str) { Int16 i=0; // Check for err ErrNonFatalDisplayIf(str == NULL, "NULL string passed"); while(*str++) i++; return i; }
/************************************************************ * * FUNCTION: StrIToA * * DESCRIPTION: convert an integer to ascii * * PARAMETERS: Integer to convert and string pointer to store results * * RETURNS: s * * CREATED: 11/09/94 * * BY: Roger Flores * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * roger 4/2/96 MemHandle negative numbers * eric lapuyade 10/5/99 use internal unsigned variable to allow for * smallest possible negative number (bug no 15914) * *************************************************************/ Char * StrIToA(Char * s, Int32 i) { Char * s1; Char * s2; Char c1; Char c2; UInt32 ui; // Check for err ErrNonFatalDisplayIf(s == NULL, "NULL string passed"); // Handle negative numbers if (i < 0) { *s = '-'; ui = -i; s1 = s + 1; // place numbers after the negative sign we put } else { ui = i; s1 = s; // place numbers after the start } // output the string in reverse order s2 = s1; do { *s2++ = ui % 10 + '0'; ui /= 10; // CSE should reuse the above division } while (ui > 0); *s2 = '\0'; s2--; // Reverse the string while(s1 < s2) { c1 = *s1; c2 = *s2; *s1++ = c2; *s2-- = c1; } return s; }
/************************************************************ * * FUNCTION: StrToLower * * DESCRIPTION: Converts a string to a lower case one. * * PARAMETERS: 2 string pointers * * RETURNS: pointer to dest string * * HISTORY: * 11/08/95 rsf Created by Roger Flores. * 10/07/99 kwk Speed up common case for lower-case 7-bit * ascii, and call TxtTransliterate for other * situations (high ascii, ShiftJIS, etc). * *************************************************************/ Char* StrToLower(Char* dst, const Char* src) { Char *tmp = dst; UInt8 c; // Check for err ErrNonFatalDisplayIf(dst == NULL || src == NULL, "NULL string passed"); // Optimize for the case of spinning through a bunch of lower- // case 7-bit ascii. Once we're into double-byte characters, // we have to slow way down to handle lower-casing properly // anyway, so this doesn't cost us that much extra as a percentage. while ((c = *src++) != chrNull) { if (c < 'A') { *tmp++ = c; } else if (c > 'Z') { // We assume that any character less than 0x80 can be // treated as 7-bit ascii. This isn't strictly true for // Shift-JIS, since 0x5C is the yen character, but that // can't be lower-cased anyway, so we're OK. if (c < 0x80) { *tmp++ = c; } else { // We need to do the slower lower-casing, so set up for // the call to TxtTransliterate. We don't know the size // of the dst buffer, so make it as big as possible. UInt16 dstLength = 0xFFFF; src--; TxtTransliterate(src, StrLen(src), tmp, &dstLength, translitOpLowerCase); *(tmp + dstLength) = chrNull; return(dst); } } else { *tmp++ = c + ('a' - 'A'); } } *tmp = 0; return dst; }
/*********************************************************************** * * FUNCTION: FntWCharWidth * * DESCRIPTION: This routine returns the width of the specified character, * which can be any valid character character. If the specified * character does not exist within the current font, the Missing Char * Symbol will be substituted. * * PARAMETERS: ch character whose width is desired * * RETURNED: width of the specified character, in pixels * * HISTORY: * 05/12/00 kwk Created by Ken Krugler from TxtCharWidth. * 05/17/00 kwk Add call to TxtCharIsValid on debug ROMs. * ***********************************************************************/ Int16 FntWCharWidth(WChar iChar) { Char buffer[maxCharBytes]; if (iChar >= 0xFF80) { ErrNonFatalDisplay("Sign extended char passed to FntWCharWidth"); iChar &= 0x00FF; } // On debug ROMs, make sure the character is valid (e.g. not a // virtual character). ErrNonFatalDisplayIf(!TxtCharIsValid(iChar), "Invalid char passed to FntWCharWidth"); return(FntCharsWidth(buffer, TxtSetNextChar(buffer, 0, iChar))); } // FntWCharWidth
static Char * PrvAddPadding(Char * startOfBlock, Char * dstP, const Int16 minimumSize, const Boolean leftJustify, Boolean zeroPad, Char sign) { Int16 stringSize = StrLen(startOfBlock); ErrNonFatalDisplayIf( sign && (sign != '+') && (sign != ' '), "illegal sign character specified in PrvAddPadding" ); if (leftJustify && stringSize < minimumSize) // Left Justified { MemSet(dstP, minimumSize - stringSize, ' '); dstP += minimumSize - stringSize; *dstP = '\0'; } else if (!leftJustify && stringSize < minimumSize) // Right Justified { // If there is a sign present and the calling function as specified padding with // zero bytes then do not move the sign character with the rest of the value. if ( (sign == '+' || sign == ' ') && zeroPad ) { // If there is a sign present then only MemMove the value and not the sign. // The value will be moved minimum size specified for this value minus the // actual string size of the value plus the size of the sign (1). MemMove(startOfBlock + minimumSize - stringSize + 1, startOfBlock + 1, stringSize - 1); // MemSet the space between the sign and moved value with the desired // padding value. MemSet(startOfBlock + 1, minimumSize - stringSize, zeroPad ? '0' : ' '); } else { // MemMove the value and any potential sign character to make room for padding // characters. The number of bytes to move is determined by the minimum string // specified for the value minus the actual string size of the value. MemMove(startOfBlock + minimumSize - stringSize, startOfBlock, stringSize); // MemSet the space between the sign and moved value with the desired // padding value. MemSet(startOfBlock, minimumSize - stringSize, zeroPad ? '0' : ' '); } dstP += minimumSize - stringSize; *dstP = '\0'; } return dstP; }
/************************************************************ * * FUNCTION: PrvStrIToA <internal> * * DESCRIPTION: convert an integer to ascii * * PARAMETERS: Integer to convert and string pointer to store results * * RETURNS: s * * CREATED: 11/09/94 * * BY: Roger Flores * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * roger 4/2/96 MemHandle negative numbers * adamh 7/31/97 Modified to return the end of string to work with * StrVPrintF * roger 5/22/98 Added isSigned to MemHandle UInt32 numbers correctly. * *************************************************************/ static Char * PrvConvertIToA(Char * s, UInt32 i, Boolean isSigned) { Char * s1; Char * s2; Char c1; Char c2; // Check for err ErrNonFatalDisplayIf(s == NULL, "NULL string passed"); // MemHandle negative numbers if (isSigned && (Int32) i < 0) { *s++ = '-'; i = -(Int32)i; } s1 = s; // numbers start after the negative if it exists or at the start of the string. // output the string in reverse order do { *s++ = i % 10 + '0'; i /= 10; // CSE should reuse the above division } while (i > 0); *s = '\0'; s2 = s; s2--; // Reverse the string while(s1 < s2) { c1 = *s1; c2 = *s2; *s1++ = c2; *s2-- = c1; } return s; }
/************************************************************ * * FUNCTION: PrvConvertIToH <internal> * * DESCRIPTION: convert an integer to hexadecimal ascii * * PARAMETERS: Integer to convert and string pointer to store results * * RETURNS: s * * HISTORY: * 07/04/95 RM Created by Ron Marianetti * 07/31/97 AdamH Modified to return the end of the string to work with * StrVPrintF. * 04/02/98 roger Added sizeModifier and fixed to emit less than 8 digits when not a long * 11/08/99 kwk Non-fatal alert if unknown sizeModifier. * *************************************************************/ static Char * PrvConvertIToH(Char * s, UInt32 number, SizeModifierType sizeModifier) { UInt32 mask; UInt32 digit; UInt16 digitCount; // Check for err ErrNonFatalDisplayIf(s == NULL, "NULL string passed"); switch (sizeModifier) { case sizeLong: digitCount = 8; break; case sizeShort: digitCount = 4; number <<= 16; break; case sizeInt: digitCount = 4; number <<= 16; break; default: ErrNonFatalDisplay("Invalid sizeModifier"); digitCount = 8; break; } mask = 0xF0000000; while (digitCount-- > 0) { digit = (number & mask) >> 28; if (digit < 0x0A) *s++ = digit + '0'; else *s++ = digit - 10 + 'A'; number <<= 4; } *s = '\0'; return s; }
/* SetFieldTextFromHandle -- Fills a field with contents of a handle * Args: * Word fieldID -- ID of field to fill, see cwimp.rpc file * VoidHand txtH -- Handle of String to fill ID with * Returns: * FieldPtr -- Ptr to the field set. */ FieldPtr SetFieldTextFromHandle(Word fieldID, VoidHand txtH) { Handle oldTxtH; FormPtr frm = FrmGetActiveForm(); FieldPtr fldP; fldP = FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, fieldID)); ErrNonFatalDisplayIf(!fldP, "missing field"); oldTxtH = FldGetTextHandle(fldP); FldSetTextHandle(fldP, (Handle) txtH); // FldEraseField( fldP ); FldDrawField(fldP); if (oldTxtH) MemHandleFree((VoidHand) oldTxtH); return fldP; }
Err IntlSetRoutineAddress(IntlSelector iSelector, void* iProcPtr) { #if (EMULATION_LEVEL == EMULATION_NONE) void** tablePtr; Int16 i; if (iSelector > intlMaxSelector) { return(intlErrInvalidSelector); } ErrNonFatalDisplayIf(iProcPtr == NULL, "Null proc ptr parameter"); tablePtr = (void**)GIntlDispatchTableP; if (tablePtr == NULL) { tablePtr = (void**)MemPtrNew((intlMaxSelector + 1) * sizeof(Int32*)); if (tablePtr == NULL) { return(memErrNotEnoughSpace); } // Make sure it doesn't get tossed when the current app quits. MemPtrSetOwner(tablePtr, 0); // Initialize the table with all of the default routine addresses. for (i = 0; i <= intlMaxSelector; i++) { tablePtr[i] = IntlGetRoutineAddress(i); } // Set up the low-memory global with our new, valid table. GIntlDispatchTableP = tablePtr; } tablePtr[iSelector] = iProcPtr; return(errNone); #else // EMULATION_LEVEL != EMULATION_NONE ErrFatalDisplay("Can't call IntlSetRoutineAddress in Simulator"); return(errNone); #endif } // IntlSetRoutineAddress
void SetFieldFromHandle ( UInt16 fieldID, MemHandle txtH ) { MemHandle oldTxtH; /* Old text */ FormType * frmP; /* Form pointer */ FieldType * fldP; /* Field pointer */ frmP = FrmGetActiveForm(); /* Find form pointer */ fldP = FrmGetObjectPtr (frmP, FrmGetObjectIndex ( frmP, fieldID)); /* Find field pointer */ ErrNonFatalDisplayIf ( !fldP, "missing field"); /* Check if the current object exists */ oldTxtH = FldGetTextHandle(fldP); /* Find text pointer of old text */ FldSetTextHandle(fldP, txtH); /* Set the new text */ FldDrawField(fldP); /* Redraw field */ if (oldTxtH != NULL) /* Free up old text */ MemHandleFree(oldTxtH); }
/************************************************************ * * FUNCTION: StrNCompareAscii * * DESCRIPTION: Compares two strings, up to a maximum of * n bytes. It assumes that both strings are 7-bit ASCII, * and the comparison is case-sensitive. * * PARAMETERS: 2 string pointers, max length to compare. * * RETURNS: 0 if they match, non-zero if not * + if s1 > s2 * - if s1 < s2 * * HISTORY: * 08/18/00 kwk Created by Ken Krugler. * *************************************************************/ Int16 StrNCompareAscii(const Char* s1, const Char* s2, Int32 n) { ErrNonFatalDisplayIf((s1 == NULL) || (s2 == NULL), "NULL string passed"); while (n--) { UInt8 c1 = *s1++; UInt8 c2 = *s2++; Int16 result = c1 - c2; if (result) { return(result); } else if (c1 == chrNull) { return(0); } } return(0); } // StrNCompareAscii
/************************************************************ * * FUNCTION: StrIToH * * DESCRIPTION: convert an integer to hexadecimal ascii * * PARAMETERS: Integer to convert and string pointer to store results * * RETURNS: s * * CREATED: 7/4/95 * * BY: Ron Marianetti * *************************************************************/ Char * StrIToH(Char * s, UInt32 i) { UInt32 mask; UInt32 digit; UInt16 j; // Check for err ErrNonFatalDisplayIf(s == NULL, "NULL string passed"); mask = 0xF0000000; for (j=0; j<8; j++) { digit = (i & mask) >> 28; if (digit <= 9) s[j] = digit + '0'; else s[j] = digit - 10 + 'A'; i <<= 4; } s[j] = 0; return s; }
/************************************************************ * * FUNCTION: Prv4HToI * * DESCRIPTION: Converts a 4 character hex string into an integer * Used exclusively by ErrAlertCustom below * * PARAMETERS: * str -> start of 4 character hex string * * RETURNS: integer value of str * * CREATED: 2/25/98 * * BY: Ron Marianetti * *************************************************************/ static UInt16 Prv4HToI(Char * strP) { UInt16 hex = 0; UInt16 digit; Int16 i; Char c; for (i=0; i<4; i++) { c = *strP++; if (c >= 'a') digit = c - 'a' + 10; else if (c >= 'A') digit = c - 'A' + 10; else digit = c - '0'; ErrNonFatalDisplayIf(digit > 0x0F, "invalid hex string"); hex = (hex << 4) + digit; } return hex; }
void FntCharsInWidth (Char const * string, Int16 *stringWidthP, Int16 *stringLengthP, Boolean *fitWithinWidth) { Int16 width = 0; Int16 charWidth; Int16 length = 0; Int16 maxLength = *stringLengthP; Int16 maxWidth = *stringWidthP; Int16 firstChar; Int16 lastChar; Int16 charSize; UInt8 ch; Char const * s2; FontCharInfoType * info; FontPtr fontP; ErrNonFatalDisplayIf(string == NULL, "Null string"); ErrNonFatalDisplayIf(stringWidthP == NULL, "Null stringWidthP"); ErrNonFatalDisplayIf(stringLengthP == NULL, "Null stringLengthP"); ErrNonFatalDisplayIf(fitWithinWidth == NULL, "Null fitWithinWidth"); fontP = UICurrentFontPtr; if (((UInt16)fontP->fontType & fntFontMapMask) != fntFontMapMask) { firstChar = UICurrentFontPtr->firstChar; lastChar = UICurrentFontPtr->lastChar; info = (FontCharInfoType *) (&UICurrentFontPtr->owTLoc) + UICurrentFontPtr->owTLoc; while (*string != '\0' && *string != linefeedChr && length < maxLength) { // If the character exist, get its width, otherwise get the width // of the Missing Character symbol. ch = *string; if (ch >= firstChar && ch <= lastChar && info[ch - firstChar].width != fntMissingChar) charWidth = info[ch - firstChar].width; else charWidth = info[lastChar - firstChar +1].width; if (width + charWidth <= maxWidth) { width += charWidth; length++; } else break; // can't add any more characters. string++; } } else { while (*string != '\0' && *string != linefeedChr && length < maxLength) { charWidth = GetCharsWidth (string, &charSize); if (width + charWidth <= maxWidth) { width += charWidth; length += charSize; } else break; // can't add any more characters. string += charSize; } } // string is the first character that didn't get included. A '\0' // means the entire string fit, a linefeedChr means the string wrapped // (didn't fit), and anything else means the string was too wide. // Now, if the string is too wide because of blank characters, then // the string shouldn't considered to be truncated. It's entire visible // contents does fit. // If the character we were adding was a whitespace and // all the characters until the end of the string are white spaces // then we don't consider the string truncated. if (length >= maxLength) // used up all the characters *fitWithinWidth = true; else if (*string == linefeedChr) *fitWithinWidth = false; else if (*string == '\0') *fitWithinWidth = true; else { s2 = string; while (*s2 == ' ' || *s2 == tabChr) s2++; if (*s2 == '\0') *fitWithinWidth = true; else *fitWithinWidth = false; } // Visual optimization. If the last char was unseen remove it. // Drawing it adds nothing of value. string--; while (length > 0 && (*string == ' ' || *string == linefeedChr || *string == tabChr)) { width -= FntCharWidth(*string); string--; length--; } *stringWidthP = width; *stringLengthP = length; }
/*********************************************************************** * * FUNCTION: FntWidthToOffset * * DESCRIPTION: This routine returns the byte offset which corresponds * to the pixel position (relative to the beginning of the * text). The leadingEdge flag is set if the pixel position * falls on the left side of the character; if this position * is beyond the end of the text then leadingEdge is always * true. Note that both leadingEdge & truncWidth parameters * can be NULL if the caller doesn't want those results * returned. * * PARAMETERS: charsP pointer to a string of characters * length number of character in the string * pixelWidth position in pixels from beginning of text * leadingEdge boolean flag => true if left side of char * truncWidth width of text up to the returned offset * * RETURNED: UInt8 offset to inter-character boundary before first * character located beyond pixelWidth. * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * kwk 07/01/98 Initial Revision * kwk 08/19/98 Change test to be OK if width <= pixelWidth, versus * less than. * ***********************************************************************/ Int16 FntWidthToOffset(Char const * charsP, UInt16 length, Int16 pixelWidth, Boolean *leadingEdge, Int16 * truncWidth) { FontPtr fontP = UICurrentFontPtr; Int16 offset = 0; Int16 curWidth = 0; Int16 charWidth = 0; Int16 charSize; ErrNonFatalDisplayIf(charsP == NULL, "Null string"); // If it's a simple font (only single-byte characters) then process // it directly, otherwise we need to use the GetCharsWidth routine. if (((UInt16)fontP->fontType & fntFontMapMask) != fntFontMapMask) { Int16 firstChar = UICurrentFontPtr->firstChar; Int16 lastChar = UICurrentFontPtr->lastChar; FontCharInfoType *info = (FontCharInfoType *) (&UICurrentFontPtr->owTLoc) + UICurrentFontPtr->owTLoc; while (offset < length) { UInt8 ch = *charsP++; if ((ch >= firstChar) && (ch <= lastChar)) { charWidth = info[ch - firstChar].width; if (charWidth == fntMissingChar) { charWidth = info[lastChar - firstChar +1].width; } } else { charWidth = info[lastChar - firstChar +1].width; } curWidth += charWidth; if (curWidth <= pixelWidth) { offset += 1; } else { break; } } } else { while (offset < length) { charWidth = GetCharsWidth(charsP, &charSize); curWidth += charWidth; if (curWidth <= pixelWidth) { offset += charSize; charsP += charSize; } else { break; } } } // If we ran over the end of the string, we know that the leading // edge result must be false, and we also want to prune back the // returned offset to be the length (just in case we got passed a // bogus double-byte character at the end of the string). if (offset >= length) { if (leadingEdge != NULL) { *leadingEdge = true; } if (truncWidth != NULL) { *truncWidth = curWidth; } return(length); } else { if (leadingEdge != NULL) { *leadingEdge = (curWidth - pixelWidth > (charWidth / 2)); } if (truncWidth != NULL) { *truncWidth = curWidth - charWidth; } return(offset); } } // FntWidthToOffset
/************************************************************ * * FUNCTION: StrNCat * * DESCRIPTION: Concatenates 1 string to another clipping the * destination string to a max of N characters (including null * at end). * * PARAMETERS: * dstP <-> String to receive catenated result. * srcP -> String to catenate to the end of dstP. * n -> Max length of resulting string, including null byte. * * RETURNS: pointer to dest string * * HISTORY: * 11/09/94 ron Created by Ron Marianetti * 10/24/96 rsf Added ec code * 12/18/96 vmk Removed ec code -- it was trashing data during * "copy in place" operations * 05/13/00 kwk Made it work for all char encodings, not just Latin. * 11/02/00 kwk Cast src to unsigned before comparing to kTxtMaxNeverMultiByte. * 01/02/01 rsf Fix bug reading from srcP when n is 0. * *************************************************************/ Char* StrNCat(Char* dstP, const Char* srcP, Int16 n) { Char* tmp; const Char* savedSrcP; Int16 len; #if (ERROR_CHECK_LEVEL == ERROR_CHECK_FULL) Char* endDstP; #endif // Check for err ErrFatalDisplayIf((dstP == NULL) || (srcP == NULL), "NULL string passed"); ErrNonFatalDisplayIf(dstP == srcP, "dest and source can't be the same"); // If we already are full, we can quickly return. This means that // following code knows there's enough space to copy at least one // byte of data plus a terminating null. len = StrLen(dstP); if (len >= n - 1) { return(dstP); } // Do the cat. Note that we leave space for the terminating null, thus // N is total size limit of the dst string, including the null. tmp = dstP + len; savedSrcP = srcP; while ((len < (n - 1)) && *srcP) { *tmp++ = *srcP++; len++; } // Null terminate the string if there's room if (len < n) { *tmp = '\0'; } // Make sure we didn't wind up copying over a partial byte. If we // still have source data then we must have been limited by n, and // thus need to check the bounds of the last character copied in the // source string. Though this check only needs to be made if the // first byte of the remaining source _could_ be part of a multi- // byte character. if (*(UInt8*)srcP > kTxtMaxNeverMultiByte) { UInt32 charStart, charEnd; UInt32 offset = srcP - savedSrcP; TxtCharBounds(savedSrcP, offset, &charStart, &charEnd); if (charStart < offset) { tmp -= (offset - charStart); *tmp = '\0'; } } // Fill up the unused dest buffer with bytes to reveal errors. // Only copy over the remaining unused bytes. This works correctly when // the src and dest overlap. #if (ERROR_CHECK_LEVEL == ERROR_CHECK_FULL) tmp++; // skip terminating null endDstP = dstP + n; if (tmp < endDstP) { // Make sure that the MemSet call changes at least one value or it can // complain that it didn't change anything and thus didn't need to be called. // This is basically extra debug code to help out other debug code. tmp[0] = 0; // Fill up the destination as much as allowed with a value to reveal errors. MemSet(tmp, endDstP - tmp, 0xfe); } #endif return(dstP); } // StrNCat
/*********************************************************************** * * FUNCTION: FntDefineFont * * DESCRIPTION: Define a font. Only an app font may be defined. The * application is responsible for freeing or releasing the font when * the application quits. * * PARAMETERS: fontID - id of the font to define. Should be a app defined * font only. * fontP - Pointer to font to use. * * RETURNED: memErrNotEnoughSpace - if it isn't able to allocate * space for the new font in the font table. * 0 - if no error * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * roger 9/26/97 Initial Revision * SCL 12/10/97 Rewrote to support new (separate) app font table * roger 11/ 9/98 Fixed MemMove reading past end of source. * gavin 11/18/98 set UINumAppFonts to count, not index * SCL 11/25/98 Fixed MemMove to copy exact size of old table * vivek 06/07/00 Added support for hierarchical application fonts * ***********************************************************************/ Err FntDefineFont (FontID fontID, FontPtr fontP) { UInt32 reqSize; FontTablePtr tableP; FontTablePtr newTableP; Err err; Int16 appFontIndex; Int16 fontIndex; Int16 numAppFonts; Boolean isSubFont; ErrNonFatalDisplayIf (!FntIsAppDefined(fontID), "App defined fonts only"); // KEY POINT: "...Index" is a zero-based array index, whereas // "...Num...Fonts" is a one-based number of fonts. // Thus, appFontIndex is the array index into which fontP will be installed. // The font table must be large enough to support this new font index. isSubFont = (fontP->fontType & fntAppSubFontMask) ? true : false; if (isSubFont) { numAppFonts = MemPtrSize(GAppSubFontListPtr) / sizeof(FontPtr); tableP = GAppSubFontListPtr; } else { tableP = UIAppFontTablePtr; numAppFonts = UINumAppFonts; } appFontIndex = (FontID) (fontID - fntAppFontCustomBase); // See if there's room in the app font table for this font if (appFontIndex >= numAppFonts) { // if not, try to resize the table (new size is appFontIndex+1 entries) reqSize = (appFontIndex+1) * sizeof(FontPtr); err = MemPtrResize(tableP, reqSize); // If we couldn't resize it, try and reallocate it if (err) { newTableP = MemPtrNew(reqSize); if (!newTableP) return memErrNotEnoughSpace; // Copy old table (numFonts entries) into new table MemMove(newTableP, tableP, numAppFonts * sizeof(FontPtr)); MemPtrSetOwner(newTableP, 0); // Change global to point to new table, and free the old one if (isSubFont) GAppSubFontListPtr = newTableP; else UIAppFontTablePtr = newTableP; MemPtrFree(tableP); tableP = newTableP; } // Zero out (only) the newly added slots in the table for (fontIndex = numAppFonts; fontIndex <= appFontIndex; fontIndex++) { tableP[fontIndex] = NULL; } // Save the new table size if (!isSubFont) UINumAppFonts = appFontIndex+1; } tableP[appFontIndex] = fontP; return 0; }
/************************************************************ * * FUNCTION: ErrAlertCustom * NOT present in PalmOS <= 3.0 * * DESCRIPTION: * * This routine can be used to display an alert for normal * run-time errors that occur in an application. This is most * likely to be used by network applications to display errors * like "server not found", "network down", etc. In most cases * the alert will simply have an OK button and execution will * continue when the OK button is pressed. * * This routine will lookup the text assoicated with the given * error code 'errCode' and display that in the Alert. If 'errMsgP' * is not nil however, that text will be used in place of the * text associated with 'errCode'. In addition, the 'preMsgP' and * 'postMsgP' text strings, if specified, will be pre-pended and * post-pended respectively. * * The text associated with an error code is looked up from a * 'tSTL' resource using the SysErrString() routine. A 'tSTL' * resource contains a list of strings that can be looked up * by index. All of the system defined error code strings are * defined in the 'tSTL' resources numbered 10000 -> (10000+errClass) where * 'errClass' is the upper 8 bits of the error number. For example, * the error strings for the DataManager (0x0200 -> 0x02FF) are * found in 'tSTL' resource number 10002. * * The text associated with application specific error codes * are always numbered 0x8000 -> 0x80FF (appErrorClass + X). These * are always looked up from a 'tSTL' resource number 0 contained * within the application itself. * * NOTE: The following paragraph is NOT IMPLEMENTED YET: * For system error codes that correspond to Libraries (like * netErrorClass, inetErrorClass, etc.) This routine will first * check for a 'tSTL' #0 resource in the library database itself before * checking the appropriately numbered system 'tSTL' resource. In * this way, libraries can contain their own error strings and don't * have to rely on the error strings in the system resource file. * Unfortunately, there is no programmatic way of determining if an * error number corresponds to a library or not. This routine thus * must be updated whenever a new error class is defined for a new * library. * * * Button Command Strings * --------------------------------------------------------------- * By default, only an OK button will be displayed in the alert and * no particular action will be taken when the OK button is pressed. * But, a cancel button can be added and special actions can be * specified through control strings inserted in the front of the * error text. Here's the format of the control sequence: * * "<" <btnID> [<cmdChar> <cmdVars>] ">" * * The <btnID> can be either 0 or 1. 0 is always an OK button and * 1 is a Cancel button. If a control sequence with a btnID if 1 * is not specified, then the alert will not show a Cancel button. * * The <cmdChar> is a single character command. The only two currently * supported are: 'K' and 'S'. The 'K' command will cause a key event * to be posted to the event queue and the 'S' command will cause * an application switch through posting a quit event. * * Here's an example text string that specifies an OK and a Cancel button * and makes a switch to the Memo application if the user hits the OK * button: * "<0Smemoappl0000><1>Hit OK to switch to Memos, Cancel to ignore" * * Here are the formats of the commands: * * Key Command: "K" <ascii> <keyCode> <modifiers> * where <ascii> <keyCode>, and <modifiers> are 4 character hex * strings that specify the various fields of the key event. For * example: * "K011300000008" * will generate a key event with an ascii code of 0x0113 (backlightChr) * a keyCode of 0x0000, and a modifiers of 0x0008 (commandKeyMask). * * SwitchApp command: "S" <creator> <type> <launchCmd> * where <creator> and <type> are the 4 character creator/type * of the new application to switch to. * launchCmd is a 4 character hex string that specifies the * action code to send the application: For example: * "Smemoappl0004" * will make a call to SysUIAppSwitch to have it launch the * Memo application with a launch code of 4. * * * Aliased Error Strings * --------------------------------------------------------------- * Another possible control sequence that can appear as the error * text is: * * "<" "*" <aliasErrCode> ">" * * This sequence acts as an alias to another error code. The <aliasErrCode> * is a 4 character hex string representing the error code to alias to. * This is useful when two or more error codes should display the * same error string. * example: * "<*1437>" * will make this routine lookup the error string used by the 0x1437 * error code. * * * PARAMETERS: * errCode -> 16 bit error code to display * errMsgP -> if not NULL, then this text will be used in place * of the associated 'errCode' text from the string * resource * preMsgP -> if not NULL, text to prepend to error text * postMsgP -> if not NULL, text to append to error text * * * RETURNS: index of button pressed: * 0 is always the OK button * 1 is the Cancel button, if present. * * CREATED: 2/25/98 * * BY: Ron Marianetti * *************************************************************/ UInt16 ErrAlertCustom(Err errCode, Char * errMsgP, Char * preMsgP, Char * postMsgP) { const Int16 maxErrLen = errMaxMsgLength+1; Char * errBufP = 0; UInt16 result = 0; Char emptyString[1]; UInt16 index; UInt16 resID; Char * cP; UInt16 alertID; Err tmpErr; Int16 aliasIndex; Err tmpErrCode; Char neumonicString [maxErrNeumonicLength + 1]; // Information parsed from error Text Boolean parseErr = false; Boolean hasCancel = false; Char * okCmdP = 0; Char * cancelCmdP = 0; Char * cmdP = 0; UInt16 keyAscii, keyCode, keyMod; UInt32 appCreator, appType; // Used for doing appSwitch DmSearchStateType dmState; UInt16 cardNo; LocalID dbID; UInt16 launchCmd; UInt16 okAlertID; UInt16 okCancelAlertID; UInt16 cancelAlertID; UInt16 errClass; // Allocate a buffer to hold the error text errBufP = MemPtrNew(maxErrLen); ErrNonFatalDisplayIf (!errBufP, "out of memory"); if (!errBufP) goto Exit; //============================================================== // Very Very First, Determine the buttons to use. //============================================================== errClass = errCode & 0xFF00; // Must use an If statement here because the complier otherwise generates code that // cannot link if ((errClass==errInfoClass) || (errClass==netErrorClass) || (errClass==inetErrorClass) || (errClass==webErrorClass) || (errClass==pwrErrorClass) ) { okAlertID = InfoOKAlert; okCancelAlertID = InfoOKCancelAlert; cancelAlertID = InfoCancelAlert; if (errClass == errInfoClass) errCode = 0; // ignore errors in this class } else { okAlertID = ErrOKAlert; okCancelAlertID = ErrOKCancelAlert; cancelAlertID = ErrCancelAlert; } //============================================================== // First, lookup the error text if not specified in the 'errMsgP' // parameter //============================================================== if (!errMsgP) { errMsgP = errBufP; tmpErrCode = errCode; // Loop till we get the error string. If we find an // alias escape code, we need to follow that to get // the error string. We only follow a limited number of // aliases in order to avoid recursion. for (aliasIndex = 0; aliasIndex < 5; aliasIndex++) { // Get the index of the error string index = tmpErrCode & 0x00FF; //---------------------------------------------------------- // Compute which resource ID to fetch //---------------------------------------------------------- // If it's not an application specific error code, get it // out of the appropriate system string resource. if ((tmpErrCode & 0xFF00) != appErrorClass) resID = sysResIDErrStrings + ((tmpErrCode >> 8) & 0x00FF); // For application custom errors, get it out of the // #0 resource in the application database. else resID = 0; //---------------------------------------------------------- // Read in the error text string //---------------------------------------------------------- cP = SysStringByIndex(resID, index, errBufP, maxErrLen); if (!cP) errBufP[0] = 0; // If it's an alias string, follow it if (cP[0] == '<' && cP[1] == '*') tmpErrCode = Prv4HToI(cP+2); else break; // out of for(aliasIndex; ;) loop }