Example #1
0
		/// <summary>
		/// Finds and sets the value, inserting or replacing as necessary
		/// </summary>
		/// <param name="file">The complete file path to open</param>
		/// <param name="nodeSpec">The path to the node that will have a new child.</param>
		/// <param name="attributeValue">The attribute to add or replace.</param>
		/// <param name="comment">The text of the comment (not including the //)</param>
		public static void SetICUDataFileAttribute(string file, NodeSpecification nodeSpec,
			String attributeValue, string comment)
		{
			// Get the node they chose
			IcuDataNode chosenNode = nodeSpec.FindNode( ParsedFile(file), true );
			// Add the attribute
			chosenNode.AddAttributeSmart(
				new IcuDataNode.IcuDataAttribute(attributeValue, ", //" + comment + Environment.NewLine, true));
		}
Example #2
0
		public static int RemoveICUDataFileAttribute(IcuDataNode rootNode, NodeSpecification nodeSpec, string attributeValue)
		{
			IcuDataNode specifiedNode = nodeSpec.FindNode(rootNode,false);
			if( specifiedNode == null )
				return -1;
			return specifiedNode.removeAttribute(attributeValue);
		}
Example #3
0
		public static bool RemoveICUDataFileChild(IcuDataNode rootNode, NodeSpecification nodeSpec, string childName)
		{
			IcuDataNode specifiedNode = nodeSpec.FindNode(rootNode,false);
			if( specifiedNode == null )
				return false;
			return specifiedNode.removeChild(childName);
		}
Example #4
0
		/// <summary>
		/// Finds whether node contains the value "value"
		/// Actually "value in this case is a sub-node
		/// </summary>
		/// <param name="file">The full file pathname of the file to check.</param>
		/// <param name="nodeSpec">The node we wish to check in the file.</param>
		/// <returns>The <c>InstallLanguage.LocaleFileClass.eAction</c> to perform on this node</returns>
		public static bool NodeExists(string file,
			NodeSpecification nodeSpec)
		{
			IcuDataNode specifiedNode = nodeSpec.FindNode(ParsedFile(file),false);
			if( specifiedNode == null )
				return false;
			return true;
		}
Example #5
0
		/// <summary>
		/// Finds and sets the childNode, inserting or replacing as necessary.
		/// </summary>
		/// <param name="file">The complete file path to open</param>
		/// <param name="nodeSpec">The path to the node that will have a new child.</param>
		/// <param name="newChild">The new child to add, replacing existing children as necessary.</param>
		public static void SetICUDataFileNode(string file, NodeSpecification nodeSpec,
			IcuDataNode newChild, bool addAtTop)
		{
			// Get the node they chose
			IcuDataNode chosenNode = nodeSpec.FindNode( ParsedFile(file), false );
			// Add the child
			if (chosenNode != null)
				chosenNode.AddChildSmart(newChild, addAtTop);
		}
Example #6
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Get a CustomResourceInfo object that contains the boolean properties for all
		/// of the locale portions existance in the custom resource in the passed in
		/// file (root.txt).
		/// </summary>
		/// <param name="inputFile">full path to root.txt file</param>
		/// <param name="locale">the locale to be parsed and looked for</param>
		/// <returns>an object (CustomResourceInfo) that contains the bool properties</returns>
		/// ------------------------------------------------------------------------------------
		public CustomResourceInfo GetCustomResourceInfo(string inputFile, string locale, string [] icuLocales)
		{
			string lang, script, country, variant;
			#region Compute the Lang, Script, Country and Variant portion of the Locale
			ParseLocaleName(ref locale, out lang, out script, out country, out variant);
			#endregion

			bool bCustom, bLocale, bLanguage, bScript, bCountry, bVariant;	// C# defaults to 'false' at construction time

			// define all the nodes used for finding the custom resources in the root.txt file
			NodeSpecification custom          = new NodeSpecification("root", "Custom");
			NodeSpecification customLocales   = new NodeSpecification("root", "Custom", "LocalesAdded");
			NodeSpecification customLanguages = new NodeSpecification("root", "Custom", "LanguagesAdded", lang);
			NodeSpecification customScripts   = new NodeSpecification("root", "Custom", "ScriptsAdded", script);
			NodeSpecification customCountries = new NodeSpecification("root", "Custom", "CountriesAdded", country);
			NodeSpecification customVariants  = new NodeSpecification("root", "Custom", "VariantsAdded", variant);

			// now set all the boolean values for each custom type
			bCustom = ICUDataFiles.NodeExists(inputFile, custom);
			bLocale = ICUDataFiles.AttributeExists(inputFile, customLocales, locale);

			// The following custom properties are associated with each Xx.txt file,
			//  so only say it's there if it exists and has all the wsNames as attributes.
			if (icuLocales != null && icuLocales.Length > 0)
			{
				// Start at true and set to false if any aren't found
				bLanguage = bScript = bCountry = bVariant = true;
				foreach (string name in icuLocales)
				{
					bLanguage = ICUDataFiles.AttributeExists(inputFile, customLanguages, name) && bLanguage;
					if (script.Length > 0)
						bScript = ICUDataFiles.AttributeExists(inputFile, customScripts, name) && bScript;
					else
						bScript = false;	// not applicable if empty
					if (country.Length > 0)
						bCountry = ICUDataFiles.AttributeExists(inputFile, customCountries, name) && bCountry;
					else
						bCountry = false;	// not applicable if empty
					if (variant.Length > 0)
						bVariant = ICUDataFiles.AttributeExists(inputFile, customVariants, name) && bVariant;
					else
						bVariant = false;
				}
			}
			else
			{
				bLanguage = ICUDataFiles.NodeExists(inputFile, customLanguages);
				bScript = ICUDataFiles.NodeExists(inputFile, customScripts);
				bCountry = ICUDataFiles.NodeExists(inputFile, customCountries);
				bVariant = ICUDataFiles.NodeExists(inputFile, customVariants);
			}
			#region Test code (commented out until moved to NUnit...)
			/*
			string testFile = "root {\r\n}";
			AddCustomResource(ref testFile);
			AddCustomCountry(ref testFile, "ZZZ");
			AddCustomCountry(ref testFile, "AAA");
			AddCustomCountry(ref testFile, "WWW");
			AddCustomCountry(ref testFile, "RRR");
			StreamWriter sw = new StreamWriter(@"C:\Dev\fwtexp\DistFiles\icu\data\locales\root_dlh_testA.txt");
			sw.Write(testFile);
			sw.Close();
			DeleteCustomCountry(ref testFile, "AAA");
			sw = new StreamWriter(@"C:\Dev\fwtexp\DistFiles\icu\data\locales\root_dlh_testB.txt");
			sw.Write(testFile);
			sw.Close();
			*/
			#endregion

			return new CustomResourceInfo(locale, bCustom, bLocale, bLanguage, bScript, bCountry, bVariant);
		}
Example #7
0
		/// <summary>
		/// Finds whether node contains the value "value"
		/// Actually "value in this case is a sub-node
		/// </summary>
		/// <param name="file">The full file pathname of the file to check.</param>
		/// <param name="nodeSpec">The node we wish to check in the file.</param>
		/// <param name="attributeValue">An attribute that should be in the given node.</param>
		/// <returns>The <c>InstallLanguage.LocaleFileClass.eAction</c> to perform on this node</returns>
		public static bool AttributeExists(string file,
			NodeSpecification nodeSpec, String attributeValue)
		{
			IcuDataNode specifiedNode = nodeSpec.FindNode(ParsedFile(file),false);
			if( specifiedNode == null )
				return false;
			return specifiedNode.containsAttribute(attributeValue);
		}
