Add agda, bash, c, nix, python and rust

main
xenia 2023-11-11 23:27:21 +01:00
commit 7c0c72b8b7
78 changed files with 43816 additions and 0 deletions

21
LICENSE 100644
View File

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

9
README.md 100644
View File

@ -0,0 +1,9 @@
# xenia/tree-sitters — a collection of tree-sitter grammars, built with nix for static linking
Languages:
* c: https://github.com/tree-sitter/tree-sitter-c (MIT)
* agda: https://github.com/tree-sitter/tree-sitter-agda (MIT)
* bash: https://github.com/tree-sitter/tree-sitter-bash (MIT)
* nix: https://github.com/nix-community/tree-sitter-nix (MIT)
* python: https://github.com/tree-sitter/tree-sitter-python (MIT)
* rust: https://github.com/tree-sitter/tree-sitter-rust (MIT)

21
agda/LICENSE 100644
View File

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

View File

@ -0,0 +1,8 @@
record RawMonoid c : Set (suc (c ⊔ )) where
infixl 7 _∙_
infix 4 _≈_
field
Carrier : Set c
_≈_ : Rel Carrier
_b_ : Op Carrier
a : Carrier

1084
agda/grammar.js 100644

File diff suppressed because it is too large Load Diff

291
agda/src/scanner.c 100644
View File

