text:
// DatalogParser.java, created May 15, 2005 4:53:12 PM by jwhaley
// Copyright (C) 2004 John Whaley <jwhaley@alum.mit.edu>
// Licensed under the terms of the GNU LGPL; see COPYING for details.
package net.sf.bddbddb;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintStream;
import java.math.BigInteger;
import jwutil.collections.AppendIterator;
import jwutil.collections.Pair;
import jwutil.io.SystemProperties;
import jwutil.strings.MyStringTokenizer;
import jwutil.util.Assert;
import net.sf.bddbddb.Solver.MyReader;
import net.sf.bddbddb.dataflow.PartialOrder.BeforeConstraint;
import net.sf.bddbddb.dataflow.PartialOrder.InterleavedConstraint;

/**
 * DatalogParser
 *
 * @author jwhaley
 * @version $Id: DatalogParser.java 549 2005-05-17 10:17:33Z joewhaley $
 */
public class DatalogParser {

    /** Solver object we are modifying. */
    Solver solver;

    /** Trace flag. */
    boolean TRACE = SystemProperties.getProperty("traceparse") != null;

    /** Trace output stream. */
    public PrintStream out;
    public PrintStream err;

    /**
     * Construct a new Datalog parser with the given solver.
     *
     * @param solver  add rules, relations, etc. to this solver
     */
    public DatalogParser(Solver solver) {
        this.solver = solver;
        this.out = solver.out;
        this.err = solver.err;
    }

    /**
     * Utility function to read a line from the given reader.
     * Allows line wrapping using backslashes, among other things.
     *
     * @param in  input reader
     * @return  line
     * @throws IOException
     */
    static String readLine(MyReader in) throws IOException {
        String s = in.readLine();
        if (s == null) return null;
        s = s.trim();
        while (s.endsWith("\\")) {
            String s2 = in.readLine();
            if (s2 == null) break;
            s2 = s2.trim();
            s = s.substring(0, s.length() - 1) + s2;
        }
        return s;
    }

    /**
     * Get the next token, skipping over spaces.
     *
     * @param st  string tokenizer
     * @return  next non-space token
     */
    static String nextToken(MyStringTokenizer st) {
        String s;
        do {
            s = st.nextToken();
        } while (s.equals(" ") || s.equals("\t"));
        return s;
    }

    /**
     * Read and parse a Datalog program.
     *
     * @param inputFilename  name of file to read
     * @throws IOException
     */
    public void readDatalogProgram(String inputFilename) throws IOException {
        MyReader in = null;
        try {
            in = new MyReader(new LineNumberReader(new FileReader(inputFilename)));
            readDatalogProgram(in);
        } finally {
            if (in != null) try { in.close(); } catch (IOException _) { }
        }
    }

    /**
     * Read and parse a Datalog program.
     *
     * @param in  input reader
     * @throws IOException
     */
    public void readDatalogProgram(MyReader in) throws IOException {
        for (;;) {
            String s = readLine(in);
            if (s == null) break;
            parseDatalogLine(s, in);
        }
    }

    /**
     * Parse a line from a Datalog program.
     *
     * @param s  line to parse
     * @param in  input reader
     * @return  the rule, relation, domain, or list of rules we parsed, or null
     * @throws IOException
     */
    Object parseDatalogLine(String s, MyReader in) throws IOException {
		    int i = s.indexOf('#');
		    if (i != -1) s = s.substring(0, i);
        s = s.trim();
		    if (s.length() == 0) return null;
        int lineNum = in.getLineNumber();
        if (s.startsWith(".")) {
            // directive
            parseDirective(in, lineNum, s);
            return null;
        }
        MyStringTokenizer st = new MyStringTokenizer(s);
        if (st.hasMoreTokens()) {
            st.nextToken(); // name
            if (st.hasMoreTokens()) {
                String num = st.nextToken();
                boolean isNumber;
                try {
                    new BigInteger(num);
                    isNumber = true;
                } catch (NumberFormatException x) {
                    isNumber = false;
                }
                if (isNumber) {
                    // field domain
                    Domain fd = parseDomain(lineNum, s);
                    if (TRACE) out.println("Parsed field domain " + fd + " size " + fd.size);
                    if (solver.nameToDomain.containsKey(fd.name)) {
                        err.println("Error, field domain " + fd.name + " redefined on line " + in.getLineNumber() + ", ignoring.");
                    } else {
                        solver.nameToDomain.put(fd.name, fd);
                    }
                    return fd;
                }
            }
        }
        int dotIndex = s.indexOf('.');
        int braceIndex = s.indexOf('{');
        int qIndex = s.indexOf('?');
        if (dotIndex > 0 && (braceIndex == -1 || dotIndex < braceIndex)) {
            // rule
            InferenceRule ir = parseRule(lineNum, s);
            if (TRACE) out.println("Parsed rule " + ir);
            solver.rules.add(ir);
            return Collections.singletonList(ir);
        } else if (qIndex > 0 && (braceIndex == -1 || qIndex < braceIndex)) {
            // query
            List/*<InferenceRule>*/ ir = parseQuery(lineNum, s);
            if (ir != null) {
                if (TRACE) out.println("Parsed query " + ir);
                solver.rules.addAll(ir);
            }
            return ir;
        } else {
            // relation
            Relation r = parseRelation(lineNum, s);
            if (TRACE && r != null) out.println("Parsed relation " + r);
            return r;
        }
    }

    /**
     * Output a parse error at the given location.
     *
     * @param linenum  line number of error
     * @param colnum  column number of error
     * @param line  text of line containing error
     * @param msg  error message
     */
    void outputError(int linenum, int colnum, String line, String msg) {
        err.println("Error on line " + linenum + ":");
        err.println(line);
        while (--colnum >= 0)
            err.print(' ');
        err.println('^');
        err.println(msg);
    }

