Beispiel #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));
		}
Beispiel #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);
		}
Beispiel #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);
		}
Beispiel #4
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);
		}
Beispiel #5
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;
		}
Beispiel #6
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);
		}
Beispiel #7
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();
			}
		}
Beispiel #8
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");
				}

			}
		}