Example #8
0
		public ICUInfo GetIcuResourceInfo(string inputFile, string locale, string icuLocale)
		{
			string lang, script, country, variant;
			#region Compute the Lang, Script, Country and Variant portion of the Locale
			ParseLocaleName(ref locale, out lang, out script, out country, out variant);
			#endregion

			bool bLanguage, bScript, bCountry, bVariant;	// C# defaults to 'false' at construction time

			// define all the nodes used for finding the resources in the XX.txt file
			NodeSpecification icuLanguages = new NodeSpecification(icuLocale, "Languages", lang);
			NodeSpecification icuScripts = new NodeSpecification(icuLocale, "Scripts", script);
			NodeSpecification icuCountries = new NodeSpecification(icuLocale, "Countries", country);
			NodeSpecification icuVariants = new NodeSpecification(icuLocale, "Variants", variant);

			bLanguage = ICUDataFiles.NodeExists(inputFile, icuLanguages);
			if (script.Length > 0)
				bScript = ICUDataFiles.NodeExists(inputFile, icuScripts);
			else
				bScript = false;	// not applicable if empty
			if (country.Length > 0)
				bCountry = ICUDataFiles.NodeExists(inputFile, icuCountries);
			else
				bCountry = false;	// not applicable if empty
			if (variant.Length > 0)
				bVariant = ICUDataFiles.NodeExists(inputFile, icuVariants);
			else
				bVariant = false;
			return new ICUInfo(locale, bLanguage, bScript, bCountry, bVariant);
		}
Example #9
0
		/// <summary>
		/// Write the collation file.
		/// </summary>
		/// <param name="newLocaleName"></param>
		/// <param name="outputFilespec"></param>
		public void WriteCollationFile(string baseLocale, string newLocaleName, string outputFilespec)
		{
			// TODO:::
			// If there is a base locale
			//   copy it to the newlocale name
			//
			// Overwrite the standard collation sequence with the contents from the XML file
			//
			string newLocaleFileName = m_collDirectory + newLocaleName + ".txt";
			if (baseLocale != null && File.Exists(m_collDirectory + baseLocale + ".txt"))
			{
				string baseFile = m_collDirectory + baseLocale + ".txt";
				newLocaleFileName = outputFilespec;

				// read in the collation information
				IcuDataNode node = ICUDataFiles.ParsedFile(baseFile);

				// create a nodespec to use
				NodeSpecification stdColl = new NodeSpecification(baseLocale);
				node.ChangeRootName(newLocaleName);
				ICUDataFiles.WriteFileAs(baseFile, outputFilespec);
			}
			else if (!File.Exists(newLocaleFileName))
			{
				CreateNewLocaleFile(newLocaleName, outputFilespec);
				return;
			}

			// make sure there is some collation information in the lang xml file
			string coll = m_ldData.CollationElements;
			if (coll != null && coll.Length > 0)
			{
				// read in the collation information
				IcuDataNode node = ICUDataFiles.ParsedFile(outputFilespec);

				if (node != null && node.Child("___") != null && node.Children.Count == 1)
				{
					NodeSpecification nodeSpec = new NodeSpecification(newLocaleName);
					ICUDataFiles.RemoveICUDataFileChild(node, nodeSpec, "___");
					ICUDataFiles.SetICUDataFileNode(outputFilespec, nodeSpec, new IcuDataNode("Version", "1.08", ""), true);

					ICUDataFiles.SetICUDataFileNode(outputFilespec, nodeSpec, new IcuDataNode("collations", node, "", ""), false);
					NodeSpecification nodeSpecColl = new NodeSpecification(newLocaleName, "collations");
					IcuDataNode nodeColl = node.Child("collations");
					ICUDataFiles.SetICUDataFileNode(outputFilespec, nodeSpecColl, new IcuDataNode("standard", nodeColl, "", ""), true);
				}
				// create a nodespec to use
				NodeSpecification stdColl = new NodeSpecification(newLocaleName, "collations", "standard");
				ICUDataFiles.SetICUDataFileNode(outputFilespec, stdColl, new IcuDataNode("Sequence", coll, ""), true);
				ICUDataFiles.SetICUDataFileNode(outputFilespec, stdColl, new IcuDataNode("Version", "1.08", ""), false);
				ICUDataFiles.WriteFile(outputFilespec);
			}
			else
			{
				// This code will make sure we replace any existing collation information with 'nothing'.
				StreamWriter outputStream = new StreamWriter(outputFilespec, false,
					System.Text.Encoding.UTF8);

				// Output locale name and opening brace.
				outputStream.WriteLine("// " + m_comment);
				outputStream.WriteLine(newLocaleName + "{");
				outputStream.WriteLine("    // [SIL-Corp] the following comment and section copied from ICU files");
				outputStream.WriteLine("    /**");
				outputStream.WriteLine("     * so genrb doesn't issue warnings");
				outputStream.WriteLine("     */");
				outputStream.WriteLine("    ___{\"\"}");
				// Output closing brace.
				outputStream.WriteLine("}");

				// Close the output file.
				outputStream.Close();
				return;
			}
		}
