| /* --COPYRIGHT--,EPL |
| *Copyright (c) 2008 Texas Instruments and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Texas Instruments - initial implementation |
| * |
| * --/COPYRIGHT--*/ |
| /** |
| * ======== utils ======== |
| * |
| * utils is a global object that that encapsulates several utility |
| * functions useful in the startup script. By placing these functions |
| * in the utils object, we minimize the chance of name conflicts with |
| * other scripts. |
| *<P> |
| * These functions often take advantage of "environment" variable |
| * settings made by the tconf runtime:<P> |
| *<DD> config.rootDir - root directory of the tconf support |
| *<DD> config.path - path used to locate tconf components |
| *<P> |
| * The following environment variables are optionally specified on the |
| * command-line of tconf:<P> |
| *<DD> config.importPath - path used to search for imported files |
| * |
| * @see none |
| * |
| */ |
| var utils = {}; |
| |
| /* |
| * ======== utils.csd ======== |
| * The current script directory. |
| * |
| * utils.csd is always the directory of the script file that is currently |
| * being loaded; at any point in time there is always exactly one script |
| * file that is loading. Note that this file is not necessarily the same |
| * as the file containing the function currently executing. |
| * |
| * During the load of a script, the script can refer to its location and |
| * posibly load/read/write files relative to this location. When a |
| * function defined by the script runs, however, the directory of currently |
| * loading script (utils.csd) may not be the directory of the script where |
| * the function is defined. |
| * |
| * utils.csd is initialized by utils.init() below and is set to the |
| * directory containing the script being loaded just prior to loading the |
| * script and restored to its previous value after the loading completes. |
| * |
| * utils.csd always ends with a directory separator so that clients can |
| * simply append this string to the beginning of a relative path to obtain |
| * an absolute path; there is no need for clients to use a host platform |
| * specific directory separator. |
| */ |
| utils.csd = "./"; |
| |
| /* |
| * ======== utils.cwd ======== |
| * The current working directory. |
| * |
| * utils.cwd is the beginning point for file searches using the |
| * utils.findFile() function, when the path name begin with "./". |
| * |
| * The initial value of utils.cwd is the Java current working directory, |
| * which is a global constant within each JVM invocation. |
| * |
| * utils.cwd always ends with a directory separator so that clients can |
| * simply append this string to the beginning of a relative path to obtain |
| * an absolute path. |
| */ |
| utils.cwd = environment['user.dir'].replace(/\\/g, "/") + "/"; |
| |
| /* |
| * ======== utils.global ======== |
| * Save the top-most object. This object is the "global" object that |
| * contains all variables defined at the top level of the shell. |
| */ |
| utils.global = this; |
| |
| /* |
| * ======== utils.global.$trace ======== |
| * $trace must be available whenever a script is evaluated. This function |
| * is called from within scripts evaluated through load() and from within |
| * templates. Capsules get $trace attached to them, and that version masks |
| * the global $trace function. |
| * Whenever a Rhino evaluation function is invoked, $tracePath has to be set |
| * if this version of $trace is not masked. |
| */ |
| utils.global.$tracePath = "utils.tci"; |
| utils.global.$trace = function(inMsg, level, groups) { |
| var msg = utils.global.$tracePath + ": " + inMsg; |
| var pkg = utils.global.$tracePath.replace(/\//g, "."); |
| if (!level) { |
| level = 0; |
| } |
| |
| var groupsArr; |
| if (!groups) { |
| groupsArr = ["all"]; |
| } |
| else if (typeof(groups) == "string") { |
| groupsArr = [groups, "all"]; |
| } |
| else if (groups instanceof Array) { |
| groups.push("all"); |
| groupsArr = groups; |
| } |
| utils._tracePrint(msg, utils.global.$tracePath, pkg, groupsArr, level); |
| }; |
| |
| /* |
| * ======== utils.hasReportedError ======== |
| * The replacement for config.hasReportedError. |
| */ |
| utils.hasReportedError = function() |
| { |
| var cx = Packages.org.mozilla.javascript.Context.getCurrentContext(); |
| var er = cx.getErrorReporter(); |
| return (er.hasReportedError()); |
| }; |
| |
| /* |
| * ======== utils.loadedFiles ======== |
| * This table maintains all files that have been loaded. |
| */ |
| utils.loadedFiles = {}; |
| |
| /* If a user creates a variable 'load', it would break utils.load(), which |
| * calls load(). To avoid that problem, utils.load() calls utils.$$load(). |
| */ |
| utils.$$load = load; |
| |
| /** |
| * ======== utils.compareFiles ======== |
| * Compare two files and return true iff they are equal. |
| */ |
| utils.compareFiles = function(file, gold) |
| { |
| var status = true; |
| |
| var f, g; |
| try { |
| f = new java.io.BufferedReader(new java.io.FileReader(file)); |
| g = new java.io.BufferedReader(new java.io.FileReader(gold)); |
| } |
| catch (e) { |
| return (false); |
| } |
| |
| do { |
| var fline = f.readLine(); |
| var gline = g.readLine(); |
| if (("" + fline) != ("" + gline)) { // add "" to force string compare |
| status = false; |
| break; |
| } |
| } while (fline != null && gline != null); |
| |
| if (fline != null || gline != null) { |
| status = false; |
| } |
| |
| f.close(); /* close the files so we can delete them as necessary */ |
| g.close(); |
| |
| return (status); |
| }; |
| |
| /** |
| * ======== utils.deprecate ======== |
| */ |
| utils.deprecate = function(name) |
| { |
| print("remark: the function '" + name + "' has been deprecated."); |
| }; |
| |
| /** |
| * ======== utils.evaluateScript ======== |
| * Evaluate an XS script provided as an argument |
| * |
| * @param script - String containing the 'XS' script to be evaluated |
| * |
| * @return none |
| * |
| * @throws 'Error' exception in case of errors in interpreting the |
| * script. |
| */ |
| utils.evaluateScript = function(script) |
| { |
| try { |
| var cx = Packages.org.mozilla.javascript.Context.getCurrentContext(); |
| var rdr = new java.io.BufferedReader(new java.io.StringReader(script)); |
| Packages.config.Shell.evaluateLoad(cx, utils.global, rdr, "", 1); |
| } |
| finally { |
| rdr.close(); |
| } |
| }; |
| |
| /** |
| * ======== utils.exec ======== |
| * Execute an arbitrary shell command and optionally put output |
| * into a file. Both stderr and stdout are combined into a single output |
| * stream. |
| * |
| * @command command string to execute |
| * |
| * @param attrs optional set of attributes used to control the |
| * environment of the command:<P> |
| *<DD> envs - array of environment variable settings |
| *<DD> cwd - the command's current working directory |
| *<DD> outName - the name of the output file to create; if |
| * the file exists, output is appended to the |
| * end of the file. |
| * filter - regular expression used to filter command |
| * output |
| * |
| * @param status optional output parameter: if non-null, the following |
| * fields are set:<P> |
| *<DD> output - string containing all output from command |
| *<DD> exitStatus - exit status of the command |
| * |
| * @return command's exit status |
| */ |
| utils.exec = function(command, attrs, status) |
| { |
| |
| /* WARNING: loading xdc.tci and calling xdc functions induces circularity |
| * between utils and xdc objects. That may not be too important unless we |
| * ever decide to release Tconf without XDC ever again. |
| * XDC users should move to xdc.exec, but there is no deprecation notice |
| * here as of now, because there may be some more 5.xx releases, in which |
| * Tconf scripts are used. Tconf scripts have utils object available, but |
| * not xdc, so a deprecation warning would be confusing. |
| */ |
| |
| utils.importFile("xdc/xdc.tci"); |
| return (xdc.exec(command, attrs, status)); |
| }; |
| |
| /** |
| * ======== utils.findFile ======== |
| * |
| * Find the file name fileName along the path specified by |
| * <CODE>path</CODE>. If no path is specified, findFile looks |
| * along the path ".;config.path;config.rootDir/include; |
| * config.rootDir/packages;config.importPath". |
| * |
| * If fileName is absolute or begins with the string "./", then path is |
| * ignored and findFile returns null if the (as specified) file does not |
| * exist; otherwise it simply returns the file's name. |
| * |
| * @param fileName name of file to locate |
| * |
| * @param path optional path to use to search for fileName. If no path |
| * is specified, a default path of |
| * ". config.path config.rootDir/include config.rootDir/packages" |
| * is used, where config.path and config.rootDir are defined by |
| * tconf. |
| * |
| * @param pathSep optional character separating directories in path. If |
| * not specified pathSep defaults to the path separator |
| * defined by the Java runtime: path.separator. |
| * |
| * @return full path name of file found along path; otherwise |
| * null |
| * |
| * @see tconf |
| */ |
| utils.findFile = function (fileName, path, pathSep) |
| { |
| var fileSep = environment["file.separator"]; |
| |
| if (fileName == null || fileName == "") { |
| return (null); |
| } |
| |
| var file = new java.io.File(fileName); |
| |
| /* if file name is absolute, don't search path */ |
| if (file.isAbsolute()) { |
| return (file.exists() ? (file.getPath() + "") : null); |
| } |
| |
| /* ensure that fileName is a javascript string */ |
| fileName = String(fileName); |
| |
| /* if file name starts with "./", use utils.cwd */ |
| if (fileName[0] == '.' |
| && (fileName[1] == '/' || fileName[1] == '\\')) { |
| file = new java.io.File(utils.cwd, fileName); |
| return (file.exists() ? (file.getPath() + "") : null); |
| } |
| |
| /* if path separator is not supplied, assume host OS's default */ |
| if (pathSep == null) { |
| pathSep = environment["path.separator"]; |
| } |
| |
| /* if path argument is not supplied, create a default path */ |
| if (path == null) { |
| path = "." + pathSep + environment["config.path"] |
| + pathSep + environment["config.rootDir"] + "/include" |
| + pathSep + environment["config.rootDir"] + "/packages"; |
| var imp = environment["config.importPath"]; |
| if (imp != null) { |
| path += pathSep + imp.replace(/\s*;\s*/g, pathSep); |
| } |
| } |
| |
| /* search along path for specified file */ |
| var dirArray = path.split(pathSep); |
| for (var i = 0; i < dirArray.length; i++) { |
| var dir = (dirArray[i] == ".") ? utils.cwd : dirArray[i]; |
| file = new java.io.File(dir, fileName); |
| if (file.exists()) { |
| return (file.getCanonicalPath() + ""); /* + "" makes a JavaScript string*/ |
| } |
| } |
| |
| /* if file is not found, return null */ |
| return (null); |
| }; |
| |
| /** |
| * ======== utils.findPkgFile ======== |
| * |
| * Created qualified file name (concat package name with file name and |
| * replace '.' with '/') and then call utils.findFile() to find the file. |
| * |
| * @param pkgName name of package containing fileName |
| * |
| * @param fileName name of file to locate |
| * |
| * @param path optional path to use to search for fileName |
| * |
| * @param pathSep optional character separating directories in path |
| * |
| * @return full path name of file found along path; otherwise null |
| * |
| * @see tconf |
| */ |
| utils.findPkgFile = function(pkgName, fileName, path, pathSep) |
| { |
| if (pkgName == undefined) { |
| return (null); |
| } |
| |
| var base = utils.findFile(pkgName.replace(/\./g, '/') + '/' + fileName); |
| if (base == null) { |
| return (null); |
| } |
| |
| var apath = java.io.File(base).getAbsolutePath() + ""; |
| apath = apath.replace(/\\/g, "/"); |
| |
| return (apath); |
| }; |
| |
| /** |
| * ======== utils.importFile ======== |
| * Load the specified script. If the script file name is a relative |
| * path, utils.importFile searches for the file along the path: |
| * |
| * utils.csd;config.importPath;config.rootDir/include; |
| * config.rootDir/packages |
| * |
| * where utils.csd is the directory containing the script that calls |
| * utils.importFile, config.importPath is the path specified on the |
| * tconf command line, "config.rootDir/include" is the include |
| * sub-directory of the tconf installation directory, and |
| * "config.rootDir/packages" is the packages repository of the xdc |
| * installation directory. |
| * |
| * If pathPrefix is defined, the following path is used: |
| * |
| * pathPrefix;config.rootDir/include;config.rootDir/packages |
| * |
| * If neither pathPrefix nor config.importPath is defined the path |
| * defaults to: |
| * |
| * utils.csd;config.rootDir/include;config.rootDir/packages |
| * |
| * If the file name specified does not have an extension (e.g., |
| * "foo") and is not found along the path, the extensions ".tci" |
| * and ".js" are successively appended to the file name and the |
| * search is repeated. |
| * |
| * @param fileName name of the script to load |
| * @param pathPrefix optional search path (directories separated with ';') |
| * @param silent optional flag if false (or undefined), throw exception on |
| * error; otherwise return error string |
| * @param status optional object if non-null, status.name is set to the file |
| * name imported. |
| * @return string error message on error; otherwise null |
| */ |
| utils.importFile = function (fileName, pathPrefix, silent, status) |
| { |
| var tmp; |
| var path = utils.csd; |
| var err = null; |
| |
| /* build up path from arguments, importPath and rootDir/include */ |
| if (pathPrefix != null) { |
| path = pathPrefix; |
| } |
| else if (environment["config.importPath"] != null) { |
| path += ";" + environment["config.importPath"]; |
| } |
| if (environment["config.rootDir"] != null) { |
| path += ";" + environment["config.rootDir"] + "/include"; |
| path += ";" + environment["config.rootDir"] + "/packages"; |
| } |
| |
| utils._tracePrint("importFile: searching for " + fileName |
| + " along the path: " + path, "utils.tci"); |
| |
| /* look for file along path */ |
| if ((tmp = utils.findFile(fileName, path, ";")) == null) { |
| err = "Can't find import file: '" + fileName |
| + "' (not found along '" + path + "')"; |
| |
| /* if fileName doesn't have an extension, try suitable extensions */ |
| if (String(fileName).match(/.*\.(\w*)$/) == null) { |
| if ((tmp = utils.findFile(fileName + ".tci", path, ";")) != null |
| || (tmp = utils.findFile(fileName+".js", path, ";")) != null) { |
| err = null; |
| } |
| } |
| } |
| |
| if (tmp != null) { |
| /* the file was found, so load it up! */ |
| utils.load(tmp); |
| } |
| else { |
| if (silent == null || silent == false) { |
| throw new Error(err); |
| } |
| } |
| |
| /* return loaded file name, if requested */ |
| if (status != null) { |
| status.name = tmp; |
| } |
| |
| return (err); |
| }; |
| |
| /* |
| * ======== utils.importPkgFile ======== |
| */ |
| utils.importPkgFile = function(pkgName, fileName, sflg) |
| { |
| utils.importFile(pkgName.replace(/\./g, '/') + '/' + fileName, null, sflg); |
| }; |
| |
| /** |
| * ======== utils.init ======== |
| * Initialize the utils package. This function is called implicitly when |
| * loading utils.tci. |
| * |
| * @param void |
| * |
| * @return void |
| */ |
| utils.init = function () |
| { |
| /* remove leading and trailing spaces from the import path so that |
| * path searches don't have inadvertent spaces in file names |
| */ |
| var imp = environment["config.importPath"]; |
| if (imp != null) { |
| environment["config.importPath"] = imp.replace(/\s*;\s*/g, ";"); |
| } |
| |
| /* initialize the "current script directory", it must end with the |
| * directory separator |
| */ |
| utils.csd = environment["user.dir"] + '/'; |
| }; |
| |
| /* |
| * ======== utils.load ======== |
| * Load the specified script if it has not already been loaded. No |
| * searching is performed by this function. |
| * |
| * Note: All script loads must come through this function; we track the |
| * current script directory here and a "rogue" load will spoof |
| * utils.loadFile's ability to locate files relative to the current script. |
| */ |
| utils.load = function (name) |
| { |
| /* only load a file once */ |
| var uname = "" + (new java.io.File(name)).getCanonicalPath(); |
| if (utils.loadedFiles[uname] == null) { |
| utils.loadedFiles[uname] = String(name); |
| |
| /* load it using the built-in load function */ |
| var save = utils.csd; |
| utils.csd = uname.substr(0, uname.replace(/\\/g, '/').lastIndexOf('/')) + '/'; |
| var pathSave = utils.global.$tracePath; |
| utils.global.$tracePath = uname; |
| utils.$$load(uname); |
| utils.global.$tracePath = pathSave; |
| utils.csd = save; |
| } |
| }; |
| |
| /* |
| * ======== utils.loadCapsule ======== |
| * Load capsule specified by fname |
| * |
| * @param fname - string file name of the capsule to be loaded. The actual |
| * file used is determined as follows: |
| * 1. If fname is an absolute path or begins with "./" |
| * and exists, fname is used directly |
| * 2. If fname is a relative path that does not start |
| * with "./", then the following directories are |
| * searched in order: |
| * 1. the current script directory (see utils.csd()) |
| * 2. the directories specified by the XDC package |
| * path |
| * |
| * @param noTrack - if true, don't record this capsule in the list of |
| * loaded files |
| * |
| * @param searchPath - if set, the file is searched for on the supplied |
| * path |
| * |
| * @return capsule object |
| * |
| * @throws an Error exception if fname can not be found, or |
| * Exceptions due to syntax errors in the loaded capsule |
| */ |
| utils.$$capmap = {}; |
| utils.loadCapsule = function(fname, noTrack, searchPath) |
| { |
| /* get the package path from the local environment */ |
| var xdcpath = environment['xdc.path']; |
| |
| /* if not set in the local environment, derive it */ |
| if (xdcpath === undefined) { |
| /* use a temp instance of Env to compute the package path */ |
| var env = new Packages.xdc.services.global.Env(environment); |
| xdcpath = env.curpath(); |
| |
| /* undo the side-effect of setting xdc.path property, to avoid |
| * prematurely fixing the value of "^". |
| */ |
| env.properties.remove('xdc.path'); |
| } |
| |
| var spath = utils.csd + ';' + xdcpath; |
| if (searchPath != null) { |
| spath = searchPath; |
| } |
| |
| utils._tracePrint("loadCapsule: searching for " + fname |
| + " along the path: " + spath, "utils.tci"); |
| |
| var path = utils.findFile(fname, spath, ';'); |
| if (path == null) { |
| throw new Error("utils.loadCapsule: can't find '" + fname |
| + "' along the path '" + spath + "'"); |
| } |
| |
| var file = new java.io.File(path); |
| var cname = "" + file.getCanonicalPath(); |
| if (!file.isFile()) { |
| throw new Error("utils.loadCapsule: can't load capsule file '" + cname |
| + "': it's not an ordinary file"); |
| } |
| var cap = utils.$$capmap[cname]; |
| if (!cap) { |
| /* make sure that we record the fact that we depend on this capsule */ |
| if (!noTrack) { |
| utils.loadedFiles[cname] = path; |
| } |
| |
| /* setup utils.csd */ |
| var oldcsd = utils.csd; |
| utils.csd = file.getParentFile().getCanonicalPath(); |
| |
| /* create the capsule object */ |
| cap = { |
| prototype: utils.global, |
| $path: cname, |
| $private: {path: cname}, |
| $capsule: undefined /* set to cap below */ |
| }; |
| /* 'this.$capsule' is always cap object; even if 'this' is a Module */ |
| cap.$capsule = cap; |
| |
| /* set-up trace infrastructure */ |
| cap.$trace = function(inMsg, level, groups) { |
| var msg = this.$capsule.$path + ": " + inMsg; |
| var pkg = this.$capsule.$path.replace(/\//g, "."); |
| if (!level) { |
| level = 0; |
| } |
| |
| if (!groups) { |
| var groupsArr = ["all"]; |
| } |
| else if (typeof(groups) == "string") { |
| groupsArr = [groups, "all"]; |
| } |
| else if (groups instanceof Array) { |
| groups.push("all"); |
| groupsArr = groups; |
| } |
| |
| utils._tracePrint(msg, this.$capsule.$path, pkg, groupsArr, level); |
| }; |
| cap.$traceQuery = function(groups, lvl) { |
| if (lvl && utils.trace.level < lvl) { |
| /* default message level is 0 */ |
| return (false); |
| } |
| |
| if (utils._traceQuery(this.$capsule.$path, "capsule")) { |
| return (true); |
| } |
| else if (utils._traceQuery(this.$capsule.$path.replace(/\//g, "."), |
| "package")) { |
| return (true); |
| } |
| else if (groups) { |
| if (typeof(groups) == "string") { |
| return (utils._traceQuery(groups, "group")); |
| } |
| else { |
| for (var i = 0; i < groups.length; i++) { |
| if (utils._traceQuery(groups[i], "group")) { |
| return (true); |
| } |
| } |
| } |
| } |
| return (false); |
| }; |
| |
| /* load the capsule */ |
| try { |
| var cx = Packages.org.mozilla.javascript.Context.getCurrentContext(); |
| var rdr = new java.io.BufferedReader(new java.io.FileReader(cname)); |
| Packages.config.Shell.evaluateLoad(cx, cap, rdr, cname, 1); |
| } |
| finally { |
| |
| /* Close stream */ |
| if (rdr) { |
| rdr.close(); |
| } |
| |
| /* restore the current script directory */ |
| utils.csd = oldcsd; |
| |
| /* save the capsule object */ |
| utils.$$capmap[cname] = cap; |
| } |
| |
| } |
| |
| return (cap); |
| }; |
| |
| /** |
| * ======== utils.saveFile ======== |
| * Save string to a file only if the string differs from what is |
| * already in the file. |
| * |
| * @param content the contents of the file to save (in a string) |
| * @param fileName the name of the file to create/update (if necessary) |
| * @return true if the file was not updated; otherwise false |
| */ |
| utils.saveFile = function (content, fileName) |
| { |
| return (Packages.xdc.services.intern.xsr.Utils.saveFile(content, fileName)); |
| }; |
| |
| /** |
| * ======== utils.toHex ======== |
| * Convert a number to hexadecimal string. This function should be |
| * called in-lieu of toString(16) since ECMA states that different |
| * implementations of toString() may return different strings when the |
| * radix is not 10. |
| * |
| * @param num number to convert |
| * |
| * @return string string representation of num beginning with the |
| * characters '0x'. |
| * |
| * @see tconf |
| */ |
| utils.toHex = function (num) |
| { |
| if (typeof num != "number") { |
| throw new Error("utils.toHex passed a non-number ('" + num + "')"); |
| } |
| |
| /* make positive and integral */ |
| var sign = num < 0 ? -1 : 1; |
| num = Math.floor(sign * num); |
| |
| if (num == 0) { |
| return ("0x0"); |
| } |
| |
| /* generate one digit at a time */ |
| for (var hex = ""; num > 0; num = Math.floor(num / 16)) { |
| var digits = "0123456789abcdef"; |
| hex = digits[num % 16] + hex; |
| } |
| |
| return ((sign < 0 ? "-0x" : "0x") + hex); |
| }; |
| |
| /* |
| * ======== genDep ======== |
| * Generate dependency files determined by running a program configuration |
| * script. In particular, generate the following files: |
| * 1. base.dep - goals base.c base.h base.xdl: all files in list |
| * 2. base.inc - list of all files in list one per line for tar -I |
| * |
| * Note that these files are not modified if their contents do not change. |
| * And files not in the current working directory (or below) are ignored. |
| */ |
| utils.genDep = function (base, pkgName, list, content, goals) |
| { |
| goals = goals == null ? "" : (goals + " "); |
| |
| var cout = "#\n# The following is generated by utils.genDep for " |
| + base + "\n#\n"; |
| var ilist = []; /* list of dependencies in this package */ |
| var elist = []; /* list of dependencies external to this package */ |
| |
| /* separate files not in (or below) the current working directory */ |
| /* BUG: we should really be separating files into those that are in this |
| * package and those that are not (including those in nested packages!). |
| */ |
| var cwd = (new java.io.File(".")).getCanonicalPath() |
| + java.io.File.separator; |
| for (var fname in list) { |
| var tmp = "" + (new java.io.File(fname)).getCanonicalPath(); |
| if (tmp.indexOf(cwd) == 0) { |
| ilist[ilist.length] = tmp.substring(cwd.length).replace(/\\/g, "/"); |
| } |
| else { |
| elist[elist.length] = tmp.replace(/\\/g, "/").replace(/ /g, "\\ "); |
| } |
| } |
| |
| /* sort loaded files lists to ensure canonical output */ |
| ilist.sort(); |
| elist.sort(); |
| |
| if ((ilist.length + elist.length) > 0) { |
| /* generate dependencies on loaded files */ |
| cout += goals + base + ".c " + base + ".h " + base + ".xdl:"; |
| for (var i = 0; i < ilist.length; i++) { |
| cout += ilist[i] + " "; |
| } |
| for (var i = 0; i < elist.length; i++) { |
| cout += elist[i] + " "; |
| } |
| cout += "\n\n"; |
| } |
| |
| /* generate "empty" rules for external includes */ |
| if (elist.length > 0) { |
| for (var i = 0; i < elist.length; i++) { |
| /* |
| * This rule causes make to re-make any goal that depends on |
| * this file *if* make can not find the file; no rule |
| * causes make to believe that the file is updated, forcing |
| * any file that depends on these to be re-built. Rebuilding |
| * the *.c file re-runs the configuration which, in turn, |
| * re-generates the list of dependencies! |
| */ |
| cout += elist[i] + ":\n"; |
| } |
| cout += "\n\n"; |
| } |
| |
| /* add optional content */ |
| cout += content == null ? "" : content; |
| |
| /* generate the makefile dependency file */ |
| utils.saveFile(cout, base + ".dep"); |
| |
| /* generate a tar include file */ |
| cout = ""; |
| for (var i = 0; i < ilist.length; i++) { |
| cout += ilist[i] + "\n"; |
| } |
| |
| /* if inc file exists and is identical to cout, don't overwrite it */ |
| utils.saveFile(cout, base + ".xdc.inc"); |
| }; |
| |
| /* ----------------- trace support ----------------------------------- */ |
| |
| /* |
| * ======== utils.trace ======== |
| * |
| * This structure contains the list of capsules, packages and groups for |
| * which the trace is enabled. The trace is also filtered by the value of |
| * 'level'. All trace statements marked with a number lower or equal to the |
| * current 'level', and belonging to one of the enabled trace categories, |
| * are printed. |
| */ |
| utils.trace = { |
| capsuleList : [], |
| packageList : [], |
| groupList : [], |
| level: 0, |
| $maxLevel: 2 |
| }; |
| |
| /* |
| * ======== utils.setTraceLevel ======== |
| * Define how much trace is printed |
| * |
| * @param level higher integer number passed as a parameter |
| * enables more trace statements |
| */ |
| utils.setTraceLevel = function(n) |
| { |
| var cur = utils.trace.level; |
| utils.trace.level = n; |
| if (n > utils.trace.$maxLevel) { |
| utils.trace.level = utils.trace.$maxLevel; |
| } |
| else if (n < 0) { |
| utils.trace.level = 0; |
| } |
| return (cur); |
| }; |
| |
| |
| /* |
| * ======== utils.traceCapsuleEnable ======== |
| * Add a list of patterns to the list that will be matched against |
| * capsules calling $trace |
| */ |
| utils.traceCapsuleEnable = function(pat) |
| { |
| if (!("length" in pat)) { |
| print("Warning: utils.traceCapsuleEnable called with a non-array " |
| + " argument. The function call is ignored."); |
| return (undefined); |
| } |
| |
| var cur = []; |
| for (var i = 0; i < utils.trace.capsuleList.length; i++) { |
| cur[i] = utils.trace.capsuleList[i].source; |
| } |
| |
| if (pat.length > 0) { |
| utils.trace.capsuleList = []; |
| for (var i = 0; i < pat.length; i++) { |
| var rs = pat[i]; |
| if (rs.length > 0) { |
| /* allow either Unix or Windows separators in match */ |
| rs = rs.replace(/(\/|\\)/g, "(\\/|\\\\)"); |
| rs = rs.replace(/\*/g, "(\\w|\.)*"); |
| rs = "\\.*" + rs + "(\\.\\w*)?$"; |
| utils.trace.capsuleList.push(RegExp(rs)); |
| } |
| } |
| } |
| |
| return (cur); |
| }; |
| |
| /* |
| * ======== utils.tracePackageEnable ======== |
| * Add a list of patterns to the list that will be matched against |
| * packages calling $trace |
| */ |
| utils.tracePackageEnable = function(pat) |
| { |
| if (!("length" in pat)) { |
| print("Warning: utils.tracePackageEnable called with a non-array " |
| + " argument. The function call is ignored."); |
| return (undefined); |
| } |
| |
| var cur = []; |
| for (var i = 0; i < utils.trace.packageList.length; i++) { |
| cur[i] = utils.trace.packageList[i].source; |
| } |
| |
| if (pat.length > 0) { |
| utils.trace.packageList = []; |
| for (var i = 0; i < pat.length; i++) { |
| var rs = pat[i]; |
| if (rs.length > 0) { |
| utils.trace.packageList.push(RegExp(rs)); |
| } |
| } |
| } |
| |
| return (cur); |
| }; |
| |
| /* |
| * ======== utils.traceGroupEnable ======== |
| * Add a list of patterns to the list that will be matched against |
| * groups calling $trace |
| */ |
| utils.traceGroupEnable = function(pat) |
| { |
| if (!("length" in pat)) { |
| print("Warning: utils.traceGroupEnable called with a non-array " |
| + " argument. The function call is ignored."); |
| return (undefined); |
| } |
| |
| var cur = []; |
| for (var i = 0; i < utils.trace.groupList.length; i++) { |
| cur[i] = utils.trace.groupList[i].source; |
| } |
| |
| if (pat.length > 0) { |
| utils.trace.groupList = []; |
| for (var i = 0; i < pat.length; i++) { |
| var rs = pat[i]; |
| if (rs.length > 0) { |
| utils.trace.groupList.push(RegExp(rs)); |
| } |
| } |
| } |
| |
| return (cur); |
| }; |
| |
| /* |
| * ======== utils._traceQuery ======== |
| */ |
| utils._traceQuery = function(term, mode) |
| { |
| var prop = mode + "List"; |
| for (var i = 0; i < utils.trace[prop].length; i++) { |
| if (term.search(utils.trace[prop][i]) != -1) { |
| return (true); |
| } |
| } |
| |
| return (false); |
| }; |
| |
| /* |
| * ======== utils._tracePrint ======== |
| */ |
| utils._tracePrint = function(msg, path, pkg, groups, msgLevel) |
| { |
| if (utils.trace.level < msgLevel) { |
| return; |
| } |
| |
| if (utils._traceQuery(path, "capsule")) { |
| var fmt = new java.text.SimpleDateFormat("hh:mm:ss.SSS a"); |
| /* The code that generates 'addMsg' is repeated three times, for each |
| * traceQuery, for optimization reasons. When the trace is disabled, |
| * that code is never run, which saves time. |
| */ |
| var addMsg = ""; |
| if (groups != null) { |
| addMsg += " ("; |
| for (var i = 0; i < groups.length; i++) { |
| if (i != 0) { |
| addMsg += ", "; |
| } |
| addMsg += groups[i]; |
| } |
| addMsg += ")"; |
| } |
| print("TIME=" + fmt.format(new java.util.Date()) + " -- " + msg + |
| addMsg); |
| return; |
| } |
| if (pkg != null) { |
| if (utils._traceQuery(pkg, "package")) { |
| var fmt = new java.text.SimpleDateFormat("hh:mm:ss.SSS a"); |
| var addMsg = ""; |
| if (groups != null) { |
| addMsg += " ("; |
| for (var i = 0; i < groups.length; i++) { |
| if (i != 0) { |
| addMsg += ", "; |
| } |
| addMsg += groups[i]; |
| } |
| addMsg += ")"; |
| } |
| print("TIME=" + fmt.format(new java.util.Date()) + " -- " + msg + |
| addMsg); |
| return; |
| } |
| } |
| |
| if (groups != null) { |
| for (var i = 0; i < groups.length; i++) { |
| if (utils._traceQuery(groups[i], "group")) { |
| var fmt = new java.text.SimpleDateFormat("hh:mm:ss.SSS a"); |
| var addMsg = ""; |
| if (groups != null) { |
| addMsg += " ("; |
| for (var j = 0; j < groups.length; j++) { |
| if (j != 0) { |
| addMsg += ", "; |
| } |
| addMsg += groups[j]; |
| } |
| addMsg += ")"; |
| } |
| print("TIME=" + fmt.format(new java.util.Date()) + " -- " |
| + msg + addMsg); |
| return; |
| } |
| } |
| } |
| }; |
| |
| /* |
| * ======== initialize utils ======== |
| */ |
| utils.init(); |
| |
| /* |
| * Bind RTSC runtime to top-level scope (this scope may be a config.Shell |
| * or a org.mozilla.javascript.tools.Global object). |
| */ |
| try { |
| tmp = utils.findFile("xdc/services/global/java"); |
| if (tmp != null) { |
| addJars(tmp); |
| if ((tmp = utils.findFile("xdc/services/intern/xsr/java")) != null) { |
| addJars(tmp); |
| Packages.xdc.services.intern.xsr.Global.setTopScope(this); |
| } |
| else { |
| print("Warning: can't find xdc/services/intern/xsr/java"); |
| } |
| } |
| delete tmp; |
| } |
| catch (e) { |
| print("utils.js: " + e); /* we should never get here; should we fail?!?! */ |
| } |