JBoolean
CBTCLCompleter::IsWordCharacter
	(
	const JString&	s,
	const JIndex	index,
	const JBoolean	includeNS
	)
	const
{
	const JCharacter c = s.GetCharacter(index);
	return JI2B(isalnum(c) || c == '_' || (includeNS && c == ':'));
}
JString
XDLink::Build1DArrayExpression
	(
	const JCharacter*	origExpr,
	const JInteger		index
	)
{
	JString expr = origExpr;

	const JString indexStr(index, 0);	// must use floating point conversion
	if (expr.Contains("$i"))
		{
		// double literal $'s

		for (JIndex i=expr.GetLength()-1; i>=1; i--)
			{
			if (expr.GetCharacter(i)   == '$' &&
				expr.GetCharacter(i+1) != 'i')
				{
				expr.InsertCharacter('$', i);
				}
			}

		const JCharacter* map[] =
			{
			"i", indexStr.GetCString()
			};
		(JGetStringManager())->Replace(&expr, map, sizeof(map));
		}
	else
		{
		expr.AppendCharacter('[');
		expr += indexStr;
		expr.AppendCharacter(']');
		}

	return expr;
}
void
CBCSharpScanner::Undo
	(
	const JIndexRange&	range,
	const JString&		text
	)
{
	for (JIndex i=text.GetLength(); i>=1; i--)
		{
		yyunput(text.GetCharacter(i), yytext);
		}

	itsCurrentRange.first = itsCurrentRange.last = range.first - 1;
}
JBoolean
GMessageHeader::RangeContainsNWS
	(
	const JString&	text,
	const JIndex	index1,
	const JIndex	index2
	)
{
	for (JIndex i = index1; i <= index2; i++)
		{
		JCharacter c	= text.GetCharacter(i);
		if (!isspace(c) && (c != '\n'))
			{
			return kJTrue;
			}
		}
	return kJFalse;
}
void
JDirInfo::AppendRegex
	(
	const JCharacter*	origStr,
	JString*			regexStr
	)
{
JIndex i;

	JString str = origStr;

	// Convert wildcard multiples (*) to regex multiples (.*)
	// and wildcard singles (?) to regex singles (.)

	for (i = str.GetLength(); i>=1; i--)
		{
		const JCharacter c = str.GetCharacter(i);
		if (c == '*')
			{
			str.InsertSubstring(".", i);
			}
		else if (c == '?')
			{
			str.SetCharacter(i, '.');
			}
		else if (JRegex::NeedsBackslashToBeLiteral(c))
			{
			str.InsertSubstring("\\", i);
			}
		}

	// Add instructions that it must match the entire file name.

	str.PrependCharacter('^');
	str.AppendCharacter('$');

	// append to regexStr

	if (!regexStr->IsEmpty())
		{
		regexStr->AppendCharacter('|');
		}
	*regexStr += str;
}
void
JFunctionWithVar::DrawString
	(
	const JExprRenderer&	renderer,
	const JCoordinate		left,
	const JCoordinate		midline,
	const JSize				fontSize,
	const JString&			str
	)
	const
{
	JCoordinate x = left;

	const JCharacter* greekPrefix = JPGetGreekCharPrefixString();
	const JSize greekPrefixLength = JPGetGreekCharPrefixLength();

	JString s = str;
	JIndex greekIndex;
	while (s.LocateSubstring(greekPrefix, &greekIndex) &&
		   greekIndex < s.GetLength() - greekPrefixLength + 1)
		{
		if (greekIndex > 1)
			{
			const JString s1 = s.GetSubstring(1, greekIndex-1);
			renderer.DrawString(x, midline, fontSize, s1);
			x += renderer.GetStringWidth(fontSize, s1);
			}

		const JCharacter c = s.GetCharacter(greekIndex + greekPrefixLength);
		renderer.DrawGreekCharacter(x, midline, fontSize, c);
		x += renderer.GetGreekCharWidth(fontSize, c);

		s.RemoveSubstring(1, greekIndex + greekPrefixLength);
		}

	if (!s.IsEmpty())
		{
		renderer.DrawString(x, midline, fontSize, s);
		}
}
JSize
JFunctionWithVar::GetStringWidth
	(
	const JExprRenderer&	renderer,
	const JSize				fontSize,
	const JString&			str
	)
	const
{
	JSize w = 0;

	const JCharacter* greekPrefix = JPGetGreekCharPrefixString();
	const JSize greekPrefixLength = JPGetGreekCharPrefixLength();

	JString s = str;
	JIndex greekIndex;
	while (s.LocateSubstring(greekPrefix, &greekIndex) &&
		   greekIndex < s.GetLength() - greekPrefixLength + 1)
		{
		if (greekIndex > 1)
			{
			const JString s1 = s.GetSubstring(1, greekIndex-1);
			w += renderer.GetStringWidth(fontSize, s1);
			}

		const JCharacter c = s.GetCharacter(greekIndex + greekPrefixLength);
		w += renderer.GetGreekCharWidth(fontSize, c);

		s.RemoveSubstring(1, greekIndex + greekPrefixLength);
		}

	if (!s.IsEmpty())
		{
		w += renderer.GetStringWidth(fontSize, s);
		}

	return w;
}
void
GMMIMEParser::FindStringEnd
	(
	const JString&	val,
	JIndex*		index
	)
{
	JSize length = val.GetLength();
	*index = *index + 1;
	while (*index <= length)
		{
		JCharacter c = val.GetCharacter(*index);
		if (c == '\"')
			{
			return;
			}
		else if ((c == '\\') && (*index < length))
			{
			*index = *index + 1;
			}
		*index = *index + 1;
		}
}
JString
XDLink::Build2DArrayExpression
	(
	const JCharacter*	origExpr,
	const JInteger		rowIndex,
	const JInteger		colIndex
	)
{
	JString expr = origExpr;

	const JBoolean usesI = expr.Contains("$i");		// row
	const JBoolean usesJ = expr.Contains("$j");		// col

	const JString iStr(rowIndex, 0);	// must use floating point conversion
	const JString jStr(colIndex, 0);	// must use floating point conversion

	// We have to do both at the same time because otherwise we lose a $.

	if (usesI || usesJ)
		{
		// double literal $'s

		for (JIndex i=expr.GetLength()-1; i>=1; i--)
			{
			if (expr.GetCharacter(i)   == '$' &&
				expr.GetCharacter(i+1) != 'i' &&
				expr.GetCharacter(i+1) != 'j')
				{
				expr.InsertCharacter('$', i);
				}
			}

		const JCharacter* map[] =
			{
			"i", iStr.GetCString(),
			"j", jStr.GetCString()
			};
		(JGetStringManager())->Replace(&expr, map, sizeof(map));
		}

	if (!usesI || !usesJ)
		{
		if (expr.GetFirstCharacter() != '(' ||
			expr.GetLastCharacter()  != ')')
			{
			expr.PrependCharacter('(');
			expr.AppendCharacter(')');
			}

		if (!usesI)
			{
			expr.AppendCharacter('[');
			expr += iStr;
			expr.AppendCharacter(']');
			}
		if (!usesJ)
			{
			expr.AppendCharacter('[');
			expr += jStr;
			expr.AppendCharacter(']');
			}
		}

	return expr;
}
JString
JConvertToRelativePath
	(
	const JCharacter* origPath,
	const JCharacter* origBase
	)
{
	// Check that they are both absolute paths.

	assert( origPath != NULL && origPath[0] == '/' &&
			origBase != NULL && origBase[0] == '/' );

	// Remove extra directory separators
	// and make sure that base ends with one.

	JString path = origPath;
	JCleanPath(&path);

	JString base = origBase;
	JCleanPath(&base);
	JAppendDirSeparator(&base);

	// Find and remove the matching directories at the beginning.
	// The while loop backs us up so we only consider complete directory names.

	JBoolean hadTDS = kJTrue;
	if (path.GetLastCharacter() != '/')
		{
		path.AppendCharacter('/');
		hadTDS = kJFalse;
		}

	JSize matchLength = JCalcMatchLength(path, base);

	if (!hadTDS)
		{
		path.RemoveSubstring(path.GetLength(), path.GetLength());
		}

	while (base.GetCharacter(matchLength) != '/')
		{
		matchLength--;
		}
	assert( matchLength >= 1 );
	if (matchLength == 1)
		{
		return path;
		}

	if (matchLength > path.GetLength())
		{
		base.RemoveSubstring(matchLength, matchLength);
		matchLength--;
		}

	path.RemoveSubstring(1, matchLength);
	base.RemoveSubstring(1, matchLength);

	if (base.IsEmpty())
		{
		path.Prepend("./");
		return path;
		}

	// The number of remaining directory separators in base
	// is the number of levels to go up.

	JSize upCount = 0;

	const JSize baseLength = base.GetLength();
	for (JIndex i=1; i<=baseLength; i++)
		{
		if (base.GetCharacter(i) == '/')
			{
			upCount++;
			path.Prepend("../");
			}
		}
	assert( upCount > 0 );

	return path;
}
void
CBCompileDocument::AppendText
	(
	const JString& origText
	)
{
	const JString* text = &origText;
	JBoolean deleteText = kJFalse;
	if (strchr(*text, kMultibyteMarker) != NULL)
		{
		JString* s = jnew JString(origText);
		assert( s != NULL );
		text       = s;
		deleteText = kJTrue;

		JSize length = s->GetLength();
		for (JIndex i=1; i<=length; i++)
			{
			if (s->GetCharacter(i) == kMultibyteMarker && i <= length-2)
				{
				const unsigned char c1 = s->GetCharacter(i+1);
				const unsigned char c2 = s->GetCharacter(i+2);
				const JIndex u = (((unsigned int) (unsigned char) c1) << 8) |
								 ((unsigned int) (unsigned char) c2);

				if (u == 32920 || u == 32921)
					{
					s->ReplaceSubstring(i, i+2, "'");
					}
				else
					{
					std::cout << "jcc: AppendText: unicode: " << u << std::endl;
					s->ReplaceSubstring(i, i+2, "\x80");
					}

				length -= 2;
				}
			}
		}

	const JBoolean isJavacError = javacOutputRegex.Match(*text);

	JIndexRange gccPrevLineRange, gccRange;
	const JBoolean isGCCError = JI2B(!isJavacError && gccErrorRegex.Match(*text, &gccRange));

	JIndexRange flexRange;
	const JBoolean isFlexError = flexErrorRegex.Match(*text, &flexRange);

	JIndexRange bisonRange;
	const JBoolean isBisonError = bisonErrorRegex.Match(*text, &bisonRange);

	JIndexRange makeRange;
	const JBoolean isMakeError = JI2B(
		makeErrorRegex.Match(*text, &makeRange) && !text->EndsWith(makeIgnoreErrorStr) );

	JArray<JIndexRange> absoftRangeList;
	const JBoolean isAbsoftError = absoftErrorRegex.Match(*text, &absoftRangeList);

	JArray<JIndexRange> maven2RangeList;
	const JBoolean isMaven2Error = maven2ErrorRegex.Match(*text, &maven2RangeList);

	JArray<JIndexRange> maven3RangeList;
	const JBoolean isMaven3Error = maven3ErrorRegex.Match(*text, &maven3RangeList);

	if (isGCCError &&
		gccErrorRegex.Match(itsPrevLine, &gccPrevLineRange) &&
		gccPrevLineRange == gccRange &&
		JCompareMaxN(itsPrevLine, *text, gccRange.last, kJTrue))
		{
		JString s = *text;
		s.RemoveSubstring(1, gccRange.last - 1);
		s.Prepend(" /");

		// in front of 1 or 2 trailing newlines

		CBTextEditor* te = GetTextEditor();
		te->SetCaretLocation(te->GetTextLength() - (theDoubleSpaceFlag ? 1 : 0));
		te->Paste(s);
		}
	else if (!isJavacError && !isGCCError &&
			 gccErrorRegex.Match(itsPrevLine, &gccPrevLineRange) &&
			 text->BeginsWith(gccMultilinePrefix) &&
			 text->GetLength() > kGCCMultilinePrefixLength &&
			 !isspace(text->GetCharacter(kGCCMultilinePrefixLength+1)))
		{
		JString s = *text;
		s.RemoveSubstring(1, strlen(gccMultilinePrefix));

		CBTextEditor* te = GetTextEditor();
		te->SetCaretLocation(te->GetTextLength() - (theDoubleSpaceFlag ? 1 : 0));
		te->Paste(s);
		}
	else
		{
		CBTextEditor* te        = GetTextEditor();
		const JIndex startIndex = te->GetTextLength() + 1;

		CBExecOutputDocument::AppendText(*text);
		if (theDoubleSpaceFlag)
			{
			te->Paste("\n");
			}

		itsPrevLine = *text;

		// display file name in bold and activate Errors menu

		JIndexRange boldRange;
		if (isJavacError)
			{
			JArray<JIndexRange> javacMatchList;
			if (javacErrorRegex.Match(*text, &javacMatchList))
				{
				const JIndexRange r = javacMatchList.GetElement(2);
				boldRange.Set(startIndex + r.first-1, startIndex + r.last-1);
				}
			}
		else if (isGCCError)
			{
			boldRange.Set(startIndex, startIndex + gccRange.first - 1);
			}
		else if (isFlexError)
			{
			boldRange.Set(startIndex+1, startIndex + flexRange.first);
			}
		else if (isBisonError)
			{
			boldRange.Set(startIndex+2, startIndex + bisonRange.first + 1);
			}
		else if (isMakeError)
			{
			boldRange.SetFirstAndLength(startIndex, text->GetLength());
			}
		else if (isAbsoftError)
			{
			boldRange  = absoftRangeList.GetElement(2);
			boldRange += startIndex-1;
			}
		else if (isMaven2Error)
			{
			boldRange  = maven2RangeList.GetElement(2);
			boldRange += startIndex-1;
			}
		else if (isMaven3Error)
			{
			boldRange  = maven3RangeList.GetElement(2);
			boldRange += startIndex-1;
			}

		if (!boldRange.IsEmpty())
			{
			te->JTextEditor::SetFont(boldRange.first, boldRange.last, GetErrorFont(), kJTrue);

			if (!itsHasErrorsFlag)
				{
				itsHasErrorsFlag = kJTrue;
				itsErrorMenu->Activate();

				JXWindow* window    = GetWindow();
				JString windowTitle = window->GetTitle();
				windowTitle.SetCharacter(1, '!');
				windowTitle.SetCharacter(2, '!');
				windowTitle.SetCharacter(3, '!');
				window->SetTitle(windowTitle);
				}
			}
		}

	if (deleteText)
		{
		jdelete text;
		}
}
Exemple #12
0
void
SMTPMessage::ReadReturnValue()
{
	JString line;
	JBoolean ok = itsLink->GetNextMessage(&line);
	assert(ok);

	if (itsCurrentMode != kDataHeader)
		{
		GMGetSMTPDebugDir()->AddText(line);
		}

	if ((itsCurrentMode != kStartUp) && (itsCurrentMode != kDataHeader))
		{
		JInteger value;
		JIndex findex;
		ok = line.LocateSubstring(" ", &findex);
		if (ok && (findex > 1))
			{
			JString number = line.GetSubstring(1, findex - 1);
			if (number.IsInteger())
				{
				number.ConvertToInteger(&value);
				}
			else
				{
				ok	= kJFalse;
				}
			}
		else
			{
			ok	= kJFalse;
			}

		if (!ok)
			{
			const JIndex kDashIndex	= 4;
			if (line.GetCharacter(kDashIndex) == '-')
				{
				// this is a multiline response.
				return;
				}
			}

		if (!ok || (value != kOKValue))
			{
			if (!itsIsTryingToQuit)
				{
				const JCharacter* map[] =
					{
					"err", line
					};
				const JString msg = JGetString("SMTPERROR", map, sizeof(map));

				JGetUserNotification()->ReportError(msg);
				}
			itsIsFinished = kJTrue;
			Broadcast(SendFailure());
			if (!itsIsTryingToQuit)
				{
				itsDeleteTask = new JXTimerTask(1000,kJTrue);
				assert( itsDeleteTask != NULL );
				itsDeleteTask->Start();
				ListenTo(itsDeleteTask);
				}
			return;
			}
		}

	if (itsCurrentMode < kTo)
		{
		itsCurrentMode++;
		}
	else if (itsCurrentMode == kTo)
		{
		if (itsCurrentIndex < itsToNames->GetElementCount())
			{
			itsCurrentIndex++;
			}
		else if (itsCcNames->GetElementCount() != 0)
			{
			itsCurrentMode = kCc;
			itsCurrentIndex = 1;
			}
		else if (itsBccNames->GetElementCount() != 0)
			{
			itsCurrentMode = kBcc;
			itsCurrentIndex = 1;
			}
		else
			{
			itsCurrentMode = kDataHeader;
			}
		}
	else if (itsCurrentMode == kCc)
		{
		if (itsCurrentIndex < itsCcNames->GetElementCount())
			{
			itsCurrentIndex++;
			}
		else if (itsBccNames->GetElementCount() != 0)
			{
			itsCurrentMode = kBcc;
			itsCurrentIndex = 1;
			}
		else
			{
			itsCurrentMode = kDataHeader;
			}
		}
	else if (itsCurrentMode == kBcc)
		{
		if (itsCurrentIndex < itsBccNames->GetElementCount())
			{
			itsCurrentIndex++;
			}
		else
			{
			itsCurrentMode = kDataHeader;
			}
		}
	else if (itsCurrentMode == kData)
		{
		itsIsFinished = kJTrue;
		Broadcast(MessageSent());
		GMGetSMTPDebugDir()->AddText("\n-------------------------------------\n");
		if (!itsIsTryingToQuit)
			{
			itsDeleteTask = new JXTimerTask(1000,kJTrue);
			assert( itsDeleteTask != NULL );
			itsDeleteTask->Start();
			ListenTo(itsDeleteTask);
			}
		return;
		}
	else
		{
		itsCurrentMode++;
		}

	SendNextData();
}