    /**
     * Parse a directive.
     *
     * @param in  input reader
     * @param lineNum  current line number, for debugging purposes
     * @param s  string containing directive to parse
     * @throws IOException
     */
    void parseDirective(MyReader in, int lineNum, String s) throws IOException {
        if (s.startsWith(".include")) {
            int index = ".include".length() + 1;
            String fileName = s.substring(index).trim();
            if (fileName.startsWith("\"")) {
                if (!fileName.endsWith("\"")) {
                    outputError(lineNum, index, s,
                        "Unmatched quotes");
                    throw new IllegalArgumentException();
                }
                fileName = fileName.substring(1, fileName.length() - 1);
            }
            if (!fileName.startsWith("/")) {
                String[] dirs = solver.includedirs.split(SystemProperties.getProperty("path.separator"));
                for (int i=0; i<dirs.length; i++) {
                    if ((new File(dirs[i],fileName)).exists()) {
                        fileName = dirs[i]+SystemProperties.getProperty("file.separator")+fileName;
                        break;
                    }
                }
            }
            in.registerReader(new LineNumberReader(new FileReader(fileName)));
        } else if (s.startsWith(".split_all_rules")) {
            boolean b = true;
            int index = ".split_all_rules".length() + 1;
            if (s.length() > index) {
                String option = s.substring(index).trim();
                b = !option.equals("false");
            }
            solver.SPLIT_ALL_RULES = b;
        } else if (s.startsWith(".report_stats")) {
            boolean b = true;
            int index = ".report_stats".length() + 1;
            if (s.length() > index) {
                String option = s.substring(index).trim();
                b = !option.equals("false");
            }
            solver.REPORT_STATS = b;
        } else if (s.startsWith(".noisy")) {
            boolean b = true;
            int index = ".noisy".length() + 1;
            if (s.length() > index) {
                String option = s.substring(index).trim();
                b = !option.equals("false");
            }
            solver.NOISY = b;
        } else if (s.startsWith(".trace")) {
            boolean b = true;
            int index = ".trace".length() + 1;
            if (s.length() > index) {
                String option = s.substring(index).trim();
                b = !option.equals("false");
            }
            TRACE = b;
        } else if (s.startsWith(".bddvarorder")) {
            if (SystemProperties.getProperty("bddvarorder") == null) {
                int index = ".bddvarorder".length() + 1;
                String varOrder = s.substring(index).trim();
                if (solver instanceof BDDSolver) {
                    ((BDDSolver) solver).VARORDER = varOrder;
                } else {
                    err.println("Ignoring .bddvarorder "+varOrder);
                }
            }
        } else if (s.startsWith(".bddnodes")) {
            if (SystemProperties.getProperty("bddnodes") == null) {
                int index = ".bddnodes".length() + 1;
                int n = Integer.parseInt(s.substring(index).trim());
                if (solver instanceof BDDSolver) {
                    ((BDDSolver) solver).BDDNODES = n;
                } else {
                    err.println("Ignoring .bddnodes "+n);
                }
            }
        } else if (s.startsWith(".bddcache")) {
            if (SystemProperties.getProperty("bddcache") == null) {
                int index = ".bddcache".length() + 1;
                int n = Integer.parseInt(s.substring(index).trim());
                if (solver instanceof BDDSolver) {
                    ((BDDSolver) solver).BDDCACHE = n;
                } else {
                    err.println("Ignoring .bddcache "+n);
                }
            }
        } else if (s.startsWith(".bddminfree")) {
            if (SystemProperties.getProperty("bddminfree") == null) {
                int index = ".bddminfree".length() + 1;
                double n = Double.parseDouble(s.substring(index).trim());
                if (solver instanceof BDDSolver) {
                    ((BDDSolver) solver).BDDMINFREE = n;
                } else {
                    err.println("Ignoring .bddminfree "+n);
                }
            }
        } else if (s.startsWith(".findbestorder")) {
            int index = ".findbestorder".length() + 1;
            String val = "";
            if (s.length() > index) val = s.substring(index).trim();
            System.setProperty("findbestorder", val);
        } else if (s.startsWith(".learnbestorder")){
            int index = ".learnbestorder".length() + 1;
            String val = "";
            if (s.length() > index) val = s.substring(index).trim();
            solver.LEARN_BEST_ORDER = true;
            solver.LEARN_ALL_RULES = true;
            System.setProperty("learnbestorder", val);
        } else if (s.startsWith(".incremental")) {
            int index = ".incremental".length() + 1;
            String val = "";
            if (s.length() > index) val = s.substring(index).trim();
            System.setProperty("incremental", val);
        } else if (s.startsWith(".dot")) {
            int index = ".dot".length() + 1;
            String dotSpec = "";
            if (s.length() > index) dotSpec = s.substring(index).trim();
            Dot dot = new Dot();
            LineNumberReader lnr = new LineNumberReader(new FileReader(solver.basedir + dotSpec));
            if (TRACE) out.println("Parsing dot " + dotSpec);
            dot.parseInput(solver, lnr);
            if (TRACE) out.println("Done parsing dot " + dotSpec);
            lnr.close();
            solver.dotGraphsToDump.add(dot);
        } else if (s.startsWith(".basedir")) {
            if (SystemProperties.getProperty("basedir") == null) {
                int index = ".basedir".length() + 1;
                String dirName = s.substring(index).trim();
                if (dirName.startsWith("\"") && dirName.endsWith("\"")) {
                    dirName = dirName.substring(1, dirName.length() - 1);
                }
                solver.basedir += dirName;
                String sep = SystemProperties.getProperty("file.separator");
                if (!solver.basedir.endsWith(sep) && !solver.basedir.endsWith("/")) {
                    solver.basedir += sep;
                }
                if (TRACE) out.println("Base directory is now \"" + solver.basedir + "\"");
                Assert._assert(solver.includedirs != null);
                solver.includedirs += SystemProperties.getProperty("path.separator") + solver.basedir;
            }
        } else {
            outputError(lineNum, 0, s,
                "Unknown directive \"" + s + "\"");
            throw new IllegalArgumentException();
        }
    }

    /**
     * Parse a domain declaration.
     *
     * @param lineNum  current line number for outputting error messages
     * @param s  string containing relation declaration
     * @return  new domain
     */
    Domain parseDomain(int lineNum, String s) {
        MyStringTokenizer st = new MyStringTokenizer(s);
        String name = nextToken(st);
        String num = nextToken(st);
        BigInteger size;
        try {
            size = new BigInteger(num);
        } catch (NumberFormatException x) {
            outputError(lineNum, st.getPosition(), s,
                "Expected a number, got \"" + num + "\"");
            throw new IllegalArgumentException();
        }
        Domain fd = new Domain(name, size);
        if (st.hasMoreTokens()) {
            String mapName = nextToken(st);
            BufferedReader dis = null;
            try {
                dis = new BufferedReader(new FileReader(solver.basedir + mapName));
                fd.loadMap(dis);
            } catch (IOException x) {
                err.println("WARNING: Cannot load mapfile \"" + solver.basedir + mapName + "\", skipping.");
            } finally {
                if (dis != null) try { dis.close(); } catch (IOException x) { }
            }
        }
        return fd;
    }

    static final char[] badchars = new char[] { '!', '=', ':', '-', '<', '>', '(', ')', ',', ' ', '\t', '\f' };

    /**
     * Parse a relation declaration.
     *
     * @param lineNum  current line number for outputting error messages
     * @param s  string containing relation declaration
     * @return  new relation, or null if the relation was already defined
     */
    Relation parseRelation(int lineNum, String s) {
        MyStringTokenizer st = new MyStringTokenizer(s, " \t(:,)", true);
        String name = nextToken(st);
        for (int i = 0; i < badchars.length; ++i) {
            if (name.indexOf(badchars[i]) >= 0) {
                outputError(lineNum, st.getPosition(), s,
                    "Relation name cannot contain '"+badchars[i]+"'");
                throw new IllegalArgumentException();
            }
        }
        String openParen = nextToken(st);
        if (!openParen.equals("(")) {
            outputError(lineNum, st.getPosition(), s,
                "Expected \"(\", got \"" + openParen + "\"");
            throw new IllegalArgumentException();
        }
        List attributes = new LinkedList();
        for (;;) {
            String fName = nextToken(st);
            String colon = nextToken(st);
            if (!colon.equals(":")) {
                outputError(lineNum, st.getPosition(), s,
                    "Expected \":\", got \"" + colon + "\"");
                throw new IllegalArgumentException();
            }
            String fdName = nextToken(st);
            int numIndex = fdName.length() - 1;
            for (;;) {
                char c = fdName.charAt(numIndex);
                if (c < '0' || c > '9') break;
                --numIndex;
                if (numIndex < 0) {
                    outputError(lineNum, st.getPosition(), s,
                        "Expected field domain name, got \"" + fdName + "\"");
                    throw new IllegalArgumentException();
                }
            }
            ++numIndex;
            int fdNum = -1;
            if (numIndex < fdName.length()) {
                String number = fdName.substring(numIndex);
                try {
                    fdNum = Integer.parseInt(number);
                } catch (NumberFormatException x) {
                    outputError(lineNum, st.getPosition(), s,
                        "Cannot parse field domain number \"" + number + "\"");
                    throw new IllegalArgumentException();
                }
                fdName = fdName.substring(0, numIndex);
            }
            Domain fd = solver.getDomain(fdName);
            if (fd == null) {
                outputError(lineNum, st.getPosition(), s,
                    "Unknown field domain " + fdName);
                throw new IllegalArgumentException();
            }
            String option;
            if (fdNum != -1) option = fdName + fdNum;
            else option = "";
            attributes.add(new Attribute(fName, fd, option));
            String comma = nextToken(st);
            if (comma.equals(")")) break;
            if (!comma.equals(",")) {
                outputError(lineNum, st.getPosition(), s,
                    "Expected \",\" or \")\", got \"" + comma + "\"");
                throw new IllegalArgumentException();
            }
        }
        if (solver.nameToRelation.containsKey(name)) {
            err.println("Error, relation " + name + " redefined on line " + lineNum + ", ignoring.");
            return null;
        }
        Relation r = solver.createRelation(name, attributes);
        Pattern constraintPattern = Pattern.compile("(\\w+)([=<])(\\w+)");
        while (st.hasMoreTokens()) {
            String option = nextToken(st);
            Matcher constraintMatcher = constraintPattern.matcher(option);
            if (option.equals("preload")) {
                solver.relationsToPreLoad.add(r);
            } else if (option.equals("preloadOutput")) {
                solver.relationsToPreLoad.add(r);
                solver.relationsToDump.add(r);
            } else if (option.equals("output")) {
                solver.relationsToDump.add(r);
            } else if (option.equals("outputtuples")) {
                solver.relationsToDumpTuples.add(r);
            } else if (option.equals("input")) {
                solver.relationsToLoad.add(r);
            } else if (option.equals("inputtuples")) {
                solver.relationsToLoadTuples.add(r);
            } else if (option.equals("printtuples")) {
                solver.relationsToPrintTuples.add(r);
            } else if (option.equals("printsize")) {
                solver.relationsToPrintSize.add(r);
            } else if (option.startsWith("pri")) {
                String num = option.substring(4);
                int pri = Integer.parseInt(num);
                r.priority = pri;
            } else if (option.equals("{")) {
                String s2 = nextToken(st);
                StringBuffer sb = new StringBuffer();
                while (!s2.equals("}")) {
                    sb.append(' ');
                    sb.append(s2);
                    if (!st.hasMoreTokens()) {
                        outputError(lineNum, st.getPosition(), s,
                            "Expected \"}\" to terminate code block");
                        throw new IllegalArgumentException();
                    }
                    s2 = nextToken(st);
                }
                CodeFragment f = new CodeFragment(sb.toString(), r);
                r.onUpdate.add(f);
            } else if (constraintMatcher.matches()) {
                parseAndAddConstraint(r, constraintMatcher);
            } else {
                outputError(lineNum, st.getPosition(), s,
                    "Unexpected option '" + option + "'");
                throw new IllegalArgumentException();
            }
        }
        if (!r.constraints.isEmpty()) {
            r.constraints.satisfy();
        }
        return r;
    }

