Added support for "strict comments".
In this mode, Getdown only treats a # as a comment starter in column zero. All other #s are ignored. You enable it by putting: strict_comments = true in your getdown.txt file. Yes the same file that has to be parsed with or without strict comments. If we see that, we reparse the file with strict comments.
This commit is contained in:
@@ -503,16 +503,17 @@ public class Application
|
||||
{
|
||||
Map<String,Object> cdata = null;
|
||||
File config = _config;
|
||||
ConfigUtil.ParseOpts opts = ConfigUtil.createOpts(checkPlatform);
|
||||
try {
|
||||
// if we have a configuration file, read the data from it
|
||||
if (config.exists()) {
|
||||
cdata = ConfigUtil.parseConfig(_config, checkPlatform);
|
||||
cdata = ConfigUtil.parseConfig(_config, opts);
|
||||
}
|
||||
// otherwise, try reading data from our backup config file; thanks to funny windows
|
||||
// bullshit, we have to do this backup file fiddling in case we got screwed while
|
||||
// updating getdown.txt during normal operation
|
||||
else if ((config = getLocalPath(CONFIG_FILE + "_old")).exists()) {
|
||||
cdata = ConfigUtil.parseConfig(config, checkPlatform);
|
||||
cdata = ConfigUtil.parseConfig(config, opts);
|
||||
}
|
||||
// otherwise, issue a warning that we found no getdown file
|
||||
else {
|
||||
@@ -772,7 +773,7 @@ public class Application
|
||||
File pairFile = getLocalPath(pairLocation);
|
||||
if (pairFile.exists()) {
|
||||
try {
|
||||
List<String[]> args = ConfigUtil.parsePairs(pairFile, false, false);
|
||||
List<String[]> args = ConfigUtil.parsePairs(pairFile, ConfigUtil.createOpts(false));
|
||||
for (String[] pair : args) {
|
||||
if (pair[1].length() == 0) {
|
||||
collector.add(pair[0]);
|
||||
@@ -1238,7 +1239,7 @@ public class Application
|
||||
try {
|
||||
in = ConnectionUtil.open(_latest).getInputStream();
|
||||
BufferedReader bin = new BufferedReader(new InputStreamReader(in));
|
||||
for (String[] pair : ConfigUtil.parsePairs(bin, false, false)) {
|
||||
for (String[] pair : ConfigUtil.parsePairs(bin, ConfigUtil.createOpts(false))) {
|
||||
if (pair[0].equals("version")) {
|
||||
_targetVersion = Math.max(Long.parseLong(pair[1]), _targetVersion);
|
||||
if (fileVersion != -1 && _targetVersion > fileVersion) {
|
||||
|
||||
@@ -113,9 +113,11 @@ public class Digest
|
||||
String filename = digestFile(version);
|
||||
StringBuilder data = new StringBuilder();
|
||||
File dfile = new File(appdir, filename);
|
||||
ConfigUtil.ParseOpts opts = ConfigUtil.createOpts(false);
|
||||
// bias = toward key: the key is the filename and could conceivably contain = signs, value
|
||||
// is the hex encoded hash which will not contain =
|
||||
for (String[] pair : ConfigUtil.parsePairs(dfile, false, true)) {
|
||||
opts.biasToKey = true;
|
||||
for (String[] pair : ConfigUtil.parsePairs(dfile, opts)) {
|
||||
if (pair[0].equals(filename)) {
|
||||
_metaDigest = pair[1];
|
||||
break;
|
||||
|
||||
@@ -313,7 +313,8 @@ public abstract class Getdown extends Thread
|
||||
File pfile = _app.getLocalPath("proxy.txt");
|
||||
if (pfile.exists()) {
|
||||
try {
|
||||
Map<String, Object> pconf = ConfigUtil.parseConfig(pfile, false);
|
||||
Map<String, Object> pconf =
|
||||
ConfigUtil.parseConfig(pfile, ConfigUtil.createOpts(false));
|
||||
setProxyProperties((String)pconf.get("host"), (String)pconf.get("port"));
|
||||
return true;
|
||||
} catch (IOException ioe) {
|
||||
|
||||
@@ -366,7 +366,8 @@ public class GetdownAppletConfig
|
||||
boolean createGetdown = !gdfile.exists();
|
||||
if (!createGetdown) {
|
||||
try {
|
||||
Map<String,Object> cdata = ConfigUtil.parseConfig(gdfile, false);
|
||||
Map<String,Object> cdata =
|
||||
ConfigUtil.parseConfig(gdfile, ConfigUtil.createOpts(false));
|
||||
String oappbase = StringUtil.trim((String)cdata.get(APPBASE));
|
||||
createGetdown = (appbase != null && !appbase.trim().equals(oappbase));
|
||||
if (createGetdown) {
|
||||
|
||||
@@ -26,6 +26,30 @@ import static com.threerings.getdown.Log.log;
|
||||
*/
|
||||
public class ConfigUtil
|
||||
{
|
||||
/** Options that control the {@link #parsePairs} function. */
|
||||
public static class ParseOpts {
|
||||
// these should be tweaked as desired by the caller
|
||||
public boolean biasToKey = false;
|
||||
public boolean strictComments = false;
|
||||
|
||||
// these are filled in by parseConfig
|
||||
public String osname = null;
|
||||
public String osarch = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a parse configuration, filling in the platform filters (or not) depending on the
|
||||
* value of {@code checkPlatform}.
|
||||
*/
|
||||
public static ParseOpts createOpts (boolean checkPlatform) {
|
||||
ParseOpts opts = new ParseOpts();
|
||||
if (checkPlatform) {
|
||||
opts.osname = StringUtil.deNull(System.getProperty("os.name")).toLowerCase();
|
||||
opts.osarch = StringUtil.deNull(System.getProperty("os.arch")).toLowerCase();
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a configuration file containing key/value pairs. The file must be in the UTF-8
|
||||
* encoding.
|
||||
@@ -39,25 +63,68 @@ public class ConfigUtil
|
||||
* @return a list of <code>String[]</code> instances containing the key/value pairs in the
|
||||
* order they were parsed from the file.
|
||||
*/
|
||||
public static List<String[]> parsePairs (File config, boolean checkPlatform, boolean biasToKey)
|
||||
public static List<String[]> parsePairs (File source, ParseOpts opts)
|
||||
throws IOException
|
||||
{
|
||||
// annoyingly FileReader does not allow encoding to be specified (uses platform default)
|
||||
InputStreamReader input = new InputStreamReader(new FileInputStream(config), "UTF-8");
|
||||
return parsePairs(input, checkPlatform, biasToKey);
|
||||
InputStreamReader input = new InputStreamReader(new FileInputStream(source), "UTF-8");
|
||||
return parsePairs(input, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #parsePairs(File,boolean,boolean)}.
|
||||
* See {@link #parsePairs(File,ParseOpts)}.
|
||||
*/
|
||||
public static List<String[]> parsePairs (Reader config, boolean checkPlatform,
|
||||
boolean biasToKey) throws IOException
|
||||
public static List<String[]> parsePairs (Reader source, ParseOpts opts) throws IOException
|
||||
{
|
||||
return parsePairs(
|
||||
config,
|
||||
checkPlatform ? StringUtil.deNull(System.getProperty("os.name")).toLowerCase() : null,
|
||||
checkPlatform ? StringUtil.deNull(System.getProperty("os.arch")).toLowerCase() : null,
|
||||
biasToKey);
|
||||
List<String[]> pairs = new ArrayList<String[]>();
|
||||
for (String line : FileUtil.readLines(source)) {
|
||||
// nix comments
|
||||
int cidx = line.indexOf("#");
|
||||
if (opts.strictComments ? cidx == 0 : cidx != -1) {
|
||||
line = line.substring(0, cidx);
|
||||
}
|
||||
|
||||
// trim whitespace and skip blank lines
|
||||
line = line.trim();
|
||||
if (StringUtil.isBlank(line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse our key/value pair
|
||||
String[] pair = new String[2];
|
||||
// if we're biasing toward key, put all the extra = in the key rather than the value
|
||||
int eidx = opts.biasToKey ? line.lastIndexOf("=") : line.indexOf("=");
|
||||
if (eidx != -1) {
|
||||
pair[0] = line.substring(0, eidx).trim();
|
||||
pair[1] = line.substring(eidx+1).trim();
|
||||
} else {
|
||||
pair[0] = line;
|
||||
pair[1] = "";
|
||||
}
|
||||
|
||||
// if the pair has an os qualifier, we need to process it
|
||||
if (pair[1].startsWith("[")) {
|
||||
int qidx = pair[1].indexOf("]");
|
||||
if (qidx == -1) {
|
||||
log.warning("Bogus platform specifier", "key", pair[0], "value", pair[1]);
|
||||
continue; // omit the pair entirely
|
||||
}
|
||||
// if we're checking qualifiers and the os doesn't match this qualifier, skip it
|
||||
String quals = pair[1].substring(1, qidx);
|
||||
if (opts.osname != null && !checkQualifiers(quals, opts.osname, opts.osarch)) {
|
||||
log.debug("Skipping", "quals", quals,
|
||||
"osname", opts.osname, "osarch", opts.osarch,
|
||||
"key", pair[0], "value", pair[1]);
|
||||
continue;
|
||||
}
|
||||
// otherwise filter out the qualifier text
|
||||
pair[1] = pair[1].substring(qidx+1).trim();
|
||||
}
|
||||
|
||||
pairs.add(pair);
|
||||
}
|
||||
|
||||
return pairs;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,7 +134,7 @@ public class ConfigUtil
|
||||
* @return a map from keys to values, where a value will be an array of strings if more than
|
||||
* one key/value pair in the config file was associated with the same key.
|
||||
*/
|
||||
public static Map<String, Object> parseConfig (File config, boolean checkPlatform)
|
||||
public static Map<String, Object> parseConfig (File source, ParseOpts opts)
|
||||
throws IOException
|
||||
{
|
||||
Map<String, Object> data = new HashMap<String, Object>();
|
||||
@@ -75,7 +142,7 @@ public class ConfigUtil
|
||||
// I thought that we could use HashMap<String, String[]> and put new String[] {pair[1]} for
|
||||
// the null case, but it mysteriously dies on launch, so leaving it as HashMap<String,
|
||||
// Object> for now
|
||||
for (String[] pair : parsePairs(config, checkPlatform, false)) {
|
||||
for (String[] pair : parsePairs(source, opts)) {
|
||||
Object value = data.get(pair[0]);
|
||||
if (value == null) {
|
||||
data.put(pair[0], pair[1]);
|
||||
@@ -90,6 +157,14 @@ public class ConfigUtil
|
||||
}
|
||||
}
|
||||
|
||||
// special magic for the getdown.txt config: if the parsed data contains 'strict_comments =
|
||||
// true' then we reparse the file with strict comments (i.e. # is only assumed to start a
|
||||
// comment in column 0)
|
||||
if (!opts.strictComments && Boolean.parseBoolean((String)data.get("strict_comments"))) {
|
||||
opts.strictComments = true;
|
||||
return parseConfig(source, opts);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -107,64 +182,9 @@ public class ConfigUtil
|
||||
}
|
||||
}
|
||||
|
||||
/** A helper function for {@link #parsePairs(Reader,boolean}. */
|
||||
protected static List<String[]> parsePairs (Reader config, String osname, String osarch,
|
||||
boolean biasToKey)
|
||||
throws IOException
|
||||
{
|
||||
List<String[]> pairs = new ArrayList<String[]>();
|
||||
for (String line : FileUtil.readLines(config)) {
|
||||
// nix comments
|
||||
int cidx = line.indexOf("#");
|
||||
if (cidx != -1) {
|
||||
line = line.substring(0, cidx);
|
||||
}
|
||||
|
||||
// trim whitespace and skip blank lines
|
||||
line = line.trim();
|
||||
if (StringUtil.isBlank(line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse our key/value pair
|
||||
String[] pair = new String[2];
|
||||
// if we're biasing toward key, put all the extra = in the key rather than the value
|
||||
int eidx = biasToKey ? line.lastIndexOf("=") : line.indexOf("=");
|
||||
if (eidx != -1) {
|
||||
pair[0] = line.substring(0, eidx).trim();
|
||||
pair[1] = line.substring(eidx+1).trim();
|
||||
} else {
|
||||
pair[0] = line;
|
||||
pair[1] = "";
|
||||
}
|
||||
|
||||
// if the pair has an os qualifier, we need to process it
|
||||
if (pair[1].startsWith("[")) {
|
||||
int qidx = pair[1].indexOf("]");
|
||||
if (qidx == -1) {
|
||||
log.warning("Bogus platform specifier", "key", pair[0], "value", pair[1]);
|
||||
continue; // omit the pair entirely
|
||||
}
|
||||
// if we're checking qualifiers and the os doesn't match this qualifier, skip it
|
||||
String quals = pair[1].substring(1, qidx);
|
||||
if (osname != null && !checkQualifiers(quals, osname, osarch)) {
|
||||
log.debug("Skipping", "quals", quals, "osname", osname, "osarch", osarch,
|
||||
"key", pair[0], "value", pair[1]);
|
||||
continue;
|
||||
}
|
||||
// otherwise filter out the qualifier text
|
||||
pair[1] = pair[1].substring(qidx+1).trim();
|
||||
}
|
||||
|
||||
pairs.add(pair);
|
||||
}
|
||||
|
||||
return pairs;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function for {@link #parsePairs(Reader,String,String)}. Qualifiers have the
|
||||
* following form:
|
||||
* A helper function for {@link #parsePairs(Reader,ParseOpts)}. Qualifiers have the following
|
||||
* form:
|
||||
* <pre>
|
||||
* id = os[-arch]
|
||||
* ids = id | id,ids
|
||||
|
||||
@@ -38,7 +38,8 @@ public class ConfigUtilTest
|
||||
|
||||
@Test public void testSimplePairs () throws IOException
|
||||
{
|
||||
List<String[]> pairs = ConfigUtil.parsePairs(toReader(SIMPLE_PAIRS), true, false);
|
||||
List<String[]> pairs = ConfigUtil.parsePairs(
|
||||
toReader(SIMPLE_PAIRS), ConfigUtil.createOpts(true));
|
||||
for (int ii = 0; ii < SIMPLE_PAIRS.length; ii++) {
|
||||
assertEquals(SIMPLE_PAIRS[ii].key, pairs.get(ii)[0]);
|
||||
assertEquals(SIMPLE_PAIRS[ii].value, pairs.get(ii)[1]);
|
||||
@@ -57,7 +58,10 @@ public class ConfigUtilTest
|
||||
Pair notWin = new Pair("fifteen", "[!windows] sixteen");
|
||||
Pair[] pairs = { linux, mac, linuxAndMac, linux64, linux64s, mac64, win64, notWin };
|
||||
|
||||
List<String[]> parsed = ConfigUtil.parsePairs(toReader(pairs), "linux", "i386", false);
|
||||
ConfigUtil.ParseOpts opts = ConfigUtil.createOpts(false);
|
||||
opts.osname = "linux";
|
||||
opts.osarch = "i386";
|
||||
List<String[]> parsed = ConfigUtil.parsePairs(toReader(pairs), opts);
|
||||
assertTrue(exists(parsed, linux.key));
|
||||
assertTrue(!exists(parsed, mac.key));
|
||||
assertTrue(exists(parsed, linuxAndMac.key));
|
||||
@@ -67,7 +71,8 @@ public class ConfigUtilTest
|
||||
assertTrue(!exists(parsed, win64.key));
|
||||
assertTrue(exists(parsed, notWin.key));
|
||||
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), "linux", "x86_64", false);
|
||||
opts.osarch = "x86_64";
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), opts);
|
||||
assertTrue(exists(parsed, linux.key));
|
||||
assertTrue(!exists(parsed, mac.key));
|
||||
assertTrue(exists(parsed, linuxAndMac.key));
|
||||
@@ -77,7 +82,8 @@ public class ConfigUtilTest
|
||||
assertTrue(!exists(parsed, win64.key));
|
||||
assertTrue(exists(parsed, notWin.key));
|
||||
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), "linux", "amd64", false);
|
||||
opts.osarch = "amd64";
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), opts);
|
||||
assertTrue(exists(parsed, linux.key));
|
||||
assertTrue(!exists(parsed, mac.key));
|
||||
assertTrue(exists(parsed, linuxAndMac.key));
|
||||
@@ -87,7 +93,9 @@ public class ConfigUtilTest
|
||||
assertTrue(!exists(parsed, win64.key));
|
||||
assertTrue(exists(parsed, notWin.key));
|
||||
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), "mac os x", "x86_64", false);
|
||||
opts.osname = "mac os x";
|
||||
opts.osarch = "x86_64";
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), opts);
|
||||
assertTrue(!exists(parsed, linux.key));
|
||||
assertTrue(exists(parsed, mac.key));
|
||||
assertTrue(exists(parsed, linuxAndMac.key));
|
||||
@@ -97,7 +105,9 @@ public class ConfigUtilTest
|
||||
assertTrue(!exists(parsed, win64.key));
|
||||
assertTrue(exists(parsed, notWin.key));
|
||||
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), "windows", "i386", false);
|
||||
opts.osname = "windows";
|
||||
opts.osarch = "i386";
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), opts);
|
||||
assertTrue(!exists(parsed, linux.key));
|
||||
assertTrue(!exists(parsed, mac.key));
|
||||
assertTrue(!exists(parsed, linuxAndMac.key));
|
||||
@@ -107,7 +117,8 @@ public class ConfigUtilTest
|
||||
assertTrue(!exists(parsed, win64.key));
|
||||
assertTrue(!exists(parsed, notWin.key));
|
||||
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), "windows", "x86_64", false);
|
||||
opts.osarch = "x86_64";
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), opts);
|
||||
assertTrue(!exists(parsed, linux.key));
|
||||
assertTrue(!exists(parsed, mac.key));
|
||||
assertTrue(!exists(parsed, linuxAndMac.key));
|
||||
@@ -117,7 +128,8 @@ public class ConfigUtilTest
|
||||
assertTrue(exists(parsed, win64.key));
|
||||
assertTrue(!exists(parsed, notWin.key));
|
||||
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), "windows", "amd64", false);
|
||||
opts.osarch = "amd64";
|
||||
parsed = ConfigUtil.parsePairs(toReader(pairs), opts);
|
||||
assertTrue(!exists(parsed, linux.key));
|
||||
assertTrue(!exists(parsed, mac.key));
|
||||
assertTrue(!exists(parsed, linuxAndMac.key));
|
||||
|
||||
Reference in New Issue
Block a user