Rename interpretor to interpreter.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / compiler / documentator / doc_lang.cpp
diff --git a/interpreter/preprocessor/faust-0.9.47mr3/compiler/documentator/doc_lang.cpp b/interpreter/preprocessor/faust-0.9.47mr3/compiler/documentator/doc_lang.cpp
new file mode 100644 (file)
index 0000000..41c8ff9
--- /dev/null
@@ -0,0 +1,262 @@
+/************************************************************************
+ ************************************************************************
+ 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);
+}
+
+