    /**
     * Parse and add an attribute constraint.
     *
     * @param r  relation to add constraint for
     * @param m  constraint pattern matcher
     */
    public void parseAndAddConstraint(Relation r, Matcher m) {
        if (m.matches()) {
            String leftAttr = m.group(1);
            String type = m.group(2);
            String rightAttr = m.group(3);
            Attribute left = null;
            Attribute right = null;
            for (Iterator it = r.getAttributes().iterator(); it.hasNext();) {
                Attribute a = (Attribute) it.next();
                if (a.attributeName.equals(leftAttr)) left = a;
                if (a.attributeName.equals(rightAttr)) right = a;
            }
            if (left == null) {
                out.println("Specified Attribute not found: " + leftAttr);
                throw new IllegalArgumentException();
            } else if (right == null) {
                out.println("Specified Attribute not found: " + rightAttr);
                throw new IllegalArgumentException();
            }

            if (type.equals("=")) r.constraints.addInterleavedConstraint(new InterleavedConstraint(r,left,r,right,10));
            else if (type.equals("<")) r.constraints.addBeforeConstraint(new BeforeConstraint(r,left,r,right,10));
            if (TRACE) out.println("parsed constraint: " + leftAttr + " " + type + " " + rightAttr);
        } else {
            //handle error
        }
    }

    /**
     * Parse an inference rule.
     *
     * @param lineNum  current line number for outputting error messages
     * @param s  string containing rule to parse
     * @return  new inference rule
     */
    InferenceRule parseRule(int lineNum, String s) {
        MyStringTokenizer st = new MyStringTokenizer(s, " \t(,/).=!<>", true);
        Map/*<String,Variable>*/ nameToVar = new HashMap();
        undeclaredRelations.clear();
        RuleTerm bottom = parseRuleTerm(lineNum, s, nameToVar, st);
        String sep = nextToken(st);
        List/*<RuleTerm>*/ terms = new LinkedList();
        if (!sep.equals(".")) {
            if (!sep.equals(":-")) {
                outputError(lineNum, st.getPosition(), s,
                    "Expected \":-\", got \"" + sep + "\"");
                throw new IllegalArgumentException();
            }
            for (;;) {
                RuleTerm rt = parseRuleTerm(lineNum, s, nameToVar, st);
                if (rt == null) break;
                terms.add(rt);
                sep = nextToken(st);
                if (sep.equals(".")) break;
                if (!sep.equals(",")) {
                    outputError(lineNum, st.getPosition(), s,
                        "Expected \".\" or \",\", got \"" + sep + "\"");
                    throw new IllegalArgumentException();
                }
            }
        }
        handleUndeclaredRelations(lineNum, s, nameToVar, terms, bottom);
        InferenceRule ir = solver.createInferenceRule(terms, bottom);
        Variable v = ir.checkUniversalVariables();
        if (v != null) {
            outputError(lineNum, st.getPosition(), s,
                "Variable "+v+" was only used once!  Use '_' instead.");
            throw new IllegalArgumentException();
        }
        ir = parseRuleOptions(lineNum, s, ir, st);
        return ir;
    }

    /**
     * Finish the declaration of undeclared relations.
     */
    void handleUndeclaredRelations(int lineNum, String s, Map nameToVar,
        List terms, RuleTerm bottom) {
        for (;;) {
            boolean change = false;
            for (Iterator i = undeclaredRelations.iterator(); i.hasNext(); ) {
                Relation r = (Relation) i.next();
                boolean any = false;
                for (Iterator j = r.attributes.iterator(); j.hasNext(); ) {
                    Attribute a = (Attribute) j.next();
                    if (a.attributeDomain == null) {
                        // We didn't know the domain then, maybe we do now.
                        any = true;
                        String name = a.attributeName;
                        Variable v = (Variable) nameToVar.get(name);
                        if (v == null) {
                            outputError(lineNum, 0, s,
                                "Cannot find variable "+name);
                            throw new IllegalArgumentException();
                        }
                        if (v.domain != null) {
                            a.attributeDomain = v.domain;
                            change = true;
                        }
                    }
                }
                if (!any) {
                    if (solver.NOISY) out.println("Implicitly defining relation "+r.verboseToString());
                    i.remove();
                    // Handle other uses of this relation in this rule.
                    for (Iterator j = new AppendIterator(terms.iterator(), Collections.singleton(bottom).iterator());
                         j.hasNext(); ) {
                        RuleTerm rt = (RuleTerm) j.next();
                        if (rt.relation != r) continue;
                        for (int k = 0; k < r.numberOfAttributes(); ++k) {
                            Variable v = rt.getVariable(k);
                            if (v.domain != null) continue;
                            Attribute a = r.getAttribute(k);
                            v.domain = a.attributeDomain;
                            change = true;
                        }
                    }
                }
            }
            if (!change) break;
        }
        if (!undeclaredRelations.isEmpty()) {
            outputError(lineNum, 0, s,
                "Cannot infer attributes for undeclared relations "+undeclaredRelations);
            throw new IllegalArgumentException();
        }
    }