Example #10
0
		/// <summary>
		/// Process all changes related to ICU locale and collation files. This updates three
		/// source text files in icu\data\locales, and possibly two source text files in
		/// icu\data\coll, then uses these to generate corresponding res files in icu\icudtXXl
		/// and icu\icudtXXl\coll. Before modifying any of the files, it makes an original
		/// backup if one doesn't already exist. During the process, it makes backup files so
		/// that if anything goes wrong during the process, it can restore everything to the
		/// state prior to making these changes.
		/// </summary>
		/// <param name="m_ldData">The parser holding information from the language
		/// definition file</param>
		public void InstallLDFile(string ldFilename)
		{
			#region Just some test code Base Local Parsers
			//	This method was left here as a location where the parser test could be called
			//
			//			bool passed = TestBaseLocaleParsers();
			//
			//			bool test = true;
			//			if (test)
			//				throw new LDExceptions(ErrorCodes.ProgrammingError);
			#endregion

			// Parse the xml file into m_ldData
			ParseLanguageDataFile(ldFilename);

			// create the core 6 files:
			// root.txt, res_index.txt, xx.txt,
			// icu26ldt_root.res, icu26ldt_res_index.res, icu26ldt_xx.res
			//
			string rootTxtInput = m_localeDirectory + "root.txt";
			string resIndexTxtInput = m_localeDirectory + "res_index.txt";
			string rootResInput = m_icuBase + m_IcuData + "root.res";
			string resIndexResInput = m_icuBase + m_IcuData + "res_index.res";
			string xxTxtFile = m_localeDirectory + m_ldData.NewLocale + ".txt";
			string xxCollTxtFile = m_collDirectory + m_ldData.NewLocale + ".txt";
			string xxResFile = m_icuBase + m_IcuData + m_ldData.NewLocale + ".res";

			// the root file text has to exist for this process to work - throw exception
			if (!File.Exists(rootTxtInput))
				throw new LDExceptions(ErrorCodes.RootTxt_FileNotFound);

			// the res index file has to exist for this process to work - throw exception
			if (!File.Exists(resIndexTxtInput))
				throw new LDExceptions(ErrorCodes.ResIndexTxt_FileNotFound);

			// Determine which ICU locale resources should be updated with the name of the new language.
			int cwsNames = m_ldData.Names.Count;
			ICUInfo[] icuInfo = new ICUInfo[cwsNames];
			string[] rgXx = new string[cwsNames];
			string[] rgXxTxtFiles = new string[cwsNames];
			string[] rgXxResFiles = new string[cwsNames];
			string icuLocales = "";				// used for output tracing
			for (int iws = 0; iws < cwsNames; ++iws)
			{
				rgXx[iws] = ((StringWithWs)m_ldData.Names[iws]).icuLocale;
				icuLocales += " " + rgXx[iws];
				if (rgXx[iws] == m_ldData.NewLocale)
				{
					rgXxTxtFiles[iws] = null;	// (probably redundant...)
					rgXxResFiles[iws] = null;
				}
				else
				{
					rgXxTxtFiles[iws] = m_localeDirectory + rgXx[iws] + ".txt";
					rgXxResFiles[iws] = m_icuBase + m_IcuData + rgXx[iws] + ".res";
					// get information for this locale in the
					icuInfo[iws] = GetIcuResourceInfo(rgXxTxtFiles[iws], m_ldData.NewLocale, rgXx[iws]);
				}
			}

			// DN-271 use the Custom resource that contains all the Locales, Languages,
			// Countries and Variants that we've added to the root.txt file to see if
			// this is one of them.
			CustomResourceInfo newLangInfo = GetCustomResourceInfo(rootTxtInput, m_ldData.NewLocale, rgXx);

			if (LogFile.IsLogging())	// put out some debugging info
			{
				LogFile.AddLine("Locale  : <" + newLangInfo.LocaleItems.Locale + ">");
				LogFile.AddLine("Language: <" + newLangInfo.LocaleItems.LangKey + ">");
				LogFile.AddLine("Script  : <" + newLangInfo.LocaleItems.ScriptKey + ">");
				LogFile.AddLine("Country : <" + newLangInfo.LocaleItems.CountryKey + ">");
				LogFile.AddLine("Variant : <" + newLangInfo.LocaleItems.VariantKey + ">");

				string custom = "";
				if (newLangInfo.HasLocale)
					custom += " Locale";
				if (newLangInfo.HasLanguage)
					custom += " Language(" + icuLocales + ")";
				if (newLangInfo.HasScript)
					custom += " Script(" + icuLocales + ")";
				if (newLangInfo.HasCountry)
					custom += " Country(" + icuLocales + ")";
				if (newLangInfo.HasVariant)
					custom += " Variant(" + icuLocales + ")";
				if (custom.Length <= 0)
					custom = " None";

				LogFile.AddLine("Components that already exist in the custom resource: " + custom);

				for (int i = 0; i < cwsNames; i++)
				{
					string icu = "";
					ICUInfo info = icuInfo[i];
					if (info != null)
					{
						if (info.HasLanguage)
							icu += " Language";
						if (info.HasScript)
							icu += " Script";
						if (info.HasCountry)
							icu += " Country";
						if (info.HasVariant)
							icu += " Variant";
					}
					if (icu.Length <= 0)
						icu = " None";
					LogFile.AddLine("Components that already exist in " + rgXx[i] + ".txt: " + icu);
				}
			}

			// DN-246 1. see if it's a factory locale - if so, do Nothing, just return
			if (newLangInfo.HasLocale == false &&
				(File.Exists(xxTxtFile) || File.Exists(xxCollTxtFile)))
			{
				LogFile.AddLine("It's a factory Locale - do nothing");
				return;	// factory locale
			}

			// Check for ICU script and actual locale script key
			if (newLangInfo.LocaleItems.ScriptKey.Length > 0)
			{
				string icuScript, displayScript;
				Icu.UErrorCode err;
				StringUtils.InitIcuDataDir();	// initialize ICU data dir
				Icu.GetScriptCode(newLangInfo.LocaleItems.Locale, out icuScript, out err);

				if (newLangInfo.LocaleItems.ScriptKey != icuScript)
				{
					string script = newLangInfo.LocaleItems.ScriptKey;
					Icu.GetDisplayScript(newLangInfo.LocaleItems.Locale, "en", out displayScript, out err);

					string emsg = "For Locale " + newLangInfo.LocaleItems.Locale + ": ";
					emsg += "The script code <" + script +
						"> is mapping to the Icu code of <";
					emsg += icuScript + ">.  If you are specifying <" + displayScript;
					emsg += ">, please use <" + icuScript+ ">.  Otherwise, ";
					emsg += "please use a different script code.";
					LogFile.AddErrorLine(emsg);

					throw new LDExceptions(ErrorCodes.LDUsingISO3ScriptName, emsg);
				}
			}



			// Check for ICU country and actual locale country key : ISO
			if (newLangInfo.LocaleItems.CountryKey.Length > 0)
			{
				string icuCountry, displayCountry;
				Icu.UErrorCode err;
				StringUtils.InitIcuDataDir();	// initialize ICU data dir
				Icu.GetCountryCode(newLangInfo.LocaleItems.Locale, out icuCountry, out err);

				if (newLangInfo.LocaleItems.CountryKey != icuCountry)
				{
					string country = newLangInfo.LocaleItems.CountryKey;
					//					string isoCountry = GetISO3Country(newLangInfo.LocaleItems.Locale);
					Icu.GetDisplayCountry(newLangInfo.LocaleItems.Locale, "en",
						out displayCountry, out err);

					string emsg = "For Locale " + newLangInfo.LocaleItems.Locale + ": ";
					emsg += "The country code <" + country +
						"> is mapping to the Icu code of <";
					emsg += icuCountry + ">.  If you are specifying <" + displayCountry;
					emsg += ">, please use <" + icuCountry + ">.  Otherwise, ";
					emsg += "please use a different country code.";
					LogFile.AddErrorLine(emsg);

					throw new LDExceptions(ErrorCodes.LDUsingISO3CountryName, emsg);
				}
			}

			// Check for ICU language and actual locale language key
			if (newLangInfo.LocaleItems.LangKey.Length > 0)
			{
				string icuLanguage, displayLanguage;
				Icu.UErrorCode err;
				StringUtils.InitIcuDataDir();	// initialize ICU data dir
				Icu.GetLanguageCode(newLangInfo.LocaleItems.Locale, out icuLanguage, out err);

				if (newLangInfo.LocaleItems.LangKey != icuLanguage &&
					icuLanguage.Length > 0)
				{
					string language = newLangInfo.LocaleItems.LangKey;
					Icu.GetDisplayLanguage(newLangInfo.LocaleItems.Locale, "en",
						out displayLanguage, out err);

					string emsg = "For Locale " + newLangInfo.LocaleItems.Locale + ": ";
					emsg += "The language code <" + language +
						"> is mapping to the Icu code of <";
					emsg += icuLanguage + ">.  If you are specifying <" + displayLanguage;
					emsg += ">, please use <" + icuLanguage + ">.  Otherwise, ";
					emsg += "please use a different language code.";
					LogFile.AddErrorLine(emsg);

					throw new LDExceptions(ErrorCodes.LDUsingISO3LanguageName, emsg);
				}
			}

			// The icuSummary variables are only true if all the iculocales are true.
			// The icuAddToOne variables are true if any of the iculocales are false.
			bool icuSummaryLang = true, icuSummaryScript = true, icuSummaryCountry = true, icuSummaryVariant = true;
			bool icuAddToOneLang = false, icuAddToOneScript = false, icuAddToOneCountry = false, icuAddToOneVariant = false;
			foreach (ICUInfo info in icuInfo)
			{
				icuSummaryLang &= info.HasLanguage;
				icuSummaryScript &= info.HasScript;
				icuSummaryCountry &= info.HasCountry;
				icuSummaryVariant &= info.HasVariant;

				icuAddToOneLang |= !info.HasLanguage;
				icuAddToOneScript |= !info.HasScript;
				icuAddToOneCountry |= !info.HasCountry;
				icuAddToOneVariant |= !info.HasVariant;
			}

			// custom flags
			bool addToCLocale = !newLangInfo.HasLocale;
			bool addToCLanguage = !newLangInfo.HasLanguage && !icuSummaryLang;
			bool addToCScript = newLangInfo.LocaleItems.ScriptKey.Length > 0 && !newLangInfo.HasScript && !icuSummaryScript;
			bool addToCCountry = newLangInfo.LocaleItems.CountryKey.Length > 0 && !newLangInfo.HasCountry && !icuSummaryCountry;
			bool addToCVariant = newLangInfo.LocaleItems.VariantKey.Length>0 && !newLangInfo.HasVariant && !icuSummaryVariant;

			// A. ------------------------------------------------------------
			// Create the Original backups
			Generic.BackupOrig(rootTxtInput);
			Generic.BackupOrig(rootResInput);
			Generic.BackupOrig(resIndexTxtInput);
			Generic.BackupOrig(resIndexResInput);
			Generic.BackupOrig(xxTxtFile);
			Generic.BackupOrig(xxResFile);
			for (int iws = 0; iws < cwsNames; ++iws)
			{
				if (rgXxTxtFiles[iws] == null)
					continue;	// would match xxTxtFile
				Generic.BackupOrig(rgXxTxtFiles[iws]);
				Generic.BackupOrig(rgXxResFiles[iws]);
			}

			// B. ------------------------------------------------------------
			// Create the temporary files to serve as working copies
			string rootTxtTemp = Generic.CreateTempFile(rootTxtInput);	// root.txt
			string resIndexTxtTemp = Generic.CreateTempFile(resIndexTxtInput);	// res_index.txt
			string xxTxtTemp = Generic.CreateTempFile(xxTxtFile); // XX_YY_ZZ.txt

			AddTempFile(rootTxtTemp);
			AddTempFile(resIndexTxtTemp);
			AddTempFile(xxTxtTemp);

			string[] rgXxTxtTemps = new string[cwsNames];
			for (int iws = 0; iws < cwsNames; ++iws)
			{
				if (rgXxTxtFiles[iws] == null)
				{
					rgXxTxtTemps[iws] = null;	// (probably redundant...)
				}
				else
				{
					rgXxTxtTemps[iws] = Generic.CreateTempFile(rgXxTxtFiles[iws]);
					AddTempFile(rgXxTxtTemps[iws]);
				}
			}

			// C. ------------------------------------------------------------
			// Create the Undo-Restore backup files
			string rootTxtBackup = Generic.CreateBackupFile(rootTxtInput);
			string rootResBackup = Generic.CreateBackupFile(rootResInput);
			string resIndexTxtBackup = Generic.CreateBackupFile(resIndexTxtInput);
			string resIndexResBackup = Generic.CreateBackupFile(resIndexResInput);
			string xxTxtBackup = Generic.CreateBackupFile(xxTxtFile);
			string xxResBackup = Generic.CreateBackupFile(xxResFile);

			AddUndoFileFrame(rootTxtInput, rootTxtBackup);
			AddUndoFileFrame(rootResInput, rootResBackup);
			AddUndoFileFrame(resIndexTxtInput, resIndexTxtBackup);
			AddUndoFileFrame(resIndexResInput, resIndexResBackup);

			AddUndoFileFrame(xxTxtFile, xxTxtBackup);
			AddUndoFileFrame(xxResFile, xxResBackup);

			string[] rgXxTxtBackups = new string[cwsNames];
			string[] rgXxResBackups = new string[cwsNames];
			for (int iws = 0; iws < cwsNames; ++iws)
			{
				if (rgXxTxtFiles[iws] == null)
				{
					rgXxTxtBackups[iws] = null;		// (probably redundant...)
					rgXxResBackups[iws] = null;
				}
				else
				{
					rgXxTxtBackups[iws] = Generic.CreateBackupFile(rgXxTxtFiles[iws]);
					rgXxResBackups[iws] = Generic.CreateBackupFile(rgXxResFiles[iws]);
					AddUndoFileFrame(rgXxTxtFiles[iws], rgXxTxtBackups[iws]);
					AddUndoFileFrame(rgXxResFiles[iws], rgXxResBackups[iws]);
				}
			}

			int lineNumber;
			eAction er;

			// more logging information
			if (LogFile.IsLogging())	// put out some debuging info
			{
				LogFile.AddLine("The following changes are to be made to root.txt");
				LogFile.AddLine(" - Adding to Custom Locale  : " + addToCLocale.ToString());
				LogFile.AddLine(" - Adding to Custom Language: " + addToCLanguage.ToString());
				LogFile.AddLine(" - Adding to Custom Script  : " + addToCScript.ToString());
				LogFile.AddLine(" - Adding to Custom Country : " + addToCCountry.ToString());
				LogFile.AddLine(" - Adding to Custom Variant : " + addToCVariant.ToString());

				for (int iws = 0; iws < cwsNames; ++iws)
				{
					LogFile.AddLine("The following changes are to be made to " + rgXx[iws] + ".txt");
					LogFile.AddLine(" - Adding to ICU Language: " + (!icuInfo[iws].HasLanguage).ToString());

					LogFile.AddLine(" - Adding to ICU Script  : " + (newLangInfo.LocaleItems.ScriptKey.Length > 0 && !icuInfo[iws].HasScript).ToString());
					LogFile.AddLine(" - Adding to ICU Country : " + (newLangInfo.LocaleItems.CountryKey.Length > 0 && !icuInfo[iws].HasCountry).ToString());
					LogFile.AddLine(" - Adding to ICU Variant : " + (newLangInfo.LocaleItems.VariantKey.Length > 0 && !icuInfo[iws].HasVariant).ToString());
				}
			}

			//bool modifyCLanguage = false;
			//bool modifyCCountry = false;
			//bool modifyCVariant = false;
			//if (!addToCLanguage)
			//{
			//}
			//if (!addToCCountry)
			//{
			//}
			//if (!addToCVariant)
			//{
			//}

			// Add the custom resources to the root text input file
			// Those are children of 'root.Custom'
			if (addToCLocale || addToCLanguage || addToCScript || addToCCountry || addToCVariant ||	!newLangInfo.HasCustom)
			{
				if( !m_runSlow )
				{
					IcuDataNode rootNode = ICUDataFiles.ParsedFile(rootTxtInput);

					// If Custom doesn't exist, make it and it's four children
					if (new NodeSpecification("root","Custom").FindNode(rootNode,false) == null )
					{
						// Get the process name for the comment
						string exeName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;

						System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
						// the comment
						string comment = "";
						comment += m_StartComment + NL;
						comment += "// This section is maintained by the '" + exeName;
						comment += "' Application." + NL;
						// Note we can't use local culture info as Korean/Chinese, etc. will introduce utf-8
						// characters that will cause icu tools to fail.
						comment += "// Created: " + DateTime.Now.ToString("F", ci);

						IcuDataNode customNode = new IcuDataNode("Custom",rootNode,comment,m_EndComment + NL + NL);

						customNode.AddChildSmart(new IcuDataNode("LocalesAdded",customNode,"",""),false);
						customNode.AddChildSmart(new IcuDataNode("LanguagesAdded",customNode,"",""),false);
						customNode.AddChildSmart(new IcuDataNode("ScriptsAdded", customNode, "", ""), false);
						customNode.AddChildSmart(new IcuDataNode("CountriesAdded", customNode, "", ""), false);
						customNode.AddChildSmart(new IcuDataNode("VariantsAdded", customNode, "", ""), false);

						// Add custom to root
						ICUDataFiles.SetICUDataFileNode(rootTxtInput, new NodeSpecification("root"), customNode, true);
					}
					// Make all the Custom Nodes
					if (addToCLocale)
						ICUDataFiles.SetICUDataFileAttribute(rootTxtInput,
							new NodeSpecification("root","Custom","LocalesAdded"),
							newLangInfo.LocaleItems.Locale, m_comment);

					if (addToCLanguage)
					{
						IcuDataNode customNode = rootNode.Child("Custom");
						IcuDataNode addedNames = customNode.Child("LanguagesAdded");
						IcuDataNode dnXX = new IcuDataNode(newLangInfo.LocaleItems.LangKey, addedNames, "", "");
						addedNames.AddChildSmart(dnXX, false);
						for (int iws = 0; iws < cwsNames; ++iws)
						{
							if (!icuInfo[iws].HasLanguage)	// rgfAddToICULanguage[iws])
							{
								string xx = ((StringWithWs)m_ldData.Names[iws]).icuLocale;
								Debug.Assert(xx != m_ldData.NewLocale);
								Debug.Assert(rgXxTxtFiles[iws] != null);
								dnXX.AddAttributeSmart(
									new IcuDataNode.IcuDataAttribute(xx, ", //" + m_comment + NL, true));
							}
						}
					}

					if (addToCScript)
					{
						// If ScriptsAdded doesn't exist, make it
						if (new NodeSpecification("root", "Custom", "ScriptsAdded").FindNode(rootNode, false) == null)
						{
							// Get the process name for the comment
							string exeName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;

							System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
							// the comment
							string comment = "";
							comment += m_StartComment + NL;
							comment += "// This section is maintained by the '" + exeName;
							comment += "' Application." + NL;
							// Note we can't use local culture info as Korean/Chinese, etc. will introduce utf-8
							// characters that will cause icu tools to fail.
							comment += "// Created: " + DateTime.Now.ToString("F", ci);

							IcuDataNode customNode = rootNode.Child("Custom");
							customNode.AddChildSmart(new IcuDataNode("ScriptsAdded", customNode, "", ""), false);

							//// Add custom to root
							//ICUDataFiles.SetICUDataFileNode(rootTxtInput, new NodeSpecification("root"), customNode, true);
						}


						// first see if the script already exists, if so just add the icuLocale(s) to the attributes
						NodeSpecification scriptNodeSpec = new NodeSpecification("root", "Custom", "ScriptsAdded", newLangInfo.LocaleItems.ScriptKey);
						IcuDataNode scriptNode = scriptNodeSpec.FindNode(rootNode, false);
						if (scriptNode != null)
						{
							for (int iws = 0; iws < cwsNames; ++iws)
							{
								if (!icuInfo[iws].HasScript)
									scriptNode.AddAttribute(rgXx[iws], ", //" + m_comment + NL, true);
							}
						}
						else
						{
							IcuDataNode customNode = rootNode.Child("Custom");
							IcuDataNode addedNames = customNode.Child("ScriptsAdded");
							IcuDataNode dnXX = new IcuDataNode(newLangInfo.LocaleItems.ScriptKey, addedNames, "", "");
							addedNames.AddChildSmart(dnXX, false);
							for (int iws = 0; iws < cwsNames; ++iws)
							{
								if (!icuInfo[iws].HasScript)
								{
									string xx = ((StringWithWs)m_ldData.Names[iws]).icuLocale;
									Debug.Assert(xx != m_ldData.NewLocale);
									Debug.Assert(rgXxTxtFiles[iws] != null);
									dnXX.AddAttributeSmart(
										new IcuDataNode.IcuDataAttribute(xx, ", //" + m_comment + NL, true));
								}
							}
						}
					}

					if (addToCCountry)
					{
						// first see if the country already exists, if so just add the icuLocale(s) to the attributes
						NodeSpecification countryNodeSpec = new NodeSpecification("root", "Custom", "CountriesAdded", newLangInfo.LocaleItems.CountryKey);
						IcuDataNode countryNode = countryNodeSpec.FindNode(rootNode, false);
						if (countryNode != null)
						{
							for (int iws = 0; iws < cwsNames; ++iws)
							{
								if (!icuInfo[iws].HasCountry)
									countryNode.AddAttribute(rgXx[iws], ", //" + m_comment + NL, true);
							}
						}
						else
						{
							IcuDataNode customNode = rootNode.Child("Custom");
							IcuDataNode addedNames = customNode.Child("CountriesAdded");
							IcuDataNode dnXX = new IcuDataNode(newLangInfo.LocaleItems.CountryKey, addedNames, "", "");
							addedNames.AddChildSmart(dnXX, false);
							for (int iws = 0; iws < cwsNames; ++iws)
							{
								if (!icuInfo[iws].HasCountry)
								{
									string xx = ((StringWithWs)m_ldData.Names[iws]).icuLocale;
									Debug.Assert(xx != m_ldData.NewLocale);
									Debug.Assert(rgXxTxtFiles[iws] != null);
									dnXX.AddAttributeSmart(
										new IcuDataNode.IcuDataAttribute(xx, ", //" + m_comment + NL, true));
								}
							}
						}
					}

					if (addToCVariant)
					{
						// first see if the variant alredy exists, if so just add the icuLocale(s) to the attributes
						NodeSpecification variantNodeSpec = new NodeSpecification("root", "Custom", "VariantsAdded", newLangInfo.LocaleItems.VariantKey);
						IcuDataNode variantNode = variantNodeSpec.FindNode(rootNode, false);
						if (variantNode != null)
						{
							for (int iws = 0; iws < cwsNames; ++iws)
							{
								if (!icuInfo[iws].HasVariant)
									variantNode.AddAttribute(rgXx[iws], ", //" + m_comment + NL, true);
							}
						}
						else
						{

							IcuDataNode customNode = rootNode.Child("Custom");
							IcuDataNode addedNames = customNode.Child("VariantsAdded");
							IcuDataNode dnXX = new IcuDataNode(newLangInfo.LocaleItems.VariantKey, addedNames, "", "");
							addedNames.AddChildSmart(dnXX, false);
							for (int iws = 0; iws < cwsNames; ++iws)
							{
								if (!icuInfo[iws].HasVariant)
								{
									string xx = ((StringWithWs)m_ldData.Names[iws]).icuLocale;
									Debug.Assert(xx != m_ldData.NewLocale);
									Debug.Assert(rgXxTxtFiles[iws] != null);
									dnXX.AddAttributeSmart(
										new IcuDataNode.IcuDataAttribute(xx, ", //" + m_comment + NL, true));
								}
							}
						}
					}
				}
				else
				{
					// read in the root.txt file for custom resource processing
					string fileData = FileToString(rootTxtInput);

					// make sure the custom resource exists
					if (newLangInfo.HasCustom == false)
						AddCustomResource(ref fileData);

					if (addToCLocale)
						AddCustomLocale(ref fileData, newLangInfo.LocaleItems.Locale);

					if (addToCLanguage)
						AddCustomLanguage(ref fileData, newLangInfo.LocaleItems.LangKey);

					if (addToCScript)
						AddCustomScript(ref fileData, newLangInfo.LocaleItems.ScriptKey);

					if (addToCCountry)
						AddCustomCountry(ref fileData, newLangInfo.LocaleItems.CountryKey);

					if (addToCVariant)
						AddCustomVariant(ref fileData, newLangInfo.LocaleItems.VariantKey);

					StringToFile(rootTxtTemp, fileData);
					// put the file back out - with new custom resource changes
				}
			}

			// DN-246 Step #2
			// pull out the NewLocale data and create the new locale.txt file for writing
			if (m_ldData.NewLocale == string.Empty || m_ldData.NewLocale.Length <= 0)
			{
				// no NewLocale information - not valid
				throw new LDExceptions(ErrorCodes.NewLocaleFile);
			}

			// create the output file, replace previous if one already exists

			// DN-246 Step #3

			// Required data for locale file (in case base locale not defined)
			ReadAndHashString("    // Default Version" + NL +
				"    Version { \"1.0\" }" + NL);
			ReadAndHashString("    // Default to English" + NL +
				"    LocaleID:int { 0x09 }" + NL);

			string newLocaleAbbr_name = newLangInfo.LocaleItems.LangKey;
			string newLocaleAbbr_script = newLangInfo.LocaleItems.ScriptKey;
			string newLocaleAbbr_country = newLangInfo.LocaleItems.CountryKey;
			string newLocaleAbbr_variant = newLangInfo.LocaleItems.VariantKey;

			// If BaseLocale is populated in the LD file, fill the output file with information
			// from the source files for the BaseLocale name.
			// sample BaseLocale = "en_gb_EURO"
			if (m_ldData.BaseLocale != null && m_ldData.BaseLocale.Length > 0)
			{
				string baseName = "";
				string baseScript = "";
				string baseCountry = "";
				string baseVariant = "";
				string baseLocale = m_ldData.BaseLocale;

				ParseLocaleName(ref baseLocale, out baseName, out baseScript, out baseCountry,
					out baseVariant);

				// Read all of the base source locale files and write to the output file storage
				// area - m_entries.  Only write to the outputfile after this process is
				// method has completed sucessfully.

				string filename = m_localeDirectory;
				if (baseName.Length > 0)
				{
					filename += baseName;
					try
					{
						ReadAndHashLocaleFile(filename + ".txt");
					}
					catch
					{
						// just skip if the txt file doesn't exist - not required at this point
					}
				}
				filename += "_";
				if (baseScript.Length > 0)
				{
					filename += baseScript;
					try
					{
						ReadAndHashLocaleFile(filename + ".txt");
					}
					catch
					{
						// just skip if the txt file doesn't exist - not required at this point
					}
				}
				filename += "_";
				if (baseCountry.Length > 0)
				{
					filename += baseCountry;
					try
					{
						ReadAndHashLocaleFile(filename + ".txt");
					}
					catch
					{
						// just skip if the txt file doesn't exist - not required at this point
					}
				}
				filename += "_";
				if (baseVariant.Length > 0)
				{
					filename += baseVariant;
					try
					{
						ReadAndHashLocaleFile(filename + ".txt");
					}
					catch
					{
						// just skip if the txt file doesn't exist - not required at this point
					}
				}
			}
			else
			{
			}

			// DN-246 Step #4
			// Add LocaleResources to the output area - m_entries
			if (m_ldData.LocaleResources != null && m_ldData.LocaleResources.Length > 0)
			{
				ReadAndHashString(m_ldData.LocaleResources);
			}

			// Add The Locale ID value to the output area - m_entries
			if (m_ldData.LocaleWinLCID != null && m_ldData.LocaleWinLCID.Length > 0)
			{
				string IDLine = "    LocaleID:int { " + m_ldData.LocaleWinLCID + " }" + NL;
				ReadAndHashString(IDLine);
			}

			if( !m_runSlow )
				Generic.FileCopyWithLogging(rootTxtTemp, rootTxtInput, true);

			// DN-246 Step #5

			// This is where we update each XX.txt file with the needed locale properties: lang, country, variant.
			for (int iws = 0; iws < cwsNames; ++iws)
			{
				if (rgXxTxtFiles[iws] == null)
				{
					Debug.Assert(rgXx[iws] == m_ldData.NewLocale);
					Debug.Assert(icuInfo[iws].HasLanguage == false);	// rgfAddToICULanguage[iws] == false);
					continue;
				}
				bool fAddOrReplace = !icuInfo[iws].HasLanguage;
				if (!fAddOrReplace)
				{
					// Maybe we need to modify the value?
					string sNew = m_ldData.LocaleName;
					if (sNew != null && sNew.Length > 0)
					{
						string sOld = sNew;
						Icu.UErrorCode uerr = Icu.UErrorCode.U_ZERO_ERROR;
						Icu.GetDisplayName(m_ldData.NewLocale, rgXx[iws], out sOld, out uerr);
						if (uerr == Icu.UErrorCode.U_ZERO_ERROR)
							fAddOrReplace = (sNew != sOld);
					}
				}
				if (fAddOrReplace)
				{
					string name = m_ldData.LocaleName;
					if (name == null || name.Length <= 0 )
						name = newLocaleAbbr_name;

					ICUDataFiles.SetICUDataFileNode(rgXxTxtFiles[iws],
							new NodeSpecification(rgXx[iws], "Languages"),
							new IcuDataNode(newLocaleAbbr_name, name, "// " + m_comment),
							false);
				}
				// first Guess at adding the Script code
				fAddOrReplace = !icuInfo[iws].HasScript;
				if (!fAddOrReplace)
				{
					// Maybe we need to modify the value?
					string sNew = m_ldData.LocaleScript;
					if (sNew != null && sNew.Length > 0)
					{
						string sOld = sNew;
						Icu.UErrorCode uerr = Icu.UErrorCode.U_ZERO_ERROR;
						Icu.GetDisplayScript(m_ldData.NewLocale, rgXx[iws], out sOld, out uerr);
						if (uerr == Icu.UErrorCode.U_ZERO_ERROR)
							fAddOrReplace = (sNew != sOld);
					}
				}
				if (newLocaleAbbr_script.Length > 0 && fAddOrReplace)
				{
					string name = m_ldData.LocaleScript;
					if (name == null || name.Length <= 0)
						name = newLocaleAbbr_script;

					ICUDataFiles.SetICUDataFileNode(rgXxTxtFiles[iws],
							new NodeSpecification(rgXx[iws], "Scripts"),
							new IcuDataNode(newLocaleAbbr_script, name, "// " + m_comment), false);
				}
				// DN-246 Step #6
				fAddOrReplace = !icuInfo[iws].HasCountry;
				if (!fAddOrReplace)
				{
					// Maybe we need to modify the value?
					string sNew = m_ldData.LocaleCountry;
					if (sNew != null && sNew.Length > 0)
					{
						string sOld = sNew;
						Icu.UErrorCode uerr = Icu.UErrorCode.U_ZERO_ERROR;
						Icu.GetDisplayCountry(m_ldData.NewLocale, rgXx[iws], out sOld, out uerr);
						if (uerr == Icu.UErrorCode.U_ZERO_ERROR)
							fAddOrReplace = (sNew != sOld);
					}
				}
				if (newLocaleAbbr_country.Length > 0 && fAddOrReplace)
				{
					string name = m_ldData.LocaleCountry;
					if (name == null || name.Length <= 0 )
						name = newLocaleAbbr_country;

					ICUDataFiles.SetICUDataFileNode(rgXxTxtFiles[iws],
							new NodeSpecification(rgXx[iws],"Countries"),
							new IcuDataNode(newLocaleAbbr_country, name, "// " + m_comment),false);
				}
				// DN-246 Step #7
				fAddOrReplace = !icuInfo[iws].HasVariant;
				if (!fAddOrReplace)
				{
					// Maybe we need to modify the value?
					string sNew = m_ldData.LocaleVariant;
					if (sNew != null && sNew.Length > 0)
					{
						string sOld = sNew;
						Icu.UErrorCode uerr = Icu.UErrorCode.U_ZERO_ERROR;
						Icu.GetDisplayVariant(m_ldData.NewLocale, rgXx[iws], out sOld, out uerr);
						if (uerr == Icu.UErrorCode.U_ZERO_ERROR)
							fAddOrReplace = (sNew != sOld);
					}
				}
				if (newLocaleAbbr_variant.Length > 0 && fAddOrReplace)
				{
					string name = m_ldData.LocaleVariant;
					if (name == null || name.Length <= 0 )
						name = newLocaleAbbr_variant;

					ICUDataFiles.SetICUDataFileNode(rgXxTxtFiles[iws],
							new NodeSpecification(rgXx[iws],"Variants"),
							new IcuDataNode(newLocaleAbbr_variant, name, "// " + m_comment),false);
				}
			}


			// DN-246 Step #8

			// Produce the XXX.txt file.  Close the output file.
			WriteLocaleFile(m_ldData.NewLocale, xxTxtTemp);

			if( !m_runSlow )
			{
				ICUDataFiles.SetICUDataFileNode(resIndexTxtInput,
					new NodeSpecification("res_index:table(nofallback)","InstalledLocales"),
					new IcuDataNode(m_ldData.NewLocale, "", "// " + m_comment),false);
			}
			else
			{
				// Add to res_index.txt file if not already present.
				er = FindResource(resIndexTxtInput, "InstalledLocales", m_ldData.NewLocale, "",
					out lineNumber);
				ModifyFile(resIndexTxtInput, resIndexTxtTemp, lineNumber,
					"        " + m_ldData.NewLocale + " {\"\"}",	er, ErrorCodes.ResIndexFile);
			}

			if( !m_runSlow )
			{
				// Write all Files for all steps so far
				ICUDataFiles.WriteFiles();
				// Copy to the temp files because these are what we are going to use.
				Generic.FileCopyWithLogging(rootTxtInput,rootTxtTemp,true);
				Generic.FileCopyWithLogging(resIndexTxtInput,resIndexTxtTemp,true);
				for (int iws = 0; iws < cwsNames; ++iws)
				{
					if (rgXxTxtTemps[iws] != null)
						Generic.FileCopyWithLogging(rgXxTxtFiles[iws], rgXxTxtTemps[iws], true);
				}
			}

			// DN-246 Step #9 - generate .res files

			// Process all files together and catch errors.
			ArrayList Files = new ArrayList();
			Files.Add(resIndexTxtTemp);
			Files.Add(xxTxtTemp);
			Files.Add(rootTxtTemp);
			for (int iws = 0; iws < cwsNames; ++iws)
			{
				if (rgXxTxtTemps[iws] != null)
					Files.Add(rgXxTxtTemps[iws]);
			}
			GenerateResFile(Files, m_localeDirectory, m_icuBase + m_IcuData,
				ErrorCodes.GeneralFile, "InstallLDFile");
			Generic.FileCopyWithLogging(rootTxtTemp, rootTxtInput, true);
			Generic.FileCopyWithLogging(resIndexTxtTemp, resIndexTxtInput, true);
			Generic.FileCopyWithLogging(xxTxtTemp, xxTxtFile, true);
			for (int iws = 0; iws < cwsNames; ++iws)
			{
				if (rgXxTxtTemps[iws] != null)
					Generic.FileCopyWithLogging(rgXxTxtTemps[iws], rgXxTxtFiles[iws], true);
			}

			// FINAL STEP: Check for Collation information.
			string sColl = m_ldData.CollationElements;
			// Note, if we already have a collation file, we need to process it again in case
			// the user removed all collation elements to revert to the default collation.
			string colFile = m_collDirectory + m_ldData.NewLocale + ".txt";
			if (File.Exists(colFile) || sColl != null && sColl != "")
				InstallCollation();
			else if (m_ldData.BaseLocale != null && File.Exists(m_collDirectory + m_ldData.BaseLocale + ".txt"))
			{
				// make sure if it has a baselocale - and that has a collation - use it
				InstallCollation();
			}
		}