@ -0,0 +1,291 @@
#include "tree_sitter/parser.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define VEC_RESIZE(vec, _cap) \
void *tmp = realloc((vec).data, (_cap) * sizeof((vec).data[0])); \
assert(tmp != NULL); \
(vec).data = tmp; \
(vec).cap = (_cap);
#define VEC_GROW(vec, _cap) \
if ((vec).cap < (_cap)) { \
VEC_RESIZE((vec), (_cap)); \
}
#define VEC_PUSH(vec, el) \
if ((vec).cap == (vec).len) { \
VEC_RESIZE((vec), MAX(16, (vec).len * 2)); \
} \
(vec).data[(vec).len++] = (el);
#define VEC_POP(vec) (vec).len--;
#define VEC_NEW \
{ .len = 0, .cap = 0, .data = NULL }
#define VEC_BACK(vec) ((vec).data[(vec).len - 1])
#define VEC_FREE(vec) \
{ \
if ((vec).data != NULL) \
free((vec).data); \
}
#define VEC_CLEAR(vec) (vec).len = 0;
#define QUEUE_RESIZE(queue, _cap) \
do { \
void *tmp = realloc((queue).data, (_cap) * sizeof((queue).data[0])); \
assert(tmp != NULL); \
(queue).data = tmp; \
(queue).cap = (_cap); \
} while (0)
#define QUEUE_GROW(queue, _cap) \
do { \
if ((queue).cap < (_cap)) { \
QUEUE_RESIZE((queue), (_cap)); \
} \
} while (0)
#define QUEUE_PUSH(queue, el) \
do { \
if ((queue).cap == 0) { \
QUEUE_RESIZE((queue), 16); \
} else if ((queue).cap == ((queue).tail - (queue).head)) { \
QUEUE_RESIZE((queue), (queue).cap * 2); \
} \
(queue).data[(queue).tail % (queue).cap] = (el); \
(queue).tail++; \
} while (0)
#define QUEUE_POP(queue) \
do { \
assert((queue).head < (queue).tail); \
(queue).head++; \
} while (0)
#define QUEUE_FRONT(queue) (queue).data[(queue).head % (queue).cap]
#define QUEUE_EMPTY(queue) ((queue).head == (queue).tail)
#define QUEUE_NEW \
{ .head = 0, .tail = 0, .cap = 0, .data = NULL }
#define QUEUE_FREE(queue) \
do { \
if ((queue).data != NULL) \
free((queue).data); \
} while (0)
#define QUEUE_CLEAR(queue) \
do { \
(queue).head = 0; \
(queue).tail = 0; \
} while (0)
enum TokenType {
NEWLINE,
INDENT,
DEDENT,
};
typedef struct {
uint32_t len;
uint32_t cap;
uint16_t *data;
} indent_vec;
static indent_vec indent_vec_new() {
indent_vec vec = VEC_NEW;
vec.data = calloc(1, sizeof(uint16_t));
vec.cap = 1;
return vec;
}
typedef struct {
uint32_t head;
uint32_t tail;
uint32_t cap;
uint16_t *data;
} token_queue;
static token_queue token_queue_new() {
token_queue queue = QUEUE_NEW;
queue.data = calloc(1, sizeof(uint16_t));
queue.cap = 1;
return queue;
}
typedef struct {
indent_vec indents;
uint32_t queued_dedent_count;
token_queue tokens;
} Scanner;
static inline void advance(TSLexer *lexer) { lexer->advance(lexer, false); }
static inline void skip(TSLexer *lexer) { lexer->advance(lexer, true); }
bool tree_sitter_agda_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
Scanner *scanner = (Scanner *)payload;
if (QUEUE_EMPTY(scanner->tokens)) {
if (valid_symbols[DEDENT] && scanner->queued_dedent_count > 0) {
scanner->queued_dedent_count--;
QUEUE_PUSH(scanner->tokens, DEDENT);
QUEUE_PUSH(scanner->tokens, NEWLINE);
} else {
bool skipped_newline = false;
while (lexer->lookahead == ' ' || lexer->lookahead == '\t' ||
lexer->lookahead == '\r' || lexer->lookahead == '\n') {
if (lexer->lookahead == '\n') {
skipped_newline = true;
skip(lexer);
} else {
skip(lexer);
}
}
if (lexer->eof(lexer)) {
if (valid_symbols[DEDENT] && scanner->indents.len > 1) {
VEC_POP(scanner->indents);
QUEUE_PUSH(scanner->tokens, DEDENT);
QUEUE_PUSH(scanner->tokens, NEWLINE);
} else if (valid_symbols[NEWLINE]) {
QUEUE_PUSH(scanner->tokens, NEWLINE);
}
} else {
bool next_token_is_comment = false;
uint16_t indent_length = (uint16_t)lexer->get_column(lexer);
bool indent = indent_length > VEC_BACK(scanner->indents);
bool dedent = indent_length < VEC_BACK(scanner->indents);
if (!next_token_is_comment) {
if (skipped_newline) {
if (indent) {
if (valid_symbols[INDENT]) {
VEC_PUSH(scanner->indents, indent_length);
QUEUE_PUSH(scanner->tokens, INDENT);
}
} else if (dedent) {
if (valid_symbols[NEWLINE]) {
QUEUE_PUSH(scanner->tokens, NEWLINE);
}
} else {
if (valid_symbols[NEWLINE]) {
QUEUE_PUSH(scanner->tokens, NEWLINE);
}
}
} else {
if (indent) {
if (valid_symbols[INDENT]) {
VEC_PUSH(scanner->indents, indent_length);
QUEUE_PUSH(scanner->tokens, INDENT);
}
} else if (dedent) {
VEC_POP(scanner->indents);
while (indent_length < VEC_BACK(scanner->indents)) {
VEC_POP(scanner->indents);
scanner->queued_dedent_count++;
}
if (valid_symbols[DEDENT]) {
QUEUE_PUSH(scanner->tokens, DEDENT);
QUEUE_PUSH(scanner->tokens, NEWLINE);
} else {
scanner->queued_dedent_count++;
}
}
}
}
}
}
}
if (QUEUE_EMPTY(scanner->tokens)) {
return false;
}
lexer->result_symbol = QUEUE_FRONT(scanner->tokens);
QUEUE_POP(scanner->tokens);
return true;
}
unsigned tree_sitter_agda_external_scanner_serialize(void *payload,
char *buffer) {
Scanner *scanner = (Scanner *)payload;
if (scanner->indents.len * sizeof(uint16_t) + 1 >
TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {
return 0;
}
unsigned size = 0;
buffer[size++] = (char)scanner->queued_dedent_count;
memcpy(&buffer[size], scanner->indents.data,
scanner->indents.len * sizeof(uint16_t));
size += (unsigned)(scanner->indents.len * sizeof(uint16_t));
return size;
}
void tree_sitter_agda_external_scanner_deserialize(void *payload,
const char *buffer,
unsigned length) {
Scanner *scanner = (Scanner *)payload;
scanner->queued_dedent_count = 0;
VEC_CLEAR(scanner->indents);
if (length == 0) {
if (buffer == NULL) {
VEC_PUSH(scanner->indents, 0);
}
return;
}
scanner->queued_dedent_count = (uint8_t)buffer[0];
unsigned size = 1;
if (length > size) {
VEC_GROW(scanner->indents,
(uint32_t)(length - size) / sizeof(uint16_t));
scanner->indents.len = (length - size) / sizeof(uint16_t);
memcpy(scanner->indents.data, &buffer[size],
scanner->indents.len * sizeof(uint16_t));
size += (unsigned)(scanner->indents.len * sizeof(uint16_t));
}
if (scanner->indents.len == 0) {
VEC_PUSH(scanner->indents, 0);
return;
}
assert(size == length);
}
void *tree_sitter_agda_external_scanner_create() {
Scanner *scanner = calloc(1, sizeof(Scanner));
scanner->indents = indent_vec_new();
scanner->tokens = token_queue_new();
tree_sitter_agda_external_scanner_deserialize(scanner, NULL, 0);
return scanner;
}
void tree_sitter_agda_external_scanner_destroy(void *payload) {
Scanner *scanner = (Scanner *)payload;
VEC_FREE(scanner->indents);
QUEUE_FREE(scanner->tokens);
free(scanner);
}

21
bash/LICENSE 100644
View File

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

View File

@ -0,0 +1,143 @@
#!/bin/bash
if [ "$(uname)" == 'Darwin' ]; then
OS='Mac'
elif [ "$(expr substr $(uname -s) 1 5)" == 'Linux' ]; then
OS='Linux'
else
echo "Your platform ($(uname -a)) is not supported."
exit 1
fi
if [ "$(basename $0)" == 'atom-beta' ]; then
BETA_VERSION=true
else
BETA_VERSION=
fi
export ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT=true
while getopts ":wtfvh-:" opt; do
case "$opt" in
-)
case "${OPTARG}" in
wait)
WAIT=1
;;
help|version)
REDIRECT_STDERR=1
EXPECT_OUTPUT=1
;;
foreground|benchmark|benchmark-test|test)
EXPECT_OUTPUT=1
;;
esac
;;
w)
WAIT=1
;;
h|v)
REDIRECT_STDERR=1
EXPECT_OUTPUT=1
;;
f|t)
EXPECT_OUTPUT=1
;;
esac
done
if [ $REDIRECT_STDERR ]; then
exec 2> /dev/null
fi
if [ $EXPECT_OUTPUT ]; then
export ELECTRON_ENABLE_LOGGING=1
fi
if [ $OS == 'Mac' ]; then
if [ -L "$0" ]; then
SCRIPT="$(readlink "$0")"
else
SCRIPT="$0"
fi
ATOM_APP="$(dirname "$(dirname "$(dirname "$(dirname "$SCRIPT")")")")"
if [ "$ATOM_APP" == . ]; then
unset ATOM_APP
else
ATOM_PATH="$(dirname "$ATOM_APP")"
ATOM_APP_NAME="$(basename "$ATOM_APP")"
fi
if [ -n "$BETA_VERSION" ]; then
ATOM_EXECUTABLE_NAME="Atom Beta"
else
ATOM_EXECUTABLE_NAME="Atom"
fi
if [ -z "${ATOM_PATH}" ]; then
# If ATOM_PATH isn't set, check /Applications and then ~/Applications for Atom.app
if [ -x "/Applications/$ATOM_APP_NAME" ]; then
ATOM_PATH="/Applications"
elif [ -x "$HOME/Applications/$ATOM_APP_NAME" ]; then
ATOM_PATH="$HOME/Applications"
else
# We haven't found an Atom.app, use spotlight to search for Atom
ATOM_PATH="$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | grep -v ShipIt | head -1 | xargs -0 dirname)"
# Exit if Atom can't be found
if [ ! -x "$ATOM_PATH/$ATOM_APP_NAME" ]; then
echo "Cannot locate ${ATOM_APP_NAME}, it is usually located in /Applications. Set the ATOM_PATH environment variable to the directory containing ${ATOM_APP_NAME}."
exit 1
fi
fi
fi
if [ $EXPECT_OUTPUT ]; then
"$ATOM_PATH/$ATOM_APP_NAME/Contents/MacOS/$ATOM_EXECUTABLE_NAME" --executed-from="$(pwd)" --pid=$$ "$@"
exit $?
else
open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ --path-environment="$PATH" "$@"
fi
elif [ $OS == 'Linux' ]; then
SCRIPT=$(readlink -f "$0")
USR_DIRECTORY=$(readlink -f $(dirname $SCRIPT)/..)
if [ -n "$BETA_VERSION" ]; then
ATOM_PATH="$USR_DIRECTORY/share/atom-beta/atom"
else
ATOM_PATH="$USR_DIRECTORY/share/atom/atom"
fi
ATOM_HOME="${ATOM_HOME:-$HOME/.atom}"
mkdir -p "$ATOM_HOME"
: ${TMPDIR:=/tmp}
[ -x "$ATOM_PATH" ] || ATOM_PATH="$TMPDIR/atom-build/Atom/atom"
if [ $EXPECT_OUTPUT ]; then
"$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@"
exit $?
else
(
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$ATOM_HOME/nohup.out" 2>&1
if [ $? -ne 0 ]; then
cat "$ATOM_HOME/nohup.out"
exit $?
fi
) &
fi
fi
# Exits this process when Atom is used as $EDITOR
on_die() {
exit 0
}
trap 'on_die' SIGQUIT SIGTERM
# If the wait flag is set, don't exit this process until Atom tells it to.
if [ $WAIT ]; then
while true; do
sleep 1
done
fi

