--- /dev/null
+/************************************************************************
+ ************************************************************************
+ FAUST compiler
+ Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+
+#include <iostream>
+#include <fstream>
+#include <set>
+#include <string>
+#include <time.h>
+#include <cstdlib>
+#include <errno.h>
+
+#include "doc_lang.hh"
+#include "doc_notice.hh"
+#include "doc_autodoc.hh"
+#include "doc_metadatas.hh"
+#include "lateq.hh"
+#include "enrobage.hh"
+#include "compatibility.hh"
+
+
+
+extern map<string, string> gDocNoticeStringMap;
+extern set<string> gDocNoticeKeySet;
+
+extern map<string, string> gDocAutodocStringMap;
+extern set<string> gDocAutodocKeySet;
+
+extern map<string, string> gDocMathStringMap;
+extern set<string> gDocMathKeySet;
+
+extern map<string, string> gDocMetadatasStringMap;
+extern set<string> gDocMetadatasKeySet;
+
+static const string gDocTextsDefaultFile = "mathdoctexts-default.txt";
+
+static void importDocStrings(const string& filename);
+static void getKey(string& s, string& key, size_t& pt1);
+static void getText(string& s, size_t& pt1, string& text);
+static void storePair(const string& key, const string& text);
+
+static void printStringMapContent(map<string,string>& map, const string& name);
+
+static istream* openArchFile (const string& filename);
+static void getCurrentDir();
+static int cholddir();
+
+static string gCurrentDir; ///< Room to save current directory name.
+
+
+
+
+/*****************************************************************************
+ Public functions
+ *****************************************************************************/
+
+
+void loadTranslationFile(const string& lang)
+{
+ initDocMath();
+ initDocNotice();
+ initDocAutodoc();
+ initDocMetadatas();
+
+ /** First ensure that the default file is loaded a least. */
+ importDocStrings(gDocTextsDefaultFile);
+
+ /** Then try and load the target file. */
+ if ( ! lang.empty() ) {
+ importDocStrings( "mathdoctexts-" + lang + ".txt" );
+ }
+}
+
+
+
+/*****************************************************************************
+ Static functions
+ *****************************************************************************/
+
+
+
+/**
+ * @brief Feed the content of doc texts maps from a file.
+ *
+ * This mecchanism allows to load different files for translation.
+ *
+ * "mathdoctexts" files must have been formatted as follows :
+ * - a line beginning by ':' immediately declares a keyword,
+ * - a line beginning by '"' contains text until the last '"',
+ * - text can directly follow a keyword, if separated by one or
+ * many separator characters (space or tab).
+ * - a direct line break between two double quoted strings
+ * will insert a '\n' line break in the resulting notice string.
+ */
+static void importDocStrings(const string& filename)
+{
+ string s;
+ string key, text;
+ istream* file = openArchFile(filename);
+
+ while ( getline(*file, s) ) {
+ size_t pt1; // Text pointer.
+
+ /* The first character determines whether will follow a key or a text. */
+ switch (s[0]) {
+ case ':':
+ text = "";
+ getKey(s, key, pt1);
+ if (pt1==string::npos) continue;
+ break;
+ case '\"':
+ pt1 = 0;
+ break;
+ default:
+ continue;
+ }
+ getText(s, pt1, text);
+ storePair(key, text);
+ }
+ printStringMapContent(gDocNoticeStringMap, "gDocNoticeStringMap");
+ printStringMapContent(gDocAutodocStringMap, "gDocAutodocStringMap");
+ printStringMapContent(gDocMathStringMap, "gDocMathStringMap");
+ printStringMapContent(gDocMetadatasStringMap, "gDocMetadatasStringMap");
+}
+
+
+static void getKey(string& s, string& key, size_t& pt1)
+{
+ /* Initialisation. */
+ key = "";
+ string separators = " \t";
+ size_t pk1 = 1;
+ size_t pk2 = s.find_first_of(separators);
+
+ /* Immediate '\n' after keyword case. */
+ if (pk2==string::npos) pk2 = s.size();
+
+ /* Capture and check the keyword. */
+ key = s.substr(pk1, pk2-1);
+
+ /* Prepare text capture. */
+ pt1 = s.find_first_of("\"", pk2);
+}
+
+
+static void getText(string& s, size_t& pt1, string& text)
+{
+ /* Capture the text on the current line. */
+ size_t pt2;
+ pt2 = s.find_last_not_of("\"");
+ if (pt2!=string::npos) {
+ if (text.size() > 0) text += "\n"; // Handle line breaks.
+ text += s.substr(pt1+1, pt2-pt1);
+ }
+}
+
+
+static void storePair(const string& key, const string& text)
+{
+ /* Store the current pair. */
+ if(!key.empty() && !text.empty()) {
+
+ if (gDocNoticeKeySet.find(key) != gDocNoticeKeySet.end()) {
+ gDocNoticeStringMap[key] = text;
+ }
+ else if (gDocAutodocKeySet.find(key) != gDocAutodocKeySet.end()) {
+ gDocAutodocStringMap[key] = text;
+ }
+ else if (gDocMathKeySet.find(key) != gDocMathKeySet.end()) {
+ gDocMathStringMap[key] = text;
+ }
+ else if (gDocMetadatasKeySet.find(key) != gDocMetadatasKeySet.end()) {
+ gDocMetadatasStringMap[key] = text;
+ }
+ else {
+ cerr << "Documentator : importDocStings : " << "warning : unknown key \"" << key << "\"" << endl;
+ }
+ //cerr << "gDocNoticeStringMap[\"" << key << "\"] = \"" << gDocNoticeStringMap[key] << "\"" << endl;
+ }
+}
+
+
+/**
+ * Simple trace function.
+ */
+static void printStringMapContent(map<string,string>& m, const string& name) {
+ bool trace = false;
+ if(trace) {
+ cout << name << ".size() = " << m.size() << endl;
+ map<string,string>::iterator it;
+ int i = 1;
+ for(it = m.begin(); it!=m.end(); ++it)
+ cout << i++ << ".\t" << name << "[" << it->first << "] \t= '" << it->second << "'" << endl;
+ }
+}
+
+
+
+
+//------------------------ file managment -------------------------
+
+
+/**
+ * Open architecture file.
+ */
+static istream* openArchFile (const string& filename)
+{
+ istream* file;
+ getCurrentDir(); // Save the current directory.
+ if ( (file = open_arch_stream(filename.c_str())) ) {
+ //cerr << "Documentator : openArchFile : Opening '" << filename << "'" << endl;
+ } else {
+ cerr << "ERROR : can't open architecture file " << filename << endl;
+ exit(1);
+ }
+ cholddir(); // Return to current directory.
+ return file;
+}
+
+
+/**
+ * Switch back to the previously stored current directory
+ */
+static int cholddir ()
+{
+ if (chdir(gCurrentDir.c_str()) == 0) {
+ return 0;
+ } else {
+ perror("cholddir");
+ exit(errno);
+ }
+}
+
+
+/**
+ * Get current directory and store it in gCurrentDir.
+ */
+static void getCurrentDir ()
+{
+ char buffer[FAUST_PATH_MAX];
+ gCurrentDir = getcwd (buffer, FAUST_PATH_MAX);
+}
+
+