    /**
     * Parse the options for an inference rule.
     *
     * @param lineNum  current line number for outputting error messages
     * @param s  current line for outputting error messages
     * @param ir  inference rule to parse options for
     * @param st  string tokenizer containing options to parse
     * @return  the resulting rule
     */
    InferenceRule parseRuleOptions(int lineNum, String s, InferenceRule ir, MyStringTokenizer st) {
        while (st.hasMoreTokens()) {
            String option = nextToken(st);
            if (option.equals("split")) {
                if (!solver.SPLIT_NO_RULES) {
                    if (TRACE) out.println("Splitting rule " + ir);
                    ir.split = true;
                }
            } else if (option.equals("number")) {
                if (TRACE) out.println("Rule " + ir + " defines a numbering");
                ir = solver.createNumberingRule(ir);
            } else if (option.equals("single")) {
                if (TRACE) out.println("Rule " + ir + " only adds a single satisfying assignment");
                ir.single = true;
            } else if (option.equals("cacheafterrename")) {
                BDDInferenceRule r = (BDDInferenceRule) ir;
                r.cache_before_rename = false;
            } else if (option.equals("findbestorder")) {
                BDDInferenceRule r = (BDDInferenceRule) ir;
                r.find_best_order = true;
            } else if (option.equals("trace")) {
                BDDInferenceRule r = (BDDInferenceRule) ir;
                r.TRACE = true;
            } else if (option.equals("tracefull")) {
                BDDInferenceRule r = (BDDInferenceRule) ir;
                r.TRACE = true;
                r.TRACE_FULL = true;
            } else if (option.equals("pri")) {
                String num = nextToken(st);
                if (num.equals("=")) num = nextToken(st);
                int pri = Integer.parseInt(num);
                ir.priority = pri;
            } else if (option.equals("pre") || option.equals("post") || option.equals("{")) {
                StringBuffer sb = new StringBuffer();
                String s2 = nextToken(st);
                int type = 2;
                if (!option.equals("{")) {
                    if (option.equals("pre")) type = 1;
                    if (!s2.equals("{")) {
                        outputError(lineNum, st.getPosition(), s,
                            "Expected \"{\", but found \""+s2+"\"");
                        throw new IllegalArgumentException();
                    }
                    s2 = nextToken(st);
                }
                while (!s2.equals("}")) {
                    sb.append(' ');
                    sb.append(s2);
                    if (!st.hasMoreTokens()) {
                        outputError(lineNum, st.getPosition(), s,
                            "Expected \"}\" to terminate code block");
                        throw new IllegalArgumentException();
                    }
                    s2 = nextToken(st);
                }
                CodeFragment f = new CodeFragment(sb.toString(), ir);
                if (type == 1) ir.preCode.add(f);
                else ir.postCode.add(f);
            } else if (option.equals("modifies")) {
                String relationName = nextToken(st);
                if (relationName.equals("(")) {
                    for (;;) {
                        relationName = nextToken(st);
                        if (relationName.equals(",")) continue;
                        if (relationName.equals(")")) break;
                        Relation r = solver.getRelation(relationName);
                        if (r == null) {
                            outputError(lineNum, st.getPosition(), s,
                                "Unknown relation \""+relationName+"\"");
                            throw new IllegalArgumentException();
                        }
                        ir.extraDefines.add(r);
                    }
                } else {
                    Relation r = solver.getRelation(relationName);
                    if (r == null) {
                        outputError(lineNum, st.getPosition(), s,
                            "Unknown relation \""+relationName+"\"");
                        throw new IllegalArgumentException();
                    }
                    ir.extraDefines.add(r);
                }
            } else {
                // todo: maxiter=#
                outputError(lineNum, st.getPosition(), s,
                    "Unknown rule option \"" + option + "\"");
                throw new IllegalArgumentException();
            }
        }
        if (hasDuplicateVars && !(ir instanceof NumberingRule)) {
            outputError(lineNum, st.getPosition(), s,
                "Variable repeated multiple times in a single term");
            throw new IllegalArgumentException();
        }
        hasDuplicateVars = false;
        return ir;
    }

    /**
     * Flag that is set if a rule term has repeated variables.
     */
    boolean hasDuplicateVars;

    /**
     * Temporary collection to hold undeclared relations.
     */
    Collection undeclaredRelations = new LinkedList();

    /**
     * Parse a term of an inference rule.
     *
     * @param lineNum  current line number for outputting error messages
     * @param s  current line for outputting error messages
     * @param nameToVar  map from variable names to variables
     * @param st  string tokenizer containing rule term to parse
     * @return  rule term, or null if string is "?"
     */
    RuleTerm parseRuleTerm(int lineNum, String s, Map/*<String,Variable>*/ nameToVar, MyStringTokenizer st) {
        boolean negated = false;
        String relationName = nextToken(st);
        if (relationName.equals("?")) {
            return null;
        }
        if (relationName.equals("!")) {
            negated = true;
            relationName = nextToken(st);
        }
        String openParen = nextToken(st);
        boolean flip = false;
        boolean less = false;
        boolean greater = false;
        if (openParen.equals("!")) {
            flip = true;
            openParen = nextToken(st);
        } else if (openParen.equals("<")) {
            less = true;
            openParen = nextToken(st);
        } else if (openParen.equals(">")) {
            greater = true;
            openParen = nextToken(st);
        }
        if (openParen.equals("=") || less || greater) {
            if (negated) {
                outputError(lineNum, st.getPosition(), s,
                    "Unexpected \"!\"");
                throw new IllegalArgumentException();
            }
            // "a = b".
            boolean equals = openParen.equals("=");
            String varName1 = relationName;
            String varName2 = equals ? nextToken(st) : openParen;
            Variable var1, var2;
            var1 = (Variable) nameToVar.get(varName1);
            Relation r;
            if (equals && varName2.equals(">")) {
                if (negated || less || greater) {
                    outputError(lineNum, st.getPosition(), s,
                        "Unexpected \"!\", \"<\", or \">\" with \"=>\"");
                    throw new IllegalArgumentException();
                }
                // "a => b".
                varName2 = nextToken(st);
                var2 = (Variable) nameToVar.get(varName2);
                if (var1 == null || var2 == null) {
                    outputError(lineNum, st.getPosition(), s,
                        "Cannot use \"=>\" on unbound variables.");
                    throw new IllegalArgumentException();
                }
                r = solver.getMapRelation(var1.domain, var2.domain);
            } else {
                var2 = (Variable) nameToVar.get(varName2);
                if (var1 == null) {
                    if (var2 == null) {
                        outputError(lineNum, st.getPosition(), s,
                            "Cannot use \"=\", \"!=\", \"<\", \"<=\", \">\", \">=\", on two unbound variables.");
                        throw new IllegalArgumentException();
                    }
                    var1 = parseVariable(var2.domain, nameToVar, varName1);
                } else {
                    if (var2 == null) {
                        var2 = parseVariable(var1.domain, nameToVar, varName2);
                    }
                }
                if (var1.domain == null) var1.domain = var2.domain;
                if (var2.domain == null) var2.domain = var1.domain;
                if (var1.domain == null && var2.domain == null) {
                    outputError(lineNum, st.getPosition(), s,
                        "Cannot infer domain for variables "+var1+" and "+var2+" used in comparison.");
                    throw new IllegalArgumentException();
                }
                if (less) {
                    r = equals ? solver.getLessThanOrEqualRelation(var1.domain, var2.domain) : solver.getLessThanRelation(var1.domain, var2.domain);
                } else if (greater) {
                    r = equals ? solver.getGreaterThanOrEqualRelation(var1.domain, var2.domain) : solver.getGreaterThanRelation(var1.domain, var2.domain);
                } else {
                    r = flip ? solver.getNotEquivalenceRelation(var1.domain, var2.domain) : solver.getEquivalenceRelation(var1.domain, var2.domain);
                }
            }
            List vars = new Pair(var1, var2);
            RuleTerm rt = new RuleTerm(r, vars);
            return rt;
        } else if (!openParen.equals("(")) {
            outputError(lineNum, st.getPosition(), s,
                "Expected \"(\" or \"=\", got \"" + openParen + "\"");
            throw new IllegalArgumentException();
        }
        if (flip) {
            outputError(lineNum, st.getPosition(), s,
                "Unexpected \"!\"");
            throw new IllegalArgumentException();
        }
        Relation r = solver.getRelation(relationName);
        //if (r == null) {
        //    outputError(lineNum, st.getPosition(), s,
        //        "Unknown relation " + relationName);
        //    throw new IllegalArgumentException();
        //}
        if (negated && r != null) r = r.makeNegated(solver);
        List/*<Variable>*/ vars = new LinkedList();
        for (;;) {
            if (r != null && r.attributes.size() <= vars.size()) {
                outputError(lineNum, st.getPosition(), s,
                    "Too many fields for " + r);
                throw new IllegalArgumentException();
            }
            Attribute a = null;
            Domain fd = null;
            if (r != null) {
                a = (Attribute) r.attributes.get(vars.size());
                fd = a.attributeDomain;
            }
            String varName = nextToken(st);
            Variable var = parseVariable(fd, nameToVar, varName);
            if (vars.contains(var)) {
                hasDuplicateVars = true;
            }
            vars.add(var);
            if (var.domain == null) var.domain = fd;
            else if (fd != null && var.domain != fd) {
                outputError(lineNum, st.getPosition(), s,
                    "Variable " + var + " used as both " + var.domain + " and " + fd);
                throw new IllegalArgumentException();
            }
            String sep = nextToken(st);
            if (sep.equals(")")) break;
            if (!sep.equals(",")) {
                outputError(lineNum, st.getPosition(), s,
                    "Expected ',' or ')', got '" + sep + "'");
                throw new IllegalArgumentException();
            }
        }
        if (r != null && r.attributes.size() != vars.size()) {
            outputError(lineNum, st.getPosition(), s,
                "Wrong number of vars in rule term for " + relationName);
            throw new IllegalArgumentException();
        }
        if (r == null) {
            // Implicit creation of relation.
            List/*<Attribute>*/ attribs = new ArrayList(vars.size());
            for (Iterator i = vars.iterator(); i.hasNext(); ) {
                Variable v = (Variable) i.next();
                if (v instanceof Constant || "_".equals(v.name)) {
                    outputError(lineNum, st.getPosition(), s,
                        "Cannot infer attribute for '"+v.name+"' in undeclared relation "+relationName);
                    throw new IllegalArgumentException();
                }
                Attribute a = new Attribute(v.name, v.domain, null);
                attribs.add(a);
            }
            r = solver.createRelation(relationName, attribs);
            undeclaredRelations.add(r);
        }
        RuleTerm rt = new RuleTerm(r, vars);
        return rt;
    }

