(.+)<\/ProjectName>/);
if (filename) {
//return only first item of regexp
return filename[1];
} else {
//There is no specified ProjectName, thus use filename without extension as our langpack name
return FSO.GetBaseName(plugin_project_file);
}
}
//Get MUUID of plugin from source file.
function GetMUUID (folder,array) {
//first, find necessary file list, we are looking for UNICODE_AWARE function, usually this function are in *.cpp, sometimes in *.c and *.h
//init fillelist array
muuidfilelist=new Array();
//search for files in "folder" by mask, put result into muuidfilelist
FindFiles (folder,"\\.cpp$|\\.c$|\\.h$",muuidfilelist);
//now we have files, let's put them to Enumerator
filesenum=new Enumerator(muuidfilelist);
//cycle through file list and lookup each file for UNICODE_AWARE
while (!filesenum.atEnd()) {
//curfile is our current file in files enumerator
curfile=filesenum.item();
//If file not zero size, read it and do the job
if (FSO.GetFile(curfile).Size!=0) {
//open file as text stream
file_stream=FSO.GetFile(curfile).OpenAsTextStream(ForReading, TristateUseDefault);
//this is a regexp to search UNICODE_AWARE
var find=/(?:UNICODE_AWARE,[\s\S]*?\{)(.+?)(?=\}\s{0,2}\})/g;
//read file fully into var "allstrings"
allstrings=file_stream.ReadAll();
//search regexp in "allstrings" and put results into var "string"
string=find.exec(allstrings);
//if current file have found UNICODE_AWARE, var "string" exists, so parse it.
if (string) {
//remove spaces, "0x" and "{", in second [1] item of array "string". RegExp "find" have subregexp (.+?), which are our MUUID in "string[1]"
vals=string[1].replace(/0x|\{|\x20/g,"");
//now split values of muuid in "vals" by "," into array "values"
values=vals.split(",");
//we get array of values, if length of this array not equal to 12 values (starting from zero, thus length is 11), that's mean we found something else, not MUUID. Log it and quit, if length is 12, so check it and generate MUUID
if (values.length==11) {
//now check, is there some values, which have omitted zero after 0x, like in alarms: " 0x4dd7762b, 0xd612, 0x4f84, { 0xaa, 0x86, 0x(no_zero_here_)6, 0x8f, 0x17, 0x85, 0x9b, 0x6d}"
//first value in values have to be 8 bytes, while length less than 8, add leading "0" to values[0],
while (values[0].length<8) {values[0]="0"+values[0]};
//next two values have to be 4 bytes, adding leading zeroes, while length less than 4.
for (i=1;i<=2;i++) {
while (values[i].length<4) {
values[i]="0"+values[i];
}
}
//other values have to be 2 bytes, same as above, adding zeroes
for (i=3;i<=10;i++) {
while (values[i].length<2) {
values[i]="0"+values[i];
}
}
//Push to array founded #muuid
var muuid="#muuid {"+values[0]+"-"+values[1]+"-"+values[2]+"-"+values[3]+values[4]+"-"+values[5]+values[6]+values[7]+values[8]+values[9]+values[10]+"}";
};
};
//close file
file_stream.Close();
}
//move to next file
filesenum.moveNext();
};
//if we didn't find muuid, put alarm into "muuid"
if (!muuid) {muuid=";#muuid not found, please specify manually!"}
//output result into array
array.push(muuid)
//log output
if (log=="yes") WScript.Echo(muuid);
};
//Parsing filelist into stringsarray by parsefunction (ParseSourceFile OR ParseRCFile)
function ParseFiles (filelist,stringsarray, parsefunction) {
//create enumerator filesenum from filelist
filesenum=new Enumerator(filelist);
//cycle through file list
while (!filesenum.atEnd()) {
//record into current_strings current length of stringsarray
var current_strings=stringsarray.length;
//curfile is our current file in files enumerator
curfile=filesenum.item();
//now apply a parsing function to current file, and put result into stringsarray
parsefunction(curfile,stringsarray);
//string variable to cut out a trunkPath from absolute path
curfilepath=new String(curfile);
//if after parsing file our stringsarray length greater then var "current_strings", so parsed file return some strings. Thus, we need add a comment with filename
if (stringsarray.length>current_strings) stringsarray.splice(current_strings,0,";file "+curfilepath.substring(trunkPath.length));
//move to next file
filesenum.moveNext();
};
}
//*.RC files line-by-line parser for RC_File, return result into "array"
function ParseRCFile(RC_File,array) {
//If file zero size, return;
if (FSO.GetFile(RC_File).Size==0) return;
//reading current file
RC_File_stream=RC_File.OpenAsTextStream(ForReading, TristateUseDefault);
//Reading line-by-line
while (!RC_File_stream.AtEndOfStream) {
//Init regexp array for getting only $1 from regexp search
regexpstring=new Array();
//clear up variable
stringtolangpack="";
//read on line into rcline
rcline=RC_File_stream.ReadLine();
//find string to translate in rcline by regexp
regexpstring=rcline.match(/\s*(?:CONTROL|(?:DEF)?PUSHBUTTON|[LRC]TEXT|GROUPBOX|CAPTION|MENUITEM|POPUP)\s*\"([^\"]+(\"\")?[^\"]*(\"\")?[^\"]*)\"\,/);
// if exist regexpstring, do checks, double "" removal and add strings to array
if (regexpstring) {
// check for some garbage like "List1","Tab1" etc. in *.rc files, we do not need this.
switch (regexpstring[1]) {
case "List1": {break};
case "List2": {break};
case "Tab1": {break};
case "Tree1": {break};
case "Tree2": {break};
case "Spin1": {break};
case "Spin2": {break};
case "Spin5": {break};
case "Custom1": {break};
case "Custom2": {break};
case "Slider1": {break};
case "Slider2": {break};
//default action is to wrote text inside quoted into array
default:
//if there is double "", replace with single one
stringtolangpack=regexpstring[1].replace(/\"{2}/g,"\"");
//add string to array
array.push("["+stringtolangpack+"]");
}
}
}
//closing file
RC_File_stream.Close();
};
//Source files C++ (*.h,*.c,*.cpp) and *.pas,*.dpr,*.inc (Pascal) multiline parser for translations using LPGEN() LPGENT() TranslateT() Translate() _T() TranslateW()
function ParseSourceFile (SourceFile,array) {
//If file zero size, return;
if (FSO.GetFile(SourceFile).Size==0) return;
//open file
sourcefile_stream=FSO.GetFile(SourceFile).OpenAsTextStream(ForReading, TristateUseDefault);
//this is final great regexp ever /(?:LPGENT?|Translate[TW]?|_T)(?:[\s])*?(?:\(['"])([\S\s]*?)(?=["']\x20*?\))/mg
//not store ?: functions LPGEN or LPGENT? or Translate(T or W) or _T, than any unnecessary space \s, than not stored ?: "(" followed by ' or " than \S\s - magic with multiline capture, ending with not stored ?= " or ', than none or few spaces \x20 followed by )/m=multiline g=global
var find= /(?:LPGENT?|Translate[TW]?|_T)(?:[\s])*?(?:\(['"])([\S\s]*?)(?=["'],?\x20*?(?:tmp)?\))/mg;
//read file fully into var
allstrings=sourcefile_stream.ReadAll();
//now make a job, till end of matching regexp
while ((string = find.exec(allstrings)) != null) {
//first, init empty var
var string;
//replace newlines with \r\n in second [1] subregexp ([\S\s]*?), Delphi newlines "'#13#10+" also replace
onestring=string[1].replace(/'?(\#13\#10)*?\+?\r\n(\x20*?\')?/g,"\\r\\n");
//remove escape slashes before ' and "
stringtolangpack=onestring.replace(/\\(['"])/g,"$1");
//if our string still exist, and length more than 2 symbol (nothing to translate if only two symbols, well, except No and OK, but they are in core. But dozens crap with variables are filtered)
if (stringtolangpack.length>2) {
//brand new _T() crap filtering engine :)
clearstring=filter_T(stringtolangpack);
//finally put string into array including cover []
if (clearstring) {array.push("["+clearstring+"]")}};
}
//close file, we've finish.
sourcefile_stream.Close();
};
//filter _T() function results
function filter_T(string) {
//filter not begin with symbols :.-[]"?;#~{!/_+$
var filter1=/^[^\:\-\[\]\"\?\;\#\~\|\{\!\/\_\+\\$].+$/g;
//filter string starting from following words
var filter2=/^(?:(SOFTWARE\\|SYSTEM\\|http|ftp|UTF-|utf-|TEXT|EXE|exe|txt|css|html|dat|txt|MS\x20|CLVM|TM_|CLCB|CLSID|CLUI|d\x20|HKEY_|DWORD|WORD|BYTE|MButton|BUTTON|WindowClass|MHeader|RichEdit|RICHEDIT|STATIC|EDIT|CList|\d|listbox|LISTBOX|combobox|COMBOBOX|TitleB|std\w|iso-|windows-||\w\\\w|urn\:|<\?xml|<\!|h\d|%s[%\-\\]|\.!\.)).*$/g;
//filter string ending with following words
var filter3=/^.+(\.\w{2,4}|001|\/value|\*!\*|=)$/g;
test1=filter1.test(string);
test2=filter2.test(string);
test3=filter3.test(string);
//WScript.Echo(string+" 1: "+test1);
//WScript.Echo(string+" 2: "+test2);
if (test1 && !test2 && !test3) {
return string;
} else return;
};
//Parse Version.h file to get one translated stirng from "Description" and make a pluging template header.
function ParseVersion_h (VersionFile,array) {
//If file zero size, return;
if (!FSO.GetFileName(VersionFile)) return;
//open file
versionfile_stream=FSO.GetFile(VersionFile).OpenAsTextStream(ForReading, TristateUseDefault);
//read file fully into var
allstrings=versionfile_stream.ReadAll();
//define RegExp for var defines.
var filename=/(?:#define\s+__FILENAME\s+")(.+)(?=")/m;
var pluginname=/(?:#define\s+__PLUGIN_NAME\s+")(.+)(?=")/i;
var author=/(?:#define\s+__AUTHOR\s+")(.+)(?=")/i;
var MAJOR_VERSION=/(?:#define\s+__MAJOR_VERSION\s+)(\d+)/i;
var MINOR_VERSION=/(?:#define\s+__MINOR_VERSION\s+)(\d+)/i;
var RELEASE_NUM=/(?:#define\s+__RELEASE_NUM\s+)(\d+)/i;
var BUILD_NUM=/(?:#define\s+__BUILD_NUM\s+)(\d+)/i;
var description=/(?:#define\s+__DESCRIPTION\s+")(.+)(?=")/i;
//exec RegExps
filename=filename.exec(allstrings);
pluginname=pluginname.exec(allstrings);
MAJOR_VERSION=MAJOR_VERSION.exec(allstrings);
MINOR_VERSION=MINOR_VERSION.exec(allstrings);
RELEASE_NUM=RELEASE_NUM.exec(allstrings);
BUILD_NUM=BUILD_NUM.exec(allstrings);
author=author.exec(allstrings);
description=description.exec(allstrings);
//add a header start mark
array.push(";============================================================");
//push results of regexp vars into array
if (filename) array.push("; File: "+filename[1]); else array.push("; File: "+plugin+".dll");
if (pluginname) array.push("; Plugin: "+pluginname[1]); else array.push("; Plugin: "+plugin);
if (MAJOR_VERSION) array.push("; Version: "+MAJOR_VERSION[1]+"."+MINOR_VERSION[1]+"."+RELEASE_NUM[1]+"."+BUILD_NUM[1]); else array.push("; Version: x.x.x.x");
if (author) array.push("; Authors: "+author[1]); else array.push("; Authors: ");
//add a header end mark
array.push(";============================================================");
if (description) array.push("["+description[1]+"]");
//close file
versionfile_stream.Close();
}
//Removes duplicates, not mine, found at http://dreaminginjavascript.wordpress.com/2008/08/22/eliminating-duplicates/
function eliminateDuplicates(arr) {
var i,
len=arr.length,
out=[],
obj={};
for (i=0;i