View File

@ -0,0 +1,165 @@
#!/bin/bash
# look for old 0.x cruft, and get rid of it.
# Should already be sitting in the npm folder.
# This doesn't have to be quite as cross-platform as install.sh.
# There are some bash-isms, because maintaining *two*
# fully-portable posix/bourne sh scripts is too much for
# one project with a sane maintainer.
# If readlink isn't available, then this is just too tricky.
# However, greadlink is fine, so Solaris can join the party, too.
readlink="readlink"
which $readlink >/dev/null 2>/dev/null
if [ $? -ne 0 ]; then
readlink="greadlink"
which $readlink >/dev/null 2>/dev/null
if [ $? -ne 0 ]; then
echo "Can't find the readlink or greadlink command. Aborting."
exit 1
fi
fi
if [ "x$npm_config_prefix" != "x" ]; then
PREFIXES=$npm_config_prefix
else
node="$NODE"
if [ "x$node" = "x" ]; then
node=`which node`
fi
if [ "x$node" = "x" ]; then
echo "Can't find node to determine prefix. Aborting."
exit 1
fi
PREFIX=`dirname $node`
PREFIX=`dirname $PREFIX`
echo "cleanup prefix=$PREFIX"
PREFIXES=$PREFIX
altprefix=`"$node" -e process.installPrefix`
if [ "x$altprefix" != "x" ] && [ "x$altprefix" != "x$PREFIX" ]; then
echo "altprefix=$altprefix"
PREFIXES="$PREFIX $altprefix"
fi
fi
# now prefix is where npm would be rooted by default
# go hunting.
packages=
for prefix in $PREFIXES; do
packages="$packages
"`ls "$prefix"/lib/node/.npm 2>/dev/null | grep -v .cache`
done
packages=`echo $packages`
filelist=()
fid=0
for prefix in $PREFIXES; do
# remove any links into the .npm dir, or links to
# version-named shims/symlinks.
for folder in share/man bin lib/node; do
find $prefix/$folder -type l | while read file; do
target=`$readlink $file | grep '/\.npm/'`
if [ "x$target" != "x" ]; then
# found one!
filelist[$fid]="$file"
let 'fid++'
# also remove any symlinks to this file.
base=`basename "$file"`
base=`echo "$base" | awk -F@ '{print $1}'`
if [ "x$base" != "x" ]; then
find "`dirname $file`" -type l -name "$base"'*' \
| while read l; do
target=`$readlink "$l" | grep "$base"`
if [ "x$target" != "x" ]; then
filelist[$fid]="$1"
let 'fid++'
fi
done
fi
fi
done
# Scour for shim files. These are relics of 0.2 npm installs.
# note: grep -r is not portable.
find $prefix/$folder -type f \
| xargs grep -sl '// generated by npm' \
| while read file; do
filelist[$fid]="$file"
let 'fid++'
done
done
# now remove the package modules, and the .npm folder itself.
if [ "x$packages" != "x" ]; then
for pkg in $packages; do
filelist[$fid]="$prefix/lib/node/$pkg"
let 'fid++'
for i in $prefix/lib/node/$pkg\@*; do
filelist[$fid]="$i"
let 'fid++'
done
done
fi
for folder in lib/node/.npm lib/npm share/npm; do
if [ -d $prefix/$folder ]; then
filelist[$fid]="$prefix/$folder"
let 'fid++'
fi
done
done
# now actually clean, but only if there's anything TO clean
if [ "${#filelist[@]}" -gt 0 ]; then
echo ""
echo "This script will find and eliminate any shims, symbolic"
echo "links, and other cruft that was installed by npm 0.x."
echo ""
if [ "x$packages" != "x" ]; then
echo "The following packages appear to have been installed with"
echo "an old version of npm, and will be removed forcibly:"
for pkg in $packages; do
echo " $pkg"
done
echo "Make a note of these. You may want to install them"
echo "with npm 1.0 when this process is completed."
echo ""
fi
OK=
if [ "x$1" = "x-y" ]; then
OK="yes"
fi
while [ "$OK" != "y" ] && [ "$OK" != "yes" ] && [ "$OK" != "no" ]; do
echo "Is this OK?"
echo " enter 'yes' or 'no'"
echo " or 'show' to see a list of files "
read OK
if [ "x$OK" = "xshow" ] || [ "x$OK" = "xs" ]; then
for i in "${filelist[@]}"; do
echo "$i"
done
fi
done
if [ "$OK" = "no" ]; then
echo "Aborting"
exit 1
fi
for i in "${filelist[@]}"; do
rm -rf "$i"
done
fi
echo ""
echo 'All clean!'
exit 0

