text:
//
// Parses WebAssembly code in S-Expression format, as in .wast files
// such as are in the spec test suite.
//

#ifndef wasm_wasm_s_parser_h
#define wasm_wasm_s_parser_h

#include <cmath>
#include <cctype>
#include <limits>

#include "wasm.h"
#include "wasm-binary.h"
#include "shared-constants.h"
#include "asmjs/shared-constants.h"
#include "mixed_arena.h"
#include "parsing.h"
#include "asm_v_wasm.h"
#include "ast_utils.h"
#include "wasm-builder.h"

namespace wasm {

using namespace cashew;

// Globals

inline int unhex(char c) {
  if (c >= '0' && c <= '9') return c - '0';
  if (c >= 'a' && c <= 'f') return c - 'a' + 10;
  if (c >= 'A' && c <= 'F') return c - 'A' + 10;
  abort();
}

//
// An element in an S-Expression: a list or a string
//

class Element {
  typedef ArenaVector<Element*> List;

  bool isList_;
  List list_;
  IString str_;
  bool dollared_;

public:
  Element(MixedArena& allocator) : isList_(true), list_(allocator), line(-1), col(-1) {}

  bool isList() { return isList_; }
  bool isStr() { return !isList_; }
  bool dollared() { return dollared_; }

  size_t line, col;

  // list methods

  List& list() {
    if (!isList()) throw ParseException("expected list", line, col);
    return list_;
  }

  Element* operator[](unsigned i) {
    if (i >= list().size()) throw ParseException("expected more elements in list", line, col);
    return list()[i];
  }

  size_t size() {
    return list().size();
  }

  // string methods

  IString str() {
    assert(!isList_);
    return str_;
  }

  const char* c_str() {
    assert(!isList_);
    return str_.str;
  }

  Element* setString(IString str__, bool dollared__) {
    isList_ = false;
    str_ = str__;
    dollared_ = dollared__;
    return this;
  }

  Element* setMetadata(size_t line_, size_t col_) {
    line = line_;
    col = col_;
    return this;
  }

  // printing

  friend std::ostream& operator<<(std::ostream& o, Element& e) {
    if (e.isList_) {
      o << '(';
      for (auto item : e.list_) o << ' ' << *item;
      o << " )";
    } else {
      o << e.str_.str;
    }
    return o;
  }

  void dump() {
    std::cout << "dumping " << this << " : " << *this << ".\n";
  }
};

//
// Generic S-Expression parsing into lists
//

class SExpressionParser {
  char* input;
  size_t line;
  char* lineStart;

  MixedArena allocator;

public:
  // Assumes control of and modifies the input.
  SExpressionParser(char* input) : input(input) {
    root = nullptr;
    line = 0;
    lineStart = input;
    while (!root) { // keep parsing until we pass an initial comment
      root = parse();
    }
  }

  Element* root;

private:
  Element* parse() {
    std::vector<Element *> stack;
    Element *curr = allocator.alloc<Element>();
    while (1) {
      skipWhitespace();
      if (input[0] == 0) break;
      if (input[0] == '(') {
        input++;
        stack.push_back(curr);
        curr = allocator.alloc<Element>()->setMetadata(line, input - lineStart - 1);
      } else if (input[0] == ')') {
        input++;
        auto last = curr;
        curr = stack.back();
        assert(stack.size());
        stack.pop_back();
        curr->list().push_back(last);
      } else {
        curr->list().push_back(parseString());
      }
    }
    if (stack.size() != 0) throw ParseException("stack is not empty", curr->line, curr->col);
    return curr;
  }

  void skipWhitespace() {
    while (1) {
      while (isspace(input[0])) {
        if (input[0] == '\n') {
          line++;
          lineStart = input + 1;
        }
        input++;
      }
      if (input[0] == ';' && input[1] == ';') {
        while (input[0] && input[0] != '\n') input++;
        line++;
        lineStart = input;
      } else if (input[0] == '(' && input[1] == ';') {
        // Skip nested block comments.
        input += 2;
        int depth = 1;
        while (1) {
          if (input[0] == 0) {
            return;
          }
          if (input[0] == '(' && input[1] == ';') {
            input += 2;
            depth++;
          } else if (input[0] == ';' && input[1] == ')') {
            input += 2;
            --depth;
            if (depth == 0) {
              break;
            }
          } else {
            input++;
          }
        }
      } else {
        return;
      }
    }
  }

  Element* parseString() {
    bool dollared = false;
    if (input[0] == '$') {
      input++;
      dollared = true;
    }
    char *start = input;
    if (input[0] == '"') {
      // parse escaping \", but leave code escaped - we'll handle escaping in memory segments specifically
      input++;
      std::string str;
      while (1) {
        if (input[0] == '"') break;
        if (input[0] == '\\') {
          str += input[0];
          str += input[1];
          input += 2;
          continue;
        }
        str += input[0];
        input++;
      }
      input++;
      return allocator.alloc<Element>()->setString(IString(str.c_str(), false), dollared)->setMetadata(line, start - lineStart);
    }
    while (input[0] && !isspace(input[0]) && input[0] != ')' && input[0] != '(' && input[0] != ';') input++;
    if (start == input) throw ParseException("expected string", line, input - lineStart);
    char temp = input[0];
    input[0] = 0;
    auto ret = allocator.alloc<Element>()->setString(IString(start, false), dollared)->setMetadata(line, start - lineStart);
    input[0] = temp;
    return ret;
  }
};

//
// SExpressions => WebAssembly module
//

class SExpressionWasmBuilder {
  Module& wasm;
  MixedArena& allocator;
  std::vector<Name> functionNames;
  int functionCounter;
  int importCounter;
  int globalCounter;
  std::map<Name, WasmType> functionTypes; // we need to know function return types before we parse their contents

public:
  // Assumes control of and modifies the input.
  SExpressionWasmBuilder(Module& wasm, Element& module) : wasm(wasm), allocator(wasm.allocator), importCounter(0), globalCounter(0) {
    assert(module[0]->str() == MODULE);
    if (module.size() > 1 && module[1]->isStr()) {
      // these s-expressions contain a binary module, actually
      std::vector<char> data;
      size_t i = 1;
      while (i < module.size()) {
        auto str = module[i++]->c_str();
        if (auto size = strlen(str)) {
          stringToBinary(str, size, data);
        }
      }
      WasmBinaryBuilder binaryBuilder(wasm, data, false);
      binaryBuilder.read();
      return;
    }
    functionCounter = 0;
    for (unsigned i = 1; i < module.size(); i++) {
      preParseFunctionType(*module[i]);
      preParseImports(*module[i]);
    }
    functionCounter = 0;
    for (unsigned i = 1; i < module.size(); i++) {
      parseModuleElement(*module[i]);
    }
  }

private:

  // pre-parse types and function definitions, so we know function return types before parsing their contents
  void preParseFunctionType(Element& s) {
    IString id = s[0]->str();
    if (id == TYPE) return parseType(s);
    if (id != FUNC) return;
    size_t i = 1;
    Name name, exportName;
    i = parseFunctionNames(s, name, exportName);
    if (!name.is()) {
      // unnamed, use an index
      name = Name::fromInt(functionCounter);
    }
    functionNames.push_back(name);
    functionCounter++;
    FunctionType* type = nullptr;
    functionTypes[name] = none;
    std::vector<WasmType> params;
    for (;i < s.size(); i++) {
      Element& curr = *s[i];
      IString id = curr[0]->str();
      if (id == RESULT) {
        functionTypes[name] = stringToWasmType(curr[1]->str());
      } else if (id == TYPE) {
        Name typeName = curr[1]->str();
        if (!wasm.checkFunctionType(typeName)) throw ParseException("unknown function");
        type = wasm.getFunctionType(typeName);
        functionTypes[name] = type->result;
      } else if (id == PARAM && curr.size() > 1) {
        Index j = 1;
        if (curr[j]->dollared()) {
          // dollared input symbols cannot be types
          params.push_back(stringToWasmType(curr[j + 1]->str(), true));
        } else {
          while (j < curr.size()) {
            params.push_back(stringToWasmType(curr[j++]->str(), true));
          }
        }
      }
    }
    if (!type) {
      // if no function type provided, generate one, but reuse a previous one with the
      // right structure if there is one.
      // see https://github.com/WebAssembly/spec/pull/301
      bool need = true;
      std::unique_ptr<FunctionType> functionType = make_unique<FunctionType>();
      functionType->result = functionTypes[name];
      functionType->params = std::move(params);
      for (auto& existing : wasm.functionTypes) {
        if (existing->structuralComparison(*functionType)) {
          need = false;
          break;
        }
      }
      if (need) {
        wasm.addFunctionType(functionType.release());
      }
    }
  }

  void preParseImports(Element& curr) {
    IString id = curr[0]->str();
    if (id == IMPORT) parseImport(curr);
  }

  void parseModuleElement(Element& curr) {
    IString id = curr[0]->str();
    if (id == START) return parseStart(curr);
    if (id == FUNC) return parseFunction(curr);
    if (id == MEMORY) return parseMemory(curr);
    if (id == EXPORT) return parseExport(curr);
    if (id == IMPORT) return; // already done
    if (id == GLOBAL) return parseGlobal(curr);
    if (id == TABLE) return parseTable(curr);
    if (id == TYPE) return; // already done
    std::cerr << "bad module element " << id.str << '\n';
    throw ParseException("unknown module element");
  }

  // function parsing state
  std::unique_ptr<Function> currFunction;
  std::map<Name, WasmType> currLocalTypes;
  size_t localIndex; // params and vars
  size_t otherIndex;
  std::vector<Name> labelStack;
  bool brokeToAutoBlock;

  Name getPrefixedName(std::string prefix) {
    return IString((prefix + std::to_string(otherIndex++)).c_str(), false);
  }

  Name getFunctionName(Element& s) {
    if (s.dollared()) {
      return s.str();
    } else {
      // index
      size_t offset = atoi(s.str().c_str());
      if (offset >= functionNames.size()) throw ParseException("unknown function");
      return functionNames[offset];
    }
  }

  void parseStart(Element& s) {
    wasm.addStart(getFunctionName(*s[1]));
  }

  // returns the next index in s
  size_t parseFunctionNames(Element& s, Name& name, Name& exportName) {
    size_t i = 1;
    while (i < s.size() && s[i]->isStr()) {
      if (!s[i]->dollared()) {
        // an export name
        exportName = s[i]->str();
        i++;
      } else {
        name = s[i]->str();
        i++;
      }
    }
    return i;
  }

