void
CBSearchDocument::AppendText
	(
	const JString& text
	)
{
	if (text.GetFirstCharacter() == CBSearchTE::kIncrementProgress)
		{
		itsIndicator->IncrementValue();
		return;
		}

	CBTextEditor* te = GetTextEditor();

	itsFoundFlag = kJTrue;
	const std::string s(text.GetCString(), text.GetLength());
	std::istringstream input(s);

	if (text.GetFirstCharacter() == CBSearchTE::kError)
		{
		input.ignore();
		JString msg;
		JReadAll(input, &msg);

		const JIndex startIndex = te->GetTextLength() + 1;
		te->SetCaretLocation(startIndex);
		te->Paste(msg);
		te->Paste("\n");
		if (!itsOnlyListFilesFlag)
			{
			te->Paste("\n");
			}

		te->SetFontStyle(startIndex, startIndex + msg.GetLength()-1,
						 GetErrorStyle(), kJTrue);
		}
	else if (itsOnlyListFilesFlag)
		{
		JString fileName;
		input >> fileName;
		CBExecOutputDocument::AppendText(fileName);

		if (itsIsReplaceFlag)
			{
			ReplaceAll(fileName);
			}
		}
	else
		{
void
CBCommandPathInput::AdjustStylesBeforeRecalc
	(
	const JString&		buffer,
	JRunArray<JFont>*	styles,
	JIndexRange*		recalcRange,
	JIndexRange*		redrawRange,
	const JBoolean		deletion
	)
{
	if (!buffer.IsEmpty() && buffer.GetFirstCharacter() == '@')
		{
		const JColormap* colormap = GetColormap();
		const JSize totalLength   = buffer.GetLength();
		JFont f                   = styles->GetFirstElement();
		styles->RemoveAll();
		f.SetColor(colormap->GetBlackColor());
		styles->AppendElements(f, totalLength);
		*redrawRange += JIndexRange(1, totalLength);
		}
	else
		{
		return JXPathInput::AdjustStylesBeforeRecalc(buffer, styles, recalcRange,
													 redrawRange, deletion);
		}
}
Beispiel #3
0
JString
CMLink::Build1DArrayExpressionForCFamilyLanguage
	(
	const JCharacter*	origExpr,
	const JInteger		index
	)
{
	JString expr = origExpr;

	const JString indexStr(index, 0);	// must use floating point conversion
	if (expr.Contains("$i"))
		{
		const JCharacter* map[] =
			{
			"i", indexStr.GetCString()
			};
		(JGetStringManager())->Replace(&expr, map, sizeof(map));
		}
	else
		{
		if (expr.GetFirstCharacter() != '(' ||
			expr.GetLastCharacter()  != ')')
			{
			expr.PrependCharacter('(');
			expr.AppendCharacter(')');
			}

		expr.AppendCharacter('[');
		expr += indexStr;
		expr.AppendCharacter(']');
		}

	return expr;
}
JBoolean
GAddressBookMgr::NameIsAlias
	(
	const JCharacter*	name,
	JString&			alias,
	JString&			fcc
	)
{
	GAddressBookEntry* entry;
	if (!itsAddresses->GetElement(name, &entry))
		{
		return kJFalse;
		}

	alias = entry->address;
	if (alias.IsEmpty())
		{
		return kJFalse;
		}

	if (alias.GetFirstCharacter() == '(' &&
		alias.GetLastCharacter() == ')')
		{
		if (entry->address.GetLength() > 2)
			{
			alias = entry->address.GetSubstring(2, entry->address.GetLength() - 1);
			}			
		}

	fcc = entry->fcc;
	if (!fcc.IsEmpty() && 
		fcc.GetFirstCharacter() == '(' &&
		fcc.GetLastCharacter() == ')')
		{
		if (entry->fcc.GetLength() > 2)
			{
			fcc = entry->fcc.GetSubstring(2, entry->fcc.GetLength() - 1);
			}
		}

	return kJTrue;
}
Beispiel #5
0
JString
CMLink::Build2DArrayExpressionForCFamilyLanguage
	(
	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)
		{
		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;
}
JBoolean
JXStringCompletionMenu::AddString
	(
	const JCharacter* str
	)
{
	const JIndex i = GetItemCount()+1;
	if (i <= kMaxItemCount)
		{
		if (IsEmpty())
			{
			JFontID id;
			JSize size;
			JFontStyle style;
			itsTE->GetDefaultFont(&id, &size, &style);
			SetDefaultFont(id, size, style, kJFalse);
			}

		JString shortcut;
		if (i <= 10)
			{
			shortcut = JString(i%10, JString::kBase10);
			}
		else if (i <= 36)
			{
			shortcut = " ";
			shortcut.SetCharacter(1, 'a' + i - 11);
			}

		JString s = kItemPrefixStr;
		s += str;
		if (!shortcut.IsEmpty())
			{
			s.SetCharacter(1, shortcut.GetFirstCharacter());
			s.SetCharacter(3, '-');
			}

		AppendItem(s, kPlainType, shortcut);
		return kJTrue;
		}
	else if (i == kMaxItemCount+1)
		{
		AppendItem(kTruncationStr);
		SetItemFont(i, JGetDefaultFontName(), kJDefaultFontSize,
					JFontStyle(kJFalse, kJTrue, 0, kJFalse));
		return kJFalse;
		}
	else
		{
		return kJFalse;
		}
}
JBoolean
GAddressBookMgr::GetNextRecord
	(
	JString& line,
	JString& record,
	std::istream& is
	)
{
	if (line.IsEmpty())
		{
		return kJFalse;
		}
	JIndex index;
	if (line.LocateSubstring("\t", &index))
		{
		if (index > 1)
			{
			record = line.GetSubstring(1, index - 1);
			line.RemoveSubstring(1, index);
			return kJTrue;
			}
		line.RemoveSubstring(1, 1);
		return kJFalse;
		}
	record = line;
	if (record.Contains("(") && !record.Contains(")"))
		{
		JString temp = JReadUntil(is, ')');
		record += temp + ")";
		line = JReadLine(is);
		if (!line.IsEmpty() && (line.GetFirstCharacter() == '\t'))
			{
			line.RemoveSubstring(1, 1);
			}
		}
	else
		{
		line.Clear();
		}
	return kJTrue;
}
JString
CMLineAddressTable::GetLineTextFromAddress
	(
	const JString& addr
	)
	const
{
	JString s = addr;
	if (s.BeginsWith("0x"))
		{
		s.RemoveSubstring(1,2);
		}

	while (s.GetFirstCharacter() == '0' &&
		   s.GetLength() > itsLineTextList->LastElement()->GetLength())
		{
		s.RemoveSubstring(1,1);
		}

	return s;
}
void
CBApp::GetSystemIncludeDirectories()
{
	int pid, fd, inFD;
	const JError err = JExecute("gcc -Wp,-v -x c++ -fsyntax-only -", &pid,
								kJCreatePipe, &inFD,
								kJCreatePipe, &fd,
								kJAttachToFromFD);
	if (!err.OK())
		{
		for (const JCharacter* s : kSysIncludeDir)
			{
			itsSystemIncludeDirs->Append(s);
			}
		return;
		}

	close(inFD);

	JString s;
	while (1)
		{
		s = JReadUntil(fd, '\n');
		if (s.IsEmpty())
			{
			break;
			}

		if (s.GetFirstCharacter() == ' ')
			{
			s.RemoveSubstring(1,1);
			if (!s.Contains(" "))
				{
				itsSystemIncludeDirs->Append(s);
				}
			}
		}
}
void
CBCommandTable::TableDrawCell
	(
	JPainter&		p,
	const JPoint&	cell,
	const JRect&	rect
	)
{
	JPoint editCell;
	if (GetEditedCell(&editCell) && cell == editCell)
		{
		return;
		}

	HilightIfSelected(p, cell, rect);

	const CBCommandManager::CmdInfo info = itsCmdList->GetElement(cell.y);
	if (info.separator)
		{
		JPoint pt1 = rect.bottomLeft(), pt2 = rect.bottomRight();
		pt1.y--;
		pt2.y--;
		p.Line(pt1, pt2);
		}

	if (cell.x == kOptionsColumn)
		{
		JString s;
		if (info.isMake)
			{
			s += ",M";
			}
		if (info.isVCS)
			{
			s += ",V";
			}
		if (info.saveAll)
			{
			s += ",S";
			}
		if (info.oneAtATime)
			{
			s += ",O";
			}
		if (info.useWindow)
			{
			s += ",W";
			}
		if (info.raiseWindowWhenStart)
			{
			s += ",R";
			}
		if (info.beepWhenFinished)
			{
			s += ",B";
			}

		if (!s.IsEmpty())
			{
			if (s.GetFirstCharacter() == ',')
				{
				s.RemoveSubstring(1,1);
				}
			p.String(rect, s, JPainter::kHAlignCenter, JPainter::kVAlignCenter);
			}
		}
	else
		{
		const JString* s = NULL;
		JFontStyle style;
		if (cell.x == kMenuTextColumn)
			{
			s = info.menuText;
			}
		else if (cell.x == kMenuShortcutColumn)
			{
			s = info.menuShortcut;
			}
		else if (cell.x == kScriptNameColumn)
			{
			s = info.name;
			}
		else if (cell.x == kCommandColumn)
			{
			s = info.cmd;
			}
		else if (cell.x == kPathColumn)
			{
			s = info.path;
			style.color =
				CBCommandPathInput::GetTextColor(*s, itsBasePath, kJFalse, p.GetColormap());
			}
		assert( s != NULL );

		p.SetFont(itsFontName, itsFontSize, style);

		JRect r = rect;
		r.left += kHMarginWidth;
		p.String(r, *s, JPainter::kHAlignLeft, JPainter::kVAlignCenter);
		}
}
JBoolean
CBCtagsUser::HasExuberantCtags()
{
	if (itsHasExuberantCtagsFlag == kUntested)
		{
		itsHasExuberantCtagsFlag = kFailure;

		// this hack is required on Linux kernel 2.3.x (4/19/2000)
		j_sig_func*	origHandler = signal(SIGCHLD, emptyHandler);

		pid_t pid;

		#if defined _J_SUNOS
		pid_t* ppid = NULL;
		#else
		pid_t* ppid = &pid;
		#endif

		int fromFD;
		JError err = JExecute(kCheckVersionCmd, ppid,
							  kJIgnoreConnection, NULL,
							  kJCreatePipe, &fromFD,
							  kJTossOutput, NULL);
		if (err.OK())
			{
			JString vers;
			JReadAll(fromFD, &vers);

			JArray<JIndexRange> matchList;
			if (versionPattern.Match(vers, &matchList))
				{
				matchList.RemoveElement(1);

				const JSize count = matchList.GetElementCount();
				JString s;
				for (JIndex i=1; i<=count; i++)
					{
					JUInt v = 0;
					const JIndexRange r = matchList.GetElement(i);
					if (!r.IsEmpty())
						{
						s = vers.GetSubstring(r);
						while (!isdigit(s.GetFirstCharacter()))
							{
							s.RemoveSubstring(1, 1);
							}
						const JBoolean ok = s.ConvertToUInt(&v);
						assert( ok );
						}

					if (v > kMinVersion[i-1] ||
						(i == count && v == kMinVersion[i-1]))
						{
						itsHasExuberantCtagsFlag = kSuccess;
						break;
						}
					else if (v < kMinVersion[i-1])
						{
						break;
						}
					}
				}
			}

		if (origHandler != SIG_ERR)
			{
			signal(SIGCHLD, origHandler);
			}
		}

	return JI2B( itsHasExuberantCtagsFlag == kSuccess );
}
void
CMVarNode::ConvertToBase()
{
	itsCanConvertBaseFlag = kJFalse;
	if (itsOrigValue != NULL && !itsOrigValue->IsEmpty())
		{
		JTree* tree;
		if (itsValue != *itsOrigValue && GetTree(&tree))
			{
			tree->BroadcastChange(this);
			}
		itsValue = *itsOrigValue;
		}

	if (itsBase == 0 || itsIsPointerFlag)
		{
		return;		// avoid constructing matchList
		}

	JArray<JIndexRange> matchList;
	if (valuePattern.Match(itsValue, &matchList))
		{
		JString vStr = itsValue.GetSubstring(matchList.GetElement(2));

		JUInt v;
		itsCanConvertBaseFlag = JI2B(
			vStr.ConvertToUInt(&v, vStr.GetFirstCharacter() == '0' ? 8 : 10) &&
			(itsBase != 1 || (0 <= v && v <= 255)));
		if (itsCanConvertBaseFlag)
			{
			// save value for when base reset to "default"

			itsOrigValue = new JString(itsValue);
			assert( itsOrigValue != NULL );

			// replace only the value, preserving whatever else is there

			if (itsBase == 1)
				{
				assert( 0 <= v && v <= 255 );

				vStr  = JString(v, JString::kBase16, kJTrue);
				vStr += " '";

				JBoolean found = kJFalse;
				for (JIndex i=0; i<kSpecialCharCount; i++)
					{
					if (JCharacter(v) == kSpecialCharInfo[i].c)
						{
						vStr += kSpecialCharInfo[i].s;
						found = kJTrue;
						}
					}
				if (!found)
					{
					vStr.AppendCharacter(v);
					}

				vStr.AppendCharacter('\'');
				}
			else
				{
				vStr = JString(v, (JString::Base) itsBase, kJTrue);
				if (itsBase == 8)
					{
					vStr.PrependCharacter('0');
					}
				}

			JIndexRange r;
			itsValue.ReplaceSubstring(matchList.GetElement(2), vStr, &r);

			JTree* tree;
			if (GetTree(&tree))
				{
				tree->BroadcastChange(this);
				}
			}
		}
}
void
CBSymbolList::ReadSymbolList
	(
	istream&			input,
	const CBLanguage	lang,
	const JCharacter*	fullName,
	const JFAID_t		fileID
	)
{
	JString path, fileName;
	JSplitPathAndName(fullName, &path, &fileName);

	input >> ws;
	while (input.peek() == '!')
		{
		JIgnoreLine(input);
		input >> ws;
		}

	JStringPtrMap<JString> flags(JPtrArrayT::kDeleteAll);
	while (1)
		{
		JString* name = new JString;
		assert( name != NULL );

		input >> ws;
		*name = JReadUntil(input, '\t');		// symbol name
		if (input.eof() || input.fail())
			{
			delete name;
			break;
			}

		JIgnoreUntil(input, '\t');				// file name

		JIndex lineIndex;
		input >> lineIndex;						// line index

		ReadExtensionFlags(input, &flags);

		JCharacter typeChar = ' ';
		JString* value;
		if (flags.GetElement("kind", &value) && !value->IsEmpty())
			{
			typeChar = value->GetFirstCharacter();
			}

		JString* signature = NULL;
		if (flags.GetElement("signature", &value) && !value->IsEmpty())
			{
			signature = new JString(*value);
			assert( signature != NULL );
			signature->PrependCharacter(' ');
			}

		if (IgnoreSymbol(*name))
			{
			delete name;
			}
		else
			{
			const Type type = DecodeSymbolType(lang, typeChar);
			if (signature == NULL &&
				(IsFunction(type) || IsPrototype(type)))
				{
				signature = new JString(" ( )");
				assert( signature != NULL );
				}

			const SymbolInfo info(name, signature, lang, type,
								  kJFalse, fileID, lineIndex);
			itsSymbolList->InsertSorted(info);

			// add file:name

			if (IsFileScope(type))
				{
				JString* name1 = new JString(fileName);
				assert( name1 != NULL );
				*name1 += ":";
				*name1 += *name;

				JString* sig1 = NULL;
				if (signature != NULL)
					{
					sig1 = new JString(*signature);
					assert( sig1 != NULL );
					}

				const SymbolInfo info1(name1, sig1, lang, type,
									   kJTrue, fileID, lineIndex);
				itsSymbolList->InsertSorted(info1);
				}
			}
		}
}
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;
}
void
GenerateCode
	(
	istream&			input,
	ostream&			output,
	const JString&		stringPath,
	const JString&		formName,
	const JString&		tagName,
	const JString&		userTopEnclVarName,
	JPtrArray<JString>*	objTypes,
	JPtrArray<JString>*	objNames
	)
{
JIndex i;

	// width

	input >> ws;
	JString line = JReadUntilws(input);
	assert( line == kFormWidthMarker );
	JSize formWidth;
	input >> formWidth;

	// height

	input >> ws;
	line = JReadUntilws(input);
	assert( line == kFormHeightMarker );
	JSize formHeight;
	input >> formHeight;

	// object count (marker contains whitespace)

	input >> ws;
	line = JReadUntil(input, ':') + ":";
	assert( line == kFormObjCountMarker );
	JSize itemCount;
	input >> itemCount;

	// create window

	const JString topEnclFrameName = tagName + "_Frame";
	const JString topEnclApName    = tagName + "_Aperture";

	JString topEnclVarName;
	if (tagName == kDefaultDelimTag)
		{
		topEnclVarName = kDefTopEnclVarName;

		output << "    JXWindow* window = new JXWindow(this, ";
		output << formWidth << ',' << formHeight;
		output << ", \"\");" << endl;
		output << "    assert( window != NULL );" << endl;
		output << endl;
		}
	else
		{
		assert( !userTopEnclVarName.IsEmpty() );
		topEnclVarName = userTopEnclVarName;

		output << "    const JRect ";
		topEnclFrameName.Print(output);
		output << "    = ";
		topEnclVarName.Print(output);
		output << "->GetFrame();" << endl;

		output << "    const JRect ";
		topEnclApName.Print(output);
		output << " = ";
		topEnclVarName.Print(output);
		output << "->GetAperture();" << endl;

		output << "    ";
		topEnclVarName.Print(output);
		output << "->AdjustSize(" << formWidth << " - ";
		topEnclApName.Print(output);
		output << ".width(), " << formHeight << " - ";
		topEnclApName.Print(output);
		output << ".height());" << endl;

		output << endl;
		}

	// We need to calculate the enclosure for each object.  Since objects
	// are drawn in the order added, an object must come after its enclosure
	// in the list in order to be visible.

	JArray<JRect>    rectList(10);
	JArray<JBoolean> isInstanceVar(10);

	// This array is used to send the options to ApplyOptions.
	// It does not own the pointers that it contains.

	JPtrArray<JString> optionValues(JPtrArrayT::kForgetAll, kOptionCount);
	for (i=1; i<=kOptionCount; i++)
		{
		optionValues.Append(NULL);
		}

	// generate code for each object

	JStringManager stringMgr;

	JIndex objCount = 1;
	for (i=1; i<=itemCount; i++)
		{
		// check for start-of-object

		input >> ws;
		line = JReadLine(input);
		assert( line == kBeginObjLine );

		// object class

		JString flClass = JReadLine(input);
		RemoveIdentifier(kObjClassMarker, &flClass);

		// object type

		JString flType = JReadLine(input);
		RemoveIdentifier(kObjTypeMarker, &flType);

		// object frame

		input >> ws;
		line = JReadUntilws(input);
		assert( line == kObjRectMarker );
		JCoordinate x,y,w,h;
		input >> x >> y >> w >> h >> ws;
		const JRect frame(y, x, y+h, x+w);
		rectList.AppendElement(frame);

		// box type

		JString boxType = JReadLine(input);
		RemoveIdentifier(kObjBoxTypeMarker, &boxType);

		// colors

		input >> ws;
		line = JReadUntilws(input);
		assert( line == kObjColorsMarker );
		JString col1 = JReadUntilws(input);
		optionValues.SetElement(kCol1Index, &col1, JPtrArrayT::kForget);
		JString col2 = JReadUntilws(input);
		optionValues.SetElement(kCol2Index, &col2, JPtrArrayT::kForget);

		// label info

		JString lAlign = JReadLine(input);
		RemoveIdentifier(kObjLAlignMarker, &lAlign);
		JString lStyle = JReadLine(input);
		RemoveIdentifier(kObjLStyleMarker, &lStyle);
		JString lSize  = JReadLine(input);
		RemoveIdentifier(kObjLSizeMarker, &lSize);
		JString lColor = JReadLine(input);
		RemoveIdentifier(kObjLColorMarker, &lColor);
		JString label  = JReadLine(input);
		RemoveIdentifier(kObjLabelMarker, &label);

		// shortcuts

		JString shortcuts = JReadLine(input);
		RemoveIdentifier(kObjShortcutMarker, &shortcuts);
		optionValues.SetElement(kShortcutsIndex, &shortcuts, JPtrArrayT::kForget);

		// resizing (ignored)

		JIgnoreLine(input);

		// gravity

		input >> ws;
		line = JReadUntilws(input);
		assert( line == kObjGravityMarker );
		const JString nwGravity = JReadUntilws(input);
		const JString seGravity = JReadUntilws(input);

		// variable name

		JBoolean isLocal = kJFalse;
		JString* varName = new JString(JReadLine(input));
		assert( varName != NULL );
		RemoveIdentifier(kObjNameMarker, varName);
		if (varName->IsEmpty())
			{
			isInstanceVar.AppendElement(kJFalse);
			GetTempVarName(tagName, varName, *objNames);
			isLocal = kJTrue;
			}
		else if (varName->GetFirstCharacter() == '(' &&
				 varName->GetLastCharacter()  == ')')
			{
			isInstanceVar.AppendElement(kJFalse);
			isLocal  = kJTrue;
			*varName = varName->GetSubstring(2, varName->GetLength()-1);
			}
		else if (varName->GetFirstCharacter() == '<' &&
				 varName->GetLastCharacter()  == '>')
			{
			isInstanceVar.AppendElement(kJFalse);
			*varName = varName->GetSubstring(2, varName->GetLength()-1);
			}
		else
			{
			isInstanceVar.AppendElement(kJTrue);
			}
		objNames->Append(varName);

		// callback (ignored)

		JIgnoreLine(input);

		// callback argument

		JString cbArg = JReadLine(input);
		RemoveIdentifier(kObjCBArgMarker, &cbArg);

		JString cbArgExtra;
		do
			{
			cbArgExtra = JReadLine(input);
			cbArgExtra.TrimWhitespace();
			}
			while (!cbArgExtra.IsEmpty());

		// don't bother to generate code for initial box
		// if it is FL_BOX, FLAT_BOX, FL_COL1

		if (i==1 && flClass == "FL_BOX" && flType == "FLAT_BOX" && col1 == "FL_COL1")
			{
			rectList.RemoveElement(objCount);
			isInstanceVar.RemoveElement(objCount);
			objNames->DeleteElement(objCount);
			continue;
			}

		// check for errors -- safe since we have read in entire object

		JString hSizing, vSizing;
		if (!ParseGravity(nwGravity, &hSizing, &vSizing))
			{
			cerr << "Illegal sizing specification ";
			cerr << nwGravity << ',' << seGravity;
			cerr << " for '" << *varName << '\'' << endl;
			rectList.RemoveElement(objCount);
			isInstanceVar.RemoveElement(objCount);
			objNames->DeleteElement(objCount);
			continue;
			}

		if (*varName == topEnclVarName)
			{
			cerr << "Cannot use reserved name '" << topEnclVarName << '\'' << endl;
			rectList.RemoveElement(objCount);
			isInstanceVar.RemoveElement(objCount);
			objNames->DeleteElement(objCount);
			continue;
			}

		// get the object's enclosure

		JIndex enclIndex;
		JString enclName;
		JRect localFrame = frame;
		if (GetEnclosure(rectList, objCount, &enclIndex))
			{
			enclName = *(objNames->NthElement(enclIndex));
			const JRect enclFrame = rectList.GetElement(enclIndex);
			localFrame.Shift(-enclFrame.topLeft());
			}
		else
			{
			enclName = topEnclVarName;
			}

		// get the class name and additional arguments

		JString* className = new JString;
		assert( className != NULL );
		objTypes->Append(className);

		JString argList;
		if (!GetConstructor(flClass, flType, &label, className, &argList))
			{
			cerr << "Unsupported class: " << flClass << ", " << flType << endl;
			rectList.RemoveElement(objCount);
			isInstanceVar.RemoveElement(objCount);
			objNames->DeleteElement(objCount);
			objTypes->DeleteElement(objCount);
			continue;
			}

		// generate the actual code

		const JBoolean needCreate = NeedsCreateFunction(*className);

		output << "    ";
		if (isLocal)
			{
			className->Print(output);
			output << "* ";
			}
		varName->Print(output);
		output << " =" << endl;
		output << "        ";
		if (!needCreate)
			{
			output << "new ";
			}
		className->Print(output);
		if (needCreate)
			{
			output << "::Create";
			}
		output << '(';
		if (!argList.IsEmpty())
			{
			argList.Print(output);
			if (argList.GetLastCharacter() != ',')
				{
				output << ',';
				}
			output << ' ';
			}

		if (!cbArg.IsEmpty())
			{
			cbArg.Print(output);
			if (cbArg.GetLastCharacter() != ',')
				{
				output << ',';
				}
			output << ' ';
			}

		if ((*className == "JXStaticText" && cbArg.IsEmpty()) ||
			NeedsStringArg(*className))
			{
			JString id = *varName;
			id += "::";
			id += formName;
			id += "::";
			id += tagName;		// last since it is almost always the same

			output << "JGetString(\"";
			id.Print(output);
			output << "\"), ";

			stringMgr.SetElement(id, label, JPtrArrayT::kDelete);
			}

		enclName.Print(output);
		output << ',' << endl;
		output << "                    JXWidget::";
		hSizing.Print(output);
		output << ", JXWidget::";
		vSizing.Print(output);
		output << ", " << localFrame.left << ',' << localFrame.top << ", ";
		output << localFrame.width() << ',' << localFrame.height() << ");" << endl;

		output << "    assert( ";
		varName->Print(output);
		output << " != NULL );" << endl;

		ApplyOptions(output, *className, formName, tagName, *varName, optionValues,
					 lSize, lStyle, lColor, &stringMgr);

		if (*className == "JXStaticText" && cbArg.IsEmpty() &&
			!lAlign.Contains("FL_ALIGN_TOP") && localFrame.height() <= 20)
			{
			output << "    ";
			varName->Print(output);
			output << "->SetToLabel();" << endl;
			}

		output << endl;

		// now we know the object is valid

		objCount++;
		}

	// write string database

	JString dbFileName = stringPath + formName;
	if (tagName != kDefaultDelimTag)
		{
		dbFileName += kCustomTagMarker + tagName;
		}
	dbFileName += "_layout";

	if (stringMgr.GetElementCount() > 0)
		{
		JEditVCS(dbFileName);
		ofstream dbOutput(dbFileName);
		stringMgr.WriteFile(dbOutput);
		}
	else
		{
		JRemoveVCS(dbFileName);
		JRemoveFile(dbFileName);
		}

	// reset enclosure size

	if (tagName != kDefaultDelimTag)
		{
		output << "    ";
		topEnclVarName.Print(output);
		output << "->SetSize(";
		topEnclFrameName.Print(output);
		output << ".width(), ";
		topEnclFrameName.Print(output);
		output << ".height());" << endl;
		output << endl;
		}

	// throw away temporary variables

	objCount--;
	assert( objCount == isInstanceVar.GetElementCount() );
	assert( objCount == objTypes->GetElementCount() );
	assert( objCount == objNames->GetElementCount() );
	for (i=objCount; i>=1; i--)
		{
		if (!isInstanceVar.GetElement(i))
			{
			objTypes->DeleteElement(i);
			objNames->DeleteElement(i);
			}
		}
}
void
GMessageHeader::SetDate
	(
	const JString& date
	)
{
	itsDate = date;
	itsDate.TrimWhitespace();
	const JSize count	= itsDate.GetLength();
	if (count == 0)
		{
		return;
		}
	JIndex findex;
	JIndex current	= 0;
	JString day;
	// dow and day of month
	if (itsDate.LocateSubstring(" ", &findex) && findex > 1)
		{
		// check for day of week (Mon|Monday|Tue...)
		if (itsDate.GetCharacter(findex - 1) == ',')
			{
			// ignore dow for now
			findex ++;
			while (findex <= itsDate.GetLength() &&
				   itsDate.GetCharacter(findex) == ' ')
				{
				findex++;
				}
			current	= findex;
			if (itsDate.LocateNextSubstring(" ", &findex) && 
				findex < count &&
				current < findex)
				{
				day	= itsDate.GetSubstring(current, findex - 1);
				}
			}
		else
			{
			day	= itsDate.GetSubstring(1, findex - 1);
			}
		if (!day.IsEmpty())
			{
			if (day.GetFirstCharacter() == '0')
				{
				day.RemoveSubstring(1,1);
				}
			}
		day.ConvertToUInt(&itsDay);

		findex ++;
		current	= findex;
		}
	else
		{
		return;
		}

	if (itsDate.LocateNextSubstring(" ", &findex) && findex > current)
		{
		itsMonth	= itsDate.GetSubstring(current, findex - 1);
		findex ++;
		current	= findex;
		}
	else
		{
		return;
		}

	if (itsDate.LocateNextSubstring(" ", &findex) && findex > current)
		{
		JString year	= itsDate.GetSubstring(current, findex - 1);
		year.ConvertToUInt(&itsYear);
		findex ++;
		current	= findex;
		}
	else
		{
		return;
		}

	if (itsDate.LocateNextSubstring(" ", &findex) && findex > current)
		{
		itsTime	= itsDate.GetSubstring(current, findex - 1);
		findex ++;
		current	= findex;
		}
	else
		{
		return;
		}

	itsShortDate = itsMonth + " " + day;
	time_t now;
	struct tm *local_time;
	time(&now);
	local_time = localtime(&now);
	if (itsYear != (JIndex)(local_time->tm_year + 1900))
		{
		JString year	= JString(itsYear, JString::kBase10);
		itsShortDate += " " + year;
		}

	return;			
	
/*	JArray<JIndexRange> subList;
	JString year	= JString(itsYear, JString::kBase10);
	JBoolean matched = monthRegex1.Match(itsDate, &subList);
	if (matched)
		{
		JIndexRange sRange = subList.GetElement(3);
		itsMonth = itsDate.GetSubstring(sRange);
		sRange = subList.GetElement(2);
		JString day = itsDate.GetSubstring(sRange);
		if (!day.IsEmpty())
			{
			if (day.GetFirstCharacter() == '0')
				{
				day.RemoveSubstring(1,1);
				}
			}
		day.ConvertToUInt(&itsDay);
		itsShortDate = itsMonth + " " + day;
		time_t now;
		struct tm *local_time;
		time(&now);
		local_time = localtime(&now);
		if (itsYear != (JIndex)(local_time->tm_year + 1900))
			{
			JString year	= JString(itsYear, JString::kBase10);
			itsShortDate += " " + year;
			}

		return;
		}
	matched = monthRegex2.Match(itsDate, &subList);
	if (matched)
		{
		JIndexRange sRange = subList.GetElement(3);
		itsMonth = itsDate.GetSubstring(sRange);
		sRange = subList.GetElement(2);
		JString day = itsDate.GetSubstring(sRange);
		if (!day.IsEmpty())
			{
			if (day.GetFirstCharacter() == '0')
				{
				day.RemoveSubstring(1,1);
				}
			}
		day.ConvertToUInt(&itsDay);
		itsShortDate = itsMonth + " " + day;
		time_t now;
		struct tm *local_time;
		time(&now);
		local_time = localtime(&now);
		if (itsYear != (JIndex)(local_time->tm_year + 1900))
			{
			JString year	= JString(itsYear, JString::kBase10);
			itsShortDate += " " + year;
			}
		return;
		}
	else
		{
		itsShortDate = itsDate;
		}*/
}
void
GARMessageHeader::SetDate
	(
	const JString& date
	)
{
	itsDate = date;
	itsDate.TrimWhitespace();
	JArray<JIndexRange> subList;
	JString year	= JString(itsYear, JString::kBase10);
	JBoolean matched = monthRegex1.Match(itsDate, &subList);
	if (matched)
		{
		JIndexRange sRange = subList.GetElement(3);
		itsMonth = itsDate.GetSubstring(sRange);
		sRange = subList.GetElement(2);
		JString day = itsDate.GetSubstring(sRange);
		if (!day.IsEmpty())
			{
			if (day.GetFirstCharacter() == '0')
				{
				day.RemoveSubstring(1,1);
				}
			}
		day.ConvertToUInt(&itsDay);
		itsShortDate = itsMonth + " " + day;
		time_t now;
		struct tm *local_time;
		time(&now);
		local_time = localtime(&now);
		if (itsYear != (JIndex)(local_time->tm_year + 1900))
			{
			JString year	= JString(itsYear, JString::kBase10);
			itsShortDate += " " + year;
			}

		return;
		}
	matched = monthRegex2.Match(itsDate, &subList);
	if (matched)
		{
		JIndexRange sRange = subList.GetElement(3);
		itsMonth = itsDate.GetSubstring(sRange);
		sRange = subList.GetElement(2);
		JString day = itsDate.GetSubstring(sRange);
		if (!day.IsEmpty())
			{
			if (day.GetFirstCharacter() == '0')
				{
				day.RemoveSubstring(1,1);
				}
			}
		day.ConvertToUInt(&itsDay);
		itsShortDate = itsMonth + " " + day;
		time_t now;
		struct tm *local_time;
		time(&now);
		local_time = localtime(&now);
		if (itsYear != (JIndex)(local_time->tm_year + 1900))
			{
			JString year	= JString(itsYear, JString::kBase10);
			itsShortDate += " " + year;
			}
		return;
		}
	else
		{
		itsShortDate = itsDate;
		}
}
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());
		}
}
void
XDLink::ReceiveMessageFromDebugger()
{
	itsLink->StopTimer();

	JString data;
	const JBoolean ok = itsLink->GetNextMessage(&data);
	assert( ok );

	if (data.IsEmpty() || data.GetFirstCharacter() != '<')
		{
		return;
		}

	Broadcast(DebugOutput(data, kOutputType));

	if (itsInitFinishedFlag)
		{
		if (!itsProgramIsStoppedFlag)
			{
			itsProgramIsStoppedFlag = kJTrue;
			Broadcast(ProgramStopped(CMLocation("", 1)));
			}

		itsDebuggerBusyFlag = kJFalse;
		Broadcast(DebuggerReadyForInput());
		}

	xmlDoc* doc = xmlReadMemory(data.GetCString(), data.GetLength(),
								NULL, NULL, XML_PARSE_NOCDATA);
	if (doc != NULL)
		{
		xmlNode* root = xmlDocGetRootElement(doc);

		if (root != NULL && strcmp((char*) root->name, "init") == 0)
			{
			itsIDEKey         = JGetXMLNodeAttr(root, "idekey");
			const JString uri = JGetXMLNodeAttr(root, "fileuri");

			const JCharacter* map[] =
				{
				"idekey", itsIDEKey,
				"uri",    uri
				};
			JString msg = JGetString("ConnectionInfo::XDLink", map, sizeof(map));
			Broadcast(UserOutput(msg, kJFalse));

			Send("feature_set -n show_hidden -v 1");
			Send("step_into");

			JString programName;
			GetProgram(&programName);

			Broadcast(AttachedToProcess());
			Broadcast(SymbolsLoaded(JI2B(uri == itsScriptURI), programName));

			itsInitFinishedFlag = kJTrue;
			itsScriptURI        = uri;
			}
		else if (root != NULL && strcmp((char*) root->name, "response") == 0)
			{
			const JString status = JGetXMLNodeAttr(root, "status");
			const JString reason = JGetXMLNodeAttr(root, "reason");
			if (status == "break" && reason == "error" &&
				root->children != NULL && root->children->children != NULL &&
				strcmp((char*) root->children->name, "error") == 0 &&
				root->children->children->type == XML_TEXT_NODE)
				{
				JString msg            = (char*) root->children->children->content;
				const JString encoding = JGetXMLNodeAttr(root->children, "encoding");
				if (encoding == "base64")
					{
					msg.DecodeBase64(&msg);
					}
				msg += "\n";
				Broadcast(UserOutput(msg, kJTrue));
				}

			const JString idStr = JGetXMLNodeAttr(root, "transaction_id");
			JUInt id;
			if (idStr.ConvertToUInt(&id))
				{
				HandleCommandRunning(id);
				}

			CMCommand* cmd;
			if (GetRunningCommand(&cmd))
				{
				itsParsedDataRoot = root;

				cmd->Finished(JI2B(
					root->children == NULL || strcmp((char*) root->children->name, "error") != 0));

				itsParsedDataRoot = NULL;

				SetRunningCommand(NULL);
				if (!HasForegroundCommands())
					{
					RunNextCommand();
					}
				}

			if (status == "stopping" || status == "stopped")
				{
				CancelAllCommands();

				XDCloseSocketTask* task = new XDCloseSocketTask(itsLink);
				assert( task != NULL );
				task->Go();
				}
			}

		xmlFreeDoc(doc);
		}
}
void
JXTextMenuData::ParseMenuItemStr
	(
	JString*	text,
	JBoolean*	isActive,
	JBoolean*	hasSeparator,
	JBoolean*	isCheckbox,
	JBoolean*	isRadio,
	JString*	shortcuts,
	JString*	nmShortcut,
	JString*	id
	)
	const
{
	*isActive     = kJTrue;
	*hasSeparator = kJFalse;
	*isCheckbox   = kJFalse;
	*isRadio      = kJFalse;

	shortcuts->Clear();
	nmShortcut->Clear();
	id->Clear();

	JIndex opIndex;
	while (text->LocateLastSubstring("%", &opIndex))
		{
		const JSize textLength = text->GetLength();
		if (opIndex == textLength)	// can't assert() because of menu_strings file
			{
			text->RemoveSubstring(textLength, textLength);
			continue;
			}

		JString op = text->GetSubstring(opIndex+1, textLength);
		text->RemoveSubstring(opIndex, textLength);

		const JCharacter opc = op.GetFirstCharacter();
		if (opc == 'd')
			{
			*isActive = kJFalse;
			}
		else if (opc == 'l')
			{
			*hasSeparator = kJTrue;
			}
		else if (opc == 'b' || opc == 'B')
			{
			*isCheckbox = kJTrue;
			}
		else if (opc == 'r' || opc == 'R')
			{
			*isCheckbox = kJTrue;
			*isRadio    = kJTrue;
			}

		else if (opc == 'h' && shortcuts->IsEmpty())
			{
			*shortcuts = op.GetSubstring(2, op.GetLength());
			shortcuts->TrimWhitespace();
			}
		else if (opc == 'h')
			{
			cerr << "Tried to use %h more than once in '" << *text << '\'' << endl;
			}

		else if (opc == 'k' && nmShortcut->IsEmpty())
			{
			*nmShortcut = op.GetSubstring(2, op.GetLength());
			nmShortcut->TrimWhitespace();
			}
		else if (opc == 'k')
			{
			cerr << "Tried to use %k more than once in '" << *text << '\'' << endl;
			}

		else if (opc == 'i' && id->IsEmpty())
			{
			*id = op.GetSubstring(2, op.GetLength());
			id->TrimWhitespace();
			}
		else if (opc == 'i')
			{
			cerr << "Tried to use %i more than once in '" << *text << '\'' << endl;
			}

		else
			{
			cerr << "Unsupported option %" << op << " in '" << *text << '\'' << endl;
			}
		}

	text->TrimWhitespace();
}