Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/devtools/shared/node-properties/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 18 kB image not shown  

SSL node-properties.js   Sprache: JAVA

 
/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Gabriel Llamas
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */


"use strict";

var hex = function (c){
  switch (c){
    case "0"return 0;
    case "1"return 1;
    case "2"return 2;
    case "3"return 3;
    case "4"return 4;
    case "5"return 5;
    case "6"return 6;
    case "7"return 7;
    case "8"return 8;
    case "9"return 9;
    case "a"case "A"return 10;
    case "b"case "B"return 11;
    case "c"case "C"return 12;
    case "d"case "D"return 13;
    case "e"case "E"return 14;
    case "f"case "F"return 15;
  }
};

var parse = function (data, options, handlers, control){
  var c;
  var code;
  var escape;
  var skipSpace = true;
  var isCommentLine;
  var isSectionLine;
  var newLine = true;
  var multiLine;
  var isKey = true;
  var key = "";
  var value = "";
  var section;
  var unicode;
  var unicodeRemaining;
  var escapingUnicode;
  var keySpace;
  var sep;
  var ignoreLine;

  var line = function (){
    if (key || value || sep){
      handlers.line (key, value);
      key = "";
      value = "";
      sep = false;
    }
  };

  var escapeString = function (key, c, code){
    if (escapingUnicode && unicodeRemaining){
      unicode = (unicode << 4) + hex (c);
      if (--unicodeRemaining) return key;
      escape = false;
      escapingUnicode = false;
      return key + String.fromCharCode (unicode);
    }

    //code 117: u
    if (code === 117){
      unicode = 0;
      escapingUnicode = true;
      unicodeRemaining = 4;
      return key;
    }

    escape = false;

    //code 116: t
    //code 114: r
    //code 110: n
    //code 102: f
    if (code === 116) return key + "\t";
    else if (code === 114) return key + "\r";
    else if (code === 110) return key + "\n";
    else if (code === 102) return key + "\f";

    return key + c;
  };

  var isComment;
  var isSeparator;

  if (options._strict){
    isComment = function (c, code, options){
      return options._comments[c];
    };

    isSeparator = function (c, code, options){
      return options._separators[c];
    };
  }else{
    isComment = function (c, code, options){
      //code 35: #
      //code 33: !
      return code === 35 || code === 33 || options._comments[c];
    };

    isSeparator = function (c, code, options){
      //code 61: =
      //code 58: :
      return code === 61 || code === 58 || options._separators[c];
    };
  }

  for (var i=~~control.resume; i<data.length; i++){
    if (control.abort) return;
    if (control.pause){
      //The next index is always the start of a new line, it's a like a fresh
      //start, there's no need to save the current state
      control.resume = i;
      return;
    }

    c = data[i];
    code = data.charCodeAt (i);

    //code 13: \r
    if (code === 13) continue;

    if (isCommentLine){
      //code 10: \n
      if (code === 10){
        isCommentLine = false;
        newLine = true;
        skipSpace = true;
      }
      continue;
    }

    //code 93: ]
    if (isSectionLine && code === 93){
      handlers.section (section);
      //Ignore chars after the section in the same line
      ignoreLine = true;
      continue;
    }

    if (skipSpace){
      //code 32: " " (space)
      //code 9: \t
      //code 12: \f
      if (code === 32 || code === 9 || code === 12){
        continue;
      }
      //code 10: \n
      if (!multiLine && code === 10){
        //Empty line or key w/ separator and w/o value
        isKey = true;
        keySpace = false;
        newLine = true;
        line ();
        continue;
      }
      skipSpace = false;
      multiLine = false;
    }

    if (newLine){
      newLine = false;
      if (isComment (c, code, options)){
        isCommentLine = true;
        continue;
      }
      //code 91: [
      if (options.sections && code === 91){
        section = "";
        isSectionLine = true;
        control.skipSection = false;
        continue;
      }
    }

    //code 10: \n
    if (code !== 10){
      if (control.skipSection || ignoreLine) continue;

      if (!isSectionLine){
        if (!escape && isKey && isSeparator (c, code, options)){
          //sep is needed to detect empty key and empty value with a
          //non-whitespace separator
          sep = true;
          isKey = false;
          keySpace = false;
          //Skip whitespace between separator and value
          skipSpace = true;
          continue;
        }
      }

      //code 92: "\" (backslash)
      if (code === 92){
        if (escape){
          if (escapingUnicode) continue;

          if (keySpace){
            //Line with whitespace separator
            keySpace = false;
            isKey = false;
          }

          if (isSectionLine) section += "\\";
          else if (isKey) key += "\\";
          else value += "\\";
        }
        escape = !escape;
      }else{
        if (keySpace){
          //Line with whitespace separator
          keySpace = false;
          isKey = false;
        }

        if (isSectionLine){
          if (escape) section = escapeString (section, c, code);
          else section += c;
        }else if (isKey){
          if (escape){
            key = escapeString (key, c, code);
          }else{
            //code 32: " " (space)
            //code 9: \t
            //code 12: \f
            if (code === 32 || code === 9 || code === 12){
              keySpace = true;
              //Skip whitespace between key and separator
              skipSpace = true;
              continue;
            }
            key += c;
          }
        }else{
          if (escape) value = escapeString (value, c, code);
          else value += c;
        }
      }
    }else{
      if (escape){
        if (!escapingUnicode){
          escape = false;
        }
        skipSpace = true;
        multiLine = true;
      }else{
        if (isSectionLine){
          isSectionLine = false;
          if (!ignoreLine){
            //The section doesn't end with ], it's a key
            control.error = new Error ("The section line \"" + section +
                "\" must end with \"]\"");
            return;
          }
          ignoreLine = false;
        }
        newLine = true;
        skipSpace = true;
        isKey = true;

        line ();
      }
    }
  }

  control.parsed = true;

  if (isSectionLine && !ignoreLine){
    //The section doesn't end with ], it's a key
    control.error = new Error ("The section line \"" + section + "\" must end" +
        "with \"]\"");
    return;
  }
  line ();
};

