123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- # Copyright (C) 2018 Tom Li <tomli at tomli.me>.
- #
- # To the extent possible under law, I, Tom Li, has waived all copyright
- # and related or neighboring rights to this work. You may copy, modify,
- # distribute and perform the work, for all purposes.
- #
- # 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.
- import sys
- from pprint import pprint
- def parse(dat):
- struct = []
- state = "STATE_INITIAL"
- ptr = [struct]
- key_buf = []
- val_buf = []
- last_type = ""
- dat = dat.replace("return {", "{")
- for i in dat:
- if i.isspace() and (not "STR" in state):
- continue
- previous_state = state
- if i == "{":
- state = "STATE_BEGIN_DICT"
- elif i == "}":
- state = "STATE_END_DICT"
- elif i == "[":
- state = "STATE_BEGIN_KEY"
- elif i == "]":
- state = "STATE_END_KEY"
- elif i == "\"":
- if state not in ["STATE_BEGIN_STR", "STATE_STR"]:
- state = "STATE_BEGIN_STR"
- elif state in ["STATE_BEGIN_STR", "STATE_STR"]:
- state = "STATE_END_STR"
- elif i == "=":
- if state not in ["STATE_BEGIN_STR", "STATE_STR"]:
- state = "STATE_ASSIGNMENT"
- elif i == ";":
- if previous_state == "STATE_VAL":
- state = "STATE_END_VAL"
- state = "STATE_END_ENTRY"
- else:
- if state == "STATE_BEGIN_KEY":
- state = "STATE_VAL"
- elif state == "STATE_BEGIN_STR":
- state = "STATE_STR"
- elif state == "STATE_ASSIGNMENT":
- state = "STATE_VAL"
- if previous_state == "STATE_BEGIN_STR":
- state = "STATE_STR"
- #print("char: %s \t state: %s" % (i, state))
- #print("previous ptr: ", end="")
- #pprint(ptr)
- if state == "STATE_BEGIN_DICT":
- dic = {}
- if ptr[-1] == None:
- #print(last_type)
- if last_type == "key":
- ptr[-2][key_buf[0]] = dic
- elif last_type == "val":
- ptr[-2][val_buf] = dic
- else:
- assert(False)
- ptr.pop()
- else:
- ptr[-1].append(dic)
- ptr.append(dic)
- if state == "STATE_BEGIN_KEY":
- last_type = "key"
- key_buf.clear()
- ptr.append(key_buf)
- if state == "STATE_BEGIN_STR":
- if previous_state != "STATE_BEGIN_KEY":
- last_type = "val"
- val_buf.clear()
- ptr.append(val_buf)
- if state in ["STATE_VAL", "STATE_STR"]:
- if previous_state == "STATE_ASSIGNMENT":
- ptr.append(val_buf)
- ptr[-1] += i
- if state in ["STATE_END_DICT"]:
- ptr.pop()
- if state in ["STATE_END_KEY", "STATE_END_ENTRY"]:
- if previous_state == "STATE_END_DICT":
- continue
- if previous_state == "STATE_VAL":
- if ("".join(ptr[-1])) == "false":
- ptr[-1].clear()
- ptr[-1].append(False)
- elif ("".join(ptr[-1])) == "true":
- ptr[-1].clear()
- ptr[-1].append(True)
- else:
- val = eval("".join(ptr[-1]))
- ptr[-1].clear()
- ptr[-1].append(val)
- else:
- assert(previous_state in ["STATE_END_STR"])
- string = "".join(ptr[-1])
- ptr[-1].clear()
- ptr[-1].append(string)
- if isinstance(ptr[-2], dict):
- ptr[-2][ptr[-1][0]] = None
- elif isinstance(ptr[-2], type(None)):
- #print("key 0 is", tuple(ptr[-3].keys())[0])
- #print("key_buf is", key_buf)
- #print("val_buf is", val_buf)
- ptr[-3]["".join(key_buf)] = ptr[-1][0]
- ptr.pop()
- ptr.pop()
- else:
- assert(False)
- val_buf.clear()
- if state == "STATE_ASSIGNMENT":
- ptr[-1] = ptr[-2][ptr[-1][0]]
- #print("struct: ", end="")
- #pprint(struct)
- #print("new ptr: ", end="")
- #pprint(ptr)
- #print()
- assert(len(struct) == 1)
- return struct[0]
- for arg in sys.argv[1:]:
- score = 0
- f = open(arg, "r")
- dat = f.read()
- f.close()
- try:
- roster = parse(dat)
- except AssertionError as e:
- print("============ INTERNAL ERROR ============", file=sys.stderr)
- print("The program fails to parse \"%s\", please" % arg, file=sys.stderr)
- print("submit a bug report, with your file attached.", file=sys.stderr)
- print("============ INTERNAL ERROR ============", file=sys.stderr)
- raise e
- server = []
- none_subscription = 0
- for s in tuple(roster.keys()):
- if not isinstance(s, str):
- continue
- if "@" not in s:
- continue
- server.append(s.split("@")[1])
- if roster[s]["subscription"] == "none":
- none_subscription += 1
- if len(server) >= 50:
- score += 1
- if len(set(server)) >= 20:
- score += 1
- if "pending" in roster and len(roster["pending"]) > 20:
- score += 1
- if len(server) > 0 and (none_subscription / len(server)) >= 0.55:
- score += 2
- if score >= 3:
- print(arg, score)
|