  void parseFunction(Element& s) {
    size_t i = 1;
    Name name, exportName;
    i = parseFunctionNames(s, name, exportName);
    if (!name.is()) {
      // unnamed, use an index
      name = Name::fromInt(functionCounter);
    }
    if (exportName.is()) {
      auto ex = make_unique<Export>();
      ex->name = exportName;
      ex->value = name;
      wasm.addExport(ex.release());
    }
    functionCounter++;
    Expression* body = nullptr;
    localIndex = 0;
    otherIndex = 0;
    brokeToAutoBlock = false;
    std::vector<NameType> typeParams; // we may have both params and a type. store the type info here
    std::vector<NameType> params;
    std::vector<NameType> vars;
    WasmType result = none;
    Name type;
    Block* autoBlock = nullptr; // we may need to add a block for the very top level
    auto makeFunction = [&]() {
      currFunction = std::unique_ptr<Function>(Builder(wasm).makeFunction(
        name,
        std::move(params),
        result,
        std::move(vars)
      ));
    };
    auto ensureAutoBlock = [&]() {
      if (!autoBlock) {
        autoBlock = allocator.alloc<Block>();
        autoBlock->list.push_back(body);
        body = autoBlock;
      }
    };
    for (;i < s.size(); i++) {
      Element& curr = *s[i];
      IString id = curr[0]->str();
      if (id == PARAM || id == LOCAL) {
        size_t j = 1;
        while (j < curr.size()) {
          IString name;
          WasmType type = none;
          if (!curr[j]->dollared()) { // dollared input symbols cannot be types
            type = stringToWasmType(curr[j]->str(), true);
          }
          if (type != none) {
            // a type, so an unnamed parameter
            name = Name::fromInt(localIndex);
          } else {
            name = curr[j]->str();
            type = stringToWasmType(curr[j+1]->str());
            j++;
          }
          j++;
          if (id == PARAM) {
            params.emplace_back(name, type);
          } else {
            vars.emplace_back(name, type);
          }
          localIndex++;
          currLocalTypes[name] = type;
        }
      } else if (id == RESULT) {
        result = stringToWasmType(curr[1]->str());
      } else if (id == TYPE) {
        Name name = curr[1]->str();
        type = name;
        if (!wasm.checkFunctionType(name)) throw ParseException("unknown function");
        FunctionType* type = wasm.getFunctionType(name);
        result = type->result;
        for (size_t j = 0; j < type->params.size(); j++) {
          IString name = Name::fromInt(j);
          WasmType currType = type->params[j];
          typeParams.emplace_back(name, currType);
          currLocalTypes[name] = currType;
        }
      } else {
        // body
        if (typeParams.size() > 0 && params.size() == 0) {
          params = typeParams;
        }
        if (!currFunction) makeFunction();
        Expression* ex = parseExpression(curr);
        if (!body) {
          body = ex;
        } else {
          ensureAutoBlock();
          autoBlock->list.push_back(ex);
        }
      }
    }
    if (brokeToAutoBlock) {
      ensureAutoBlock();
      autoBlock->name = FAKE_RETURN;
    }
    if (autoBlock) {
      autoBlock->finalize();
    }
    if (!currFunction) {
      makeFunction();
      body = allocator.alloc<Nop>();
    }
    if (currFunction->result != result) throw ParseException("bad func declaration", s.line, s.col);
    // see https://github.com/WebAssembly/spec/pull/301
    if (type.isNull()) {
      // if no function type name provided, then we generated one
      std::unique_ptr<FunctionType> functionType = std::unique_ptr<FunctionType>(sigToFunctionType(getSig(currFunction.get())));
      for (auto& existing : wasm.functionTypes) {
        if (existing->structuralComparison(*functionType)) {
          type = existing->name;
          break;
        }
      }
      if (!type.is()) throw ParseException("no function type [internal error?]", s.line, s.col);
    }
    currFunction->body = body;
    currFunction->type = type;

    wasm.addFunction(currFunction.release());
    currLocalTypes.clear();
    labelStack.clear();
  }

  WasmType stringToWasmType(IString str, bool allowError=false, bool prefix=false) {
    return stringToWasmType(str.str, allowError, prefix);
  }

  WasmType stringToWasmType(const char* str, bool allowError=false, bool prefix=false) {
    if (str[0] == 'i') {
      if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0)) return i32;
      if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0)) return i64;
    }
    if (str[0] == 'f') {
      if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0)) return f32;
      if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0)) return f64;
    }
    if (allowError) return none;
    throw ParseException("unknown type");
    abort();
  }

public:
  Expression* parseExpression(Element* s) {
    return parseExpression(*s);
  }

  #define abort_on(str) { throw ParseException(std::string("abort_on ") + str); }

  Expression* parseExpression(Element& s) {
    IString id = s[0]->str();
    const char *str = id.str;
    const char *dot = strchr(str, '.');
    if (dot) {
      // type.operation (e.g. i32.add)
      WasmType type = stringToWasmType(str, false, true);
      // Local copy to index into op without bounds checking.
      enum { maxNameSize = 15 };
      char op[maxNameSize + 1] = {'\0'};
      strncpy(op, dot + 1, maxNameSize);
      #define BINARY_INT_OR_FLOAT(op) (type == i32 ? BinaryOp::op##Int32 : (type == i64 ? BinaryOp::op##Int64 : (type == f32 ? BinaryOp::op##Float32 : BinaryOp::op##Float64)))
      #define BINARY_INT(op) (type == i32 ? BinaryOp::op##Int32 : BinaryOp::op##Int64)
      #define BINARY_FLOAT(op) (type == f32 ? BinaryOp::op##Float32 : BinaryOp::op##Float64)
      switch (op[0]) {
        case 'a': {
          if (op[1] == 'b') return makeUnary(s, type == f32 ? UnaryOp::AbsFloat32 : UnaryOp::AbsFloat64, type);
          if (op[1] == 'd') return makeBinary(s, BINARY_INT_OR_FLOAT(Add), type);
          if (op[1] == 'n') return makeBinary(s, BINARY_INT(And), type);
          abort_on(op);
        }
        case 'c': {
          if (op[1] == 'e') return makeUnary(s, type == f32 ? UnaryOp::CeilFloat32 : UnaryOp::CeilFloat64, type);
          if (op[1] == 'l') return makeUnary(s, type == i32 ? UnaryOp::ClzInt32 : UnaryOp::ClzInt64, type);
          if (op[1] == 'o') {
            if (op[2] == 'p') return makeBinary(s, BINARY_FLOAT(CopySign), type);
            if (op[2] == 'n') {
              if (op[3] == 'v') {
                if (op[8] == 's') return makeUnary(s, op[11] == '3' ? (type == f32 ? UnaryOp::ConvertSInt32ToFloat32 : UnaryOp::ConvertSInt32ToFloat64) : (type == f32 ? UnaryOp::ConvertSInt64ToFloat32 : UnaryOp::ConvertSInt64ToFloat64), type);
                if (op[8] == 'u') return makeUnary(s, op[11] == '3' ? (type == f32 ? UnaryOp::ConvertUInt32ToFloat32 : UnaryOp::ConvertUInt32ToFloat64) : (type == f32 ? UnaryOp::ConvertUInt64ToFloat32 : UnaryOp::ConvertUInt64ToFloat64), type);
              }
              if (op[3] == 's') return makeConst(s, type);
            }
          }
          if (op[1] == 't') return makeUnary(s, type == i32 ? UnaryOp::CtzInt32 : UnaryOp::CtzInt64, type);
          abort_on(op);
        }
        case 'd': {
          if (op[1] == 'i') {
            if (op[3] == '_') return makeBinary(s, op[4] == 'u' ? BINARY_INT(DivU) : BINARY_INT(DivS), type);
            if (op[3] == 0) return makeBinary(s, BINARY_FLOAT(Div), type);
          }
          if (op[1] == 'e') return makeUnary(s,  UnaryOp::DemoteFloat64, type);
          abort_on(op);
        }
        case 'e': {
          if (op[1] == 'q') {
            if (op[2] == 0) return makeBinary(s, BINARY_INT_OR_FLOAT(Eq), type);
            if (op[2] == 'z') return makeUnary(s, type == i32 ? UnaryOp::EqZInt32 : UnaryOp::EqZInt64, type);
          }
          if (op[1] == 'x') return makeUnary(s, op[7] == 'u' ? UnaryOp::ExtendUInt32 : UnaryOp::ExtendSInt32, type);
          abort_on(op);
        }
        case 'f': {
          if (op[1] == 'l') return makeUnary(s, type == f32 ? UnaryOp::FloorFloat32 : UnaryOp::FloorFloat64, type);
          abort_on(op);
        }
        case 'g': {
          if (op[1] == 't') {
            if (op[2] == '_') return makeBinary(s, op[3] == 'u' ? BINARY_INT(GtU) : BINARY_INT(GtS), type);
            if (op[2] == 0) return makeBinary(s, BINARY_FLOAT(Gt), type);
          }
          if (op[1] == 'e') {
            if (op[2] == '_') return makeBinary(s, op[3] == 'u' ? BINARY_INT(GeU) : BINARY_INT(GeS), type);
            if (op[2] == 0) return makeBinary(s, BINARY_FLOAT(Ge), type);
          }
          abort_on(op);
        }
        case 'l': {
          if (op[1] == 't') {
            if (op[2] == '_') return makeBinary(s, op[3] == 'u' ? BINARY_INT(LtU) : BINARY_INT(LtS), type);
            if (op[2] == 0) return makeBinary(s, BINARY_FLOAT(Lt), type);
          }
          if (op[1] == 'e') {
            if (op[2] == '_') return makeBinary(s, op[3] == 'u' ? BINARY_INT(LeU) : BINARY_INT(LeS), type);
            if (op[2] == 0) return makeBinary(s, BINARY_FLOAT(Le), type);
          }
          if (op[1] == 'o') return makeLoad(s, type);
          abort_on(op);
        }
        case 'm': {
          if (op[1] == 'i') return makeBinary(s, BINARY_FLOAT(Min), type);
          if (op[1] == 'a') return makeBinary(s, BINARY_FLOAT(Max), type);
          if (op[1] == 'u') return makeBinary(s, BINARY_INT_OR_FLOAT(Mul), type);
          abort_on(op);
        }
        case 'n': {
          if (op[1] == 'e') {
            if (op[2] == 0) return makeBinary(s, BINARY_INT_OR_FLOAT(Ne), type);
            if (op[2] == 'a') return makeUnary(s, type == f32 ? UnaryOp::NearestFloat32 : UnaryOp::NearestFloat64, type);
            if (op[2] == 'g') return makeUnary(s, type == f32 ? UnaryOp::NegFloat32 : UnaryOp::NegFloat64, type);
          }
          abort_on(op);
        }
        case 'o': {
          if (op[1] == 'r') return makeBinary(s, BINARY_INT(Or), type);
          abort_on(op);
        }
        case 'p': {
          if (op[1] == 'r') return makeUnary(s,  UnaryOp::PromoteFloat32, type);
          if (op[1] == 'o') return makeUnary(s, type == i32 ? UnaryOp::PopcntInt32 : UnaryOp::PopcntInt64, type);
          abort_on(op);
        }
        case 'r': {
          if (op[1] == 'e') {
            if (op[2] == 'm') return makeBinary(s, op[4] == 'u' ? BINARY_INT(RemU) : BINARY_INT(RemS), type);
            if (op[2] == 'i') return makeUnary(s, isWasmTypeFloat(type) ? (type == f32 ? UnaryOp::ReinterpretInt32 : UnaryOp::ReinterpretInt64) : (type == i32 ? UnaryOp::ReinterpretFloat32 : UnaryOp::ReinterpretFloat64), type);
          }
          if (op[1] == 'o' && op[2] == 't') {
            return makeBinary(s, op[3] == 'l' ? BINARY_INT(RotL) : BINARY_INT(RotR), type);
          }
          abort_on(op);
        }
        case 's': {
          if (op[1] == 'h') {
            if (op[2] == 'l') return makeBinary(s, BINARY_INT(Shl), type);
            return makeBinary(s, op[4] == 'u' ? BINARY_INT(ShrU) : BINARY_INT(ShrS), type);
          }
          if (op[1] == 'u') return makeBinary(s, BINARY_INT_OR_FLOAT(Sub), type);
          if (op[1] == 'q') return makeUnary(s, type == f32 ? UnaryOp::SqrtFloat32 : UnaryOp::SqrtFloat64, type);
          if (op[1] == 't') return makeStore(s, type);
          abort_on(op);
        }
        case 't': {
          if (op[1] == 'r') {
            if (op[6] == 's') return makeUnary(s, op[9] == '3' ? (type == i32 ? UnaryOp::TruncSFloat32ToInt32 : UnaryOp::TruncSFloat32ToInt64) : (type == i32 ? UnaryOp::TruncSFloat64ToInt32 : UnaryOp::TruncSFloat64ToInt64), type);
            if (op[6] == 'u') return makeUnary(s, op[9] == '3' ? (type == i32 ? UnaryOp::TruncUFloat32ToInt32 : UnaryOp::TruncUFloat32ToInt64) : (type == i32 ? UnaryOp::TruncUFloat64ToInt32 : UnaryOp::TruncUFloat64ToInt64), type);
            if (op[2] == 'u') return makeUnary(s, type == f32 ? UnaryOp::TruncFloat32 : UnaryOp::TruncFloat64, type);
          }
          abort_on(op);
        }
        case 'w': {
          if (op[1] == 'r') return makeUnary(s,  UnaryOp::WrapInt64, type);
          abort_on(op);
        }
        case 'x': {
          if (op[1] == 'o') return makeBinary(s, BINARY_INT(Xor), type);
          abort_on(op);
        }
        default: abort_on(op);
      }
    } else {
      // other expression
      switch (str[0]) {
        case 'b': {
          if (str[1] == 'l') return makeBlock(s);
          if (str[1] == 'r') {
            if (str[2] == '_' && str[3] == 't') return makeBreakTable(s);
            return makeBreak(s);
          }
          abort_on(str);
        }
        case 'c': {
          if (str[1] == 'a') {
            if (id == CALL) return makeCall(s);
            if (id == CALL_IMPORT) return makeCallImport(s);
            if (id == CALL_INDIRECT) return makeCallIndirect(s);
          } else if (str[1] == 'u') return makeHost(s, HostOp::CurrentMemory);
          abort_on(str);
        }
        case 'e': {
          if (str[1] == 'l') return makeThenOrElse(s);
          abort_on(str);
        }
        case 'g': {
          if (str[1] == 'e') {
            if (str[4] == 'l') return makeGetLocal(s);
            if (str[4] == 'g') return makeGetGlobal(s);
          }
          if (str[1] == 'r') return makeHost(s, HostOp::GrowMemory);
          abort_on(str);
        }
        case 'h': {
          if (str[1] == 'a') return makeHost(s, HostOp::HasFeature);
          abort_on(str);
        }
        case 'i': {
          if (str[1] == 'f') return makeIf(s);
          abort_on(str);
        }
        case 'l': {
          if (str[1] == 'o') return makeLoop(s);
          abort_on(str);
        }
        case 'n': {
          if (str[1] == 'o') return allocator.alloc<Nop>();
          abort_on(str);
        }
        case 'p': {
          if (str[1] == 'a') return makeHost(s, HostOp::PageSize);
          abort_on(str);
        }
        case 's': {
          if (str[1] == 'e' && str[2] == 't') {
            if (str[4] == 'l') return makeSetLocal(s);
            if (str[4] == 'g') return makeSetGlobal(s);
          }
          if (str[1] == 'e' && str[2] == 'l') return makeSelect(s);
          abort_on(str);
        }
        case 'r': {
          if (str[1] == 'e') return makeReturn(s);
          abort_on(str);
        }
        case 't': {
          if (str[1] == 'h') return makeThenOrElse(s);
          abort_on(str);
        }
        case 'u': {
          if (str[1] == 'n') return allocator.alloc<Unreachable>();
          abort_on(str);
        }
        default: abort_on(str);
      }
    }
    abort();
  }