var INCLUDE_KEY = "include";
var INDEX_FILE = "index.properties";

var cast = function (value){
  if (value === null || value === "null"return null;
  if (value === "undefined"return undefined;
  if (value === "true"return true;
  if (value === "false"return false;
  var v = Number (value);
  return isNaN (v) ? value : v;
};

var expand = function  (o, str, options, cb){
  if (!options.variables || !str) return cb (null, str);

  var stack = [];
  var c;
  var cp;
  var key = "";
  var section = null;
  var v;
  var holder;
  var t;
  var n;

  for (var i=0; i<str.length; i++){
    c = str[i];

    if (cp === "$" && c === "{"){
      key = key.substring (0, key.length - 1);
      stack.push ({
        key: key,
        section: section
      });
      key = "";
      section = null;
      continue;
    }else if (stack.length){
      if (options.sections && c === "|"){
        section = key;
        key = "";
        continue;
      }else if (c === "}"){
        holder = section !== null ? searchValue (o, section, true) : o;
        if (!holder){
          return cb (new Error ("The section \"" + section + "\" does not " +
              "exist"));
        }

        v = options.namespaces ? searchValue (holder, key) : holder[key];
        if (v === undefined){
          //Read the external vars
          v = options.namespaces
              ? searchValue (options._vars, key)
              : options._vars[key]

          if (v === undefined){
            return cb (new Error ("The property \"" + key + "\" does not " +
                "exist"));
          }
        }

        t = stack.pop ();
        section = t.section;
        key = t.key + (v === null ? "" : v);
        continue;
      }
    }

    cp = c;
    key += c;
  }

  if (stack.length !== 0){
    return cb (new Error ("Malformed variable: " + str));
  }

  cb (null, key);
};

var searchValue = function (o, chain, section){
  var n = chain.split (".");
  var str;

  for (var i=0; i<n.length-1; i++){
    str = n[i];
    if (o[str] === undefined) return;
    o = o[str];
  }

  var v = o[n[n.length - 1]];
  if (section){
    if (typeof v !== "object"return;
    return v;
  }else{
    if (typeof v === "object"return;
    return v;
  }
};

var namespaceKey = function (o, key, value){
  var n = key.split (".");
  var str;

  for (var i=0; i<n.length-1; i++){
    str = n[i];
    if (o[str] === undefined){
      o[str] = {};
    }else if (typeof o[str] !== "object"){
      throw new Error ("Invalid namespace chain in the property name '" +
          key + "' ('" + str + "' has already a value)");
    }
    o = o[str];
  }

  o[n[n.length - 1]] = value;
};

var namespaceSection = function (o, section){
  var n = section.split (".");
  var str;

  for (var i=0; i<n.length; i++){
    str = n[i];
    if (o[str] === undefined){
      o[str] = {};
    }else if (typeof o[str] !== "object"){
      throw new Error ("Invalid namespace chain in the section name '" +
          section + "' ('" + str + "' has already a value)");
    }
    o = o[str];
  }

  return o;
};

var merge = function (o1, o2){
  for (var p in o2){
    try{
      if (o1[p].constructor === Object){
        o1[p] = merge (o1[p], o2[p]);
      }else{
        o1[p] = o2[p];
      }
    }catch (e){
      o1[p] = o2[p];
    }
  }
  return o1;
}

var build = function (data, options, dirname, cb){
  var o = {};

  if (options.namespaces){
    var n = {};
  }

  var control = {
    abort: false,
    skipSection: false
  };

  if (options.include){
    var remainingIncluded = 0;

    var include = function (value){
      if (currentSection !== null){
        return abort (new Error ("Cannot include files from inside a " +
            "section: " + currentSection));
      }

      var p = path.resolve (dirname, value);
      if (options._included[p]) return;

      options._included[p] = true;
      remainingIncluded++;
      control.pause = true;

      read (p, options, function (error, included){
        if (error) return abort (error);

        remainingIncluded--;
        merge (options.namespaces ? n : o, included);
        control.pause = false;

        if (!control.parsed){
          parse (data, options, handlers, control);
          if (control.error) return abort (control.error);
        }

        if (!remainingIncluded) cb (null, options.namespaces ? n : o);
      });
    };
  }

  if (!data){
    if (cb) return cb (null, o);
    return o;
  }

  var currentSection = null;
  var currentSectionStr = null;

  var abort = function (error){
    control.abort = true;
    if (cb) return cb (error);
    throw error;
  };

  var handlers = {};
  var reviver = {
    assertfunction (){
      return this.isProperty ? reviverLine.value : true;
    }
  };
  var reviverLine = {};

  //Line handler
  //For speed reasons, if "namespaces" is enabled, the old object is still
  //populated, e.g.: ${a.b} reads the "a.b" property from { "a.b": 1 }, instead
  //of having a unique object { a: { b: 1 } } which is slower to search for
  //the "a.b" value
  //If "a.b" is not found, then the external vars are read. If "namespaces" is
  //enabled, the var "a.b" is split and it searches the a.b value. If it is not
  //enabled, then the var "a.b" searches the "a.b" value

  var line;
  var error;

  if (options.reviver){
    if (options.sections){
      line = function (key, value){
        if (options.include && key === INCLUDE_KEY) return include (value);

        reviverLine.value = value;
        reviver.isProperty = true;
        reviver.isSection = false;

        value = options.reviver.call (reviver, key, value, currentSectionStr);
        if (value !== undefined){
          if (options.namespaces){
            try{
              namespaceKey (currentSection === null ? n : currentSection,
                  key, value);
            }catch (error){
              abort (error);
            }
          }else{
            if (currentSection === null) o[key] = value;
            else currentSection[key] = value;
          }
        }
      };
    }else{
      line = function (key, value){
        if (options.include && key === INCLUDE_KEY) return include (value);

        reviverLine.value = value;
        reviver.isProperty = true;
        reviver.isSection = false;

        value = options.reviver.call (reviver, key, value);
        if (value !== undefined){
          if (options.namespaces){
            try{
              namespaceKey (n, key, value);
            }catch (error){
              abort (error);
            }
          }else{
            o[key] = value;
          }
        }
      };
    }
  }else{
    if (options.sections){
      line = function (key, value){
        if (options.include && key === INCLUDE_KEY) return include (value);

        if (options.namespaces){
          try{
            namespaceKey (currentSection === null ? n : currentSection, key,
                value);
          }catch (error){
            abort (error);
          }
        }else{
          if (currentSection === null) o[key] = value;
          else currentSection[key] = value;
        }
      };
    }else{
      line = function (key, value){
        if (options.include && key === INCLUDE_KEY) return include (value);

        if (options.namespaces){
          try{
            namespaceKey (n, key, value);
          }catch (error){
            abort (error);
          }
        }else{
          o[key] = value;
        }
      };
    }
  }

  //Section handler
  var section;
  if (options.sections){
    if (options.reviver){
      section = function (section){
        currentSectionStr = section;
        reviverLine.section = section;
        reviver.isProperty = false;
        reviver.isSection = true;

        var add = options.reviver.call (reviver, nullnull, section);
        if (add){
          if (options.namespaces){
            try{
              currentSection = namespaceSection (n, section);
            }catch (error){
              abort (error);
            }
          }else{
            currentSection = o[section] = {};
          }
        }else{
          control.skipSection = true;
        }
      };
    }else{
      section = function (section){
        currentSectionStr = section;
        if (options.namespaces){
          try{
            currentSection = namespaceSection (n, section);
          }catch (error){
            abort (error);
          }
        }else{
          currentSection = o[section] = {};
        }
      };
    }
  }

  //Variables
  if (options.variables){
    handlers.line = function (key, value){
      expand (options.namespaces ? n : o, key, options, function (error, key){
        if (error) return abort (error);

        expand (options.namespaces ? n : o, value, options,
            function (error, value){
          if (error) return abort (error);

          line (key, cast (value || null));
        });
      });
    };

    if (options.sections){
      handlers.section = function (s){
        expand (options.namespaces ? n : o, s, options, function (error, s){
          if (error) return abort (error);

          section (s);
        });
      };
    }
  }else{
    handlers.line = function (key, value){
      line (key, cast (value || null));
    };

    if (options.sections){
      handlers.section = section;
    }
  }

  parse (data, options, handlers, control);
  if (control.error) return abort (control.error);

  if (control.abort || control.pause) return;

  if (cb) return cb (null, options.namespaces ? n : o);
  return options.namespaces ? n : o;
};

var read = function (f, options, cb){
  fs.stat (f, function (error, stats){
    if (error) return cb (error);

    var dirname;

    if (stats.isDirectory ()){
      dirname = f;
      f = path.join (f, INDEX_FILE);
    }else{
      dirname = path.dirname (f);
    }

    fs.readFile (f, { encoding: "utf8" }, function (error, data){
      if (error) return cb (error);
      build (data, options, dirname, cb);
    });
  });
};

module.exports = function (data, options, cb){
  if (typeof options === "function"){
    cb = options;
    options = {};
  }

  options = options || {};
  var code;

  if (options.include){
    if (!cb) throw new Error ("A callback must be passed if the 'include' " +
        "option is enabled");
    options._included = {};
  }

  options = options || {};
  options._strict = options.strict && (options.comments || options.separators);
  options._vars = options.vars || {};

  var comments = options.comments || [];
  if (!Array.isArray (comments)) comments = [comments];
  var c = {};
  comments.forEach (function (comment){
    code = comment.charCodeAt (0);
    if (comment.length > 1 || code < 33 || code > 126){
      throw new Error ("The comment token must be a single printable ASCII " +
          "character");
    }
    c[comment] = true;
  });
  options._comments = c;

  var separators = options.separators || [];
  if (!Array.isArray (separators)) separators = [separators];
  var s = {};
  separators.forEach (function (separator){
    code = separator.charCodeAt (0);
    if (separator.length > 1 || code < 33 || code > 126){
      throw new Error ("The separator token must be a single printable ASCII " +
          "character");
    }
    s[separator] = true;
  });
  options._separators = s;

  if (options.path){
    if (!cb) throw new Error ("A callback must be passed if the 'path' " +
        "option is enabled");
    if (options.include){
      read (data, options, cb);
    }else{
      fs.readFile (data, { encoding: "utf8" }, function (error, data){
        if (error) return cb (error);
        build (data, options, ".", cb);
      });
    }
  }else{
    return build (data, options, ".", cb);
  }
};

98%


¤ Dauer der Verarbeitung: 0.18 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.