    /**
     * Parse a variable or a constant.
     *
     * @param fd  domain of variable/constant
     * @param nameToVar  map from names to variables for this rule
     * @param varName  name of variable/constant
     * @return  variable/constant
     */
    Variable parseVariable(Domain fd, Map nameToVar, String varName) {
        char firstChar = varName.charAt(0);
        Variable var;
        if (firstChar >= '0' && firstChar <= '9') {
            var = new Constant(Long.parseLong(varName));
        } else if (firstChar == '"') {
            String namedConstant = varName.substring(1, varName.length() - 1);
            var = new Constant(fd.namedConstant(namedConstant));
        } else if (!varName.equals("_")) {
            var = (Variable) nameToVar.get(varName);
            if (var == null) nameToVar.put(varName, var = new Variable(varName));
        } else {
            var = new Variable();
        }
        if (var.domain == null) var.domain = fd;
        return var;
    }

    /**
     * Parse a query.  A query is a statement that ends with '?'.
     *
     * @param lineNum  current line number, for outputting error messages
     * @param s  line to parse
     * @return  list of inference rules implementing the query.
     */
    List/*<InferenceRule>*/ parseQuery(int lineNum, String s) {
        MyStringTokenizer st = new MyStringTokenizer(s, " \t(,/).=~!?<>", true);
        Map/*<String,Variable>*/ nameToVar = new HashMap();

        if (s.indexOf(":-") > 0) {
            RuleTerm rt = parseRuleTerm(lineNum, s, nameToVar, st);
            String sep = nextToken(st);
            if (!sep.equals(":-")) {
                outputError(lineNum, st.getPosition(), s, "Expected \":-\", got \"" + sep + "\"");
                throw new IllegalArgumentException();
            }
            List/*<RuleTerm>*/ extras = new LinkedList();
            for (;;) {
                RuleTerm rt2 = parseRuleTerm(lineNum, s, nameToVar, st);
                if (rt2 == null) break;
                extras.add(rt2);
                String sep2 = nextToken(st);
                if (sep2.equals("?")) break;
                if (!sep2.equals(",")) {
                    outputError(lineNum, st.getPosition(), s, "Expected \",\", got \"" + sep2 + "\"");
                    throw new IllegalArgumentException();
                }
            }
            boolean single = false;
            while (st.hasMoreTokens()) {
                String option = nextToken(st);
                if (option.equals("single")) {
                    single = true;
                } else {
                    outputError(lineNum, st.getPosition(), s, "Unknown query option \"" + option + "\"");
                    throw new IllegalArgumentException();
                }
            }
            return solver.comeFromQuery(rt, extras, single);
        }
        List/*<RuleTerm>*/ terms = new LinkedList();
        Map varMap = new LinkedHashMap();
        for (;;) {
            RuleTerm rt = parseRuleTerm(lineNum, s, nameToVar, st);
            if (rt == null) break;
            terms.add(rt);
            for (Iterator i = rt.variables.iterator(); i.hasNext(); ) {
                Variable v = (Variable) i.next();
                if (v.name.equals("_")) continue;
                String name;
                if (v instanceof Constant) {
                    name = rt.relation.getAttribute(rt.variables.indexOf(v)).attributeName;
                } else {
                    name = v.toString();
                }
                varMap.put(v, name);
            }
            String sep = nextToken(st);
            if (sep.equals("?")) break;
            if (!sep.equals(",")) {
                outputError(lineNum, st.getPosition(), s,
                    "Expected \",\", got \"" + sep + "\"");
                throw new IllegalArgumentException();
            }
        }
        List vars = new ArrayList(varMap.keySet());
        List attributes = new ArrayList(vars.size());
        for (Iterator i = varMap.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry e = (Map.Entry) i.next();
            Variable v = (Variable) e.getKey();
            String name = (String) e.getValue();
            attributes.add(new Attribute(name, v.getDomain(), ""));
        }
        Relation r = solver.createRelation("query@"+lineNum, attributes);
        RuleTerm bottom = new RuleTerm(r, vars);
        InferenceRule ir = solver.createInferenceRule(terms, bottom);
        Variable v = ir.checkUniversalVariables();
        if (v != null) {
            outputError(lineNum, st.getPosition(), s,
                "Variable "+v+" was only used once!  Use '_' instead.");
            throw new IllegalArgumentException();
        }
        ir = parseRuleOptions(lineNum, s, ir, st);
        solver.relationsToPrintTuples.add(r);
        return Collections.singletonList(ir);
    }

}


text:
namespace CGAL{ namespace internal {