private:
  Expression* makeBinary(Element& s, BinaryOp op, WasmType type) {
    auto ret = allocator.alloc<Binary>();
    ret->op = op;
    ret->left = parseExpression(s[1]);
    ret->right = parseExpression(s[2]);
    ret->finalize();
    return ret;
  }

  Expression* makeUnary(Element& s, UnaryOp op, WasmType type) {
    auto ret = allocator.alloc<Unary>();
    ret->op = op;
    ret->value = parseExpression(s[1]);
    ret->finalize();
    // type is the reported type, e.g. i64.ctz reports i64 (but has a return type of i32, in this case)
    // verify the reported type is correct
    switch (op) {
      case EqZInt32:
      case NegFloat32:
      case AbsFloat32:
      case CeilFloat32:
      case FloorFloat32:
      case TruncFloat32:
      case NearestFloat32:
      case SqrtFloat32:
      case ClzInt32:
      case CtzInt32:
      case PopcntInt32:
      case EqZInt64:
      case NegFloat64:
      case AbsFloat64:
      case CeilFloat64:
      case FloorFloat64:
      case TruncFloat64:
      case NearestFloat64:
      case SqrtFloat64:
      case ClzInt64:
      case CtzInt64:
      case PopcntInt64: {
        if (ret->value->type != unreachable && type != ret->value->type) throw ParseException(std::string("bad type for ") + getExpressionName(ret) + ": " + printWasmType(type) + " vs value type " + printWasmType(ret->value->type), s.line, s.col);
        break;
      }
      case ExtendSInt32: case ExtendUInt32:
      case WrapInt64:
      case PromoteFloat32:
      case DemoteFloat64:
      case TruncSFloat32ToInt32:
      case TruncUFloat32ToInt32:
      case TruncSFloat64ToInt32:
      case TruncUFloat64ToInt32:
      case ReinterpretFloat32:
      case TruncSFloat32ToInt64:
      case TruncUFloat32ToInt64:
      case TruncSFloat64ToInt64:
      case TruncUFloat64ToInt64:
      case ReinterpretFloat64:
      case ReinterpretInt32:
      case ConvertSInt32ToFloat32:
      case ConvertUInt32ToFloat32:
      case ConvertSInt64ToFloat32:
      case ConvertUInt64ToFloat32:
      case ReinterpretInt64:
      case ConvertSInt32ToFloat64:
      case ConvertUInt32ToFloat64:
      case ConvertSInt64ToFloat64:
      case ConvertUInt64ToFloat64: break;
      default: WASM_UNREACHABLE();
    }
    return ret;
  }

  Expression* makeSelect(Element& s) {
    auto ret = allocator.alloc<Select>();
    ret->ifTrue = parseExpression(s[1]);
    ret->ifFalse = parseExpression(s[2]);
    ret->condition = parseExpression(s[3]);
    ret->finalize();
    return ret;
  }

  Expression* makeHost(Element& s, HostOp op) {
    auto ret = allocator.alloc<Host>();
    ret->op = op;
    if (op == HostOp::HasFeature) {
      ret->nameOperand = s[1]->str();
    } else {
      parseCallOperands(s, 1, ret);
    }
    ret->finalize();
    return ret;
  }

  Index getLocalIndex(Element& s) {
    if (!currFunction) throw ParseException("local access in non-function scope", s.line, s.col);
    if (s.dollared()) {
      auto ret = s.str();
      if (currFunction->localIndices.count(ret) == 0) throw ParseException("bad local name", s.line, s.col);
      return currFunction->getLocalIndex(ret);
    }
    // this is a numeric index
    Index ret = atoi(s.c_str());
    if (ret >= currFunction->getNumLocals()) throw ParseException("bad local index", s.line, s.col);
    return ret;
  }

  Expression* makeGetLocal(Element& s) {
    auto ret = allocator.alloc<GetLocal>();
    ret->index = getLocalIndex(*s[1]);
    ret->type = currFunction->getLocalType(ret->index);
    return ret;
  }

  Expression* makeSetLocal(Element& s) {
    auto ret = allocator.alloc<SetLocal>();
    ret->index = getLocalIndex(*s[1]);
    ret->value = parseExpression(s[2]);
    ret->type = currFunction->getLocalType(ret->index);
    return ret;
  }

  Index getGlobalIndex(Element& s) {
    if (s.dollared()) {
      auto name = s.str();
      for (Index i = 0; i < wasm.globals.size(); i++) {
        if (wasm.globals[i]->name == name) return i;
      }
      throw ParseException("bad global name", s.line, s.col);
    }
    // this is a numeric index
    Index ret = atoi(s.c_str());
    if (!wasm.checkGlobal(ret)) throw ParseException("bad global index", s.line, s.col);
    return ret;
  }

  Expression* makeGetGlobal(Element& s) {
    auto ret = allocator.alloc<GetGlobal>();
    ret->index = getGlobalIndex(*s[1]);
    ret->type = wasm.getGlobal(ret->index)->type;
    return ret;
  }

  Expression* makeSetGlobal(Element& s) {
    auto ret = allocator.alloc<SetGlobal>();
    ret->index = getGlobalIndex(*s[1]);
    ret->value = parseExpression(s[2]);
    ret->type = wasm.getGlobal(ret->index)->type;
    return ret;
  }

  Expression* makeBlock(Element& s) {
    // special-case Block, because Block nesting (in their first element) can be incredibly deep
    auto curr = allocator.alloc<Block>();
    auto* sp = &s;
    std::vector<std::pair<Element*, Block*>> stack;
    while (1) {
      stack.emplace_back(sp, curr);
      auto& s = *sp;
      size_t i = 1;
      if (i < s.size() && s[i]->isStr()) {
        curr->name = s[i]->str();
        i++;
      } else {
        curr->name = getPrefixedName("block");
      }
      labelStack.push_back(curr->name);
      if (i >= s.size()) break; // labeled empty block
      auto& first = *s[i];
      if (first[0]->str() == BLOCK) {
        // recurse
        curr = allocator.alloc<Block>();
        sp = &first;
        continue;
      }
      break;
    }
    // we now have a stack of Blocks, with their labels, but no contents yet
    for (int t = int(stack.size()) - 1; t >= 0; t--) {
      auto* sp = stack[t].first;
      auto* curr = stack[t].second;
      auto& s = *sp;
      size_t i = 1;
      if (i < s.size()) {
        if (s[i]->isStr()) {
          i++;
        }
        if (t < int(stack.size()) - 1) {
          // first child is one of our recursions
          curr->list.push_back(stack[t + 1].second);
          i++;
        }
        for (; i < s.size(); i++) {
          curr->list.push_back(parseExpression(s[i]));
        }
      }
      assert(labelStack.back() == curr->name);
      labelStack.pop_back();
      curr->finalize();
    }
    return stack[0].second;
  }

  // Similar to block, but the label is handled by the enclosing if (since there might not be a then or else, ick)
  Expression* makeThenOrElse(Element& s) {
    auto ret = allocator.alloc<Block>();
    size_t i = 1;
    if (s[1]->isStr()) {
      i++;
    }
    for (; i < s.size(); i++) {
      ret->list.push_back(parseExpression(s[i]));
    }
    ret->finalize();
    return ret;
  }

  Expression* makeConst(Element& s, WasmType type) {
    auto ret = parseConst(s[1]->str(), type, allocator);
    if (!ret) throw ParseException("bad const");
    return ret;
  }

  Expression* makeLoad(Element& s, WasmType type) {
    const char *extra = strchr(s[0]->c_str(), '.') + 5; // after "type.load"
    auto ret = allocator.alloc<Load>();
    ret->type = type;
    ret->bytes = getWasmTypeSize(type);
    if (extra[0] == '8') {
      ret->bytes = 1;
      extra++;
    } else if (extra[0] == '1') {
      assert(extra[1] == '6');
      ret->bytes = 2;
      extra += 2;
    } else if (extra[0] == '3') {
      assert(extra[1] == '2');
      ret->bytes = 4;
      extra += 2;
    }
    ret->signed_ = extra[0] && extra[1] == 's';
    size_t i = 1;
    ret->offset = 0;
    ret->align = ret->bytes;
    while (!s[i]->isList()) {
      const char *str = s[i]->c_str();
      const char *eq = strchr(str, '=');
      assert(eq);
      eq++;
      if (str[0] == 'a') {
        ret->align = atoi(eq);
      } else if (str[0] == 'o') {
        uint64_t offset = atoll(eq);
        if (offset > std::numeric_limits<uint32_t>::max()) throw ParseException("bad offset");
        ret->offset = (uint32_t)offset;
      } else throw ParseException("bad load attribute");
      i++;
    }
    ret->ptr = parseExpression(s[i]);
    return ret;
  }

  Expression* makeStore(Element& s, WasmType type) {
    const char *extra = strchr(s[0]->c_str(), '.') + 6; // after "type.store"
    auto ret = allocator.alloc<Store>();
    ret->type = type;
    ret->bytes = getWasmTypeSize(type);
    if (extra[0] == '8') {
      ret->bytes = 1;
      extra++;
    } else if (extra[0] == '1') {
      assert(extra[1] == '6');
      ret->bytes = 2;
      extra += 2;
    } else if (extra[0] == '3') {
      assert(extra[1] == '2');
      ret->bytes = 4;
      extra += 2;
    }
    size_t i = 1;
    ret->offset = 0;
    ret->align = ret->bytes;
    while (!s[i]->isList()) {
      const char *str = s[i]->c_str();
      const char *eq = strchr(str, '=');
      assert(eq);
      eq++;
      if (str[0] == 'a') {
        ret->align = atoi(eq);
      } else if (str[0] == 'o') {
        ret->offset = atoi(eq);
      } else throw ParseException("bad store attribute");
      i++;
    }
    ret->ptr = parseExpression(s[i]);
    ret->value = parseExpression(s[i+1]);
    return ret;
  }

  Expression* makeIf(Element& s) {
    auto ret = allocator.alloc<If>();
    ret->condition = parseExpression(s[1]);

    // ifTrue and ifFalse may get implicit blocks
    auto handle = [&](const char* title, Element& s) {
      Name name = getPrefixedName(title);
      bool explicitThenElse = false;
      if (s[0]->str() == THEN || s[0]->str() == ELSE) {
        explicitThenElse = true;
        if (s[1]->isStr() && s[1]->dollared()) {
          name = s[1]->str();
        }
      }
      labelStack.push_back(name);
      auto* ret = parseExpression(&s);
      labelStack.pop_back();
      if (explicitThenElse) {
        ret->dynCast<Block>()->name = name;
      } else {
        // add a block if we must
        if (BreakSeeker::has(ret, name)) {
          auto* block = allocator.alloc<Block>();
          block->name = name;
          block->list.push_back(ret);
          block->finalize();
          ret = block;
        }
      }
      return ret;
    };

    ret->ifTrue = handle("if-true", *s[2]);
    if (s.size() == 4) {
      ret->ifFalse = handle("if-else", *s[3]);
      ret->finalize();
    }
    return ret;
  }

  Expression* makeMaybeBlock(Element& s, size_t i, size_t stopAt=-1) {
    if (s.size() == i) return allocator.alloc<Nop>();
    if (s.size() == i+1) return parseExpression(s[i]);
    auto ret = allocator.alloc<Block>();
    for (; i < s.size() && i < stopAt; i++) {
      ret->list.push_back(parseExpression(s[i]));
    }
    ret->finalize();
    // Note that we do not name these implicit/synthetic blocks. They
    // are the effects of syntactic sugar, and nothing can branch to
    // them anyhow.
    return ret;
  }

  Expression* makeLoop(Element& s) {
    auto ret = allocator.alloc<Loop>();
    size_t i = 1;
    if (s.size() > i + 1 && s[i]->isStr() && s[i + 1]->isStr()) { // out can only be named if both are
      ret->out = s[i]->str();
      i++;
    } else {
      ret->out = getPrefixedName("loop-out");
    }
    if (s.size() > i && s[i]->isStr()) {
      ret->in = s[i]->str();
      i++;
    } else {
      ret->in = getPrefixedName("loop-in");
    }
    labelStack.push_back(ret->out);
    labelStack.push_back(ret->in);
    ret->body = makeMaybeBlock(s, i);
    labelStack.pop_back();
    labelStack.pop_back();
    ret->finalize();
    return ret;
  }

  Expression* makeCall(Element& s) {
    auto ret = allocator.alloc<Call>();
    ret->target = s[1]->str();
    ret->type = functionTypes[ret->target];
    parseCallOperands(s, 2, ret);
    return ret;
  }

  Expression* makeCallImport(Element& s) {
    auto ret = allocator.alloc<CallImport>();
    ret->target = s[1]->str();
    Import* import = wasm.getImport(ret->target);
    ret->type = import->type->result;
    parseCallOperands(s, 2, ret);
    return ret;
  }

  Expression* makeCallIndirect(Element& s) {
    auto ret = allocator.alloc<CallIndirect>();
    IString type = s[1]->str();
    auto* fullType = wasm.checkFunctionType(type);
    if (!fullType) throw ParseException("invalid call_indirect type", s.line, s.col);
    ret->fullType = fullType->name;
    ret->type = fullType->result;
    ret->target = parseExpression(s[2]);
    parseCallOperands(s, 3, ret);
    return ret;
  }

  template<class T>
  void parseCallOperands(Element& s, size_t i, T* call) {
    while (i < s.size()) {
      call->operands.push_back(parseExpression(s[i]));
      i++;
    }
  }
  Name getLabel(Element& s) {
    if (s.dollared()) {
      return s.str();
    } else {
      // offset, break to nth outside label
      uint64_t offset = std::stoll(s.c_str(), nullptr, 0);
      if (offset > labelStack.size()) throw ParseException("invalid label", s.line, s.col);
      if (offset == labelStack.size()) {
        // a break to the function's scope. this means we need an automatic block, with a name
        brokeToAutoBlock = true;
        return FAKE_RETURN;
      }
      return labelStack[labelStack.size() - 1 - offset];
    }
  }
  Expression* makeBreak(Element& s) {
    auto ret = allocator.alloc<Break>();
    size_t i = 1;
    ret->name = getLabel(*s[i]);
    i++;
    if (i == s.size()) return ret;
    if (s[0]->str() == BR_IF) {
      if (i + 1 < s.size()) {
        ret->value = parseExpression(s[i]);
        i++;
      }
      ret->condition = parseExpression(s[i]);
    } else {
      ret->value = parseExpression(s[i]);
    }
    ret->finalize();
    return ret;
  }

  Expression* makeBreakTable(Element& s) {
    auto ret = allocator.alloc<Switch>();
    size_t i = 1;
    while (!s[i]->isList()) {
      ret->targets.push_back(getLabel(*s[i++]));
    }
    ret->default_ = ret->targets.back();
    ret->targets.pop_back();
    ret->condition = parseExpression(s[i++]);
    if (i < s.size()) {
      ret->value = ret->condition;
      ret->condition = parseExpression(s[i++]);
    }
    return ret;
  }

  Expression* makeReturn(Element& s) {
    auto ret = allocator.alloc<Return>();
    if (s.size() >= 2) {
      ret->value = parseExpression(s[1]);
    }
    return ret;
  }

  // converts an s-expression string representing binary data into an output sequence of raw bytes
  // this appends to data, which may already contain content.
  void stringToBinary(const char* input, size_t size, std::vector<char>& data) {
    auto originalSize = data.size();
    data.resize(originalSize + size);
    char *write = data.data() + originalSize;
    while (1) {
      if (input[0] == 0) break;
      if (input[0] == '\\') {
        if (input[1] == '"') {
          *write++ = '"';
          input += 2;
          continue;
        } else if (input[1] == '\'') {
          *write++ = '\'';
          input += 2;
          continue;
        } else if (input[1] == '\\') {
          *write++ = '\\';
          input += 2;
          continue;
        } else if (input[1] == 'n') {
          *write++ = '\n';
          input += 2;
          continue;
        } else if (input[1] == 't') {
          *write++ = '\t';
          input += 2;
          continue;
        } else {
          *write++ = (char)(unhex(input[1])*16 + unhex(input[2]));
          input += 3;
          continue;
        }
      }
      *write++ = input[0];
      input++;
    }
    assert(write >= data.data());
    size_t actual = write - data.data();
    assert(actual <= data.size());
    data.resize(actual);
  }

  bool hasMemory = false;

  void parseMemory(Element& s) {
    hasMemory = true;

    wasm.memory.initial = atoi(s[1]->c_str());
    if (s.size() == 2) return;
    size_t i = 2;
    if (s[i]->isStr()) {
      uint64_t max = atoll(s[i]->c_str());
      if (max > Memory::kMaxSize) throw ParseException("total memory must be <= 4GB");
      wasm.memory.max = max;
      i++;
    }
    while (i < s.size()) {
      Element& curr = *s[i];
      assert(curr[0]->str() == SEGMENT);
      const char *input = curr[2]->c_str();
      if (auto size = strlen(input)) {
        std::vector<char> data;
        stringToBinary(input, size, data);
        wasm.memory.segments.emplace_back(atoi(curr[1]->c_str()), data.data(), data.size());
      } else {
        wasm.memory.segments.emplace_back(atoi(curr[1]->c_str()), "", 0);
      }
      i++;
    }
  }

  void parseExport(Element& s) {
    if (!s[2]->dollared() && !std::isdigit(s[2]->str()[0])) {
      assert(s[2]->str() == MEMORY);
      if (!hasMemory) throw ParseException("memory exported but no memory");
      wasm.memory.exportName = s[1]->str();
      return;
    }
    std::unique_ptr<Export> ex = make_unique<Export>();
    ex->name = s[1]->str();
    ex->value = s[2]->str();
    wasm.addExport(ex.release());
  }

  void parseImport(Element& s) {
    std::unique_ptr<Import> im = make_unique<Import>();
    size_t i = 1;
    if (s.size() > 3 && s[3]->isStr()) {
      im->name = s[i++]->str();
    } else {
      im->name = Name::fromInt(importCounter);
    }
    importCounter++;
    im->module = s[i++]->str();
    if (!s[i]->isStr()) throw ParseException("no name for import");
    im->base = s[i++]->str();
    std::unique_ptr<FunctionType> type = make_unique<FunctionType>();
    if (s.size() > i) {
      Element& params = *s[i];
      IString id = params[0]->str();
      if (id == PARAM) {
        for (size_t i = 1; i < params.size(); i++) {
          type->params.push_back(stringToWasmType(params[i]->str()));
        }
      } else if (id == RESULT) {
        type->result = stringToWasmType(params[1]->str());
      } else if (id == TYPE) {
        IString name = params[1]->str();
        if (!wasm.checkFunctionType(name)) throw ParseException("bad function type for import");
        *type = *wasm.getFunctionType(name);
      } else {
        throw ParseException("bad import element");
      }
      if (s.size() > i+1) {
        Element& result = *s[i+1];
        assert(result[0]->str() == RESULT);
        type->result = stringToWasmType(result[1]->str());
      }
    }
    im->type = ensureFunctionType(getSig(type.get()), &wasm);
    wasm.addImport(im.release());
  }

  void parseGlobal(Element& s) {
    std::unique_ptr<Global> global = make_unique<Global>();
    size_t i = 1;
    if (s.size() == 4) {
      global->name = s[i++]->str();
    } else {
      global->name = Name::fromInt(globalCounter);
    }
    globalCounter++;
    global->type = stringToWasmType(s[i++]->str());
    global->init = parseExpression(s[i++]);
    assert(i == s.size());
    wasm.addGlobal(global.release());
  }

  void parseTable(Element& s) {
    for (size_t i = 1; i < s.size(); i++) {
      wasm.table.names.push_back(getFunctionName(*s[i]));
    }
  }

  void parseType(Element& s) {
    std::unique_ptr<FunctionType> type = make_unique<FunctionType>();
    size_t i = 1;
    if (s[i]->isStr()) {
      type->name = s[i]->str();
      i++;
    }
    Element& func = *s[i];
    assert(func.isList());
    for (size_t i = 1; i < func.size(); i++) {
      Element& curr = *func[i];
      if (curr[0]->str() == PARAM) {
        for (size_t j = 1; j < curr.size(); j++) {
          type->params.push_back(stringToWasmType(curr[j]->str()));
        }
      } else if (curr[0]->str() == RESULT) {
        type->result = stringToWasmType(curr[1]->str());
      }
    }
    wasm.addFunctionType(type.release());
  }
};

} // namespace wasm

