/// <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)); }
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); }
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); }
/// <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; }
/// <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); }
/// ------------------------------------------------------------------------------------ /// <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); }
/// <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); }
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); }
/// <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; } }
/// <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(); } }
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; }
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"); } } }