View File

@ -0,0 +1,119 @@
#!/usr/bin/env bash
if [[ $DEBUG != "" ]]; then
set -x
fi
set -o errexit
set -o pipefail
if ! [ -x node_modules/.bin/marked-man ]; then
ps=0
if [ -f .building_marked-man ]; then
pid=$(cat .building_marked-man)
ps=$(ps -p $pid | grep $pid | wc -l) || true
fi
if [ -f .building_marked-man ] && [ $ps != 0 ]; then
while [ -f .building_marked-man ]; do
sleep 1
done
else
# a race to see which make process will be the one to install marked-man
echo $$ > .building_marked-man
sleep 1
if [ $(cat .building_marked-man) == $$ ]; then
make node_modules/.bin/marked-man
rm .building_marked-man
else
while [ -f .building_marked-man ]; do
sleep 1
done
fi
fi
fi
if ! [ -x node_modules/.bin/marked ]; then
ps=0
if [ -f .building_marked ]; then
pid=$(cat .building_marked)
ps=$(ps -p $pid | grep $pid | wc -l) || true
fi
if [ -f .building_marked ] && [ $ps != 0 ]; then
while [ -f .building_marked ]; do
sleep 1
done
else
# a race to see which make process will be the one to install marked
echo $$ > .building_marked
sleep 1
if [ $(cat .building_marked) == $$ ]; then
make node_modules/.bin/marked
rm .building_marked
else
while [ -f .building_marked ]; do
sleep 1
done
fi
fi
fi
src=$1
dest=$2
name=$(basename ${src%.*})
date=$(date -u +'%Y-%m-%d %H:%M:%S')
version=$(node cli.js -v)
mkdir -p $(dirname $dest)
html_replace_tokens () {
local url=$1
sed "s|@NAME@|$name|g" \
| sed "s|@DATE@|$date|g" \
| sed "s|@URL@|$url|g" \
| sed "s|@VERSION@|$version|g" \
| perl -p -e 's/<h1([^>]*)>([^\(]*\([0-9]\)) -- (.*?)<\/h1>/<h1>\2<\/h1> <p>\3<\/p>/g' \
| perl -p -e 's/npm-npm/npm/g' \
| perl -p -e 's/([^"-])(npm-)?README(?!\.html)(\(1\))?/\1<a href="..\/..\/doc\/README.html">README<\/a>/g' \
| perl -p -e 's/<title><a href="[^"]+README.html">README<\/a><\/title>/<title>README<\/title>/g' \
| perl -p -e 's/([^"-])([^\(> ]+)(\(1\))/\1<a href="..\/cli\/\2.html">\2\3<\/a>/g' \
| perl -p -e 's/([^"-])([^\(> ]+)(\(3\))/\1<a href="..\/api\/\2.html">\2\3<\/a>/g' \
| perl -p -e 's/([^"-])([^\(> ]+)(\(5\))/\1<a href="..\/files\/\2.html">\2\3<\/a>/g' \
| perl -p -e 's/([^"-])([^\(> ]+)(\(7\))/\1<a href="..\/misc\/\2.html">\2\3<\/a>/g' \
| perl -p -e 's/\([1357]\)<\/a><\/h1>/<\/a><\/h1>/g' \
| (if [ $(basename $(dirname $dest)) == "doc" ]; then
perl -p -e 's/ href="\.\.\// href="/g'
else
cat
fi)
}
man_replace_tokens () {
sed "s|@VERSION@|$version|g" \
| perl -p -e 's/(npm\\-)?([a-zA-Z\\\.\-]*)\(1\)/npm help \2/g' \
| perl -p -e 's/(npm\\-)?([a-zA-Z\\\.\-]*)\(([57])\)/npm help \3 \2/g' \
| perl -p -e 's/(npm\\-)?([a-zA-Z\\\.\-]*)\(3\)/npm apihelp \2/g' \
| perl -p -e 's/npm\(1\)/npm help npm/g' \
| perl -p -e 's/npm\(3\)/npm apihelp npm/g'
}
case $dest in
*.[1357])
./node_modules/.bin/marked-man --roff $src \
| man_replace_tokens > $dest
exit $?
;;
*.html)
url=${dest/html\//}
(cat html/dochead.html && \
cat $src | ./node_modules/.bin/marked &&
cat html/docfoot.html)\
| html_replace_tokens $url \
> $dest
exit $?
;;
*)
echo "Invalid destination type: $dest" >&2
exit 1
;;
esac