#endif // wasm_wasm_s_parser_h


text:
/**
 * Created by estin on 21/11/15.
 */
$(document).ready(function(){
    $('.top-main-gallery').slick({
        dots: true,
        arrows: true,
        infinite: true,
        slidesToShow: 1,
        slidesToScroll: 1,
        speed: 1000,
        //autoplay: true,
        //autoplaySpeed: 4000
    });
});
//
//window.addEventListener('scroll', function() {
//    //var l = $('*').length;
//    //for(var i = 0; i < l; i++) {
//    //    var elem = $('*:eq(' + i + ')');
//    //    if(elem.scrollTop() > 0) {
//    //        console.log(elem, elem.scrollTop());
//    //    }
//    //}
//
//
//
//    //console.log(frames.top.scrollY)
//    //console.log($('body').scrollTop())
//    if (window.scrollY > 0) {
//        $("#grid").addClass('shadowed');
//        //$("#img_logo_shoe").fadeOut('slow');
//        ////$("#img_logo_letters").show();
//        ////$("#img_logo_shoe").opacity = 0;
//        //$("#img_logo_shoe").css({ opacity: 0.0 });
//        //$('nav').removeClass('navbar-large');
//        //$('nav').addClass('navbar-small');
//    } else {
//
//        $("#grid").removeClass('shadowed');
//        //$("#img_logo_shoe").css({ opacity: 1.0 });
//        ////$("#img_logo_shoe").fadeIn("slow");
//        //////$("#img_logo_letters").hide();
//        ////$("#img_logo_shoe").opacity = 1;
//        //$('nav').addClass('navbar-large');
//        //$('nav').removeClass('navbar-small');
//    }
//});
//
//$(document).ready(function(){
//    // cache the window object
//    $window = $(window);
//
//    $('section[data-type="gallery"]').each(function(){
//        // declare the variable to affect the defined data-type
//        var $scroll = $(this);
//
//        $(window).scroll(function() {
//            // HTML5 proves useful for helping with creating JS functions!
//            // also, negative value because we're scrolling upwards
//            var yPos = ($window.scrollTop() / $scroll.data('speed'));
//
//            // background position
//            var coords = yPos + 'px';
//
//            // move the background
//            $scroll.css({ top: coords });
//        }); // end window scroll
//    });  // end section function
//}); // close out script
$(document).ready(function(){
    // cache the window object
    $window = $(window);

    $('section[data-type="post-main-title"]').each(function(){
        // declare the variable to affect the defined data-type
        var $scroll = $(this);

        $(window).scroll(function() {
            // HTML5 proves useful for helping with creating JS functions!
            // also, negative value because we're scrolling upwards
            var yPos = ($window.scrollTop() / $scroll.data('speed'));

            // background position
            var coords = yPos + 'px';
            // move the background
            $scroll.css({ top: coords });
            document.getElementById("post-header-title").style.marginBottom = coords;
        }); // end window scroll
    });  // end section function
}); // close out script