Example #11
0
		public ErrorCodes RemoveLocale(string locale)
		{
			ErrorCodes retVal = ErrorCodes.Success;	// hope for the best...
			LogFile.AddLine("Removing Locale: <" + locale + ">");

			try
			{
				// create the core 6 files:
				// root.txt, res_index.txt, xx.txt,
				// icu26ldt_root.res, icu26ldt_res_index.res, icu26ldt_xx.res
				//
				string rootTxtInput = m_localeDirectory + "root.txt";
				string resIndexTxtInput = m_localeDirectory + "res_index.txt";
				string rootResInput = m_icuBase + m_IcuData + "root.res";
				string resIndexResInput = m_icuBase + m_IcuData + "res_index.res";
				string xxTxtFile = m_localeDirectory + locale + ".txt";
				string xxCollTxtFile = m_collDirectory + locale + ".txt";
				string xxResFile = m_icuBase + m_IcuData + locale + ".res";
				string xxXMLFile = Path.Combine(
					DirectoryFinder.GetFWDataSubDirectory("Languages"), locale + ".xml");
				string [] icuLocale = new string[1];
				icuLocale[0] = "en";	// locale;

				// the root file text has to exist for this process to work - throw exception
				if (!File.Exists(rootTxtInput))
					throw new LDExceptions(ErrorCodes.RootTxt_FileNotFound);

				// the res index file has to exist for this process to work - throw exception
				if (!File.Exists(resIndexTxtInput))
					throw new LDExceptions(ErrorCodes.ResIndexTxt_FileNotFound);


				CustomResourceInfo newLangInfo = GetCustomResourceInfo(rootTxtInput, locale, icuLocale);

				if (LogFile.IsLogging())	// put out some debuging info
				{
					LogFile.AddLine("Locale  : <" + newLangInfo.LocaleItems.Locale + ">");
					LogFile.AddLine("Language: <" + newLangInfo.LocaleItems.LangKey + ">");
					LogFile.AddLine("Script  : <" + newLangInfo.LocaleItems.ScriptKey + ">");
					LogFile.AddLine("Country : <" + newLangInfo.LocaleItems.CountryKey + ">");
					LogFile.AddLine("Variant : <" + newLangInfo.LocaleItems.VariantKey + ">");

					string custom = "";
					if (newLangInfo.HasLocale)
						custom += " Locale";
					if (newLangInfo.HasLanguage)
						custom += " Language";
					if (newLangInfo.HasScript)
						custom += " Script";
					if (newLangInfo.HasCountry)
						custom += " Country";
					if (newLangInfo.HasVariant)
						custom += " Variant";
					if (custom.Length <= 0)
						custom = " None";

					LogFile.AddLine("Components that exist in the custom resource:" + custom);
				}

				// DN-246 1. see if it's a factory locale - if so, do Nothing, just return
				if (newLangInfo.HasLocale == false &&
					(File.Exists(xxTxtFile) || File.Exists(xxCollTxtFile)))
				{
					LogFile.AddLine("It's a factory Locale - remove only the XML file we created.");
					Generic.DeleteFile(xxXMLFile);
					return retVal;	// factory locale
				}
				else if (newLangInfo.HasCustom == false)	// no custom section, what to do...?
				{
					LogFile.AddLine("The root.txt file doesn't contain the Custom Resource section - remove only the XML file we created.");
					Generic.DeleteFile(xxXMLFile);
					return retVal;
				}

				// A.
				// Create the Original backups
				Generic.BackupOrig(rootTxtInput);
				Generic.BackupOrig(rootResInput);
				Generic.BackupOrig(resIndexTxtInput);
				Generic.BackupOrig(resIndexResInput);

				// B.
				// Create the temporary files for the input/output files

				// For the RootTxtInput file (root.txt) create a temp file and a backup up file.
				string rootTxtTemp = Generic.CreateTempFile(rootTxtInput);
				AddTempFile(rootTxtTemp);
				string rootTxtBackup = Generic.CreateBackupFile(rootTxtInput);
				AddUndoFileFrame(rootTxtInput, rootTxtBackup);

				// For the RootResInput file (icudt26l_root.res) create a backup up file.
				string rootResBackup = Generic.CreateBackupFile(rootResInput);
				AddUndoFileFrame(rootResInput, rootResBackup);

				// For the ResIndexTxt input file (res_index.txt) create a temp file and a backup up file.
				string resIndexTxtTemp = Generic.CreateTempFile(resIndexTxtInput);
				AddTempFile(resIndexTxtTemp);
				string resIndexTxtBackup = Generic.CreateBackupFile(resIndexTxtInput);
				AddUndoFileFrame(resIndexTxtInput, resIndexTxtBackup);

				// For the ResIndexRes input file (icudt26l_res_index.res) create a Backup file.
				string resIndexResBackup = Generic.CreateBackupFile(resIndexResInput);
				AddUndoFileFrame(resIndexResInput, resIndexResBackup);

				// For the RootTxtInput file (XX_YY_ZZ.txt) create a temp file and a backup up file.
				string xxTxtTemp = Generic.CreateTempFile(xxTxtFile);
				AddTempFile(xxTxtTemp);
				string xxTxtBackup = Generic.CreateBackupFile(xxTxtFile);
				AddUndoFileFrame(xxTxtFile, xxTxtBackup);

				// For the XX_YY_ZZ.res input file (icudt26l_XX_YY_ZZ.res) create a backup file.
				string xxResBackup = Generic.CreateBackupFile(xxResFile);
				AddUndoFileFrame(xxResFile, xxResBackup);


				// Create the list of files to use with "genrb"
				ArrayList Files = new ArrayList();
				Files.Add(resIndexTxtTemp);
				Files.Add(rootTxtTemp);

				if (newLangInfo.HasLocale || newLangInfo.HasLanguage ||
					newLangInfo.HasScript || newLangInfo.HasCountry || newLangInfo.HasVariant)
				{
					if (newLangInfo.HasLocale)
					{
						if (ICUDataFiles.RemoveICUDataFileAttribute(rootTxtTemp,	//rootTxtInput,
							new NodeSpecification("root", "Custom", "LocalesAdded"),
							newLangInfo.LocaleItems.Locale) >= 0)
						{
							LogFile.AddLine("Removed custom locale entry.");
						}
						else
							LogFile.AddLine("***Unable to remove custom locale entry.");

					}

					// Get a list of current custom LoacalesAdded and build usage counts for
					// future deletions.
					IcuDataNode rootTxtTempNode = ICUDataFiles.ParsedFile(rootTxtTemp);
					IcuDataNode customLocalesNode = new NodeSpecification("root", "Custom", "LocalesAdded").FindNode(rootTxtTempNode, false);
					if( customLocalesNode == null )
						throw new Exception("Couldn't find the locale to remove");

					int langCount=0, scriptCount=0, countryCount=0, variantCount=0;
					foreach (IcuDataNode.IcuDataAttribute attr in customLocalesNode.Attributes)
					{
						string lang, script, country, variant;
						string templocale = attr.StringValue;
						ParseLocaleName(ref templocale, out lang, out script, out country, out variant);
						if (newLangInfo.HasLanguage && newLangInfo.LocaleItems.LangKey == lang)
							langCount++;

						if (newLangInfo.HasScript && newLangInfo.LocaleItems.ScriptKey == script)
							scriptCount++;

						if (newLangInfo.HasCountry && newLangInfo.LocaleItems.CountryKey == country)
							countryCount++;

						if (newLangInfo.HasVariant && newLangInfo.LocaleItems.VariantKey == variant)
							variantCount++;
					}

					Hashtable lstOfxxFiles = new Hashtable();
					if (newLangInfo.HasVariant && variantCount == 0)
					{
						GetXXLangsForICULocalePortion(rootTxtTempNode, LocalePortion.Variant, newLangInfo.LocaleItems.VariantKey, ref lstOfxxFiles);
						LogFile.AddLine("Removed custom variant entry.");
					}

					if (newLangInfo.HasCountry && countryCount == 0)
					{
						GetXXLangsForICULocalePortion(rootTxtTempNode, LocalePortion.Country, newLangInfo.LocaleItems.CountryKey, ref lstOfxxFiles);
						LogFile.AddLine("Removed custom country entry.");
					}

					if (newLangInfo.HasScript && scriptCount == 0)
					{
						GetXXLangsForICULocalePortion(rootTxtTempNode, LocalePortion.Script, newLangInfo.LocaleItems.ScriptKey, ref lstOfxxFiles);
						LogFile.AddLine("Removed custom script entry.");
					}

					if (newLangInfo.HasLanguage && langCount == 0)
					{
						GetXXLangsForICULocalePortion(rootTxtTempNode, LocalePortion.Lang, newLangInfo.LocaleItems.LangKey, ref lstOfxxFiles);
						LogFile.AddLine("Removed custom language entry.");
					}

					ICUDataFiles.WriteFile(rootTxtTemp/*rootTxtInput*/);

					foreach (DictionaryEntry de in lstOfxxFiles)
					{
						// fill in the remaining infor relating to these xx.txt files
						xxFileInfo xxfi = de.Value as xxFileInfo;
						xxfi.txtName = m_localeDirectory + xxfi.xxName + ".txt";
						xxfi.resName = m_icuBase + m_IcuData + xxfi.xxName + ".res";

						// Create the original backups
						Generic.BackupOrig(xxfi.txtName);
						Generic.BackupOrig(xxfi.resName);

						xxfi.txtNameTemp = Generic.CreateTempFile(xxfi.txtName);
						AddTempFile(xxfi.txtNameTemp);
						Files.Add(xxfi.txtNameTemp);

						string txtBackup = Generic.CreateBackupFile(xxfi.txtName);
						AddUndoFileFrame(xxfi.txtName, txtBackup);

						string resBackup = Generic.CreateBackupFile(xxfi.resName);
						AddUndoFileFrame(xxfi.resName, resBackup);
					}

					// now we need to actually edit the lang.txt files (EX: "en")
					foreach (DictionaryEntry de in lstOfxxFiles)
					{
						xxFileInfo xxfi = de.Value as xxFileInfo;
						IcuDataNode xxNode = ICUDataFiles.ParsedFile(xxfi.txtNameTemp);

						// remove the locale portion from the xx.txt file ("en.txt")
						if (xxfi.rmFromLang)
						{
							if (!ICUDataFiles.RemoveICUDataFileChild(xxNode,
								new NodeSpecification(xxfi.xxName, "Languages"), xxfi.xxLangKey))
							{
								LogFile.AddVerboseLine("***Unable to remove <"+xxfi.xxLangKey+"> from the <Languages> section in " + xxfi.xxName + ".txt");
							}
						}
						if (xxfi.rmFromScript)
						{
							if (!ICUDataFiles.RemoveICUDataFileChild(xxNode,
								new NodeSpecification(xxfi.xxName, "Scripts"), xxfi.xxScriptKey))
							{
								LogFile.AddVerboseLine("***Unable to remove <" + xxfi.xxScriptKey + "> from the <Scripts> section in " + xxfi.xxName + ".txt");
							}
						}
						if (xxfi.rmFromCountry)
						{
							if (!ICUDataFiles.RemoveICUDataFileChild(xxNode,
								new NodeSpecification(xxfi.xxName, "Countries"), xxfi.xxCountryKey))
							{
								LogFile.AddVerboseLine("***Unable to remove <" + xxfi.xxCountryKey + "> from the <Countries> section in " + xxfi.xxName + ".txt");
							}
						}
						if (xxfi.rmFromVariant)
						{
							if (!ICUDataFiles.RemoveICUDataFileChild(xxNode,
								new NodeSpecification(xxfi.xxName, "Variants"), xxfi.xxVariantKey))
							{
								LogFile.AddVerboseLine("***Unable to remove <"+xxfi.xxVariantKey+"> from the <Variants> section in " + xxfi.xxName + ".txt");
							}
						}
						ICUDataFiles.WriteFileAs(xxfi.txtNameTemp, xxfi.txtNameTemp);
					}

					// put the file back out - with custom resource changes
					GenerateResFile(Files, m_localeDirectory, m_icuBase + m_IcuData,
						ErrorCodes.GeneralFile, "RemoveLocale");

					Generic.FileCopyWithLogging(rootTxtTemp, rootTxtInput, true);
					Generic.FileCopyWithLogging(resIndexTxtTemp, resIndexTxtInput, true);
					foreach (DictionaryEntry de in lstOfxxFiles)
					{
						xxFileInfo xxfi = de.Value as xxFileInfo;
						Generic.FileCopyWithLogging(xxfi.txtNameTemp, xxfi.txtName, true);
					}

					// Need to clean up by deleting all of the _TEMP files.
					// ALWAYS try to Remove the XXX.txt, XXX.res and XXX.xml files.
					Generic.DeleteFile(xxTxtFile);
					Generic.DeleteFile(xxResFile);
					Generic.DeleteFile(xxXMLFile);
					// remove the backup files from the undo/recover file name list
					RemoveBackupFiles();
					LogFile.AddErrorLine("--- Successfully removed Locale ---");
				}
				else
				{
					// ALWAYS try to Remove the XXX.txt, XXX.res and XXX.xml files.
					Generic.DeleteFile(xxTxtFile);
					Generic.DeleteFile(xxResFile);
					Generic.DeleteFile(xxXMLFile);
					// remove the backup files from the undo/recover file name list
					RemoveBackupFiles();
					LogFile.AddErrorLine("NOTE -- NO Locale Data to Remove.");
				}

				RemoveCollation(locale);

				RemoveTempFiles();
			}
			catch (LDExceptions e)
			{
				RestoreFiles();		// copy backup files to original files.
				retVal = e.ec;
				LogFile.AddErrorLine("LDException: " + e.ec.ToString() + "-" + Error.Text(e.ec));
				if (e.HasConstructorText)
					LogFile.AddErrorLine("LDException Msg: " + e.ConstructorText);
			}
			catch
			{
				retVal = ErrorCodes.NonspecificError;
				LogFile.AddErrorLine("Exception: " + retVal.ToString() + "-" + Error.Text(retVal));
				RestoreFiles();	// copy backup files to original files.
			}

			if (retVal == ErrorCodes.Success)
			{
				RemoveBackupFiles();
				LogFile.AddErrorLine("--- Success ---");
			}

			return retVal;
		}