  template <class K>
  typename Intersection_traits<K, typename K::Triangle_2, typename K::Iso_rectangle_2>::result_type
  intersection(const typename K::Triangle_2 &t, const typename K::Iso_rectangle_2 &r, const K& kk)
  {
    typedef typename K::FT FT;
    typedef typename K::Segment_2 Segment;
    typedef typename K::Triangle_2 Triangle;
    typedef typename K::Point_2   Point;

    FT xr1, yr1, xr2, yr2;
    bool position[3][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};
    bool is_inside[3] = {false, false, false}; //true when a vertex is inside rectangle

    xr1 = r.xmin(); xr2 = r.xmax();
    yr1 = r.ymax(); yr2 = r.ymin();

    Point upper_left, lower_right;
    Point p[3]; //the vertices of triangle

    upper_left = Point(xr1, yr1); //upper left
    lower_right = Point(xr2, yr2); //lower right

    p[0] = t.vertex(0);
    p[1] = t.vertex(1);
    p[2] = t.vertex(2);

    //check the points of the triangle
    for(int i=0; i<3; i++){
      if(!(compare_x(p[i], upper_left) == SMALLER))
        if(!(compare_x(p[i], lower_right) == LARGER))
          if(!(compare_y(p[i], upper_left) == LARGER))
            if(!(compare_y(p[i], lower_right) == SMALLER))
              is_inside[i] = true; //the point is inside
            else
              position[i][2] = true; //South
          else
            position[i][0] = true; //North
        else
        {
          position[i][3] = true; //East
          if(compare_y(p[i], upper_left) == LARGER)
            position[i][0] = true; //North
          else if(compare_y(p[i], lower_right) == SMALLER)
            position[i][2] = true; //South
        }
      else
      {
        position[i][1] = true;  //West
        if(compare_y(p[i], upper_left) == LARGER)
          position[i][0] = true; //North
        else if(compare_y(p[i], lower_right) == SMALLER)
          position[i][2] = true; //South

      }
    }

    //test if the triangle is completely to the left, right, below or above the rectangle
    bool intersection = true; //true if it could be a intersection with the rectangle
    for(int j=0; j<4; j++)
      if(position[0][j] && position[1][j] && position[2][j] ){
        intersection = false;
        break;
      }

    if(intersection){
      Segment s[4]; //the segments that identify the N, W, S, E
      bool outside = false;
      bool status_in_list[3] = {false, false, false}; //true if the triangle's points are in the result vector
      std::list<int> last_intersected;
      int last_intersected_segment = 5; //could be 0=N, 1=W, 2=S, 3=E
      last_intersected.push_back(5);
      int status_intersected[4] = {0, 0, 0, 0}; //the number of intersections for each segment
      std::vector<Point> result; //the vector containing the result vertices
      int next; //the index of the next vertex

      s[0] = Segment(Point(xr2, yr1), Point(xr1, yr1)); //N
      s[1] = Segment(Point(xr1, yr1), Point(xr1, yr2)); //W
      s[2] = Segment(Point(xr1, yr2), Point(xr2, yr2)); //S
      s[3] = Segment(Point(xr2, yr2), Point(xr2, yr1)); //E

      //assign to p[i] the vertices of the triangle in ccw order
      if(t.orientation() == CGAL::CLOCKWISE)
      {
        p[0] = t.vertex(2);
        p[2] = t.vertex(0);

        is_inside[0] = is_inside[2] ^ is_inside[0];
        is_inside[2] = is_inside[2] ^ is_inside[0];
        is_inside[0] = is_inside[0] ^ is_inside[2];

        for(int i=0; i<4; i++){
          position[0][i] = position[2][i] ^ position[0][i];
          position[2][i] = position[2][i] ^ position[0][i];
          position[0][i] = position[0][i] ^ position[2][i];
        }
      }

      for(int index=0; index<3; index++) //for each vertex
      {
        next=(index+1)%3;
        if(is_inside[index]){ // true if first is inside
          if(!status_in_list[index]){  //if is not yet in the list
            result.push_back(p[index]);
            status_in_list[index] = true;
          }
          if(is_inside[next]){ //true if second is inside
            //add the points in the vector
            if(!status_in_list[next]){ // if is not yet in the list
              result.push_back(p[next]);
              status_in_list[next] = true;
            }
          } else { //I'm going out, the second is outside
            for(int j=0; j<4; j++) // for all directions
              if(position[next][j]) // if it's a second point direction
              {
                //test for intersection
                typename Intersection_traits<K, Segment, Segment>::result_type
                  v = internal::intersection(Segment(p[index], p[next]), s[j], kk);
                if(v) {
                  if(const Point *p_obj = intersect_get<Point>(v))
                {
                  //intersection found
                  outside = true;
                  result.push_back(*p_obj); //add the intersection point
                  if(last_intersected.back()!=j)
                    last_intersected.push_back(j);
                  status_intersected[j]++;
                }
              }
          }
          }
        } else { //the first point is outside
          for(int j=0; j<4; j++) // for all directions
            if(position[index][j]) //watch only the first point directions
            {
              //test for intersection
              typename Intersection_traits<K, Segment, Segment>::result_type
                v = internal::intersection(Segment(p[index], p[next]), s[j], kk);
              if(v) {
                if(const Point *p_obj = intersect_get<Point>(v))
              {
                //intersection found
                outside = false;
                last_intersected_segment = last_intersected.back();
                if(last_intersected_segment != 5 && last_intersected_segment != j && status_intersected[j] == 0){
                  //add the target of each rectangle segment in the list
                  if(last_intersected_segment < j)
                    while(last_intersected_segment < j){
                      result.push_back(s[last_intersected_segment].target());
                      last_intersected_segment++;
                    }
                  else{
                    while(last_intersected_segment < 4){
                      result.push_back(s[last_intersected_segment].target());
                      last_intersected_segment++;
                    }
                    last_intersected_segment = 0;
                    while(last_intersected_segment < j){
                      result.push_back(s[last_intersected_segment].target());
                      last_intersected_segment++;
                    }
                  }
                }
                result.push_back(*p_obj); //add the intersection point in the list
                if(last_intersected.back()!=j)
                  last_intersected.push_back(j);
                status_intersected[j]++;
                if(!is_inside[next]){ //if the second point is not inside search a second intersection point
                  for(j=0; j<4; j++) // for all directions
                    if(position[next][j])
                    {
                      //test for intersection
                        typename Intersection_traits<K, Segment, Segment>
                          ::result_type
                          v = internal::intersection(Segment(p[index], p[next]), s[j], kk);
                        if(v) {
                          if(const Point *p_obj = intersect_get<Point>(v))
                           //found the second intersection
                      {
                        outside = true;
                        result.push_back(*p_obj);
                        if(last_intersected.back()!=j)
                          last_intersected.push_back(j);
                        status_intersected[j]++;
                      }
                    }
                      }
                }//end if the second point is not inside
              }
              } // end v
            }
        }//end else (the first point is outside)
      }//endfor
      if(outside){
        std::list<int>::const_iterator it = last_intersected.begin();
        while(*it == 5)
          it++;
        last_intersected_segment = *it;
        int j = last_intersected.back();
        if(last_intersected_segment != 5 && last_intersected_segment != j){
          //add the target of each rectangle segment in the list
          if(last_intersected_segment > j)
            while(last_intersected_segment > j){
              result.push_back(s[j].target());
              j++;
            }
          else{
            while(j<4){
              result.push_back(s[j].target());
              j++;
            }
            j = 0;
            while(j<last_intersected_segment){
              result.push_back(s[j].target());
              j++;
            }
          }
        }
      }//end if(outside)

      //test if were not intersections
      //between the triangle and the rectangle
      if(status_intersected[0] == 0 && status_intersected[1] == 0 &&
        status_intersected[2] == 0 && status_intersected[3] == 0)
      {
        //should test if the rectangle is inside the triangle
        if(t.bounded_side(upper_left) == CGAL::ON_BOUNDED_SIDE){
          for(int k=0; k<4; k++)
            result.push_back(s[k].source());
        }
      }
      //remove duplicated consecutive points
      typename std::vector<Point>::iterator last = std::unique(result.begin(),result.end());
      result.erase(last,result.end());

      switch(result.size()){
        case 0:
          return intersection_return<typename K::Intersect_2, Triangle, typename K::Iso_rectangle_2>();
        case 1:
          return intersection_return<typename K::Intersect_2, Triangle, typename K::Iso_rectangle_2>(result[0]);
        case 2:
          return intersection_return<typename K::Intersect_2, Triangle, typename K::Iso_rectangle_2>(Segment(result[0], result[1]));
        case 3:
          return intersection_return<typename K::Intersect_2, Triangle, typename K::Iso_rectangle_2>(Triangle(result[0], result[1], result[2]));
        default:
          return intersection_return<typename K::Intersect_2, Triangle, typename K::Iso_rectangle_2>(result);
      }

    }//end if(intersection)
    return intersection_return<typename K::Intersect_2, Triangle, typename K::Iso_rectangle_2>();
  }//end intersection

  template <class K>
  typename Intersection_traits<K, typename K::Triangle_2, typename K::Iso_rectangle_2>::result_type
  inline intersection(const typename K::Iso_rectangle_2 &r, const typename K::Triangle_2 &t, const K& k)
  {
    return intersection(t,r,k);
  }

  template <class K>
  bool do_intersect(
    const typename K::Triangle_2 &tr,
    const typename K::Iso_rectangle_2 &ir,
    const K& k)
  {
    //1) check if at least one vertex of tr is not outside ir
    //2) if not, check if at least on vertex of tr is not outside tr

    typename K::Has_on_unbounded_side_2 unbounded_side=k.has_on_unbounded_side_2_object();
    typename K::Construct_vertex_2 vertex=k.construct_vertex_2_object();

    for (int i=0;i<3;++i)
      if ( !unbounded_side( ir,vertex(tr,i) ) ) return true;
    for (int i=0;i<4;++i)
      if ( !unbounded_side( tr,vertex(ir,i) ) ) return true;

    typename K::Construct_segment_2 segment=k.construct_segment_2_object();
    for (int i=0;i<3;++i)
      if ( do_intersect(
            segment(vertex(tr,i),vertex(tr,(i+1)%3)),
            ir, k) ) return true;

    return false;
  }

  template <class K>
  inline bool do_intersect(
    const typename K::Iso_rectangle_2 &ir,
    const typename K::Triangle_2 &tr,
    const K& k)
  {
    return do_intersect(tr,ir,k);
  }

} //namespace internal

CGAL_INTERSECTION_FUNCTION(Triangle_2, Iso_rectangle_2, 2)
CGAL_DO_INTERSECT_FUNCTION(Triangle_2, Iso_rectangle_2, 2)

}//end namespace

#endif

redpajama_set_name: RedPajamaGithub


text:
//
// Copyright (c) Microsoft and contributors.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//

var _ = require('underscore');
var util = require('util');