redpajama_set_name: RedPajamaGithub


text:
Guides for programming like a boss, to the highest standard.

* Protocol
* Code Review
* [Best Practices](/best-practices)
* Style

High level guidelines:

* Be consistent.
* Don't rewrite existing code to follow this guide.
* Don't violate a guideline without a good reason.
* A reason is good when you can convince a teammate.

A note on the language:

* "Avoid" means don't do it unless you have a good reason.
* "Don't" means there's never a good reason.
* "Prefer" indicates a better option and its alternative to watch out for.
* "Use" is a positive instruction.

Contributing
------------

Please read the [contributing guidelines](#) before submitting a pull request.

Credits
-------

Thank you, [contributors](https://github.com/thoughtbot/guides/graphs/contributors)!

In particular: **if you have commit access, please don't merge changes without
waiting a week for everybody to leave feedback**.

[contribution guidelines]: /CONTRIBUTING.md


text:
package org.nypl.database;

import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

/**
 * @author hcl
 *
 */
/**
 * @author hcl
 *
 */
/**
 * @author hcl
 *
 */
public class DatabaseTable {

	// Database table

	public static final String TABLE_NAME ="PLAY";
	public static final String TABLE_NAME2 ="VERSION";
	public static final String TABLE_NAME3 ="ANCHOR";
	public static final String TABLE_NAME4 ="MEDIA";
	public static final String TABLE_NAME5 ="PLAY_NOTE";
	public static final String TABLE_NAME6="AUDIO";
	/*Column Related to Play Table
	 *
	 */
	public static final  String TABLE_PLAY_ID = "_id";
	public static final String TABLE_PLAY_LONG_ID = "PLAY_LONG_ID";
	public static final String TABLE_PLAY_NAME = "PLAY_NAME";
	public static final String TABLE_PLAY_IMAGE = "IMAGE";
	public static final String TABLE_PLAY_SCROLL_POSITION = "SCROLL_POSITION";
	public static final String TABLE_PLAY_AUTHORS = "AUTHORS";
	public static final String TABLE_PLAY_URL = "PLAY_URL";
	/*Column Related to Version Table
	 *
	 */
	public static final  String TABLE_ID = "_id";
	public static final  String TABLE_VERSION_ID = "VERSION_ID";
	public static final String TABLE_VERSION_HTML_FILE = "HTML_FILE";
	public static final String TABLE_VERSION_PLAY_ID = "PLAY_ID";
	public static final String TABLE_VERSION_NAME = "VERSION_NAME";
	public static final String TABLE_VERSION_BOOKMARK = "BOOKMARK";
	public static final String TABLE_VERSION_NOTE = "NOTE";
	public static final String TABLE_VERSION_AUDIO_NAME = "AUDIO_FILE_NAME";
	/**
	 * COlumn Related to Anchor table
	 */

	public static final  String TABLE_ANCHOR_ID = "_id";
	public static final  String TABLE_ANCHOR_PLAY_ID = "PLAY_ID";
	public static final String TABLE_ANCHOR_VERSION_PLAY_ID = "PLAY_VERSION_ID";
	public static final String TABLE_ANCHOR_HTML_ID = "ANCHOR_HTML_ID";
	/**
	 * COlumn Related to Media table
	 */

	public static final  String TABLE_MEDIA_ID = "_id";
	public static final  String TABLE_MEDIA_NAME = "MEDIA_NAME";

	/**
	 * COlumn Related to PLAY_NOTE table
	 */

	public static final  String TABLE_PLAY_NOTE_UNIQUE_ID = "_id";
	public static final  String TABLE_PLAY_NOTES = "NOTES";
	public static final  String TABLE_PLAY_NOTE_ID = "NOTE_ID";
	public static final  String TABLE_PLAY_NOTE_TEXT = "NOTE_TEXT";
	public static final  String TABLE_PLAY_NOTE_PLAY_ID = "PLAY_ID";
	public static final  String TABLE_PLAY_NOTE_VERSION_ID = "VERSION_ID";
	public static final  String TABLE_PLAY_NOTE_VERSION_NAME = "VERSION_NAME";

	/**
	 * COlumn Related to Audio table
	 */

	public static final  String TABLE_AUDIO_UNIQUE_ID = "_id";
	public static final  String TABLE_AUDIO_PLAY_ID = "PLAY_ID";
	public static final  String TABLE_AUDIO_CLIP_ID = "CLIP_ID";
	public static final  String TABLE_AUDIO_VERSION_ID = "VERSION_ID";
	public static final  String TABLE_AUDIO_CLIP_FROM = "CLIP_FROM";
	public static final  String TABLE_AUDIO_CLIP_TO = "CLIP_TO";
	public static final  String TABLE_AUDIO_PATH = "AUDIO_PATH";

	/**
	 * Database creation SQL statement
	 */
	private static final String DATABASE_CREATE = "create table "
		+ TABLE_NAME
		+ "("
		+ TABLE_PLAY_ID + " integer primary key autoincrement, "
		+ TABLE_PLAY_LONG_ID + " text not null, "
		+ TABLE_PLAY_NAME + " text not null ,"
		+ TABLE_PLAY_IMAGE + " text not null ,"
		+ TABLE_PLAY_AUTHORS + " text,  "
		+ TABLE_PLAY_SCROLL_POSITION + " text,  "
		+ TABLE_PLAY_URL+ " text "
		+ ");";

	private static final String DATABASE_CREATE2 = "create table "
		+ TABLE_NAME2
		+ "("
		+ TABLE_ID + " integer primary key autoincrement, "
		+ TABLE_VERSION_ID + " text not null, "
		+ TABLE_VERSION_PLAY_ID + " text not null ,"
		+ TABLE_VERSION_HTML_FILE + " text not null ,"
		+ TABLE_VERSION_NAME + " text not null ,"
		+ TABLE_VERSION_AUDIO_NAME + " text  "
		+ ");";

	private static final String DATABASE_CREATE3 = "create table "
		+ TABLE_NAME3
		+ "("
		+ TABLE_ANCHOR_ID + " integer primary key autoincrement, "
		+ TABLE_ANCHOR_PLAY_ID + " text not null ,"
		+ TABLE_ANCHOR_VERSION_PLAY_ID + " integer not null ,"
		+ TABLE_ANCHOR_HTML_ID + " text not null "
		+ ");";

	private static final String DATABASE_CREATE4 = "create table "
		+ TABLE_NAME4
		+ "("
		+ TABLE_MEDIA_ID + " text not null ,"
		+ TABLE_MEDIA_NAME + " text not null "
		+ ");";

	private static final String DATABASE_CREATE5 = "create table "
		+ TABLE_NAME5
		+ "("
		+ TABLE_PLAY_NOTE_UNIQUE_ID + " integer primary key autoincrement, "
		+ TABLE_PLAY_NOTE_ID + " text not null , "
		+ TABLE_PLAY_NOTES + " text not null , "
		+ TABLE_PLAY_NOTE_TEXT + " text not null , "
		+ TABLE_PLAY_NOTE_PLAY_ID + " text not null , "
		+ TABLE_PLAY_NOTE_VERSION_ID + " text not null , "
		+ TABLE_PLAY_NOTE_VERSION_NAME + " text not null  "
		+ ");";

	private static final String DATABASE_CREATE6 = "create table "
			+ TABLE_NAME6
			+ "("
			+ TABLE_AUDIO_UNIQUE_ID + " text primary key , "
			+ TABLE_AUDIO_PLAY_ID + " text not null , "
			+ TABLE_AUDIO_CLIP_ID + " text not null , "
			+ TABLE_AUDIO_VERSION_ID + " text not null , "
			+ TABLE_AUDIO_CLIP_FROM + " text not null , "
			+ TABLE_AUDIO_CLIP_TO + " text not null  ,"
			+ TABLE_AUDIO_PATH + " text not null "

			+ ");";

	public static void onCreate(SQLiteDatabase database) {
		Log.v("database create",""+database);
		   System.out.println(DATABASE_CREATE);
		database.execSQL(DATABASE_CREATE);
		database.execSQL(DATABASE_CREATE2);
		database.execSQL(DATABASE_CREATE3);
		database.execSQL(DATABASE_CREATE4);
		database.execSQL(DATABASE_CREATE5);
		database.execSQL(DATABASE_CREATE6);
	}

	//		public static void onUpgrade(SQLiteDatabase database, int oldVersion,
	//				int newVersion) {
	//
	//			database.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
	//			onCreate(database);
	//		}

}


text:
app

<form #form="ngForm" (ngSubmit)="onSubmit(form)">
    <input type="text" ngModel name="username"/>

error message

</form>


text:
from django.contrib import admin
from easy_select2 import select2_modelform

from .models import Category, Note

class NoteAdmin(admin.ModelAdmin):
    form = select2_modelform(Note)

admin.site.register(Category)
admin.site.register(Note, NoteAdmin)


text:
/*
 *  (C) Michael Bar-Sinai
 */

package edu.harvard.iq.dataverse.util;

import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author michael
 */
public class BitSetTest {

	enum TestEnum {
		Hello, World, This, Is, A, Test;
	}

	public BitSetTest() {
	}

	@BeforeClass
	public static void setUpClass() {
	}

	@AfterClass
	public static void tearDownClass() {
	}

	BitSet sut;
	@Before
	public void setUp() {
		sut = new BitSet();
	}

	@After
	public void tearDown() {
	}

	/**
	 * Test of set method, of class BitSet.
	 */
	@Test
	public void testSet() {
		for ( short i : BitSet.allIndices() ) {
			sut.set(i);
			assertTrue( sut.isSet(i) );
		}
	}

    @Test
    public void testSetByParameter() {
        BitSet tSut = BitSet.emptySet();
        List<Integer> indices = Arrays.asList(0,1,4,6,7,8,20,31);
        indices.forEach( i -> assertFalse(tSut.isSet(i)) );
        indices.forEach( i -> tSut.set(i,true) );
        indices.forEach( i -> assertTrue(tSut.isSet(i)) );
        indices.forEach( i -> tSut.set(i,false) );
        indices.forEach( i -> assertFalse(tSut.isSet(i)) );
        assertTrue( tSut.isEmpty() );
    }

	/**
	 * Test of unset method, of class BitSet.
	 */
	@Test
	public void testUnset() {
		sut = BitSet.fullSet();
		for ( short i : BitSet.allIndices() ) {
			sut.unset(i);
			assertFalse( sut.isSet(i) );
		}
	}

	/**
	 * Test of copy method, of class BitSet.
	 */
	@Test
	public void testCopy() {
		sut = new BitSet( new java.util.Random().nextLong() );
		assertEquals( sut.getBits(), sut.copy().getBits() );
	}

	/**
	 * Test of union method, of class BitSet.
	 */
	@Test
	public void testUnion() {
		BitSet sut1 = randomSet();
		BitSet sut2 = randomSet();
		sut = sut1.copy().union(sut2);
		for ( short i : BitSet.allIndices() ) {
			if ( sut.isSet(i) ) {
				assertTrue( sut1.isSet(i) || sut2.isSet(i) );
			} else {
				assertFalse( sut1.isSet(i) && sut2.isSet(i) );
			}
		}
	}

	/**
	 * Test of intersect method, of class BitSet.
	 */
	@Test
	public void testIntersect() {
		BitSet sut1 = randomSet();
		BitSet sut2 = randomSet();
		sut = sut1.copy().intersect(sut2);
		for ( short i : BitSet.allIndices() ) {
			if ( sut.isSet(i) ) {
				assertTrue( "expected true at idx " + i, sut1.isSet(i) && sut2.isSet(i) );
			} else {
				assertFalse( "expected false at idx " + i, sut1.isSet(i) && sut2.isSet(i) );
			}
		}
	}

	/**
	 * Test of xor method, of class BitSet.
	 */
	@Test
	public void testXor() {
		BitSet sut1 = randomSet();
		BitSet sut2 = randomSet();
		sut = sut1.copy().xor(sut2);
		for ( short i : BitSet.allIndices() ) {
			if ( sut.isSet(i) ) {
				assertTrue( "expected true at idx " + i, sut1.isSet(i) ^ sut2.isSet(i) );
			} else {
				assertFalse( "expected false at idx " + i, sut1.isSet(i) ^ sut2.isSet(i) );
			}
		}
	}

	@Test
	public void testAsEnumSet() {
		EnumSet<TestEnum> est = EnumSet.of(TestEnum.Hello, TestEnum.This, TestEnum.Test);

		sut = BitSet.from(est);
		assertEquals( est, sut.asSetOf(TestEnum.class) );
	}

	/**
	 * Test of getBits method, of class BitSet.
	 */
	@Test
	public void testGetBits() {
		sut.set(0);
		sut.set(1);
		sut.set(2);
		assertEquals( 0b111, sut.getBits() );
	}

	private BitSet randomSet() {
		return new BitSet( new java.util.Random().nextLong() );
	}
}


text:
#ifndef UDF_REGISTRATION_H
#define UDF_REGISTRATION_H

#include <mysql/components/service.h>
#include <mysql/udf_registration_types.h>

/**
  Service for adding and removing UDF functions
*/
BEGIN_SERVICE_DEFINITION(udf_registration)
/**
  Registers a UDF function with a given name.

  The name must be unique. Does not store in any table, just
  updates the global function list.
  Plugins/components need to handle registration deregistration
  during their initialization and deinitialization.
  Registers a scalar UDF by default.
  @sa udf_aggregates

  @param name name of the function
  @param return_type return type.
  @param func function to call
  @param init_func function to call at query start
  @param deinit_func function to call at query cleanup
  @return Status of performed operation
  @retval false success
  @retval true failure
*/
DECLARE_BOOL_METHOD(udf_register,
                    (const char *func_name, enum Item_result return_type,
                     Udf_func_any func, Udf_func_init init_func,
                     Udf_func_deinit deinit_func));

/**
  Unregisters a UDF function with a given name.

  Does not store in any table, just updates the global function list.
  Plugins/components need to handle registration deregistration
  during their initialization and deinitialization.

  @param name name of the function
  @param[out] was_present set to non-zero if the UDF was present, but locked
  @return Status of performed operation
  @retval false success
  @retval true failure
*/
DECLARE_BOOL_METHOD(udf_unregister, (const char *name, int *was_present));
END_SERVICE_DEFINITION(udf_registration)

/**
  Service for turning
*/
BEGIN_SERVICE_DEFINITION(udf_registration_aggregate)
/**
  Registers an aggregate UDF function with a given name.

  The name must be unique. Does not store in any table, just
  updates the global function list.
  Plugins/components need to handle registration deregistration
  during their initialization and deinitialization.
  You can use udf_registration::unregister to unregister the
  function.

  @sa udf_registration

  @param name name of the function
  @param return_type return type.
  @param func function to call
  @param init_func function to call at query start
  @param deinit_func function to call at query cleanup
  @param add_func function to call at adding a row to the current aggregate
  @param clear_func function to call at the start of a new aggregate group
  @return Status of performed operation
  @retval false success
  @retval true failure
*/
DECLARE_BOOL_METHOD(udf_register,
                    (const char *func_name, enum Item_result return_type,
                     Udf_func_any func, Udf_func_init init_func,
                     Udf_func_deinit deinit_func, Udf_func_add add_func,
                     Udf_func_clear clear_func));

/**
  Unregisters an aggregate UDF function with a given name.

  Does not store in any table, just updates the global function list.
  Plugins/components need to handle registration deregistration
  during their initialization and deinitialization.

  Currently it's a synonym for udf_registration::udf_unregister.

  @param name name of the function
  @param[out] was_present set to non-zero if the UDF was present, but locked
  @return Status of performed operation
  @retval false success
  @retval true failure
*/
DECLARE_BOOL_METHOD(udf_unregister, (const char *name, int *was_present));
END_SERVICE_DEFINITION(udf_registration_aggregate)
#endif


text:
from django.shortcuts import render
from django.views.generic import CreateView

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator

from .models import Project

class ProjectCreateView(CreateView):
    r"""
    View to register a `Project`, including its name, programming language
    and home page.
    """
    model = Project
    success_url = '/'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(ProjectCreateView, self).dispatch(*args, **kwargs)


text:
require 'rails_helper'

RSpec.describe Size, :type => :model do
  describe 'name' do
    it { is_expected.to have_valid(:name).when('P') }
    it { is_expected.to_not have_valid(:name).when('', nil) }
    it 'mumist be uniq' do
      Size.create(name: 'M')
      is_expected.to_not have_valid(:name).when('m')
    end
  end
end


text:
==========

Shorthand `Object.prototype.hasOwnProperty.call(obj, name)`.

```js
var assert = require('assert');
var hasOwn = require('has-own');

var o = Object.create(null);
o.name = 'has-own';

assert(hasOwn('name', o)); // true
```

Why another module? Because I like it's readability.

[LICENSE](https://github.com/pebble/has-own/blob/master/LICENSE)


text:
> Return true if a file path is (or has) a dotfile.

## Install with [npm](npmjs.org)

```bash
npm i is-dotfile --save
```

## Usage

```js
var isDotfile = require('is-dotfile');

isDotfile('a/b/c.js');
//=> false

isDotfile('a/b/.gitignore');
//=> true

isDotfile('.gitignore');
//=> true

isDotfile('/.gitignore');
//=> true

isDotfile('/.gitignore/foo');
//=> false
```

## Run tests

Install dev dependencies:

```bash
npm i -d && npm test
```

## Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/regexps/is-dotfile/issues)

## Author

**Jon Schlinkert**

+ [github/jonschlinkert](https://github.com/jonschlinkert)
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)

## License
Copyright (c) 2015 Jon Schlinkert
Released under the MIT license

***

_This file was generated by [verb](https://github.com/assemble/verb) on January 23, 2015._


text:
"""
LDAP authentication backend

Complete documentation can be found in docs/howto/auth-ldap.txt (or the thing it
compiles to).

Use of this backend requires the python-ldap module. To support unit tests, we
import ldap in a single centralized place (config._LDAPConfig) so that the test
harness can insert a mock object.

A few notes on naming conventions. If an identifier ends in _dn, it is a string
representation of a distinguished name. If it ends in _info, it is a 2-tuple
containing a DN and a dictionary of lists of attributes. ldap.search_s returns a
list of such structures. An identifier that ends in _attrs is the dictionary of
attributes from the _info structure.

A connection is an LDAPObject that has been successfully bound with a DN and
password. The identifier 'user' always refers to a User model object; LDAP user
information will be user_dn or user_info.

Additional classes can be found in the config module next to this one.
"""

import ldap
import sys
import traceback
import pprint
import copy

from django.contrib.auth.models import User, Group, Permission
from django.core.cache import cache
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
import django.dispatch
try:
    from django.utils.encoding import force_str
except ImportError:  # Django < 1.5
    from django.utils.encoding import smart_str as force_str

# Django 1.7 Removed custom profiles
try:
    from django.contrib.auth.models import SiteProfileNotAvailable
except ImportError:
    SiteProfileNotAvailable = Exception

# Support Django 1.5's custom user models
try:
    from django.contrib.auth import get_user_model
    get_user_username = lambda u: u.get_username()
except ImportError:
    get_user_model = lambda: User                                        # noqa
    get_user_username = lambda u: u.username

# Small compatibility hack
try:
    basestring
except NameError:
    basestring = str

from django_auth_ldap.config import _LDAPConfig, LDAPSearch

logger = _LDAPConfig.get_logger()

# Signals for populating user objects.
populate_user = django.dispatch.Signal(providing_args=["user", "ldap_user"])
populate_user_profile = django.dispatch.Signal(providing_args=["profile", "ldap_user"])

class LDAPBackend(object):
    """
    The main backend class. This implements the auth backend API, although it
    actually delegates most of its work to _LDAPUser, which is defined next.
    """
    supports_anonymous_user = False
    supports_object_permissions = True
    supports_inactive_user = False

    _settings = None
    _ldap = None  # The cached ldap module (or mock object)

    # This is prepended to our internal setting names to produce the names we
    # expect in Django's settings file. Subclasses can change this in order to
    # support multiple collections of settings.
    settings_prefix = 'AUTH_LDAP_'

    def __getstate__(self):
        """
        Exclude certain cached properties from pickling.
        """
        return dict((k, v) for (k, v) in self.__dict__.items()
                    if k not in ['_settings', '_ldap'])

    def _get_settings(self):
        if self._settings is None:
            self._settings = LDAPSettings(self.settings_prefix)

        return self._settings

    def _set_settings(self, settings):
        self._settings = settings

    settings = property(_get_settings, _set_settings)

    def _get_ldap(self):
        if self._ldap is None:
            from django.conf import settings

            options = getattr(settings, 'AUTH_LDAP_GLOBAL_OPTIONS', None)

            self._ldap = _LDAPConfig.get_ldap(options)

        return self._ldap
    ldap = property(_get_ldap)

    def get_user_model(self):
        """
        By default, this will return the model class configured by
        AUTH_USER_MODEL. Subclasses may wish to override it and return a proxy
        model.
        """
        return get_user_model()

    #
    # The Django auth backend API
    #

    def authenticate(self, username, password, **kwargs):
        if len(password) == 0 and not self.settings.PERMIT_EMPTY_PASSWORD:
            logger.debug('Rejecting empty password for %s' % username)
            return None

        ldap_user = _LDAPUser(self, username=username.strip())
        user = ldap_user.authenticate(password)

        return user

    def get_user(self, user_id):
        user = None

        try:
            user = self.get_user_model().objects.get(pk=user_id)
            _LDAPUser(self, user=user)  # This sets user.ldap_user
        except ObjectDoesNotExist:
            pass

        return user

    def has_perm(self, user, perm, obj=None):
        return perm in self.get_all_permissions(user, obj)

    def has_module_perms(self, user, app_label):
        for perm in self.get_all_permissions(user):
            if perm[:perm.index('.')] == app_label:
                return True

        return False

    def get_all_permissions(self, user, obj=None):
        return self.get_group_permissions(user, obj)

    def get_group_permissions(self, user, obj=None):
        if not hasattr(user, 'ldap_user') and self.settings.AUTHORIZE_ALL_USERS:
            _LDAPUser(self, user=user)  # This sets user.ldap_user

        if hasattr(user, 'ldap_user'):
            return user.ldap_user.get_group_permissions()
        else:
            return set()

    #
    # Bonus API: populate the Django user from LDAP without authenticating.
    #

    def populate_user(self, username):
        ldap_user = _LDAPUser(self, username=username)
        user = ldap_user.populate_user()

        return user

    #
    # Hooks for subclasses
    #

    def get_or_create_user(self, username, ldap_user):
        """
        This must return a (User, created) 2-tuple for the given LDAP user.
        username is the Django-friendly username of the user. ldap_user.dn is
        the user's DN and ldap_user.attrs contains all of their LDAP attributes.
        """
        model = self.get_user_model()
        username_field = getattr(model, 'USERNAME_FIELD', 'username')

        kwargs = {
            username_field + '__iexact': username,
            'defaults': {username_field: username.lower()}
        }

        return model.objects.get_or_create(**kwargs)

    def ldap_to_django_username(self, username):
        return username

    def django_to_ldap_username(self, username):
        return username

class _LDAPUser(object):
    """
    Represents an LDAP user and ultimately fields all requests that the
    backend receives. This class exists for two reasons. First, it's
    convenient to have a separate object for each request so that we can use
    object attributes without running into threading problems. Second, these
    objects get attached to the User objects, which allows us to cache
    expensive LDAP information, especially around groups and permissions.

    self.backend is a reference back to the LDAPBackend instance, which we need
    to access the ldap module and any hooks that a subclass has overridden.
    """
    class AuthenticationFailed(Exception):
        pass

    # Defaults
    _user = None
    _user_dn = None
    _user_attrs = None
    _groups = None
    _group_permissions = None
    _connection = None
    _connection_bound = False

    #
    # Initialization
    #

    def __init__(self, backend, username=None, user=None):
        """
        A new LDAPUser must be initialized with either a username or an
        authenticated User object. If a user is given, the username will be
        ignored.
        """
        self.backend = backend
        self._username = username

        if user is not None:
            self._set_authenticated_user(user)

        if username is None and user is None:
            raise Exception("Internal error: _LDAPUser improperly initialized.")

    def __deepcopy__(self, memo):
        obj = object.__new__(self.__class__)
        obj.backend = self.backend
        obj._user = copy.deepcopy(self._user, memo)

        # This is all just cached immutable data. There's no point copying it.
        obj._username = self._username
        obj._user_dn = self._user_dn
        obj._user_attrs = self._user_attrs
        obj._groups = self._groups
        obj._group_permissions = self._group_permissions

        # The connection couldn't be copied even if we wanted to
        obj._connection = self._connection
        obj._connection_bound = self._connection_bound

        return obj

    def __getstate__(self):
        """
        Most of our properties are cached from the LDAP server. We only want to
        pickle a few crucial things.
        """
        return dict((k, v) for (k, v) in self.__dict__.items()
                    if k in ['backend', '_username', '_user'])

    def _set_authenticated_user(self, user):
        self._user = user
        self._username = self.backend.django_to_ldap_username(get_user_username(user))

        user.ldap_user = self
        user.ldap_username = self._username

    def _get_ldap(self):
        return self.backend.ldap
    ldap = property(_get_ldap)

    def _get_settings(self):
        return self.backend.settings
    settings = property(_get_settings)

    #
    # Entry points
    #

    def authenticate(self, password):
        """
        Authenticates against the LDAP directory and returns the corresponding
        User object if successful. Returns None on failure.
        """
        user = None

        try:
            self._authenticate_user_dn(password)
            self._check_requirements()
            self._get_or_create_user()

            user = self._user
        except self.AuthenticationFailed as e:
            logger.debug(u"Authentication failed for %s: %s" % (self._username, e))
        except ldap.LDAPError as e:
            logger.warning(u"Caught LDAPError while authenticating %s: %s",
                           self._username, pprint.pformat(e))
        except Exception:
            logger.exception(u"Caught Exception while authenticating %s",
                             self._username)
            raise

        return user

    def get_group_permissions(self):
        """
        If allowed by the configuration, this returns the set of permissions
        defined by the user's LDAP group memberships.
        """
        if self._group_permissions is None:
            self._group_permissions = set()

            if self.settings.FIND_GROUP_PERMS:
                try:
                    self._load_group_permissions()
                except ldap.LDAPError as e:
                    logger.warning("Caught LDAPError loading group permissions: %s",
                                   pprint.pformat(e))

        return self._group_permissions

    def populate_user(self):
        """
        Populates the Django user object using the default bind credentials.
        """
        user = None

        try:
            # self.attrs will only be non-None if we were able to load this user
            # from the LDAP directory, so this filters out nonexistent users.
            if self.attrs is not None:
                self._get_or_create_user(force_populate=True)

            user = self._user
        except ldap.LDAPError as e:
            logger.warning(u"Caught LDAPError while authenticating %s: %s",
                           self._username, pprint.pformat(e))
        except Exception as e:
            logger.error(u"Caught Exception while authenticating %s: %s",
                         self._username, pprint.pformat(e))
            logger.error(''.join(traceback.format_tb(sys.exc_info()[2])))
            raise

        return user

    #
    # Public properties (callbacks). These are all lazy for performance reasons.
    #

    def _get_user_dn(self):
        if self._user_dn is None:
            self._load_user_dn()

        return self._user_dn
    dn = property(_get_user_dn)

    def _get_user_attrs(self):
        if self._user_attrs is None:
            self._load_user_attrs()

        return self._user_attrs
    attrs = property(_get_user_attrs)

    def _get_group_dns(self):
        return self._get_groups().get_group_dns()
    group_dns = property(_get_group_dns)

    def _get_group_names(self):
        return self._get_groups().get_group_names()
    group_names = property(_get_group_names)

    def _get_bound_connection(self):
        if not self._connection_bound:
            self._bind()

        return self._get_connection()
    connection = property(_get_bound_connection)

    #
    # Authentication
    #

    def _authenticate_user_dn(self, password):
        """
        Binds to the LDAP server with the user's DN and password. Raises
        AuthenticationFailed on failure.
        """
        if self.dn is None:
            raise self.AuthenticationFailed("failed to map the username to a DN.")

        try:
            sticky = self.settings.BIND_AS_AUTHENTICATING_USER

            self._bind_as(self.dn, password, sticky=sticky)
        except ldap.INVALID_CREDENTIALS:
            raise self.AuthenticationFailed("user DN/password rejected by LDAP server.")

    def _load_user_attrs(self):
        if self.dn is not None:
            search = LDAPSearch(self.dn, ldap.SCOPE_BASE)
            results = search.execute(self.connection)

            if results is not None and len(results) > 0:
                self._user_attrs = results[0][1]

    def _load_user_dn(self):
        """
        Populates self._user_dn with the distinguished name of our user. This
        will either construct the DN from a template in
        AUTH_LDAP_USER_DN_TEMPLATE or connect to the server and search for it.
        """
        if self._using_simple_bind_mode():
            self._construct_simple_user_dn()
        else:
            self._search_for_user_dn()

    def _using_simple_bind_mode(self):
        return (self.settings.USER_DN_TEMPLATE is not None)

    def _construct_simple_user_dn(self):
        template = self.settings.USER_DN_TEMPLATE
        username = ldap.dn.escape_dn_chars(self._username)

        self._user_dn = template % {'user': username}

    def _search_for_user_dn(self):
        """
        Searches the directory for a user matching AUTH_LDAP_USER_SEARCH.
        Populates self._user_dn and self._user_attrs.
        """
        search = self.settings.USER_SEARCH
        if search is None:
            raise ImproperlyConfigured('AUTH_LDAP_USER_SEARCH must be an LDAPSearch instance.')

        results = search.execute(self.connection, {'user': self._username})
        if results is not None and len(results) == 1:
            (self._user_dn, self._user_attrs) = next(iter(results))

    def _check_requirements(self):
        """
        Checks all authentication requirements beyond credentials. Raises
        AuthenticationFailed on failure.
        """
        self._check_required_group()
        self._check_denied_group()

    def _check_required_group(self):
        """
        Returns True if the group requirement (AUTH_LDAP_REQUIRE_GROUP) is
        met. Always returns True if AUTH_LDAP_REQUIRE_GROUP is None.
        """
        required_group_dn = self.settings.REQUIRE_GROUP

        if required_group_dn is not None:
            is_member = self._get_groups().is_member_of(required_group_dn)
            if not is_member:
                raise self.AuthenticationFailed("user is not a member of AUTH_LDAP_REQUIRE_GROUP")

        return True

    def _check_denied_group(self):
        """
        Returns True if the negative group requirement (AUTH_LDAP_DENY_GROUP)
        is met. Always returns True if AUTH_LDAP_DENY_GROUP is None.
        """
        denied_group_dn = self.settings.DENY_GROUP

        if denied_group_dn is not None:
            is_member = self._get_groups().is_member_of(denied_group_dn)
            if is_member:
                raise self.AuthenticationFailed("user is a member of AUTH_LDAP_DENY_GROUP")

        return True

    #
    # User management
    #

    def _get_or_create_user(self, force_populate=False):
        """
        Loads the User model object from the database or creates it if it
        doesn't exist. Also populates the fields, subject to
        AUTH_LDAP_ALWAYS_UPDATE_USER.
        """
        save_user = False

        username = self.backend.ldap_to_django_username(self._username)

        self._user, created = self.backend.get_or_create_user(username, self)
        self._user.ldap_user = self
        self._user.ldap_username = self._username

        should_populate = force_populate or self.settings.ALWAYS_UPDATE_USER or created

        if created:
            logger.debug("Created Django user %s", username)
            self._user.set_unusable_password()
            save_user = True

        if should_populate:
            logger.debug("Populating Django user %s", username)
            self._populate_user()
            save_user = True

        if self.settings.MIRROR_GROUPS:
            self._mirror_groups()

        # Give the client a chance to finish populating the user just before
        # saving.
        if should_populate:
            signal_responses = populate_user.send(self.backend.__class__, user=self._user, ldap_user=self)
            if len(signal_responses) > 0:
                save_user = True

        if save_user:
            self._user.save()

        # We populate the profile after the user model is saved to give the
        # client a chance to create the profile. Custom user models in Django
        # 1.5 probably won't have a get_profile method.
        if should_populate and django.VERSION < (1, 7) and hasattr(self._user, 'get_profile'):
            self._populate_and_save_user_profile()

    def _populate_user(self):
        """
        Populates our User object with information from the LDAP directory.
        """
        self._populate_user_from_attributes()
        self._populate_user_from_group_memberships()

    def _populate_user_from_attributes(self):
        for field, attr in self.settings.USER_ATTR_MAP.items():
            try:
                setattr(self._user, field, self.attrs[attr][0])
            except Exception:
                logger.warning("%s does not have a value for the attribute %s", self.dn, attr)

    def _populate_user_from_group_memberships(self):
        for field, group_dns in self.settings.USER_FLAGS_BY_GROUP.items():
            if isinstance(group_dns, basestring):
                group_dns = [group_dns]
            value = any(self._get_groups().is_member_of(dn) for dn in group_dns)
            setattr(self._user, field, value)

    def _populate_and_save_user_profile(self):
        """
        Populates a User profile object with fields from the LDAP directory.
        """
        try:
            profile = self._user.get_profile()
            save_profile = False

            logger.debug("Populating Django user profile for %s", get_user_username(self._user))

            save_profile = self._populate_profile_from_attributes(profile) or save_profile
            save_profile = self._populate_profile_from_group_memberships(profile) or save_profile

            signal_responses = populate_user_profile.send(self.backend.__class__, profile=profile, ldap_user=self)
            if len(signal_responses) > 0:
                save_profile = True

            if save_profile:
                profile.save()
        except (SiteProfileNotAvailable, ObjectDoesNotExist):
            logger.debug("Django user %s does not have a profile to populate", get_user_username(self._user))

    def _populate_profile_from_attributes(self, profile):
        """
        Populate the given profile object from AUTH_LDAP_PROFILE_ATTR_MAP.
        Returns True if the profile was modified.
        """
        save_profile = False

        for field, attr in self.settings.PROFILE_ATTR_MAP.items():
            try:
                # user_attrs is a hash of lists of attribute values
                setattr(profile, field, self.attrs[attr][0])
                save_profile = True
            except Exception:
                logger.warning("%s does not have a value for the attribute %s", self.dn, attr)

        return save_profile

    def _populate_profile_from_group_memberships(self, profile):
        """
        Populate the given profile object from AUTH_LDAP_PROFILE_FLAGS_BY_GROUP.
        Returns True if the profile was modified.
        """
        save_profile = False

        for field, group_dns in self.settings.PROFILE_FLAGS_BY_GROUP.items():
            if isinstance(group_dns, basestring):
                group_dns = [group_dns]
            value = any(self._get_groups().is_member_of(dn) for dn in group_dns)
            setattr(profile, field, value)
            save_profile = True

        return save_profile

    def _mirror_groups(self):
        """
        Mirrors the user's LDAP groups in the Django database and updates the
        user's membership.
        """
        group_names = self._get_groups().get_group_names()
        groups = [Group.objects.get_or_create(name=group_name)[0] for group_name
                  in group_names]

        self._user.groups = groups

    #
    # Group information
    #

    def _load_group_permissions(self):
        """
        Populates self._group_permissions based on LDAP group membership and
        Django group permissions.
        """
        group_names = self._get_groups().get_group_names()

        perms = Permission.objects.filter(group__name__in=group_names)
        perms = perms.values_list('content_type__app_label', 'codename')
        perms = perms.order_by()

        self._group_permissions = set(["%s.%s" % (ct, name) for ct, name in perms])

    def _get_groups(self):
        """
        Returns an _LDAPUserGroups object, which can determine group
        membership.
        """
        if self._groups is None:
            self._groups = _LDAPUserGroups(self)

        return self._groups

    #
    # LDAP connection
    #

    def _bind(self):
        """
        Binds to the LDAP server with AUTH_LDAP_BIND_DN and
        AUTH_LDAP_BIND_PASSWORD.
        """
        self._bind_as(self.settings.BIND_DN, self.settings.BIND_PASSWORD,
                      sticky=True)

    def _bind_as(self, bind_dn, bind_password, sticky=False):
        """
        Binds to the LDAP server with the given credentials. This does not trap
        exceptions.

        If sticky is True, then we will consider the connection to be bound for
        the life of this object. If False, then the caller only wishes to test
        the credentials, after which the connection will be considered unbound.
        """
        self._get_connection().simple_bind_s(force_str(bind_dn),
                                             force_str(bind_password))

        self._connection_bound = sticky

    def _get_connection(self):
        """
        Returns our cached LDAPObject, which may or may not be bound.
        """
        if self._connection is None:
            uri = self.settings.SERVER_URI
            if callable(uri):
                uri = uri()

            self._connection = self.backend.ldap.initialize(uri)

            for opt, value in self.settings.CONNECTION_OPTIONS.items():
                self._connection.set_option(opt, value)

            if self.settings.START_TLS:
                logger.debug("Initiating TLS")
                self._connection.start_tls_s()

        return self._connection

class _LDAPUserGroups(object):
    """
    Represents the set of groups that a user belongs to.
    """
    def __init__(self, ldap_user):
        self.settings = ldap_user.settings
        self._ldap_user = ldap_user
        self._group_type = None
        self._group_search = None
        self._group_infos = None
        self._group_dns = None
        self._group_names = None

        self._init_group_settings()

    def _init_group_settings(self):
        """
        Loads the settings we need to deal with groups. Raises
        ImproperlyConfigured if anything's not right.
        """
        self._group_type = self.settings.GROUP_TYPE
        if self._group_type is None:
            raise ImproperlyConfigured("AUTH_LDAP_GROUP_TYPE must be an LDAPGroupType instance.")

        self._group_search = self.settings.GROUP_SEARCH
        if self._group_search is None:
            raise ImproperlyConfigured("AUTH_LDAP_GROUP_SEARCH must be an LDAPSearch instance.")

    def get_group_names(self):
        """
        Returns the set of Django group names that this user belongs to by
        virtue of LDAP group memberships.
        """
        if self._group_names is None:
            self._load_cached_attr("_group_names")

        if self._group_names is None:
            group_infos = self._get_group_infos()
            self._group_names = set(
                self._group_type.group_name_from_info(group_info)
                for group_info in group_infos
            )
            self._cache_attr("_group_names")

        return self._group_names

    def is_member_of(self, group_dn):
        """
        Returns true if our user is a member of the given group.
        """
        is_member = None

        # Normalize the DN
        group_dn = group_dn.lower()

        # If we have self._group_dns, we'll use it. Otherwise, we'll try to
        # avoid the cost of loading it.
        if self._group_dns is None:
            is_member = self._group_type.is_member(self._ldap_user, group_dn)

        if is_member is None:
            is_member = (group_dn in self.get_group_dns())

        logger.debug("%s is%sa member of %s", self._ldap_user.dn,
                     is_member and " " or " not ", group_dn)

        return is_member

    def get_group_dns(self):
        """
        Returns a (cached) set of the distinguished names in self._group_infos.
        """
        if self._group_dns is None:
            group_infos = self._get_group_infos()
            self._group_dns = set(group_info[0] for group_info in group_infos)

        return self._group_dns

    def _get_group_infos(self):
        """
        Returns a (cached) list of group_info structures for the groups that our
        user is a member of.
        """
        if self._group_infos is None:
            self._group_infos = self._group_type.user_groups(self._ldap_user,
                                                             self._group_search)

        return self._group_infos

    def _load_cached_attr(self, attr_name):
        if self.settings.CACHE_GROUPS:
            key = self._cache_key(attr_name)
            value = cache.get(key)
            setattr(self, attr_name, value)

    def _cache_attr(self, attr_name):
        if self.settings.CACHE_GROUPS:
            key = self._cache_key(attr_name)
            value = getattr(self, attr_name, None)
            cache.set(key, value, self.settings.GROUP_CACHE_TIMEOUT)

    def _cache_key(self, attr_name):
        """
        Memcache keys can't have spaces in them, so we'll remove them from the
        DN for maximum compatibility.
        """
        dn = self._ldap_user.dn.replace(' ', '%20')
        key = u'auth_ldap.%s.%s.%s' % (self.__class__.__name__, attr_name, dn)

        return key

class LDAPSettings(object):
    """
    This is a simple class to take the place of the global settings object. An
    instance will contain all of our settings as attributes, with default values
    if they are not specified by the configuration.
    """
    defaults = {
        'ALWAYS_UPDATE_USER': True,
        'AUTHORIZE_ALL_USERS': False,
        'BIND_AS_AUTHENTICATING_USER': False,
        'BIND_DN': '',
        'BIND_PASSWORD': '',
        'CACHE_GROUPS': False,
        'CONNECTION_OPTIONS': {},
        'DENY_GROUP': None,
        'FIND_GROUP_PERMS': False,
        'GROUP_CACHE_TIMEOUT': None,
        'GROUP_SEARCH': None,
        'GROUP_TYPE': None,
        'MIRROR_GROUPS': False,
        'PERMIT_EMPTY_PASSWORD': False,
        'PROFILE_ATTR_MAP': {},
        'PROFILE_FLAGS_BY_GROUP': {},
        'REQUIRE_GROUP': None,
        'SERVER_URI': 'ldap://localhost',
        'START_TLS': False,
        'USER_ATTR_MAP': {},
        'USER_DN_TEMPLATE': None,
        'USER_FLAGS_BY_GROUP': {},
        'USER_SEARCH': None,
    }

    def __init__(self, prefix='AUTH_LDAP_'):
        """
        Loads our settings from django.conf.settings, applying defaults for any
        that are omitted.
        """
        from django.conf import settings

        for name, default in self.defaults.items():
            value = getattr(settings, prefix + name, default)
            setattr(self, name, value)


text:
import * as React from "react";
import Link, { NavLink } from "redux-first-router-link";

interface Payload {
    category: string;
}

export default () => {
    return (
        <div>
            { /* as a standard href path string: */ }
            <Link to='/list/db-graphql'>DB & GRAPHQL</Link>

            { /* as an array of path segments: */ }
            <Link to={['list', 'react-redux']}>REACT & REDUX</Link>

            { /* as an action object (RECOMMENDED APPROACH SO YOU CAN CHANGE ALL URLs FROM YOUR ROUTESMAP): */ }
            <Link to={{type: 'LIST', payload: { category: 'fp' }}}>FP</Link>

            <NavLink
                to={{ type: 'LIST', payload: { category: 'redux-first-router' } }}
                activeClassName='active'
                activeStyle={{ color: 'purple' }}
                exact={true}
                strict={true}
                isActive={(match, location) => (location.payload as Payload).category === 'redux-first-router'} >
                Redux First Router
            </NavLink>
        </div>
    );
};


text:
package com.shinemo.openapi.client.dto.personalremind;

import com.shinemo.openapi.client.dto.CreateUserDTO;

import java.io.Serializable;
import java.util.ArrayList;

/**
 * Created by ohun on 2017/3/22.
 *
 * @author ohun@live.cn (夜色)
 */
public class PersonalRemindInfoDTO implements Serializable {

    private CreateUserDTO createUser;
    private PersonalRemindDTO personalRemind;

    public CreateUserDTO getCreateUser() {
        return createUser;
    }

    public void setCreateUser(CreateUserDTO createUser) {
        this.createUser = createUser;
    }

    public PersonalRemindDTO getPersonalRemind() {
        return personalRemind;
    }

    public void setPersonalRemind(PersonalRemindDTO personalRemind) {
        this.personalRemind = personalRemind;
    }

    @Override
    public String toString() {
        return "PersonalRemindInfoDTO{" +
                "createUser=" + createUser +
                ", personalRemind=" + personalRemind +
                '}';
    }

}


text:
using System;
using BTDB.StreamLayer;

namespace BTDB.KVDBLayer;

class FileTransactionLog : IFileInfo, IFileTransactionLog
{
    readonly Guid? _guid;
    readonly uint _previousFileId;
    readonly long _generation;

    public FileTransactionLog(ref SpanReader reader, Guid? guid)
    {
        _guid = guid;
        _generation = reader.ReadVInt64();
        _previousFileId = (uint)reader.ReadVInt32();
    }

    public FileTransactionLog(long generation, Guid? guid, uint fileIdWithPreviousTransactionLog)
    {
        _guid = guid;
        _generation = generation;
        _previousFileId = fileIdWithPreviousTransactionLog;
    }

    public KVFileType FileType => KVFileType.TransactionLog;

    public Guid? Guid => _guid;

    public long Generation => _generation;

    public long SubDBId => 0;

    public uint PreviousFileId => _previousFileId;

    public uint NextFileId { get; set; }

    internal static void SkipHeader(ref SpanReader reader)
    {
        FileCollectionWithFileInfos.SkipHeader(ref reader);
        reader.SkipUInt8(); // type of file
        reader.SkipVInt64(); // generation
        reader.SkipVInt32(); // previous file id
    }

    internal void WriteHeader(ref SpanWriter writer)
    {
        FileCollectionWithFileInfos.WriteHeader(ref writer, _guid);
        writer.WriteUInt8((byte)KVFileType.TransactionLog);
        writer.WriteVInt64(_generation);
        writer.WriteVInt32((int)_previousFileId);
    }
}


text:
/* eslint-disable import/newline-after-import,import/first,no-undef */
import React from 'react';
import ArchiveHocFactory from '../ArchiveHocFactory';
jest.mock('../OnArchivedContainerHOC');
import OnArchivedContainerHOC from '../OnArchivedContainerHOC';

describe('ArchiveHocFactory', () => {
  const TestComponent = () => (
Test component
);
  const factoryMock = jest.fn();

  ArchiveHocFactory(TestComponent, factoryMock);

  it('Should call passed factory function', () => {
    expect(factoryMock.mock.calls.length).toBe(1);
  });

  it('Should call OnArchivedContainerHOC', () => {
    expect(OnArchivedContainerHOC.mock.calls.length).toBe(1);
  });
});


text:
using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;

int main(int argc, char* argv[]) {
    GOOGLE_PROTOBUF_VERIFY_VERSION;
    if (argc < 2) {
        cerr << "usage: " << *argv << " data.proto" << endl;
        return 1;
    }
    ifstream fin {argv[1]};
    if (not fin.is_open()) {
        cerr << *argv << ": failed to open input " << argv[1] << endl;
        return 1;
    }
    util::Memstat mem_start;
    cout << "[before] " << mem_start.info() << endl;
    util::Stopwatch stopwatch;
    {
        Data data;
        if (not data.ParseFromIstream(&fin)) {
            cerr << "failed to parse protobuf" << endl;
        }
    }
    util::MicroSec elapsed {stopwatch.elapsed()};
    util::Memstat mem_end;
    cout << "[after ] " << mem_end.info() << " (" << (mem_end - mem_start) << ") elapsed: " << elapsed  << endl;
    google::protobuf::ShutdownProtobufLibrary();
    return 0;
}


text:
'use strict';

exports.jobs = require('./jobs');
exports.Framer = require('./framer');
exports.Parser = require('./parser');
exports.Worker = require('./workerpool').Worker;
exports.WorkerPool = require('./workerpool').WorkerPool;


text:
<md-content flex-xs="90" flex-gt-xs="60">

Top up your Co-op Account

Don't use a credit card?

You can still shop online with us even without a credit card or paypal account. In the near future we will accept bank transfer directly from our checkout. Until then, here are some way to put credit on your account.

Pay Cash on Tuesday

Come by to our shop at 50 John Street on a Tuesday and browse a limited selection of our products. You can pay for your purchases with cash and pay extra to have added to your account.

Pay online with internet banking

Send us some money by internet banking. Use your customer number as a reference please. For faster clearance, email or text us with the amount you've sent and we'll charge your account faster (even before the transfer has arrived on occassion).
      <md-list><md-list-item class="md-whiteframe-3dp">

38-9022-0223521-01 Reference: {{currentUser.profile.customerNumber || "Your Reference Here"}}

      </md-list-item></md-list>

Sell goods online

Selling goods on our website initially earns you credit. This credit will be zeroed when we pay you by internet banking but you can spend any balance you earn before we zero it or ask us to deplay paying you for a set period.

Contact Us with any other Questions you have

    <md-button ui-sref="contact" class="md-raised md-primary">Contact Us</md-button>

</md-content>