Example #12
0
		private void GetXXLangsForICULocalePortion(IcuDataNode rootNode, LocalePortion portion, string localeKey, ref Hashtable xxFiles)
		{
			string customChild = LocalePortionAsString(portion);
			NodeSpecification node = new NodeSpecification("root", "Custom", customChild, localeKey);
			IcuDataNode dataNode = node.FindNode(rootNode, false);
			if (dataNode != null)
			{
				// get the list of xx.txt files to edit in this section
				foreach (IcuDataNode.IcuDataAttribute attr in dataNode.Attributes)
				{
					xxFileInfo xxFile;
					string xx = attr.StringValue;	// the lang code {ex: "en"}
					if (xxFiles.ContainsKey(xx))
					{
						xxFile = xxFiles[xx] as xxFileInfo;
					}
					else
					{
						xxFile = new xxFileInfo(xx);
						xxFiles[xx] = xxFile;
					}
					if (portion == LocalePortion.Variant)
					{
						xxFile.rmFromVariant = true;
						xxFile.xxVariantKey = localeKey;
					}
					else if (portion == LocalePortion.Lang)
					{
						xxFile.rmFromLang = true;
						xxFile.xxLangKey = localeKey;
					}
					else if (portion == LocalePortion.Script)
					{
						xxFile.rmFromScript = true;
						xxFile.xxScriptKey = localeKey;
					}
					else if (portion == LocalePortion.Country)
					{
						xxFile.rmFromCountry = true;
						xxFile.xxCountryKey = localeKey;
					}
				}
				// remove the key from the section of custom in root.txt
				if (!ICUDataFiles.RemoveICUDataFileChild(rootNode,
					new NodeSpecification("root", "Custom", customChild),
					localeKey))
				{
					LogFile.AddVerboseLine("***Unable to remove <"+localeKey+"> from the <"+customChild+"> section in the root.txt");
				}

			}
		}