var azureutil = require('./util');
var SR = require('./sr');
var check = require('validator');

exports = module.exports;

function initCallback(callbackParam, resultsCb) {
  var fail;
  if (callbackParam) {
    fail = function (err) {
      callbackParam(new Error(err));
      return false;
    };
  } else {
    fail = function (err) {
      throw new Error(err);
    };
    callbackParam = function () {};
  }

  resultsCb(fail, callbackParam);
}

/**
* Creates a anonymous function that check if the given uri is valid or not.
*
* @param {string} uri     The uri to validate.
* @return {boolean}
*/
exports.isValidUri = function (uri) {
  if (!check.isURL(uri)){
    throw new Error('The provided URI "' + uri + '" is invalid.');
  }
  return true;
};

/**
* Checks if the given host is valid or not.
*
* @param {string|object} host     The host to validate.
* @return {boolean}
*/
exports.isValidHost= function (host) {
  if (azureutil.objectIsNull(host)) {
    throw new Error(SR.STORAGE_HOST_LOCATION_REQUIRED);
  } else {
    var storageHost = {};
    storageHost.primaryHost = _.isString(host) ? host : host.primaryHost;
    if (storageHost.primaryHost && !check.isURL(storageHost.primaryHost)){
      throw new Error('The provided URI "' + storageHost.primaryHost + '" is invalid.');
    }

    storageHost.secondaryHost = _.isString(host) ? undefined : host.secondaryHost;
    if (storageHost.secondaryHost && !check.isURL(storageHost.secondaryHost)){
      throw new Error('The provided URI "' + storageHost.secondaryHost + '" is invalid.');
    }

    if (!storageHost.primaryHost && !storageHost.secondaryHost) {
      throw new Error(SR.STORAGE_HOST_LOCATION_REQUIRED);
    }
  }

  return true;
};

exports.isValidUuid = function(uuid, callback) {
  var validUuidRegex = /^[a-zA-Z0-9]{8}\-[a-zA-Z0-9]{4}\-[a-zA-Z0-9]{4}\-[a-zA-Z0-9]{4}\-[a-zA-Z0-9]{12}$/;

  var fail;

  initCallback(callback, function (f, cb) {
    fail = f;
    callback = cb;
  });

  if (!validUuidRegex.test(uuid)) {
    return fail('The value is not a valid UUID format.');
  }
};

/**
* Creates a anonymous function that check if a given key is base 64 encoded.
*
* @param {string} key The key to validate.
* @return {function}
*/
exports.isBase64Encoded = function (key) {
  var isValidBase64String = key.match(/^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$/);

  if (isValidBase64String) {
    return true;
  } else {
    throw new Error('The provided account key ' + key + ' is not a valid base64 string.');
  }
};

/**
* Validates a function.
*
* @param {object} function The function to validate.
* @return {function}
*/
exports.isValidFunction = function (functionObject, functionName) {
  if (!functionObject || !_.isFunction(functionObject)) {
    throw new Error(functionName + ' must be specified.');
  }
};

var getNameError = function(name) {
  // checks if name is null, undefined or empty
  if (azureutil.stringIsEmpty(name)) {
    return '%s name must be a non empty string.';
  }

  // check if name is between 3 and 63 characters
  if (name.length < 3 || name.length > 63) {
    return '%s name must be between 3 and 63 characters long.';
  }

  // check if name follows naming rules
  if (name.match(/^([a-z0-9]+(-[a-z0-9]+)*)$/) === null) {
    return '%s name format is incorrect.';
  }

  return null;
}

/**
* Validates a container name.
*
* @param {string} containerName The container name.
* @return {undefined}
*/
exports.containerNameIsValid = function (containerName, callback) {
  var fail;
  initCallback(callback, function (f, cb) {
    fail = f;
    callback = cb;
  });

  var nameErrorString = getNameError(containerName);

  if (!nameErrorString || containerName.match(/^(\$root|\$logs)$/)) {
    callback();
    return true;
  } else {
    return fail(util.format(nameErrorString, 'Container'));
  }
};

/**
* Validates a share name.
*
* @param {string} shareName The share name.
* @return {undefined}
*/
exports.shareNameIsValid = function (shareName, callback) {
  var fail;
  initCallback(callback, function (f, cb) {
    fail = f;
    callback = cb;
  });

  var nameErrorString = getNameError(shareName);

  if (!nameErrorString) {
    callback();
    return true;
  } else {
    return fail(util.format(nameErrorString, 'Share'));
  }
};

/**
* Validates a queue name.
*
* @param {string} queueName The queue name.
* @return {undefined}
*/
exports.queueNameIsValid = function (queueName, callback) {
  var fail;

  initCallback(callback, function (f, cb) {
    fail = f;
    callback = cb;
  });

  var nameErrorString = getNameError(queueName);

  if (!nameErrorString) {
    callback();
    return true;
  } else {
    return fail(util.format(nameErrorString, 'Queue'));
  }
};

/**
* Validates a table name.
*
* @param {string} table  The table name.
* @return {undefined}
*/
exports.tableNameIsValid = function (table, callback) {
  var fail;

  initCallback(callback, function (f, cb) {
    fail = f;
    callback = cb;
  });

  if (azureutil.stringIsEmpty(table)) {
    return fail('Table name must be a non empty string.');
  }

  if (table.length < 3 || table.length > 63) {
    return fail('Table name must be between 3 and 63 characters long.');
  }

  if(table.toLowerCase() == 'tables') {
    return fail('Table name cannot be \'Tables\'.');
  }

  if (table.match(/^([A-Za-z][A-Za-z0-9]{2,62})$/) !== null || table === '$MetricsCapacityBlob' || table.match(/^(\$Metrics(HourPrimary|MinutePrimary|HourSecondary|MinuteSecondary)?(Transactions)(Blob|Queue|Table))$/) !== null)
  {
    callback();
    return true;
  } else {
    return fail('Table name format is incorrect.');
  }

};

exports.pageRangesAreValid = function (rangeStart, rangeEnd, writeBlockSizeInBytes, callback) {
  var fail;

  initCallback(callback, function (f, cb) {
    fail = f;
    callback = cb;
  });

  if (rangeStart % 512 !== 0) {
    return fail('Start byte offset must be a modulus of 512.');
  }

  var size = null;
  if (!azureutil.objectIsNull(rangeEnd)) {
    if ((rangeEnd + 1) % 512 !== 0) {
      return fail('End byte offset must be a modulus of 512 minus 1.');
    }

    size = (rangeEnd - rangeStart) + 1;
    if (size > this.writeBlockSizeInBytes) {
      return fail('Page blob size cant be larger than ' + writeBlockSizeInBytes + ' bytes.');
    }
  }

  callback();
  return true;
};

// common functions for validating arguments

function throwMissingArgument(name, func) {
  throw new Error('Required argument ' + name + ' for function ' + func + ' is not defined');
}

function ArgumentValidator(functionName) {
  this.func = functionName;
}

_.extend(ArgumentValidator.prototype, {
  string: function (val, name) {
    this.exists(val, name);
    if (typeof val != 'string') {
      throw new Error('Parameter ' + name + ' for function ' + this.func + ' should be a non-empty string');
    }
  },

  stringAllowEmpty: function (val, name) {
    if (typeof val != 'string') {
      throwMissingArgument(name, this.func);
    }
  },

  object: function (val, name) {
    this.exists(val, name);
    if (typeof val != 'object') {
      throw new Error('Parameter ' + name + ' for function ' + this.func + ' should be an object');
    }
  },

  exists: function (val, name) {
    if (!val) {
      throwMissingArgument(name, this.func);
    }
  },

  function: function (val, name) {
    this.exists(val, name);
    if (typeof val !== 'function') {
      throw new Error('Parameter ' + name + ' for function ' + this.func + ' should be a function');
    }
  },

  value: function (val, name) {
    if (!val && val !== 0) {
      throwMissingArgument(name, this.func);
    }
  },

  nonEmptyArray: function (val, name) {
    if (!val || val.length === 0) {
      throw new Error('Required array argument ' + name + ' for function ' + this.func + ' is either not defined or empty');
    }
  },

  callback: function (val) {
    this.exists(val, 'callback');
    this.function(val, 'callback');
  },

  test: function (predicate, message) {
    if (!predicate()) {
      throw new Error(message + ' in function ' + this.func);
    }
  },

  tableNameIsValid: exports.tableNameIsValid,
  containerNameIsValid: exports.containerNameIsValid,
  shareNameIsValid: exports.shareNameIsValid,
  blobNameIsValid: exports.blobNameIsValid,
  pageRangesAreValid: exports.pageRangesAreValid,
  queueNameIsValid: exports.queueNameIsValid
});