View File

@ -0,0 +1,270 @@
#!/bin/sh
# A word about this shell script:
#
# It must work everywhere, including on systems that lack
# a /bin/bash, map 'sh' to ksh, ksh97, bash, ash, or zsh,
# and potentially have either a posix shell or bourne
# shell living at /bin/sh.
#
# See this helpful document on writing portable shell scripts:
# http://www.gnu.org/s/hello/manual/autoconf/Portable-Shell.html
#
# The only shell it won't ever work on is cmd.exe.
if [ "x$0" = "xsh" ]; then
# run as curl | sh
# on some systems, you can just do cat>npm-install.sh
# which is a bit cuter. But on others, &1 is already closed,
# so catting to another script file won't do anything.
# Follow Location: headers, and fail on errors
curl -f -L -s https://www.npmjs.org/install.sh > npm-install-$$.sh
ret=$?
if [ $ret -eq 0 ]; then
(exit 0)
else
rm npm-install-$$.sh
echo "Failed to download script" >&2
exit $ret
fi
sh npm-install-$$.sh
ret=$?
rm npm-install-$$.sh
exit $ret
fi
# See what "npm_config_*" things there are in the env,
# and make them permanent.
# If this fails, it's not such a big deal.
configures="`env | grep 'npm_config_' | sed -e 's|^npm_config_||g'`"
npm_config_loglevel="error"
if [ "x$npm_debug" = "x" ]; then
(exit 0)
else
echo "Running in debug mode."
echo "Note that this requires bash or zsh."
set -o xtrace
set -o pipefail
npm_config_loglevel="verbose"
fi
export npm_config_loglevel
# make sure that node exists
node=`which node 2>&1`
ret=$?
if [ $ret -eq 0 ] && [ -x "$node" ]; then
(exit 0)
else
echo "npm cannot be installed without node.js." >&2
echo "Install node first, and then try again." >&2
echo "" >&2
echo "Maybe node is installed, but not in the PATH?" >&2
echo "Note that running as sudo can change envs." >&2
echo ""
echo "PATH=$PATH" >&2
exit $ret
fi
# set the temp dir
TMP="${TMPDIR}"
if [ "x$TMP" = "x" ]; then
TMP="/tmp"
fi
TMP="${TMP}/npm.$$"
rm -rf "$TMP" || true
mkdir "$TMP"
if [ $? -ne 0 ]; then
echo "failed to mkdir $TMP" >&2
exit 1
fi
BACK="$PWD"
ret=0
tar="${TAR}"
if [ -z "$tar" ]; then
tar="${npm_config_tar}"
fi
if [ -z "$tar" ]; then
tar=`which tar 2>&1`
ret=$?
fi
if [ $ret -eq 0 ] && [ -x "$tar" ]; then
echo "tar=$tar"
echo "version:"
$tar --version
ret=$?
fi
if [ $ret -eq 0 ]; then
(exit 0)
else
echo "No suitable tar program found."
exit 1
fi
# Try to find a suitable make
# If the MAKE environment var is set, use that.
# otherwise, try to find gmake, and then make.
# If no make is found, then just execute the necessary commands.
# XXX For some reason, make is building all the docs every time. This
# is an annoying source of bugs. Figure out why this happens.
MAKE=NOMAKE
if [ "x$MAKE" = "x" ]; then
make=`which gmake 2>&1`
if [ $? -eq 0 ] && [ -x "$make" ]; then
(exit 0)
else
make=`which make 2>&1`
if [ $? -eq 0 ] && [ -x "$make" ]; then
(exit 0)
else
make=NOMAKE
fi
fi
else
make="$MAKE"
fi
if [ -x "$make" ]; then
(exit 0)
else
# echo "Installing without make. This may fail." >&2
make=NOMAKE
fi
# If there's no bash, then don't even try to clean
if [ -x "/bin/bash" ]; then
(exit 0)
else
clean="no"
fi
node_version=`"$node" --version 2>&1`
ret=$?
if [ $ret -ne 0 ]; then
echo "You need node to run this program." >&2
echo "node --version reports: $node_version" >&2
echo "with exit code = $ret" >&2
echo "Please install node before continuing." >&2
exit $ret
fi
t="${npm_install}"
if [ -z "$t" ]; then
# switch based on node version.
# note that we can only use strict sh-compatible patterns here.
case $node_version in
0.[01234567].* | v0.[01234567].*)
echo "You are using an outdated and unsupported version of" >&2
echo "node ($node_version). Please update node and try again." >&2
exit 99
;;
*)
echo "install npm@latest"
t="latest"
;;
esac
fi
# need to echo "" after, because Posix sed doesn't treat EOF
# as an implied end of line.
url=`(curl -SsL https://registry.npmjs.org/npm/$t; echo "") \
| sed -e 's/^.*tarball":"//' \
| sed -e 's/".*$//'`
ret=$?
if [ "x$url" = "x" ]; then
ret=125
# try without the -e arg to sed.
url=`(curl -SsL https://registry.npmjs.org/npm/$t; echo "") \
| sed 's/^.*tarball":"//' \
| sed 's/".*$//'`
ret=$?
if [ "x$url" = "x" ]; then
ret=125
fi
fi
if [ $ret -ne 0 ]; then
echo "Failed to get tarball url for npm/$t" >&2
exit $ret
fi
echo "fetching: $url" >&2
cd "$TMP" \
&& curl -SsL "$url" \
| $tar -xzf - \
&& cd "$TMP"/* \
&& (ver=`"$node" bin/read-package-json.js package.json version`
isnpm10=0
if [ $ret -eq 0 ]; then
if [ -d node_modules ]; then
if "$node" node_modules/semver/bin/semver -v "$ver" -r "1"
then
isnpm10=1
fi
else
if "$node" bin/semver -v "$ver" -r ">=1.0"; then
isnpm10=1
fi
fi
fi
ret=0
if [ $isnpm10 -eq 1 ] && [ -f "scripts/clean-old.sh" ]; then
if [ "x$skipclean" = "x" ]; then
(exit 0)
else
clean=no
fi
if [ "x$clean" = "xno" ] \
|| [ "x$clean" = "xn" ]; then
echo "Skipping 0.x cruft clean" >&2
ret=0
elif [ "x$clean" = "xy" ] || [ "x$clean" = "xyes" ]; then
NODE="$node" /bin/bash "scripts/clean-old.sh" "-y"
ret=$?
else
NODE="$node" /bin/bash "scripts/clean-old.sh" </dev/tty
ret=$?
fi
fi
if [ $ret -ne 0 ]; then
echo "Aborted 0.x cleanup. Exiting." >&2
exit $ret
fi) \
&& (if [ "x$configures" = "x" ]; then
(exit 0)
else
echo "./configure $configures"
echo "$configures" > npmrc
fi) \
&& (if [ "$make" = "NOMAKE" ]; then
(exit 0)
elif "$make" uninstall install; then
(exit 0)
else
make="NOMAKE"
fi
if [ "$make" = "NOMAKE" ]; then
"$node" cli.js rm npm -gf
"$node" cli.js install -gf
fi) \
&& cd "$BACK" \
&& rm -rf "$TMP" \
&& echo "It worked"
ret=$?
if [ $ret -ne 0 ]; then
echo "It failed" >&2
fi
exit $ret

View File

@ -0,0 +1,36 @@
#!/bin/bash
# script for creating a zip and tarball for inclusion in node
unset CDPATH
set -e
rm -rf release *.tgz || true
mkdir release
node ./cli.js pack --loglevel error >/dev/null
mv *.tgz release
cd release
tar xzf *.tgz
mkdir node_modules
mv package node_modules/npm
# make the zip for windows users
cp node_modules/npm/bin/*.cmd .
zipname=npm-$(node ../cli.js -v).zip
zip -q -9 -r -X "$zipname" *.cmd node_modules
# make the tar for node's deps
cd node_modules
tarname=npm-$(node ../../cli.js -v).tgz
tar czf "$tarname" npm
cd ..
mv "node_modules/$tarname" .
rm -rf *.cmd
rm -rf node_modules
echo "release/$tarname"
echo "release/$zipname"

View File

@ -0,0 +1,26 @@
#!/bin/bash
# Change the cli shebang to point at the specified node
# Useful for when the program is moved around after install.
# Also used by the default 'make install' in node to point
# npm at the newly installed node, rather than the first one
# in the PATH, which would be the default otherwise.
# bash /path/to/npm/scripts/relocate.sh $nodepath
# If $nodepath is blank, then it'll use /usr/bin/env
dir="$(dirname "$(dirname "$0")")"
cli="$dir"/bin/npm-cli.js
tmp="$cli".tmp
node="$1"
if [ "x$node" = "x" ]; then
node="/usr/bin/env node"
fi
node="#!$node"
sed -e 1d "$cli" > "$tmp"
echo "$node" > "$cli"
cat "$tmp" >> "$cli"
rm "$tmp"
chmod ogu+x $cli

View File

@ -0,0 +1,138 @@
#!/usr/bin/env bash
set -e
function usage {
cat <<-EOF
USAGE
$0 [-dgGhv] [-f focus-string] [-s seed]
OPTIONS
-h print this message
-b run make under scan-build static analyzer
-d run tests in a debugger (either lldb or gdb)
-g run tests with valgrind's memcheck tool
-G run tests with valgrind's memcheck tool, including a full leak check
-v run tests with verbose output
-f run only tests whose description contain the given string
-s set the seed used to control random behavior
-z pipe tests' stderr to \`dot(1)\` to render an SVG log
EOF
}
profile=
leak_check=no
mode=normal
verbose=
args=()
target=tests
export BUILDTYPE=Test
cmd="out/${BUILDTYPE}/${target}"
run_scan_build=
if [ "$(uname -s)" == "Darwin" ]; then
export LINK="clang++ -fsanitize=address"
fi
while getopts "bdf:s:gGhpvS" option; do
case ${option} in
h)
usage
exit
;;
d)
mode=debug
;;
g)
mode=valgrind
;;
G)
mode=valgrind
leak_check=full
;;
p)
profile=true
;;
f)
args+=("--only=${OPTARG}")
;;
v)
verbose=true
;;
s)
export TREE_SITTER_SEED=${OPTARG}
;;
S)
mode=SVG
;;
b)
run_scan_build=true
;;
esac
done
if [[ -n $verbose ]]; then
args+=("--reporter=spec")
else
args+=("--reporter=singleline")
fi
if [[ -n "$run_scan_build" ]]; then
. script/util/scan-build.sh
scan_build make -j2 $target
else
make -j2 $target
fi
args=${args:-""}
if [[ -n $profile ]]; then
export CPUPROFILE=/tmp/${target}-$(date '+%s').prof
fi
case ${mode} in
valgrind)
valgrind \
--suppressions=./script/util/valgrind.supp \
--dsymutil=yes \
--leak-check=${leak_check} \
$cmd "${args[@]}" 2>&1 | \
grep --color -E '\w+_tests?.cc:\d+|$'
;;
debug)
if which -s lldb; then
lldb $cmd -- "${args[@]}"
elif which -s gdb; then
gdb $cmd -- "${args[@]}"
else
echo "No debugger found"
exit 1
fi
;;
SVG)
echo "<!DOCTYPE html><style>svg { width: 100%; margin-bottom: 20px; }</style>" > index.html
$cmd "${args[@]}" 2> >(grep -v 'Assertion failed' | dot -Tsvg >> index.html)
echo "Wrote index.html"
;;
normal)
time $cmd "${args[@]}"
;;
esac
if [[ -n $profile ]]; then
pprof $cmd $CPUPROFILE
fi

View File

@ -0,0 +1,9 @@
#!/bin/sh
git log --reverse --format='%aN <%aE>' | perl -wnE '
BEGIN {
say "# Authors sorted by whether or not they\x27re me";
}
print $seen{$_} = $_ unless $seen{$_}
' > AUTHORS

1164
bash/grammar.js 100644

File diff suppressed because it is too large Load Diff

1271
bash/src/scanner.c 100644

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,708 @@
===============================
Commands
===============================
whoami
---
(program
(command (command_name (word))))
===============================
Commands with arguments
===============================
cat file1.txt
git diff --word-diff=color -- file1.txt file2.txt
echo $sing\
levar
---
(program
(command (command_name (word)) (word))
(command (command_name (word)) (word) (word) (word) (word) (word))
(command (command_name (word)) (simple_expansion (variable_name)) (word)))
===============================
Quoted command names
===============================
"$a/$b" c
---
(program
(command
(command_name (string (simple_expansion (variable_name)) (string_content) (simple_expansion (variable_name))))
(word)))
===============================
Commands with numeric arguments
===============================
exit 1
---
(program
(command (command_name (word)) (number)))
===================================
Commands with environment variables
===================================
VAR1=1 ./script/test
VAR1=a VAR2="ok" git diff --word-diff=color
---
(program
(command
(variable_assignment (variable_name) (number))
(command_name (word)))
(command
(variable_assignment (variable_name) (word))
(variable_assignment (variable_name) (string (string_content)))
(command_name (word))
(word)
(word)))
===================================
Empty environment variables
===================================
VAR1=
VAR2= echo
---
(program
(variable_assignment (variable_name))
(command (variable_assignment (variable_name)) (command_name (word))))
===============================
File redirects
===============================
whoami > /dev/null
cat a b > /dev/null
2>&1 whoami
echo "foobar" >&2
[ ! command -v go &>/dev/null ] && return
if [ ]; then
>aa >bb
fi
exec {VIRTWL[0]} {VIRTWL[1]} <&- >&-
exec {VIRTWL[0]}<&- {VIRTWL[1]}>&-
grep 2>/dev/null -q "^/usr/bin/scponly$" /etc/shells
---
(program
(redirected_statement
(command (command_name (word)))
(file_redirect (word)))
(redirected_statement
(command (command_name (word)) (word) (word))
(file_redirect (word)))
(command
(file_redirect (file_descriptor) (number))
(command_name (word)))
(redirected_statement
(command (command_name (word)) (string (string_content)))
(file_redirect (number)))
(list
(test_command
(redirected_statement
(negated_command
(command (command_name (word)) (word) (word)))
(file_redirect (word))))
(command (command_name (word))))
(if_statement
(test_command)
(redirected_statement
(file_redirect (word))
(file_redirect (word))))
(redirected_statement
(command
(command_name (word))
(concatenation (word) (word) (word) (number) (word) (word))
(concatenation (word) (word) (word) (number) (word) (word)))
(file_redirect)
(file_redirect))
(redirected_statement
(command
(command_name (word))
(concatenation (word) (word) (word) (number) (word) (word)))
(file_redirect
(concatenation (word) (word) (word) (number) (word) (word)))
(file_redirect))
(redirected_statement
(command (command_name (word)))
(file_redirect (file_descriptor) (word) (word) (string (string_content)) (word))))
===============================
File redirects (noclobber override)
===============================
whoami >| /dev/null
cat a b >| /dev/null
---
(program
(redirected_statement
(command (command_name (word)))
(file_redirect (word)))
(redirected_statement
(command (command_name (word)) (word) (word))
(file_redirect (word))))
===============================
Heredoc redirects
===============================
node <<JS
console.log("hi")
JS
bash -c <<JS
echo hi
JS
newins <<-EOF - org.freedesktop.Notifications.service
[D-BUS Service]
Name=org.freedesktop.Notifications
Exec=/usr/libexec/notification-daemon
EOF
---
(program
(redirected_statement
(command (command_name (word)))
(heredoc_redirect
(heredoc_start)
(heredoc_body)
(heredoc_end)))
(redirected_statement
(command (command_name (word)) (word))
(heredoc_redirect
(heredoc_start)
(heredoc_body)
(heredoc_end)))
(redirected_statement
(command (command_name (word)))
(heredoc_redirect
(heredoc_start)
(word)
(word)
(heredoc_body)
(heredoc_end))))
===============================
Heredocs with variables
===============================
node <<JS
a $B ${C}
JS
exit
---
(program
(redirected_statement
(command
(command_name
(word)))
(heredoc_redirect
(heredoc_start)
(heredoc_body
(simple_expansion
(variable_name))
(heredoc_content)
(expansion
(variable_name))
(heredoc_content))
(heredoc_end)))
(command
(command_name
(word))))
=================================
Heredocs with file redirects
=================================
cat <<EOF > $tmpfile
a $B ${C}
EOF
wc -l $tmpfile
---
(program
(redirected_statement
(command
(command_name
(word)))
(heredoc_redirect
(heredoc_start)
(file_redirect
(simple_expansion
(variable_name)))
(heredoc_body
(simple_expansion
(variable_name))
(heredoc_content)
(expansion
(variable_name))
(heredoc_content))
(heredoc_end)))
(command
(command_name
(word))
(word)
(simple_expansion
(variable_name))))
=================================
Heredocs with many file redirects
=================================
FOO=bar echo <<EOF 2> err.txt > hello.txt
hello
EOF
---
(program
(redirected_statement
body: (command
(variable_assignment
name: (variable_name)
value: (word))
name: (command_name
(word)))
redirect: (heredoc_redirect
(heredoc_start)
redirect: (file_redirect
descriptor: (file_descriptor)
destination: (word))
redirect: (file_redirect
destination: (word))
(heredoc_body)
(heredoc_end))))
=================================
Heredocs with pipes
=================================
one <<EOF | grep two
three
EOF
---
(program
(redirected_statement
(command