JError
JCreateDirectory
	(
	const JCharacter*	dirName,
	const mode_t		mode
	)
{
	if (JDirectoryExists(dirName))
		{
		return JSetPermissions(dirName, mode);
		}

	JString path = dirName;
	JCleanPath(&path);
	JAppendDirSeparator(&path);

	JString dir;
	JIndex slashIndex = 2;
	while (path.LocateNextSubstring("/", &slashIndex))
		{
		dir = path.GetSubstring(1, slashIndex);
		if (!JDirectoryExists(dir))
			{
			const JError err = JMkDir(dir, mode);
			if (!err.OK())
				{
				return err;
				}
			}
		slashIndex++;	// move past the slash we found
		}

	return JNoError();
}
void
GDBGetSourceFileList::HandleSuccess
	(
	const JString& origData
	)
{
	if (origData.BeginsWith("Source files for which symbols have been read in:"))
		{
		(JXGetApplication())->DisplayBusyCursor();

		JXFileListTable* table = (GetFileList())->GetTable();
		table->RemoveAllFiles();

		JString data = origData;
		JIndex i,j;
		while (data.LocateSubstring("Source files for which symbols", &i))
			{
			j = i;
			if (!data.LocateNextSubstring(":", &j))
				{
				j = data.GetLength();
				}
			data.ReplaceSubstring(i, j, ",");
			}
		data.TrimWhitespace();		// no comma after last file

		std::istrstream input(data.GetCString(), data.GetLength());
		JString fullName, path, name, s;
		JBoolean foundDelimiter;
		do
			{
			input >> ws;
			fullName = JReadUntil(input, ',', &foundDelimiter);
			fullName.TrimWhitespace();
			if (!fullName.IsEmpty())
				{
				JSplitPathAndName(fullName, &path, &name);
				table->AddFile(name);
				}
			}
			while (foundDelimiter);
		}
JBoolean
CBCClass::ViewDefinition
	(
	const JCharacter*	fnName,
	const JBoolean		caseSensitive,
	const JBoolean		reportNotFound
	)
	const
{
	JBoolean found = kJFalse;

	JString headerName;
	if (IsEnum())
		{
		found = ViewDeclaration(fnName, caseSensitive, reportNotFound);
		}
	else if (!Implements(fnName, caseSensitive))
		{
		found = ViewInheritedDefinition(fnName, caseSensitive, reportNotFound);
		if (!found && reportNotFound)
			{
			JString msg = "Unable to find any definition for \"";
			msg += fnName;
			msg += "\".";
			(JGetUserNotification())->ReportError(msg);
			}
		}
	else if (GetFileName(&headerName))
		{
		// search for class::fn

		const JCharacter* nsOp = "[[:space:]]*::[[:space:]]*";

		JString searchStr = GetFullName();

		JIndex i=1;
		while (searchStr.LocateNextSubstring("::", &i))
			{
			searchStr.ReplaceSubstring(i,i+1, nsOp);
			i += strlen(nsOp);
			}

		searchStr += nsOp;
		searchStr += fnName;
		found = FindDefinition(headerName, searchStr, caseSensitive);

		if (!found)
			{
			// "::" insures that we find the source instead of a call to the function.
			// We can't use "class::" because this doesn't work for templates.

			searchStr = "::[[:space:]]*";
			searchStr += fnName;
			found = FindDefinition(headerName, searchStr, caseSensitive);
			}

		if (!found)
			{
			CBDocumentManager* docMgr = CBGetDocumentManager();

			// look for it in the header file (pure virtual or inline in class defn)

			JIndex lineIndex;
			if (docMgr->SearchFile(headerName, fnName, caseSensitive, &lineIndex))
				{
				docMgr->OpenTextDocument(headerName, lineIndex);
				found = kJTrue;
				}

			// we couldn't find it anywhere

			else if (reportNotFound)
				{
				JString msg = "Unable to find the definition for \"";
				msg += fnName;
				msg += "\".";
				(JGetUserNotification())->ReportError(msg);
				}
			}
		}
	else if (reportNotFound)
		{
		JString msg = GetFullName();
		msg.PrependCharacter('"');
		msg += "\" is a ghost class, so no information is available for it.";
		(JGetUserNotification())->ReportError(msg);
		}

	return found;
}
Exemple #4
0
void
GDBGetCompletions::HandleSuccess
	(
	const JString& data
	)
{
	JPtrArray<JString> lines(JPtrArrayT::kDeleteAll);
	lines.SetSortOrder(JOrderedSetT::kSortAscending);
	lines.SetCompareFunction(JCompareStringsCaseSensitive);

	// loop through each line and add each one to our list

	JIndex i = 1, j = 1;
	while (data.LocateNextSubstring("\n", &j))
		{
		if (j > i)
			{
			JString* s = new JString(data, JIndexRange(i, j-1));
			assert( s != NULL );
			s->TrimWhitespace();
			if (s->IsEmpty() || !lines.InsertSorted(s, kJFalse))
				{
				delete s;
				}
			}
		i = j+1;
		j = i;
		}

	if (i <= data.GetLength())
		{
		JString* s = new JString(data, JIndexRange(i, data.GetLength()));
		assert( s != NULL );
		s->TrimWhitespace();
		if (s->IsEmpty() || !lines.InsertSorted(s, kJFalse))
			{
			delete s;
			}
		}

	if (lines.IsEmpty())
		{
		(itsInput->GetDisplay())->Beep();
		return;
		}

	// Check if we're done. If we find our test prefix in the array, and
	// the array has only one element, we're done.  Otherwise, our test
	// prefix is the 'start' of several possible commands.

	const JSize stringCount = lines.GetElementCount();
	JBoolean found;
	JIndex startIndex = lines.SearchSorted1(&itsPrefix, JOrderedSetT::kAnyMatch, &found);
	if (found)
		{
		if (stringCount == 1)
			{
			// The input text is already complete.  We just need to add a
			// space at the end to show that it is a complete word.

			itsPrefix += " ";
			}
		else
			{
			// We can't add anything to what the user has types, so we show
			// all possible completions.

			itsHistory->PlaceCursorAtEnd();
			itsHistory->Paste("\n");
			itsHistory->Paste(data);
			}
		itsInput->SetText(itsPrefix);
		itsInput->SetCaretLocation(itsInput->GetTextLength() + 1);
		return;
		}

	JString maxPrefix;

	maxPrefix = *(lines.NthElement(startIndex));
	if (stringCount == 1)
		{
		// There's only one completion, which must be what we meant so we
		// fill in the input with this word.

		maxPrefix += " ";
		itsInput->SetText(maxPrefix);
		itsInput->SetCaretLocation(itsInput->GetTextLength() + 1);
		return;
		}

	for (JIndex i=startIndex+1; i<=stringCount; i++)
		{
		const JString* s = lines.NthElement(i);
		const JSize matchLength  = JCalcMatchLength(maxPrefix, *s);
		const JSize prefixLength = maxPrefix.GetLength();
		if (matchLength < prefixLength)
			{
			maxPrefix.RemoveSubstring(matchLength+1, prefixLength);
			}
		}

	if (maxPrefix == itsPrefix)
		{
		// The input text is all that the words have in common so we can't
		// add anything to the input. We therefore need to dump everything
		// to the history window.

		itsHistory->PlaceCursorAtEnd();
		itsHistory->Paste("\n");
		itsHistory->Paste(data);
		}
	else
		{
		itsInput->SetText(maxPrefix);
		itsInput->SetCaretLocation(itsInput->GetTextLength() + 1);
		}
}
void
GMMIMEParser::ParseMIMEHeader
	(
	std::istream&		input,
	GMIMEHeader*	header,
	const JBoolean	display
	)
{
	JString data;
	JCharacter c	= input.peek();
	if (c == '\n')
		{
//		input.get(c);
		}
//	input >> std::ws;

	// first we need to search for the first empty line. This line is the
	// end of the header.

	JString line;
	while (1)
		{
		JBoolean found;
		line = JReadLine(input, &found);
		if (line.IsEmpty())
			{
			break;
			}
		if (isspace(line.GetFirstCharacter()))
			{
			line.TrimWhitespace();
			if (line.IsEmpty())
				{
				break;
				}
			data.AppendCharacter(' ');
			}
		else if (!data.IsEmpty())
			{
			data.AppendCharacter('\n');
			}
		data += line;
		}
	data.AppendCharacter('\n');

	// we now need to search through the header for parameter:value pairs
	// using the gmime_header_regex defined above.

	JArray<JIndexRange> ranges;
	gmime_header_regex.MatchAll(data, &ranges);

	JSize count = ranges.GetElementCount();
	for (JSize i = 1; i <= count; i++)
		{
		JIndexRange range = ranges.GetElement(i);
		JString parmValPair = data.GetSubstring(range);
		JString parm;
		JString val;
		if (parmValPair.BeginsWith("MIME") ||
			parmValPair.BeginsWith("Mime") ||
			parmValPair.BeginsWith("Content"))
			{
			CleanParmValPair(parmValPair, &parm, &val);
			parm.ToLower();
			if (parm == "mime-Version")
				{
				val.TrimWhitespace();
				header->SetVersion(val);
				}
			else if (parm == "content-type")
				{
				ParseContentType(val, header);
				}
			else if (parm == "content-transfer-encoding")
				{
				val.TrimWhitespace();
				val.ToLower();
				header->SetEncoding(val);
				}
			else if (parm == "content-disposition")
				{
				ParseContentDisposition(val, header);
				}
			}
		}

	// this is a nested message, so some of the headers need to be displayed
	if (display)
		{
		JString text = "---------\n";
		JIndex findex	= 1;
		if (data.BeginsWith("From: ") || data.LocateSubstring("\nFrom: ", &findex))
			{
			if (findex > 1)
				{
				findex ++;
				}
			JIndex eindex	= findex;
			if (data.LocateNextSubstring("\n", &eindex) && (eindex > findex + 1))
				{
				text += data.GetSubstring(findex, eindex - 1);
				text += "\n";
				}
			}
		findex	= 1;
		if (data.BeginsWith("Date: ") || data.LocateSubstring("\nDate: ", &findex))
			{
			if (findex > 1)
				{
				findex ++;
				}
			JIndex eindex	= findex;
			if (data.LocateNextSubstring("\n", &eindex) && (eindex > findex + 1))
				{
				text += data.GetSubstring(findex, eindex - 1);
				text += "\n";
				}
			}
		findex	= 1;
		const JCharacter* kSubjectStr	= "Subject: ";
		if (data.BeginsWith("Subject: ") || data.LocateSubstring("\nSubject: ", &findex))
			{
			if (findex > 1)
				{
				findex ++;
				}
			JIndex eindex	= findex;
			if (data.LocateNextSubstring("\n", &eindex) && (eindex > findex + 1))
				{
				text += data.GetSubstring(findex, eindex - 1);
				text += "\n";
				}
			}
		WriteTextString(&text, GMIMEHeader());
		}
}