function validateArgs(functionName, validationRules) {
  var validator = new ArgumentValidator(functionName);
  validationRules(validator);
}

exports.ArgumentValidator = ArgumentValidator;
exports.validateArgs = validateArgs;


text:
import warnings
warnings.warn("Module is deprecated.", DeprecationWarning)

from distribution import Distribution

from traits.api import Float
from traitsui.api import View, Item

class Gaussian(Distribution):
    """ A gaussian distribution """
    mean = Float(50.0)
    std = Float(2.0)

    traits_view = View(Item('mean'), Item('std'))

    def _get_value(self, n):
        return self._state.normal(self.mean, self.std, n)


text:
using MailChimp.Lists;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace MailChimp.Webhooks
{
    /// <summary>
    /// Data returned from an Unsubscribe Webhook
    /// </summary>
    [DataContract]
    public class UnsubscribeWebhookData
    {
        /// <summary>
        /// The action performed
        /// </summary>
        [DataMember(Name = "action")]
        public string Action
        {
            get;
            set;
        }

        /// <summary>
        /// The unsubscribe reason if given
        /// </summary>
        [DataMember(Name = "reason")]
        public string Reason
        {
            get;
            set;
        }

        /// <summary>
        /// The ID of the member
        /// </summary>
        [DataMember(Name = "id")]
        public string ID
        {
            get;
            set;
        }

        /// <summary>
        /// The ID of the list they unsubscribed from
        /// </summary>
        [DataMember(Name = "list_id")]
        public string ListId
        {
            get;
            set;
        }

        /// <summary>
        /// The email address that was unsubscribed
        /// </summary>
        [DataMember(Name = "email")]
        public string Email
        {
            get;
            set;
        }

        /// <summary>
        /// The type of email e.g. "Html"
        /// </summary>
        [DataMember(Name = "email_type")]
        public string EmailType
        {
            get;
            set;
        }

        /// <summary>
        /// The merges supplied
        /// </summary>
        [DataMember(Name = "merges")]
        public MergeVar Merges
        {
            get;
            set;
        }

        /// <summary>
        /// IP address
        /// </summary>
        [DataMember(Name = "ip_opt")]
        public string IPOpt
        {
            get;
            set;
        }

        /// <summary>
        /// Campaign ID
        /// </summary>
        [DataMember(Name = "campaign_id")]
        public string CampaignID
        {
            get;
            set;
        }

    }
}


text:
cask "kindle-previewer" do
  version "3.66.0"
  sha256 :no_check

  url "https://d2bzeorukaqrvt.cloudfront.net/KindlePreviewerInstaller.pkg",
      verified: "d2bzeorukaqrvt.cloudfront.net/"
  name "Kindle Previewer"
  desc "Preview and audit Kindle eBooks"
  homepage "https://www.amazon.com/Kindle-Previewer/b?ie=UTF8&node=21381691011"

  livecheck do
    url :homepage
    regex(/Kindle\s*Previewer\s*(\d+(?:\.\d+)+)/i)
  end

  auto_updates true

  pkg "KindlePreviewerInstaller.pkg"

  uninstall launchctl: "com.amazon.KindlePreviewerUpdater",
            pkgutil:   "Amazon.Kindle.Previewer.pkg"

  zap trash: [
    "/Library/LaunchDaemons/com.amazon.KindlePreviewerUpdater.plist",
    "~/.kindle",
  ]
end


text:
namespace chatterino {

class Application;
class Paths;

void registerNmHost(Paths &paths);
std::string &getNmQueueName(Paths &paths);

class NativeMessagingClient final
{
public:
    void sendMessage(const QByteArray &array);
    void writeToCout(const QByteArray &array);
};

class NativeMessagingServer final
{
public:
    void start();

private:
    class ReceiverThread : public QThread
    {
    public:
        void run() override;

    private:
        void handleMessage(const QJsonObject &root);
    };

    ReceiverThread thread;
};

}  // namespace chatterino


text:
<if condition="0 eq $follow_state['following']">

<else />

</if>


text:
Keeping documentation up-to-date is tough, non-source files such as a TODO file will not break code if it is left stale, which is why generally these files are the last to be updated.

Keeping a fresh TODO file allows users to informed on which tasks are yet to be done,
without relying on third-party issue tracking software.

Even using third-party issue tracking software requires maintainance.

### Why not generate TODO tasks automagically with simple source code comments?
Autotodo is a source code parser that extracts TODO source code lines and outputs
a TODO file for you!

A developer can now go through his/her development, mark TODO's as typical inline comments,
and run the program

Autotodo will recursively go though the passed argument and search for TODO inlne comments

### Installation
No installation required, just clone the repo for the script

### Usage
`python gen_todo.py <base_dir>`

`cat TODO`

`path_to_file_hit:line_numer: [source code line containing inline comment]`

Implemented in python 2 using standard library features
Licensed with BSD 3-Clause

Written by Jason Quisberth


text:
namespace iter {
  namespace impl {
    struct UniqueEverseenFn : Pipeable<UniqueEverseenFn> {
      template <typename Container>
      auto operator()(Container&& container) const {
        using elem_type = impl::iterator_deref<Container>;
        auto func = [elem_seen = std::unordered_set<std::decay_t<elem_type>>()](
            const std::remove_reference_t<elem_type>& e) mutable {
          return elem_seen.insert(e).second;
        };
        return filter(func, std::forward<Container>(container));
      }
    };
  }

  constexpr impl::UniqueEverseenFn unique_everseen{};
}

#endif


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Arch.SOA.ESB.Entity
{
    /// <summary>
    /// ESB结果实体
    /// 创建    刘剡    2009-1-7
    /// </summary>
    [Serializable]
    public class Response : Ctrip.SOA.Comm.ResponseBase
    {
        [System.Xml.Serialization.XmlElementAttribute("CounterList", typeof(CounterList), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        [System.Xml.Serialization.XmlElementAttribute("ReferenceIDSerial", typeof(Ctrip.SOA.Comm.Entity.ReferenceIDSerial), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        [System.Xml.Serialization.XmlElementAttribute("ESBCache", typeof(System.Data.DataSet), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public object ResponseBody;
    }

    /// <summary>
    /// 计数器列表
    /// </summary>
    [Serializable]
    public class CounterList
    {
        public List<CounterEntity> counters = new List<CounterEntity>();
    }

}


text:
require 'spec_helper'

# Put your acceptance spec helpers inside spec/acceptance/support
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}

Capybara.default_wait_time = 4

RSpec.configure do |c|
  c.include HelperMethods
  c.include NavigationHelpers
  c.include Spacepub::Ext::Capybara::Node::Actions
end


text:
$(document).ready(function() {

    //select all the a tag with name equal to modal
    $('a[name=modal]').click(function(e) {
        //Cancel the link behavior
        e.preventDefault();
        //Get the A tag
        var id = $(this).attr('href');

        //Get the screen height and width
        var maskHeight = $(document).height();
        var maskWidth = $(window).width();

        //Set height and width to mask to fill up the whole screen
        $('#mask').css({'width':maskWidth,'height':maskHeight});

        //transition effect
        $('#mask').fadeIn(1000);
        $('#mask').fadeTo("slow",0.8);

        //Get the window height and width
        var winH = $(window).height();
        var winW = $(window).width();

        //Set the popup window to center
        $(id).css('top',  winH/2-$(id).height()/2);
        $(id).css('left', winW/2-$(id).width()/2);

        //transition effect
        $(id).fadeIn(2000);

    });

    //if close button is clicked
    $('.window .close').click(function (e) {
        //Cancel the link behavior
        e.preventDefault();
        $('#mask, .window').hide();
    });

    //if mask is clicked
    $('#mask').click(function () {
        $(this).hide();
        $('.window').hide();
    });

});