Showing preview only (2,485K chars total). Download the full file or copy to clipboard to get everything.
Repository: cloudwu/skynet
Branch: master
Commit: 2b6b106e57ab
Files: 363
Total size: 2.3 MB
Directory structure:
gitextract_nfy1fgz2/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ └── readme-first.md
│ └── workflows/
│ └── build-release.yml
├── .gitignore
├── .gitmodules
├── 3rd/
│ ├── compat-mingw/
│ │ ├── arpa/
│ │ │ └── inet.h
│ │ ├── compat.c
│ │ ├── compat.h
│ │ ├── dlfcn.c
│ │ ├── dlfcn.h
│ │ ├── netdb.h
│ │ ├── netinet/
│ │ │ ├── in.h
│ │ │ └── tcp.h
│ │ ├── sys/
│ │ │ ├── epoll.h
│ │ │ ├── file.h
│ │ │ └── socket.h
│ │ ├── unistd.c
│ │ ├── unistd.h
│ │ ├── wepoll.c
│ │ └── wepoll.h
│ ├── lpeg/
│ │ ├── HISTORY
│ │ ├── README.md
│ │ ├── lpcap.c
│ │ ├── lpcap.h
│ │ ├── lpcode.c
│ │ ├── lpcode.h
│ │ ├── lpcset.c
│ │ ├── lpcset.h
│ │ ├── lpeg.html
│ │ ├── lpprint.c
│ │ ├── lpprint.h
│ │ ├── lptree.c
│ │ ├── lptree.h
│ │ ├── lptypes.h
│ │ ├── lpvm.c
│ │ ├── lpvm.h
│ │ ├── makefile
│ │ ├── re.html
│ │ ├── re.lua
│ │ └── test.lua
│ ├── lua/
│ │ ├── README
│ │ ├── README.md
│ │ ├── lapi.c
│ │ ├── lapi.h
│ │ ├── lauxlib.c
│ │ ├── lauxlib.h
│ │ ├── lbaselib.c
│ │ ├── lcode.c
│ │ ├── lcode.h
│ │ ├── lcorolib.c
│ │ ├── lctype.c
│ │ ├── lctype.h
│ │ ├── ldblib.c
│ │ ├── ldebug.c
│ │ ├── ldebug.h
│ │ ├── ldo.c
│ │ ├── ldo.h
│ │ ├── ldump.c
│ │ ├── lfunc.c
│ │ ├── lfunc.h
│ │ ├── lgc.c
│ │ ├── lgc.h
│ │ ├── linit.c
│ │ ├── liolib.c
│ │ ├── ljumptab.h
│ │ ├── llex.c
│ │ ├── llex.h
│ │ ├── llimits.h
│ │ ├── lmathlib.c
│ │ ├── lmem.c
│ │ ├── lmem.h
│ │ ├── loadlib.c
│ │ ├── lobject.c
│ │ ├── lobject.h
│ │ ├── lopcodes.c
│ │ ├── lopcodes.h
│ │ ├── lopnames.h
│ │ ├── loslib.c
│ │ ├── lparser.c
│ │ ├── lparser.h
│ │ ├── lprefix.h
│ │ ├── lstate.c
│ │ ├── lstate.h
│ │ ├── lstring.c
│ │ ├── lstring.h
│ │ ├── lstrlib.c
│ │ ├── ltable.c
│ │ ├── ltable.h
│ │ ├── ltablib.c
│ │ ├── ltests.c
│ │ ├── ltests.h
│ │ ├── ltm.c
│ │ ├── ltm.h
│ │ ├── lua.c
│ │ ├── lua.h
│ │ ├── lua.hpp
│ │ ├── luac.c
│ │ ├── luaconf.h
│ │ ├── lualib.h
│ │ ├── lundump.c
│ │ ├── lundump.h
│ │ ├── lutf8lib.c
│ │ ├── lvm.c
│ │ ├── lvm.h
│ │ ├── lzio.c
│ │ ├── lzio.h
│ │ ├── makefile
│ │ └── onelua.c
│ └── lua-md5/
│ ├── README
│ ├── compat-5.2.c
│ ├── compat-5.2.h
│ ├── md5.c
│ ├── md5.h
│ └── md5lib.c
├── HISTORY.md
├── LICENSE
├── Makefile
├── README.md
├── examples/
│ ├── abort.lua
│ ├── agent.lua
│ ├── checkdeadloop.lua
│ ├── client.lua
│ ├── cluster1.lua
│ ├── cluster2.lua
│ ├── clustername.lua
│ ├── config
│ ├── config.c1
│ ├── config.c2
│ ├── config.handle
│ ├── config.login
│ ├── config.mc
│ ├── config.mongodb
│ ├── config.mysql
│ ├── config.path
│ ├── config.userlog
│ ├── config_log
│ ├── globallog.lua
│ ├── injectlaunch.lua
│ ├── login/
│ │ ├── client.lua
│ │ ├── gated.lua
│ │ ├── logind.lua
│ │ ├── main.lua
│ │ └── msgagent.lua
│ ├── main.lua
│ ├── main_log.lua
│ ├── main_mongodb.lua
│ ├── main_mysql.lua
│ ├── preload.lua
│ ├── proto.lua
│ ├── protoloader.lua
│ ├── share.lua
│ ├── simpledb.lua
│ ├── simplemonitor.lua
│ ├── simpleweb.lua
│ ├── simplewebsocket.lua
│ ├── userlog.lua
│ └── watchdog.lua
├── lualib/
│ ├── compat10/
│ │ ├── cluster.lua
│ │ ├── crypt.lua
│ │ ├── datacenter.lua
│ │ ├── dns.lua
│ │ ├── memory.lua
│ │ ├── mongo.lua
│ │ ├── mqueue.lua
│ │ ├── multicast.lua
│ │ ├── mysql.lua
│ │ ├── netpack.lua
│ │ ├── profile.lua
│ │ ├── redis.lua
│ │ ├── sharedata.lua
│ │ ├── sharemap.lua
│ │ ├── snax.lua
│ │ ├── socket.lua
│ │ ├── socketchannel.lua
│ │ ├── socketdriver.lua
│ │ └── stm.lua
│ ├── http/
│ │ ├── httpc.lua
│ │ ├── httpd.lua
│ │ ├── internal.lua
│ │ ├── sockethelper.lua
│ │ ├── tlshelper.lua
│ │ ├── url.lua
│ │ └── websocket.lua
│ ├── loader.lua
│ ├── md5.lua
│ ├── skynet/
│ │ ├── cluster.lua
│ │ ├── coroutine.lua
│ │ ├── datacenter.lua
│ │ ├── datasheet/
│ │ │ ├── builder.lua
│ │ │ ├── dump.lua
│ │ │ └── init.lua
│ │ ├── db/
│ │ │ ├── mongo/
│ │ │ │ └── transaction.lua
│ │ │ ├── mongo.lua
│ │ │ ├── mysql.lua
│ │ │ ├── redis/
│ │ │ │ ├── cluster.lua
│ │ │ │ └── crc16.lua
│ │ │ └── redis.lua
│ │ ├── debug.lua
│ │ ├── dns.lua
│ │ ├── harbor.lua
│ │ ├── inject.lua
│ │ ├── injectcode.lua
│ │ ├── manager.lua
│ │ ├── mqueue.lua
│ │ ├── multicast.lua
│ │ ├── queue.lua
│ │ ├── remotedebug.lua
│ │ ├── require.lua
│ │ ├── service.lua
│ │ ├── sharedata/
│ │ │ └── corelib.lua
│ │ ├── sharedata.lua
│ │ ├── sharemap.lua
│ │ ├── sharetable.lua
│ │ ├── snax.lua
│ │ ├── socket.lua
│ │ └── socketchannel.lua
│ ├── skynet.lua
│ ├── snax/
│ │ ├── gateserver.lua
│ │ ├── hotfix.lua
│ │ ├── interface.lua
│ │ ├── loginserver.lua
│ │ └── msgserver.lua
│ ├── sproto.lua
│ ├── sprotoloader.lua
│ └── sprotoparser.lua
├── lualib-src/
│ ├── lsha1.c
│ ├── ltls.c
│ ├── lua-bson.c
│ ├── lua-clientsocket.c
│ ├── lua-cluster.c
│ ├── lua-crypt.c
│ ├── lua-datasheet.c
│ ├── lua-debugchannel.c
│ ├── lua-memory.c
│ ├── lua-mongo.c
│ ├── lua-multicast.c
│ ├── lua-netpack.c
│ ├── lua-seri.c
│ ├── lua-seri.h
│ ├── lua-sharedata.c
│ ├── lua-sharetable.c
│ ├── lua-skynet.c
│ ├── lua-socket.c
│ ├── lua-stm.c
│ └── sproto/
│ ├── README
│ ├── README.md
│ ├── lsproto.c
│ ├── msvcint.h
│ ├── sproto.c
│ └── sproto.h
├── mingw.mk
├── platform.mk
├── service/
│ ├── bootstrap.lua
│ ├── cdummy.lua
│ ├── clusteragent.lua
│ ├── clusterd.lua
│ ├── clusterproxy.lua
│ ├── clustersender.lua
│ ├── cmaster.lua
│ ├── cmemory.lua
│ ├── console.lua
│ ├── cslave.lua
│ ├── datacenterd.lua
│ ├── dbg.lua
│ ├── debug_agent.lua
│ ├── debug_console.lua
│ ├── gate.lua
│ ├── launcher.lua
│ ├── multicastd.lua
│ ├── service_cell.lua
│ ├── service_mgr.lua
│ ├── service_provider.lua
│ ├── sharedatad.lua
│ └── snaxd.lua
├── service-src/
│ ├── databuffer.h
│ ├── hashid.h
│ ├── service_gate.c
│ ├── service_harbor.c
│ ├── service_logger.c
│ └── service_snlua.c
├── skynet-src/
│ ├── atomic.h
│ ├── malloc_hook.c
│ ├── malloc_hook.h
│ ├── mem_info.c
│ ├── mem_info.h
│ ├── rwlock.h
│ ├── skynet.h
│ ├── skynet_daemon.c
│ ├── skynet_daemon.h
│ ├── skynet_env.c
│ ├── skynet_env.h
│ ├── skynet_error.c
│ ├── skynet_handle.c
│ ├── skynet_handle.h
│ ├── skynet_harbor.c
│ ├── skynet_harbor.h
│ ├── skynet_imp.h
│ ├── skynet_log.c
│ ├── skynet_log.h
│ ├── skynet_main.c
│ ├── skynet_malloc.h
│ ├── skynet_module.c
│ ├── skynet_module.h
│ ├── skynet_monitor.c
│ ├── skynet_monitor.h
│ ├── skynet_mq.c
│ ├── skynet_mq.h
│ ├── skynet_server.c
│ ├── skynet_server.h
│ ├── skynet_socket.c
│ ├── skynet_socket.h
│ ├── skynet_start.c
│ ├── skynet_timer.c
│ ├── skynet_timer.h
│ ├── socket_buffer.h
│ ├── socket_epoll.h
│ ├── socket_info.h
│ ├── socket_kqueue.h
│ ├── socket_poll.h
│ ├── socket_server.c
│ ├── socket_server.h
│ └── spinlock.h
└── test/
├── pingserver.lua
├── sharemap.sp
├── testbson.lua
├── testcoroutine.lua
├── testcrypt.lua
├── testdatacenter.lua
├── testdatasheet.lua
├── testdeadcall.lua
├── testdeadloop.lua
├── testdns.lua
├── testecho.lua
├── testendless.lua
├── testhandle.lua
├── testharborlink.lua
├── testhttp.lua
├── testmemlimit.lua
├── testmongodb.lua
├── testmulticast.lua
├── testmulticast2.lua
├── testmysql.lua
├── testoverload.lua
├── testping.lua
├── testpipeline.lua
├── testqueue.lua
├── testredis.lua
├── testredis2.lua
├── testrediscluster.lua
├── testresponse.lua
├── testselect.lua
├── testservice/
│ ├── init.lua
│ └── kvdb.lua
├── testsha.lua
├── testsharetable.lua
├── testsm.lua
├── testsocket.lua
├── teststm.lua
├── testterm.lua
├── testtimeout.lua
├── testtimer.lua
├── testtobeclosed.lua
├── testudp.lua
└── time.lua
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/readme-first.md
================================================
---
name: Readme First
about: Issues is bug report only
title: ''
labels: ''
assignees: ''
---
The **Issues** is for bug report only.
Goto **Discussions** for feature request , questions, etc.
**Update to master branch HEAD first**, and
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior.
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/workflows/build-release.yml
================================================
name: Build and Release Skynet
on:
push:
branches: [ master ]
tags: [ 'v*' ]
permissions:
contents: write
actions: read
jobs:
build:
name: Build ${{ matrix.platform }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- platform: windows
os: ubuntu-latest
container: debian:13
target: mingw
artifact: skynet-windows.zip
- platform: linux
os: ubuntu-latest
container: debian:13
target: linux
artifact: skynet-linux.zip
- platform: macosx
os: macos-latest
target: macosx
artifact: skynet-macosx.zip
- platform: freebsd
os: ubuntu-latest
container: debian:13
target: freebsd
artifact: skynet-freebsd.zip
container: ${{ matrix.container }}
steps:
- name: Install dependencies (Debian - Windows/Linux)
if: matrix.container == 'debian:13'
run: |
apt-get update
apt-get install -y --no-install-recommends \
build-essential \
make \
pkg-config \
mingw-w64 \
mingw-w64-tools \
mingw-w64-i686-dev \
mingw-w64-x86-64-dev \
autoconf \
automake \
libtool \
git \
zip \
ca-certificates \
curl \
libreadline-dev \
libedit-dev \
rsync
- name: Install dependencies (macOS)
if: matrix.platform == 'macosx'
run: |
# macOS usually has most build tools pre-installed
# Install any additional dependencies if needed
brew install autoconf automake libtool || true
- name: Install dependencies (FreeBSD)
if: matrix.platform == 'freebsd'
run: |
# FreeBSD build using standard build tools (cross-compilation compatible)
apt-get update
apt-get install -y --no-install-recommends \
build-essential \
make \
pkg-config \
autoconf \
automake \
libtool \
git \
zip \
ca-certificates \
curl \
libreadline-dev \
libedit-dev \
rsync
- name: Update CA certificates (Debian containers)
if: matrix.container == 'debian:13'
run: |
update-ca-certificates
- name: Configure Git SSL (Debian containers)
if: matrix.container == 'debian:13'
run: |
git config --global http.sslverify true
git config --global http.sslcainfo /etc/ssl/certs/ca-certificates.crt
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: recursive
fetch-depth: 1
- name: Build ${{ matrix.platform }}
run: |
make cleanall
make ${{ matrix.target }}
- name: Prepare build files
run: |
mkdir -p build-output
# Copy all files except .git and .github with ignore-errors flag
- name: Clean and recreate directory
run: |
rm -rf build-output/
mkdir -p build-output/
- name: Sync files to build-output excluding specific directories
run: |
rsync -av --ignore-errors --exclude='.git*' --exclude='.github' --exclude='build-output' . build-output/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: build-output/
retention-days: 30
release:
name: Create Release
needs: build
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Prepare release assets
run: |
mkdir -p release-assets
# Copy zip files from artifact directories to release assets
for artifact in skynet-windows.zip skynet-linux.zip skynet-macosx.zip skynet-freebsd.zip; do
if [ -d "artifacts/${artifact}" ]; then
# The artifacts are already organized, just copy them
cp -r "artifacts/${artifact}/"* "release-assets/" 2>/dev/null || true
# Or if we want to create new zip files with consistent naming
platform=$(echo ${artifact} | sed 's/skynet-\(.*\)\.zip/\1/')
cd "artifacts/${artifact}"
zip -r "../../release-assets/skynet-${platform}.zip" .
cd ../..
fi
done
ls -la release-assets/
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: release-assets/*.zip
generate_release_notes: true
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .gitignore
================================================
*.o
*.a
/skynet
/skynet.pid
3rd/lua/lua
3rd/lua/luac
3rd/lua/all
/cservice
/luaclib
*.so
*.dSYM
.DS_Store
.vscode
3rd/lua/lua.exe
3rd/lua/luac.exe
3rd/lua/lua54.dll
skynet.exe
*.dll
================================================
FILE: .gitmodules
================================================
[submodule "3rd/jemalloc"]
path = 3rd/jemalloc
url = https://github.com/jemalloc/jemalloc.git
================================================
FILE: 3rd/compat-mingw/arpa/inet.h
================================================
#pragma once
================================================
FILE: 3rd/compat-mingw/compat.c
================================================
#include "compat.h"
#include "dlfcn.c"
#include "unistd.c"
#include "wepoll.c"
================================================
FILE: 3rd/compat-mingw/compat.h
================================================
#pragma once
#include "unistd.h"
#include "dlfcn.h"
================================================
FILE: 3rd/compat-mingw/dlfcn.c
================================================
#include "dlfcn.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
void *dlopen(const char *path, int flag) {
return LoadLibraryA(path);
}
const char *dlerror() {
DWORD err = GetLastError();
HLOCAL LocalAddress = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, err, 0, (PTSTR)&LocalAddress, 0, NULL);
return (LPSTR)LocalAddress;
}
void *dlsym(void *dl, const char *sym) {
return GetProcAddress(dl, sym);
}
================================================
FILE: 3rd/compat-mingw/dlfcn.h
================================================
#pragma once
enum { RTLD_NOW, RTLD_GLOBAL };
void *dlopen(const char *path, int flag);
const char *dlerror();
void *dlsym(void *dl, const char *sym);
================================================
FILE: 3rd/compat-mingw/netdb.h
================================================
#pragma once
#include <ws2tcpip.h>
================================================
FILE: 3rd/compat-mingw/netinet/in.h
================================================
#pragma once
================================================
FILE: 3rd/compat-mingw/netinet/tcp.h
================================================
#pragma once
================================================
FILE: 3rd/compat-mingw/sys/epoll.h
================================================
#pragma once
#include "wepoll.h"
================================================
FILE: 3rd/compat-mingw/sys/file.h
================================================
#pragma once
================================================
FILE: 3rd/compat-mingw/sys/socket.h
================================================
#pragma once
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#undef FD_SETSIZE
#define FD_SETSIZE 1024
#include <winsock2.h>
#include <windows.h>
#include <conio.h>
#include <ws2ipdef.h>
#include <ws2tcpip.h>
#include "socket_poll.h"
#include "socket_epoll.h"
================================================
FILE: 3rd/compat-mingw/unistd.c
================================================
#include "unistd.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <stdio.h>
#include <stdint.h>
#include <windows.h>
#include <conio.h>
#include <errno.h>
// WSA error to errno mapping function
static void set_errno_from_wsa_error(int wsa_error) {
switch (wsa_error) {
case WSAECONNRESET:
errno = ECONNRESET;
break;
case WSAECONNABORTED:
errno = ECONNABORTED;
break;
case WSAECONNREFUSED:
errno = ECONNREFUSED;
break;
case WSAENETDOWN:
errno = ENETDOWN;
break;
case WSAENETUNREACH:
errno = ENETUNREACH;
break;
case WSAEHOSTDOWN:
errno = EHOSTDOWN;
break;
case WSAEHOSTUNREACH:
errno = EHOSTUNREACH;
break;
case WSAETIMEDOUT:
errno = ETIMEDOUT;
break;
case WSAENOTCONN:
errno = ENOTCONN;
break;
case WSAEWOULDBLOCK:
errno = EAGAIN;
break;
case WSAEINTR:
errno = EINTR;
break;
case WSAEINVAL:
errno = EINVAL;
break;
case WSAEACCES:
errno = EACCES;
break;
case WSAEADDRINUSE:
errno = EADDRINUSE;
break;
case WSAEADDRNOTAVAIL:
errno = EADDRNOTAVAIL;
break;
default:
errno = EIO; // Generic I/O error for unknown cases
break;
}
}
// Windows Socket initialization
static int winsock_initialized = 0;
static int init_winsock(void) {
if (!winsock_initialized) {
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0) {
return -1;
}
winsock_initialized = 1;
}
return 0;
}
static void cleanup_winsock(void) {
if (winsock_initialized) {
WSACleanup();
winsock_initialized = 0;
}
}
// Auto-initialize Winsock when the library is loaded
__attribute__((constructor))
static void auto_init_winsock(void) {
init_winsock();
}
// Auto-cleanup Winsock when the library is unloaded
__attribute__((destructor))
static void auto_cleanup_winsock(void) {
cleanup_winsock();
}
static LONGLONG get_cpu_freq() {
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
return freq.QuadPart;
}
int kill(pid_t pid, int exit_code) {
return TerminateProcess((HANDLE)(uintptr_t)pid, exit_code);
}
#define NANOSEC 1000000000
#define MICROSEC 1000000
void usleep(size_t us) {
if (us > 1000) {
Sleep(us / 1000);
return;
}
LONGLONG delta = get_cpu_freq() / MICROSEC * us;
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
LONGLONG start = counter.QuadPart;
for (;;) {
QueryPerformanceCounter(&counter);
if (counter.QuadPart - start >= delta)
return;
}
}
void sleep(size_t sec) {
Sleep(sec * 1000UL);
}
int clock_gettime(int what, struct timespec* ti) {
switch (what) {
case CLOCK_MONOTONIC:
static __int64 Freq = 0;
static __int64 Start = 0;
static __int64 StartTime = 0;
if (Freq == 0) {
StartTime = time(NULL);
QueryPerformanceFrequency((LARGE_INTEGER*)&Freq);
QueryPerformanceCounter((LARGE_INTEGER*)&Start);
}
__int64 Count = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&Count);
// 乘以1000,把秒化为毫秒
__int64 now = (__int64)((double)(Count - Start) / (double)Freq * 1000.0) + StartTime * 1000;
ti->tv_sec = now / 1000;
ti->tv_nsec = (now - now / 1000 * 1000) * 1000 * 1000;
return 0;
case CLOCK_REALTIME:
SYSTEMTIME st;
GetSystemTime(&st); // 获取 UTC 时间
// 将 SYSTEMTIME 转换为 UNIX 时间戳
FILETIME ft;
SystemTimeToFileTime(&st, &ft);
ULARGE_INTEGER u64;
u64.LowPart = ft.dwLowDateTime;
u64.HighPart = ft.dwHighDateTime;
ti->tv_sec = (uint32_t)((u64.QuadPart - 116444736000000000ULL) / 10000000); // 转换为秒
ti->tv_nsec = (uint32_t)((u64.QuadPart % 10000000) * 100); // 获取纳秒部分
return 0; // 响应成功
case CLOCK_THREAD_CPUTIME_ID:
// 获取当前线程的 CPU 时间
FILETIME creation_time, exit_time, kernel_time, user_time;
if (GetThreadTimes(GetCurrentThread(), &creation_time, &exit_time, &kernel_time, &user_time)) {
ULARGE_INTEGER u64;
u64.LowPart = user_time.dwLowDateTime;
u64.HighPart = user_time.dwHighDateTime;
ti->tv_sec = (uint32_t)((u64.QuadPart - 116444736000000000ULL) / 10000000); // 转换为秒
ti->tv_nsec = (uint32_t)((u64.QuadPart % 10000000) * 100); // 获取纳秒部分
return 0;
} else {
return -1; // 获取失败
}
}
return -1;
}
int flock(int fd, int flag) {
// Not implemented
return 3;
}
int fcntl(int fd, int cmd, long arg) {
if (cmd == F_GETFL)
return 0;
if (cmd == F_SETFL && arg == O_NONBLOCK) {
u_long ulOption = 1;
ioctlsocket(fd, FIONBIO, &ulOption);
}
return 1;
}
void sigfillset(int* flag) {
// Not implemented
}
int sigemptyset(int* set) {
/*Not implemented*/
return 0;
}
void sigaction(int flag, struct sigaction* action, void* param) {
// Not implemented
}
static void socket_keepalive(int fd) {
int keepalive = 1;
int ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepalive,
sizeof(keepalive));
assert(ret != SOCKET_ERROR);
}
int pipe(int fd[2]) {
int listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listen_fd == INVALID_SOCKET) {
return -1;
}
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
srand(time(NULL));
// use random port(range from 60000 to 60999) to simulate pipe()
int port;
for (;;) {
port = 60000 + rand() % 1000;
sin.sin_port = htons(port);
if (!bind(listen_fd, (struct sockaddr*)&sin, sizeof(sin)))
break;
}
if (listen(listen_fd, 5) == SOCKET_ERROR) {
closesocket(listen_fd);
return -1;
}
socket_keepalive(listen_fd);
int client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (client_fd == INVALID_SOCKET) {
closesocket(listen_fd);
return -1;
}
if (connect(client_fd, (struct sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR) {
closesocket(listen_fd);
closesocket(client_fd);
return -1;
}
struct sockaddr_in client_addr;
size_t name_len = sizeof(client_addr);
int client_sock = accept(listen_fd, (struct sockaddr*)&client_addr, &name_len);
if (client_sock == INVALID_SOCKET) {
closesocket(listen_fd);
closesocket(client_fd);
return -1;
}
closesocket(listen_fd); // Close listen socket as it's no longer needed
fd[0] = client_sock;
fd[1] = client_fd;
socket_keepalive(client_sock);
socket_keepalive(client_fd);
return 0;
}
int write(int fd, const void* ptr, unsigned int sz) {
WSABUF vecs[1];
vecs[0].buf = (char*)ptr;
vecs[0].len = sz;
DWORD bytesSent;
if (WSASend(fd, vecs, 1, &bytesSent, 0, NULL, NULL)) {
int wsa_error = WSAGetLastError();
set_errno_from_wsa_error(wsa_error);
return -1;
} else {
return bytesSent;
}
}
int read(int fd, void* buffer, unsigned int sz) {
WSABUF vecs[1];
vecs[0].buf = buffer;
vecs[0].len = sz;
DWORD bytesRecv = 0;
DWORD flags = 0;
if (WSARecv(fd, vecs, 1, &bytesRecv, &flags, NULL, NULL)) {
int wsa_error = WSAGetLastError();
if (wsa_error == WSAECONNRESET) {
return 0; // Connection closed by peer
}
// Map WSA error to errno for better error reporting
set_errno_from_wsa_error(wsa_error);
return -1;
} else {
return bytesRecv;
}
}
// Wrapper for recv function with better error handling
int compat_recv(SOCKET s, char *buf, int len, int flags) {
WSABUF vecs[1];
vecs[0].buf = buf;
vecs[0].len = len;
DWORD bytesRecv = 0;
DWORD wsaFlags = 0;
if (WSARecv(s, vecs, 1, &bytesRecv, &wsaFlags, NULL, NULL)) {
int wsa_error = WSAGetLastError();
// Handle non-blocking operations - these are not real errors
if (wsa_error == WSAEWOULDBLOCK || wsa_error == WSAEINTR) {
// For non-blocking sockets, this is normal - no data available right now
set_errno_from_wsa_error(wsa_error);
return -1; // Caller should check errno == EAGAIN
}
if (wsa_error == WSAECONNRESET) {
return 0; // Connection closed by peer
}
// Map WSA error to errno for better error reporting
set_errno_from_wsa_error(wsa_error);
return -1;
} else {
return bytesRecv;
}
}
int close(int fd) {
shutdown(fd, SD_BOTH);
return closesocket(fd);
}
int daemon(int a, int b) {
// Not implemented
return 0;
}
char* strsep(char** stringp, const char* delim) {
char* s;
const char* spanp;
int c, sc;
char* tok;
if ((s = *stringp) == NULL)
return (NULL);
for (tok = s;;) {
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*stringp = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
================================================
FILE: 3rd/compat-mingw/unistd.h
================================================
#pragma once
#include <assert.h>
#include <stdio.h>
#include <time.h>
#include <process.h>
#include <io.h>
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
// Define missing errno values for network errors
#ifndef ECONNRESET
#define ECONNRESET 104
#endif
#ifndef ECONNABORTED
#define ECONNABORTED 103
#endif
#ifndef ECONNREFUSED
#define ECONNREFUSED 111
#endif
#ifndef ENETDOWN
#define ENETDOWN 100
#endif
#ifndef ENETUNREACH
#define ENETUNREACH 101
#endif
#ifndef EHOSTDOWN
#define EHOSTDOWN 112
#endif
#ifndef EHOSTUNREACH
#define EHOSTUNREACH 113
#endif
#ifndef ETIMEDOUT
#define ETIMEDOUT 110
#endif
#ifndef ENOTCONN
#define ENOTCONN 107
#endif
#ifndef EADDRINUSE
#define EADDRINUSE 98
#endif
#ifndef EADDRNOTAVAIL
#define EADDRNOTAVAIL 99
#endif
// Include winsock2.h for gethostname and other network functions
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
// Undefine Windows legacy keywords that conflict with variable names
#ifdef near
#undef near
#endif
#ifdef far
#undef far
#endif
// Socket compatibility macros
#define SHUT_RD SD_RECEIVE
#define SHUT_WR SD_SEND
#define SHUT_RDWR SD_BOTH
#define ssize_t size_t
#define random rand
#define srandom srand
#define snprintf _snprintf
#define localtime_r _localtime64_s
#define pid_t int
int kill(pid_t pid, int exit_code);
void usleep(size_t us);
void sleep(size_t ms);
int clock_gettime(int what, struct timespec *ti);
enum { LOCK_EX, LOCK_NB };
int flock(int fd, int flag);
struct sigaction {
void (*sa_handler)(int);
int sa_flags;
int sa_mask;
};
enum { SIGPIPE, SIGHUP, SA_RESTART };
void sigfillset(int *flag);
int sigemptyset(int* set);
void sigaction(int flag, struct sigaction *action, void* param);
int pipe(int fd[2]);
int daemon(int a, int b);
#define O_NONBLOCK 1
#define F_SETFL 0
#define F_GETFL 1
int fcntl(int fd, int cmd, long arg);
char *strsep(char **stringp, const char *delim);
int write(int fd, const void* ptr, unsigned int sz);
int read(int fd, void* buffer, unsigned int sz);
// Wrapper function for recv with better error handling
int compat_recv(SOCKET s, char *buf, int len, int flags);
// Macro to redirect recv calls to our wrapper
#define recv compat_recv
int close(int fd);
#define getpid _getpid
#define open _open
#define dup2 _dup2
================================================
FILE: 3rd/compat-mingw/wepoll.c
================================================
/*
* wepoll - epoll for Windows
* https://github.com/piscisaureus/wepoll
*
* Copyright 2012-2020, Bert Belder <bertbelder@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef WEPOLL_EXPORT
#define WEPOLL_EXPORT
#endif
#include <stdint.h>
enum EPOLL_EVENTS {
EPOLLIN = (int) (1U << 0),
EPOLLPRI = (int) (1U << 1),
EPOLLOUT = (int) (1U << 2),
EPOLLERR = (int) (1U << 3),
EPOLLHUP = (int) (1U << 4),
EPOLLRDNORM = (int) (1U << 6),
EPOLLRDBAND = (int) (1U << 7),
EPOLLWRNORM = (int) (1U << 8),
EPOLLWRBAND = (int) (1U << 9),
EPOLLMSG = (int) (1U << 10), /* Never reported. */
EPOLLRDHUP = (int) (1U << 13),
EPOLLONESHOT = (int) (1U << 31)
};
#define EPOLLIN (1U << 0)
#define EPOLLPRI (1U << 1)
#define EPOLLOUT (1U << 2)
#define EPOLLERR (1U << 3)
#define EPOLLHUP (1U << 4)
#define EPOLLRDNORM (1U << 6)
#define EPOLLRDBAND (1U << 7)
#define EPOLLWRNORM (1U << 8)
#define EPOLLWRBAND (1U << 9)
#define EPOLLMSG (1U << 10)
#define EPOLLRDHUP (1U << 13)
#define EPOLLONESHOT (1U << 31)
#define EPOLL_CTL_ADD 1
#define EPOLL_CTL_MOD 2
#define EPOLL_CTL_DEL 3
typedef void* HANDLE;
typedef uintptr_t SOCKET;
typedef union epoll_data {
void* ptr;
int fd;
uint32_t u32;
uint64_t u64;
SOCKET sock; /* Windows specific */
HANDLE hnd; /* Windows specific */
} epoll_data_t;
struct epoll_event {
uint32_t events; /* Epoll events and flags */
epoll_data_t data; /* User data variable */
};
#ifdef __cplusplus
extern "C" {
#endif
WEPOLL_EXPORT HANDLE epoll_create(int size);
WEPOLL_EXPORT HANDLE epoll_create1(int flags);
WEPOLL_EXPORT int epoll_close(HANDLE ephnd);
WEPOLL_EXPORT int epoll_ctl(HANDLE ephnd,
int op,
SOCKET sock,
struct epoll_event* event);
WEPOLL_EXPORT int epoll_wait(HANDLE ephnd,
struct epoll_event* events,
int maxevents,
int timeout);
#ifdef __cplusplus
} /* extern "C" */
#endif
#include <assert.h>
#include <stdlib.h>
#define WEPOLL_INTERNAL static
#define WEPOLL_INTERNAL_EXTERN static
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#elif defined(_MSC_VER)
#pragma warning(push, 1)
#endif
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(_MSC_VER)
#pragma warning(pop)
#endif
WEPOLL_INTERNAL int nt_global_init(void);
typedef LONG NTSTATUS;
typedef NTSTATUS* PNTSTATUS;
#ifndef NT_SUCCESS
#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
#endif
#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS) 0x00000000L)
#endif
#ifndef STATUS_PENDING
#define STATUS_PENDING ((NTSTATUS) 0x00000103L)
#endif
#ifndef STATUS_CANCELLED
#define STATUS_CANCELLED ((NTSTATUS) 0xC0000120L)
#endif
#ifndef STATUS_NOT_FOUND
#define STATUS_NOT_FOUND ((NTSTATUS) 0xC0000225L)
#endif
typedef struct _IO_STATUS_BLOCK {
NTSTATUS Status;
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef VOID(NTAPI* PIO_APC_ROUTINE)(PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG Reserved);
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
#define RTL_CONSTANT_STRING(s) \
{ sizeof(s) - sizeof((s)[0]), sizeof(s), s }
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(ObjectName, Attributes) \
{ sizeof(OBJECT_ATTRIBUTES), NULL, ObjectName, Attributes, NULL, NULL }
#ifndef FILE_OPEN
#define FILE_OPEN 0x00000001UL
#endif
#define KEYEDEVENT_WAIT 0x00000001UL
#define KEYEDEVENT_WAKE 0x00000002UL
#define KEYEDEVENT_ALL_ACCESS \
(STANDARD_RIGHTS_REQUIRED | KEYEDEVENT_WAIT | KEYEDEVENT_WAKE)
#define NT_NTDLL_IMPORT_LIST(X) \
X(NTSTATUS, \
NTAPI, \
NtCancelIoFileEx, \
(HANDLE FileHandle, \
PIO_STATUS_BLOCK IoRequestToCancel, \
PIO_STATUS_BLOCK IoStatusBlock)) \
\
X(NTSTATUS, \
NTAPI, \
NtCreateFile, \
(PHANDLE FileHandle, \
ACCESS_MASK DesiredAccess, \
POBJECT_ATTRIBUTES ObjectAttributes, \
PIO_STATUS_BLOCK IoStatusBlock, \
PLARGE_INTEGER AllocationSize, \
ULONG FileAttributes, \
ULONG ShareAccess, \
ULONG CreateDisposition, \
ULONG CreateOptions, \
PVOID EaBuffer, \
ULONG EaLength)) \
\
X(NTSTATUS, \
NTAPI, \
NtCreateKeyedEvent, \
(PHANDLE KeyedEventHandle, \
ACCESS_MASK DesiredAccess, \
POBJECT_ATTRIBUTES ObjectAttributes, \
ULONG Flags)) \
\
X(NTSTATUS, \
NTAPI, \
NtDeviceIoControlFile, \
(HANDLE FileHandle, \
HANDLE Event, \
PIO_APC_ROUTINE ApcRoutine, \
PVOID ApcContext, \
PIO_STATUS_BLOCK IoStatusBlock, \
ULONG IoControlCode, \
PVOID InputBuffer, \
ULONG InputBufferLength, \
PVOID OutputBuffer, \
ULONG OutputBufferLength)) \
\
X(NTSTATUS, \
NTAPI, \
NtReleaseKeyedEvent, \
(HANDLE KeyedEventHandle, \
PVOID KeyValue, \
BOOLEAN Alertable, \
PLARGE_INTEGER Timeout)) \
\
X(NTSTATUS, \
NTAPI, \
NtWaitForKeyedEvent, \
(HANDLE KeyedEventHandle, \
PVOID KeyValue, \
BOOLEAN Alertable, \
PLARGE_INTEGER Timeout)) \
\
X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status))
#define X(return_type, attributes, name, parameters) \
WEPOLL_INTERNAL_EXTERN return_type(attributes* name) parameters;
NT_NTDLL_IMPORT_LIST(X)
#undef X
#define AFD_POLL_RECEIVE 0x0001
#define AFD_POLL_RECEIVE_EXPEDITED 0x0002
#define AFD_POLL_SEND 0x0004
#define AFD_POLL_DISCONNECT 0x0008
#define AFD_POLL_ABORT 0x0010
#define AFD_POLL_LOCAL_CLOSE 0x0020
#define AFD_POLL_ACCEPT 0x0080
#define AFD_POLL_CONNECT_FAIL 0x0100
typedef struct _AFD_POLL_HANDLE_INFO {
HANDLE Handle;
ULONG Events;
NTSTATUS Status;
} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO;
typedef struct _AFD_POLL_INFO {
LARGE_INTEGER Timeout;
ULONG NumberOfHandles;
ULONG Exclusive;
AFD_POLL_HANDLE_INFO Handles[1];
} AFD_POLL_INFO, *PAFD_POLL_INFO;
WEPOLL_INTERNAL int afd_create_device_handle(HANDLE iocp_handle,
HANDLE* afd_device_handle_out);
WEPOLL_INTERNAL int afd_poll(HANDLE afd_device_handle,
AFD_POLL_INFO* poll_info,
IO_STATUS_BLOCK* io_status_block);
WEPOLL_INTERNAL int afd_cancel_poll(HANDLE afd_device_handle,
IO_STATUS_BLOCK* io_status_block);
#define return_map_error(value) \
do { \
err_map_win_error(); \
return (value); \
} while (0)
#define return_set_error(value, error) \
do { \
err_set_win_error(error); \
return (value); \
} while (0)
WEPOLL_INTERNAL void err_map_win_error(void);
WEPOLL_INTERNAL void err_set_win_error(DWORD error);
WEPOLL_INTERNAL int err_check_handle(HANDLE handle);
#define IOCTL_AFD_POLL 0x00012024
static UNICODE_STRING afd__device_name =
RTL_CONSTANT_STRING(L"\\Device\\Afd\\Wepoll");
static OBJECT_ATTRIBUTES afd__device_attributes =
RTL_CONSTANT_OBJECT_ATTRIBUTES(&afd__device_name, 0);
int afd_create_device_handle(HANDLE iocp_handle,
HANDLE* afd_device_handle_out) {
HANDLE afd_device_handle;
IO_STATUS_BLOCK iosb;
NTSTATUS status;
/* By opening \Device\Afd without specifying any extended attributes, we'll
* get a handle that lets us talk to the AFD driver, but that doesn't have an
* associated endpoint (so it's not a socket). */
status = NtCreateFile(&afd_device_handle,
SYNCHRONIZE,
&afd__device_attributes,
&iosb,
NULL,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
0,
NULL,
0);
if (status != STATUS_SUCCESS)
return_set_error(-1, RtlNtStatusToDosError(status));
if (CreateIoCompletionPort(afd_device_handle, iocp_handle, 0, 0) == NULL)
goto error;
if (!SetFileCompletionNotificationModes(afd_device_handle,
FILE_SKIP_SET_EVENT_ON_HANDLE))
goto error;
*afd_device_handle_out = afd_device_handle;
return 0;
error:
CloseHandle(afd_device_handle);
return_map_error(-1);
}
int afd_poll(HANDLE afd_device_handle,
AFD_POLL_INFO* poll_info,
IO_STATUS_BLOCK* io_status_block) {
NTSTATUS status;
/* Blocking operation is not supported. */
assert(io_status_block != NULL);
io_status_block->Status = STATUS_PENDING;
status = NtDeviceIoControlFile(afd_device_handle,
NULL,
NULL,
io_status_block,
io_status_block,
IOCTL_AFD_POLL,
poll_info,
sizeof *poll_info,
poll_info,
sizeof *poll_info);
if (status == STATUS_SUCCESS)
return 0;
else if (status == STATUS_PENDING)
return_set_error(-1, ERROR_IO_PENDING);
else
return_set_error(-1, RtlNtStatusToDosError(status));
}
int afd_cancel_poll(HANDLE afd_device_handle,
IO_STATUS_BLOCK* io_status_block) {
NTSTATUS cancel_status;
IO_STATUS_BLOCK cancel_iosb;
/* If the poll operation has already completed or has been cancelled earlier,
* there's nothing left for us to do. */
if (io_status_block->Status != STATUS_PENDING)
return 0;
cancel_status =
NtCancelIoFileEx(afd_device_handle, io_status_block, &cancel_iosb);
/* NtCancelIoFileEx() may return STATUS_NOT_FOUND if the operation completed
* just before calling NtCancelIoFileEx(). This is not an error. */
if (cancel_status == STATUS_SUCCESS || cancel_status == STATUS_NOT_FOUND)
return 0;
else
return_set_error(-1, RtlNtStatusToDosError(cancel_status));
}
WEPOLL_INTERNAL int epoll_global_init(void);
WEPOLL_INTERNAL int init(void);
typedef struct port_state port_state_t;
typedef struct queue queue_t;
typedef struct sock_state sock_state_t;
typedef struct ts_tree_node ts_tree_node_t;
WEPOLL_INTERNAL port_state_t* port_new(HANDLE* iocp_handle_out);
WEPOLL_INTERNAL int port_close(port_state_t* port_state);
WEPOLL_INTERNAL int port_delete(port_state_t* port_state);
WEPOLL_INTERNAL int port_wait(port_state_t* port_state,
struct epoll_event* events,
int maxevents,
int timeout);
WEPOLL_INTERNAL int port_ctl(port_state_t* port_state,
int op,
SOCKET sock,
struct epoll_event* ev);
WEPOLL_INTERNAL int port_register_socket(port_state_t* port_state,
sock_state_t* sock_state,
SOCKET socket);
WEPOLL_INTERNAL void port_unregister_socket(port_state_t* port_state,
sock_state_t* sock_state);
WEPOLL_INTERNAL sock_state_t* port_find_socket(port_state_t* port_state,
SOCKET socket);
WEPOLL_INTERNAL void port_request_socket_update(port_state_t* port_state,
sock_state_t* sock_state);
WEPOLL_INTERNAL void port_cancel_socket_update(port_state_t* port_state,
sock_state_t* sock_state);
WEPOLL_INTERNAL void port_add_deleted_socket(port_state_t* port_state,
sock_state_t* sock_state);
WEPOLL_INTERNAL void port_remove_deleted_socket(port_state_t* port_state,
sock_state_t* sock_state);
WEPOLL_INTERNAL HANDLE port_get_iocp_handle(port_state_t* port_state);
WEPOLL_INTERNAL queue_t* port_get_poll_group_queue(port_state_t* port_state);
WEPOLL_INTERNAL port_state_t* port_state_from_handle_tree_node(
ts_tree_node_t* tree_node);
WEPOLL_INTERNAL ts_tree_node_t* port_state_to_handle_tree_node(
port_state_t* port_state);
/* The reflock is a special kind of lock that normally prevents a chunk of
* memory from being freed, but does allow the chunk of memory to eventually be
* released in a coordinated fashion.
*
* Under normal operation, threads increase and decrease the reference count,
* which are wait-free operations.
*
* Exactly once during the reflock's lifecycle, a thread holding a reference to
* the lock may "destroy" the lock; this operation blocks until all other
* threads holding a reference to the lock have dereferenced it. After
* "destroy" returns, the calling thread may assume that no other threads have
* a reference to the lock.
*
* Attemmpting to lock or destroy a lock after reflock_unref_and_destroy() has
* been called is invalid and results in undefined behavior. Therefore the user
* should use another lock to guarantee that this can't happen.
*/
typedef struct reflock {
volatile long state; /* 32-bit Interlocked APIs operate on `long` values. */
} reflock_t;
WEPOLL_INTERNAL int reflock_global_init(void);
WEPOLL_INTERNAL void reflock_init(reflock_t* reflock);
WEPOLL_INTERNAL void reflock_ref(reflock_t* reflock);
WEPOLL_INTERNAL void reflock_unref(reflock_t* reflock);
WEPOLL_INTERNAL void reflock_unref_and_destroy(reflock_t* reflock);
#include <stdbool.h>
/* N.b.: the tree functions do not set errno or LastError when they fail. Each
* of the API functions has at most one failure mode. It is up to the caller to
* set an appropriate error code when necessary. */
typedef struct tree tree_t;
typedef struct tree_node tree_node_t;
typedef struct tree {
tree_node_t* root;
} tree_t;
typedef struct tree_node {
tree_node_t* left;
tree_node_t* right;
tree_node_t* parent;
uintptr_t key;
bool red;
} tree_node_t;
WEPOLL_INTERNAL void tree_init(tree_t* tree);
WEPOLL_INTERNAL void tree_node_init(tree_node_t* node);
WEPOLL_INTERNAL int tree_add(tree_t* tree, tree_node_t* node, uintptr_t key);
WEPOLL_INTERNAL void tree_del(tree_t* tree, tree_node_t* node);
WEPOLL_INTERNAL tree_node_t* tree_find(const tree_t* tree, uintptr_t key);
WEPOLL_INTERNAL tree_node_t* tree_root(const tree_t* tree);
typedef struct ts_tree {
tree_t tree;
SRWLOCK lock;
} ts_tree_t;
typedef struct ts_tree_node {
tree_node_t tree_node;
reflock_t reflock;
} ts_tree_node_t;
WEPOLL_INTERNAL void ts_tree_init(ts_tree_t* rtl);
WEPOLL_INTERNAL void ts_tree_node_init(ts_tree_node_t* node);
WEPOLL_INTERNAL int ts_tree_add(ts_tree_t* ts_tree,
ts_tree_node_t* node,
uintptr_t key);
WEPOLL_INTERNAL ts_tree_node_t* ts_tree_del_and_ref(ts_tree_t* ts_tree,
uintptr_t key);
WEPOLL_INTERNAL ts_tree_node_t* ts_tree_find_and_ref(ts_tree_t* ts_tree,
uintptr_t key);
WEPOLL_INTERNAL void ts_tree_node_unref(ts_tree_node_t* node);
WEPOLL_INTERNAL void ts_tree_node_unref_and_destroy(ts_tree_node_t* node);
static ts_tree_t epoll__handle_tree;
int epoll_global_init(void) {
ts_tree_init(&epoll__handle_tree);
return 0;
}
static HANDLE epoll__create(void) {
port_state_t* port_state;
HANDLE ephnd;
ts_tree_node_t* tree_node;
if (init() < 0)
return NULL;
port_state = port_new(&ephnd);
if (port_state == NULL)
return NULL;
tree_node = port_state_to_handle_tree_node(port_state);
if (ts_tree_add(&epoll__handle_tree, tree_node, (uintptr_t) ephnd) < 0) {
/* This should never happen. */
port_delete(port_state);
return_set_error(NULL, ERROR_ALREADY_EXISTS);
}
return ephnd;
}
HANDLE epoll_create(int size) {
if (size <= 0)
return_set_error(NULL, ERROR_INVALID_PARAMETER);
return epoll__create();
}
HANDLE epoll_create1(int flags) {
if (flags != 0)
return_set_error(NULL, ERROR_INVALID_PARAMETER);
return epoll__create();
}
int epoll_close(HANDLE ephnd) {
ts_tree_node_t* tree_node;
port_state_t* port_state;
if (init() < 0)
return -1;
tree_node = ts_tree_del_and_ref(&epoll__handle_tree, (uintptr_t) ephnd);
if (tree_node == NULL) {
err_set_win_error(ERROR_INVALID_PARAMETER);
goto err;
}
port_state = port_state_from_handle_tree_node(tree_node);
port_close(port_state);
ts_tree_node_unref_and_destroy(tree_node);
return port_delete(port_state);
err:
err_check_handle(ephnd);
return -1;
}
int epoll_ctl(HANDLE ephnd, int op, SOCKET sock, struct epoll_event* ev) {
ts_tree_node_t* tree_node;
port_state_t* port_state;
int r;
if (init() < 0)
return -1;
tree_node = ts_tree_find_and_ref(&epoll__handle_tree, (uintptr_t) ephnd);
if (tree_node == NULL) {
err_set_win_error(ERROR_INVALID_PARAMETER);
goto err;
}
port_state = port_state_from_handle_tree_node(tree_node);
r = port_ctl(port_state, op, sock, ev);
ts_tree_node_unref(tree_node);
if (r < 0)
goto err;
return 0;
err:
/* On Linux, in the case of epoll_ctl(), EBADF takes priority over other
* errors. Wepoll mimics this behavior. */
err_check_handle(ephnd);
err_check_handle((HANDLE) sock);
return -1;
}
int epoll_wait(HANDLE ephnd,
struct epoll_event* events,
int maxevents,
int timeout) {
ts_tree_node_t* tree_node;
port_state_t* port_state;
int num_events;
if (maxevents <= 0)
return_set_error(-1, ERROR_INVALID_PARAMETER);
if (init() < 0)
return -1;
tree_node = ts_tree_find_and_ref(&epoll__handle_tree, (uintptr_t) ephnd);
if (tree_node == NULL) {
err_set_win_error(ERROR_INVALID_PARAMETER);
goto err;
}
port_state = port_state_from_handle_tree_node(tree_node);
num_events = port_wait(port_state, events, maxevents, timeout);
ts_tree_node_unref(tree_node);
if (num_events < 0)
goto err;
return num_events;
err:
err_check_handle(ephnd);
return -1;
}
#include <errno.h>
#define ERR__ERRNO_MAPPINGS(X) \
X(ERROR_ACCESS_DENIED, EACCES) \
X(ERROR_ALREADY_EXISTS, EEXIST) \
X(ERROR_BAD_COMMAND, EACCES) \
X(ERROR_BAD_EXE_FORMAT, ENOEXEC) \
X(ERROR_BAD_LENGTH, EACCES) \
X(ERROR_BAD_NETPATH, ENOENT) \
X(ERROR_BAD_NET_NAME, ENOENT) \
X(ERROR_BAD_NET_RESP, ENETDOWN) \
X(ERROR_BAD_PATHNAME, ENOENT) \
X(ERROR_BROKEN_PIPE, EPIPE) \
X(ERROR_CANNOT_MAKE, EACCES) \
X(ERROR_COMMITMENT_LIMIT, ENOMEM) \
X(ERROR_CONNECTION_ABORTED, ECONNABORTED) \
X(ERROR_CONNECTION_ACTIVE, EISCONN) \
X(ERROR_CONNECTION_REFUSED, ECONNREFUSED) \
X(ERROR_CRC, EACCES) \
X(ERROR_DIR_NOT_EMPTY, ENOTEMPTY) \
X(ERROR_DISK_FULL, ENOSPC) \
X(ERROR_DUP_NAME, EADDRINUSE) \
X(ERROR_FILENAME_EXCED_RANGE, ENOENT) \
X(ERROR_FILE_NOT_FOUND, ENOENT) \
X(ERROR_GEN_FAILURE, EACCES) \
X(ERROR_GRACEFUL_DISCONNECT, EPIPE) \
X(ERROR_HOST_DOWN, EHOSTUNREACH) \
X(ERROR_HOST_UNREACHABLE, EHOSTUNREACH) \
X(ERROR_INSUFFICIENT_BUFFER, EFAULT) \
X(ERROR_INVALID_ADDRESS, EADDRNOTAVAIL) \
X(ERROR_INVALID_FUNCTION, EINVAL) \
X(ERROR_INVALID_HANDLE, EBADF) \
X(ERROR_INVALID_NETNAME, EADDRNOTAVAIL) \
X(ERROR_INVALID_PARAMETER, EINVAL) \
X(ERROR_INVALID_USER_BUFFER, EMSGSIZE) \
X(ERROR_IO_PENDING, EINPROGRESS) \
X(ERROR_LOCK_VIOLATION, EACCES) \
X(ERROR_MORE_DATA, EMSGSIZE) \
X(ERROR_NETNAME_DELETED, ECONNABORTED) \
X(ERROR_NETWORK_ACCESS_DENIED, EACCES) \
X(ERROR_NETWORK_BUSY, ENETDOWN) \
X(ERROR_NETWORK_UNREACHABLE, ENETUNREACH) \
X(ERROR_NOACCESS, EFAULT) \
X(ERROR_NONPAGED_SYSTEM_RESOURCES, ENOMEM) \
X(ERROR_NOT_ENOUGH_MEMORY, ENOMEM) \
X(ERROR_NOT_ENOUGH_QUOTA, ENOMEM) \
X(ERROR_NOT_FOUND, ENOENT) \
X(ERROR_NOT_LOCKED, EACCES) \
X(ERROR_NOT_READY, EACCES) \
X(ERROR_NOT_SAME_DEVICE, EXDEV) \
X(ERROR_NOT_SUPPORTED, ENOTSUP) \
X(ERROR_NO_MORE_FILES, ENOENT) \
X(ERROR_NO_SYSTEM_RESOURCES, ENOMEM) \
X(ERROR_OPERATION_ABORTED, EINTR) \
X(ERROR_OUT_OF_PAPER, EACCES) \
X(ERROR_PAGED_SYSTEM_RESOURCES, ENOMEM) \
X(ERROR_PAGEFILE_QUOTA, ENOMEM) \
X(ERROR_PATH_NOT_FOUND, ENOENT) \
X(ERROR_PIPE_NOT_CONNECTED, EPIPE) \
X(ERROR_PORT_UNREACHABLE, ECONNRESET) \
X(ERROR_PROTOCOL_UNREACHABLE, ENETUNREACH) \
X(ERROR_REM_NOT_LIST, ECONNREFUSED) \
X(ERROR_REQUEST_ABORTED, EINTR) \
X(ERROR_REQ_NOT_ACCEP, EWOULDBLOCK) \
X(ERROR_SECTOR_NOT_FOUND, EACCES) \
X(ERROR_SEM_TIMEOUT, ETIMEDOUT) \
X(ERROR_SHARING_VIOLATION, EACCES) \
X(ERROR_TOO_MANY_NAMES, ENOMEM) \
X(ERROR_TOO_MANY_OPEN_FILES, EMFILE) \
X(ERROR_UNEXP_NET_ERR, ECONNABORTED) \
X(ERROR_WAIT_NO_CHILDREN, ECHILD) \
X(ERROR_WORKING_SET_QUOTA, ENOMEM) \
X(ERROR_WRITE_PROTECT, EACCES) \
X(ERROR_WRONG_DISK, EACCES) \
X(WSAEACCES, EACCES) \
X(WSAEADDRINUSE, EADDRINUSE) \
X(WSAEADDRNOTAVAIL, EADDRNOTAVAIL) \
X(WSAEAFNOSUPPORT, EAFNOSUPPORT) \
X(WSAECONNABORTED, ECONNABORTED) \
X(WSAECONNREFUSED, ECONNREFUSED) \
X(WSAECONNRESET, ECONNRESET) \
X(WSAEDISCON, EPIPE) \
X(WSAEFAULT, EFAULT) \
X(WSAEHOSTDOWN, EHOSTUNREACH) \
X(WSAEHOSTUNREACH, EHOSTUNREACH) \
X(WSAEINPROGRESS, EBUSY) \
X(WSAEINTR, EINTR) \
X(WSAEINVAL, EINVAL) \
X(WSAEISCONN, EISCONN) \
X(WSAEMSGSIZE, EMSGSIZE) \
X(WSAENETDOWN, ENETDOWN) \
X(WSAENETRESET, EHOSTUNREACH) \
X(WSAENETUNREACH, ENETUNREACH) \
X(WSAENOBUFS, ENOMEM) \
X(WSAENOTCONN, ENOTCONN) \
X(WSAENOTSOCK, ENOTSOCK) \
X(WSAEOPNOTSUPP, EOPNOTSUPP) \
X(WSAEPROCLIM, ENOMEM) \
X(WSAESHUTDOWN, EPIPE) \
X(WSAETIMEDOUT, ETIMEDOUT) \
X(WSAEWOULDBLOCK, EWOULDBLOCK) \
X(WSANOTINITIALISED, ENETDOWN) \
X(WSASYSNOTREADY, ENETDOWN) \
X(WSAVERNOTSUPPORTED, ENOSYS)
static errno_t err__map_win_error_to_errno(DWORD error) {
switch (error) {
#define X(error_sym, errno_sym) \
case error_sym: \
return errno_sym;
ERR__ERRNO_MAPPINGS(X)
#undef X
}
return EINVAL;
}
void err_map_win_error(void) {
errno = err__map_win_error_to_errno(GetLastError());
}
void err_set_win_error(DWORD error) {
SetLastError(error);
errno = err__map_win_error_to_errno(error);
}
int err_check_handle(HANDLE handle) {
DWORD flags;
/* GetHandleInformation() succeeds when passed INVALID_HANDLE_VALUE, so check
* for this condition explicitly. */
if (handle == INVALID_HANDLE_VALUE)
return_set_error(-1, ERROR_INVALID_HANDLE);
if (!GetHandleInformation(handle, &flags))
return_map_error(-1);
return 0;
}
#include <stddef.h>
#define array_count(a) (sizeof(a) / (sizeof((a)[0])))
#define container_of(ptr, type, member) \
((type*) ((uintptr_t) (ptr) - offsetof(type, member)))
#define unused_var(v) ((void) (v))
/* Polyfill `inline` for older versions of msvc (up to Visual Studio 2013) */
#if defined(_MSC_VER) && _MSC_VER < 1900
#define inline __inline
#endif
WEPOLL_INTERNAL int ws_global_init(void);
WEPOLL_INTERNAL SOCKET ws_get_base_socket(SOCKET socket);
static bool init__done = false;
static INIT_ONCE init__once = INIT_ONCE_STATIC_INIT;
static BOOL CALLBACK init__once_callback(INIT_ONCE* once,
void* parameter,
void** context) {
unused_var(once);
unused_var(parameter);
unused_var(context);
/* N.b. that initialization order matters here. */
if (ws_global_init() < 0 || nt_global_init() < 0 ||
reflock_global_init() < 0 || epoll_global_init() < 0)
return FALSE;
init__done = true;
return TRUE;
}
int init(void) {
if (!init__done &&
!InitOnceExecuteOnce(&init__once, init__once_callback, NULL, NULL))
/* `InitOnceExecuteOnce()` itself is infallible, and it doesn't set any
* error code when the once-callback returns FALSE. We return -1 here to
* indicate that global initialization failed; the failing init function is
* resposible for setting `errno` and calling `SetLastError()`. */
return -1;
return 0;
}
/* Set up a workaround for the following problem:
* FARPROC addr = GetProcAddress(...);
* MY_FUNC func = (MY_FUNC) addr; <-- GCC 8 warning/error.
* MY_FUNC func = (MY_FUNC) (void*) addr; <-- MSVC warning/error.
* To compile cleanly with either compiler, do casts with this "bridge" type:
* MY_FUNC func = (MY_FUNC) (nt__fn_ptr_cast_t) addr; */
#ifdef __GNUC__
typedef void* nt__fn_ptr_cast_t;
#else
typedef FARPROC nt__fn_ptr_cast_t;
#endif
#define X(return_type, attributes, name, parameters) \
WEPOLL_INTERNAL return_type(attributes* name) parameters = NULL;
NT_NTDLL_IMPORT_LIST(X)
#undef X
int nt_global_init(void) {
HMODULE ntdll;
FARPROC fn_ptr;
ntdll = GetModuleHandleW(L"ntdll.dll");
if (ntdll == NULL)
return -1;
#define X(return_type, attributes, name, parameters) \
fn_ptr = GetProcAddress(ntdll, #name); \
if (fn_ptr == NULL) \
return -1; \
name = (return_type(attributes*) parameters)(nt__fn_ptr_cast_t) fn_ptr;
NT_NTDLL_IMPORT_LIST(X)
#undef X
return 0;
}
#include <string.h>
typedef struct poll_group poll_group_t;
typedef struct queue_node queue_node_t;
WEPOLL_INTERNAL poll_group_t* poll_group_acquire(port_state_t* port);
WEPOLL_INTERNAL void poll_group_release(poll_group_t* poll_group);
WEPOLL_INTERNAL void poll_group_delete(poll_group_t* poll_group);
WEPOLL_INTERNAL poll_group_t* poll_group_from_queue_node(
queue_node_t* queue_node);
WEPOLL_INTERNAL HANDLE
poll_group_get_afd_device_handle(poll_group_t* poll_group);
typedef struct queue_node {
queue_node_t* prev;
queue_node_t* next;
} queue_node_t;
typedef struct queue {
queue_node_t head;
} queue_t;
WEPOLL_INTERNAL void queue_init(queue_t* queue);
WEPOLL_INTERNAL void queue_node_init(queue_node_t* node);
WEPOLL_INTERNAL queue_node_t* queue_first(const queue_t* queue);
WEPOLL_INTERNAL queue_node_t* queue_last(const queue_t* queue);
WEPOLL_INTERNAL void queue_prepend(queue_t* queue, queue_node_t* node);
WEPOLL_INTERNAL void queue_append(queue_t* queue, queue_node_t* node);
WEPOLL_INTERNAL void queue_move_to_start(queue_t* queue, queue_node_t* node);
WEPOLL_INTERNAL void queue_move_to_end(queue_t* queue, queue_node_t* node);
WEPOLL_INTERNAL void queue_remove(queue_node_t* node);
WEPOLL_INTERNAL bool queue_is_empty(const queue_t* queue);
WEPOLL_INTERNAL bool queue_is_enqueued(const queue_node_t* node);
#define POLL_GROUP__MAX_GROUP_SIZE 32
typedef struct poll_group {
port_state_t* port_state;
queue_node_t queue_node;
HANDLE afd_device_handle;
size_t group_size;
} poll_group_t;
static poll_group_t* poll_group__new(port_state_t* port_state) {
HANDLE iocp_handle = port_get_iocp_handle(port_state);
queue_t* poll_group_queue = port_get_poll_group_queue(port_state);
poll_group_t* poll_group = malloc(sizeof *poll_group);
if (poll_group == NULL)
return_set_error(NULL, ERROR_NOT_ENOUGH_MEMORY);
memset(poll_group, 0, sizeof *poll_group);
queue_node_init(&poll_group->queue_node);
poll_group->port_state = port_state;
if (afd_create_device_handle(iocp_handle, &poll_group->afd_device_handle) <
0) {
free(poll_group);
return NULL;
}
queue_append(poll_group_queue, &poll_group->queue_node);
return poll_group;
}
void poll_group_delete(poll_group_t* poll_group) {
assert(poll_group->group_size == 0);
CloseHandle(poll_group->afd_device_handle);
queue_remove(&poll_group->queue_node);
free(poll_group);
}
poll_group_t* poll_group_from_queue_node(queue_node_t* queue_node) {
return container_of(queue_node, poll_group_t, queue_node);
}
HANDLE poll_group_get_afd_device_handle(poll_group_t* poll_group) {
return poll_group->afd_device_handle;
}
poll_group_t* poll_group_acquire(port_state_t* port_state) {
queue_t* poll_group_queue = port_get_poll_group_queue(port_state);
poll_group_t* poll_group =
!queue_is_empty(poll_group_queue)
? container_of(
queue_last(poll_group_queue), poll_group_t, queue_node)
: NULL;
if (poll_group == NULL ||
poll_group->group_size >= POLL_GROUP__MAX_GROUP_SIZE)
poll_group = poll_group__new(port_state);
if (poll_group == NULL)
return NULL;
if (++poll_group->group_size == POLL_GROUP__MAX_GROUP_SIZE)
queue_move_to_start(poll_group_queue, &poll_group->queue_node);
return poll_group;
}
void poll_group_release(poll_group_t* poll_group) {
port_state_t* port_state = poll_group->port_state;
queue_t* poll_group_queue = port_get_poll_group_queue(port_state);
poll_group->group_size--;
assert(poll_group->group_size < POLL_GROUP__MAX_GROUP_SIZE);
queue_move_to_end(poll_group_queue, &poll_group->queue_node);
/* Poll groups are currently only freed when the epoll port is closed. */
}
WEPOLL_INTERNAL sock_state_t* sock_new(port_state_t* port_state,
SOCKET socket);
WEPOLL_INTERNAL void sock_delete(port_state_t* port_state,
sock_state_t* sock_state);
WEPOLL_INTERNAL void sock_force_delete(port_state_t* port_state,
sock_state_t* sock_state);
WEPOLL_INTERNAL int sock_set_event(port_state_t* port_state,
sock_state_t* sock_state,
const struct epoll_event* ev);
WEPOLL_INTERNAL int sock_update(port_state_t* port_state,
sock_state_t* sock_state);
WEPOLL_INTERNAL int sock_feed_event(port_state_t* port_state,
IO_STATUS_BLOCK* io_status_block,
struct epoll_event* ev);
WEPOLL_INTERNAL sock_state_t* sock_state_from_queue_node(
queue_node_t* queue_node);
WEPOLL_INTERNAL queue_node_t* sock_state_to_queue_node(
sock_state_t* sock_state);
WEPOLL_INTERNAL sock_state_t* sock_state_from_tree_node(
tree_node_t* tree_node);
WEPOLL_INTERNAL tree_node_t* sock_state_to_tree_node(sock_state_t* sock_state);
#define PORT__MAX_ON_STACK_COMPLETIONS 256
typedef struct port_state {
HANDLE iocp_handle;
tree_t sock_tree;
queue_t sock_update_queue;
queue_t sock_deleted_queue;
queue_t poll_group_queue;
ts_tree_node_t handle_tree_node;
CRITICAL_SECTION lock;
size_t active_poll_count;
} port_state_t;
static inline port_state_t* port__alloc(void) {
port_state_t* port_state = malloc(sizeof *port_state);
if (port_state == NULL)
return_set_error(NULL, ERROR_NOT_ENOUGH_MEMORY);
return port_state;
}
static inline void port__free(port_state_t* port) {
assert(port != NULL);
free(port);
}
static inline HANDLE port__create_iocp(void) {
HANDLE iocp_handle =
CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if (iocp_handle == NULL)
return_map_error(NULL);
return iocp_handle;
}
port_state_t* port_new(HANDLE* iocp_handle_out) {
port_state_t* port_state;
HANDLE iocp_handle;
port_state = port__alloc();
if (port_state == NULL)
goto err1;
iocp_handle = port__create_iocp();
if (iocp_handle == NULL)
goto err2;
memset(port_state, 0, sizeof *port_state);
port_state->iocp_handle = iocp_handle;
tree_init(&port_state->sock_tree);
queue_init(&port_state->sock_update_queue);
queue_init(&port_state->sock_deleted_queue);
queue_init(&port_state->poll_group_queue);
ts_tree_node_init(&port_state->handle_tree_node);
InitializeCriticalSection(&port_state->lock);
*iocp_handle_out = iocp_handle;
return port_state;
err2:
port__free(port_state);
err1:
return NULL;
}
static inline int port__close_iocp(port_state_t* port_state) {
HANDLE iocp_handle = port_state->iocp_handle;
port_state->iocp_handle = NULL;
if (!CloseHandle(iocp_handle))
return_map_error(-1);
return 0;
}
int port_close(port_state_t* port_state) {
int result;
EnterCriticalSection(&port_state->lock);
result = port__close_iocp(port_state);
LeaveCriticalSection(&port_state->lock);
return result;
}
int port_delete(port_state_t* port_state) {
tree_node_t* tree_node;
queue_node_t* queue_node;
/* At this point the IOCP port should have been closed. */
assert(port_state->iocp_handle == NULL);
while ((tree_node = tree_root(&port_state->sock_tree)) != NULL) {
sock_state_t* sock_state = sock_state_from_tree_node(tree_node);
sock_force_delete(port_state, sock_state);
}
while ((queue_node = queue_first(&port_state->sock_deleted_queue)) != NULL) {
sock_state_t* sock_state = sock_state_from_queue_node(queue_node);
sock_force_delete(port_state, sock_state);
}
while ((queue_node = queue_first(&port_state->poll_group_queue)) != NULL) {
poll_group_t* poll_group = poll_group_from_queue_node(queue_node);
poll_group_delete(poll_group);
}
assert(queue_is_empty(&port_state->sock_update_queue));
DeleteCriticalSection(&port_state->lock);
port__free(port_state);
return 0;
}
static int port__update_events(port_state_t* port_state) {
queue_t* sock_update_queue = &port_state->sock_update_queue;
/* Walk the queue, submitting new poll requests for every socket that needs
* it. */
while (!queue_is_empty(sock_update_queue)) {
queue_node_t* queue_node = queue_first(sock_update_queue);
sock_state_t* sock_state = sock_state_from_queue_node(queue_node);
if (sock_update(port_state, sock_state) < 0)
return -1;
/* sock_update() removes the socket from the update queue. */
}
return 0;
}
static inline void port__update_events_if_polling(port_state_t* port_state) {
if (port_state->active_poll_count > 0)
port__update_events(port_state);
}
static inline int port__feed_events(port_state_t* port_state,
struct epoll_event* epoll_events,
OVERLAPPED_ENTRY* iocp_events,
DWORD iocp_event_count) {
int epoll_event_count = 0;
DWORD i;
for (i = 0; i < iocp_event_count; i++) {
IO_STATUS_BLOCK* io_status_block =
(IO_STATUS_BLOCK*) iocp_events[i].lpOverlapped;
struct epoll_event* ev = &epoll_events[epoll_event_count];
epoll_event_count += sock_feed_event(port_state, io_status_block, ev);
}
return epoll_event_count;
}
static inline int port__poll(port_state_t* port_state,
struct epoll_event* epoll_events,
OVERLAPPED_ENTRY* iocp_events,
DWORD maxevents,
DWORD timeout) {
DWORD completion_count;
if (port__update_events(port_state) < 0)
return -1;
port_state->active_poll_count++;
LeaveCriticalSection(&port_state->lock);
BOOL r = GetQueuedCompletionStatusEx(port_state->iocp_handle,
iocp_events,
maxevents,
&completion_count,
timeout,
FALSE);
EnterCriticalSection(&port_state->lock);
port_state->active_poll_count--;
if (!r)
return_map_error(-1);
return port__feed_events(
port_state, epoll_events, iocp_events, completion_count);
}
int port_wait(port_state_t* port_state,
struct epoll_event* events,
int maxevents,
int timeout) {
OVERLAPPED_ENTRY stack_iocp_events[PORT__MAX_ON_STACK_COMPLETIONS];
OVERLAPPED_ENTRY* iocp_events;
uint64_t due = 0;
DWORD gqcs_timeout;
int result;
/* Check whether `maxevents` is in range. */
if (maxevents <= 0)
return_set_error(-1, ERROR_INVALID_PARAMETER);
/* Decide whether the IOCP completion list can live on the stack, or allocate
* memory for it on the heap. */
if ((size_t) maxevents <= array_count(stack_iocp_events)) {
iocp_events = stack_iocp_events;
} else if ((iocp_events =
malloc((size_t) maxevents * sizeof *iocp_events)) == NULL) {
iocp_events = stack_iocp_events;
maxevents = array_count(stack_iocp_events);
}
/* Compute the timeout for GetQueuedCompletionStatus, and the wait end
* time, if the user specified a timeout other than zero or infinite. */
if (timeout > 0) {
due = GetTickCount64() + (uint64_t) timeout;
gqcs_timeout = (DWORD) timeout;
} else if (timeout == 0) {
gqcs_timeout = 0;
} else {
gqcs_timeout = INFINITE;
}
EnterCriticalSection(&port_state->lock);
/* Dequeue completion packets until either at least one interesting event
* has been discovered, or the timeout is reached. */
for (;;) {
uint64_t now;
result = port__poll(
port_state, events, iocp_events, (DWORD) maxevents, gqcs_timeout);
if (result < 0 || result > 0)
break; /* Result, error, or time-out. */
if (timeout < 0)
continue; /* When timeout is negative, never time out. */
/* Update time. */
now = GetTickCount64();
/* Do not allow the due time to be in the past. */
if (now >= due) {
SetLastError(WAIT_TIMEOUT);
break;
}
/* Recompute time-out argument for GetQueuedCompletionStatus. */
gqcs_timeout = (DWORD)(due - now);
}
port__update_events_if_polling(port_state);
LeaveCriticalSection(&port_state->lock);
if (iocp_events != stack_iocp_events)
free(iocp_events);
if (result >= 0)
return result;
else if (GetLastError() == WAIT_TIMEOUT)
return 0;
else
return -1;
}
static inline int port__ctl_add(port_state_t* port_state,
SOCKET sock,
struct epoll_event* ev) {
sock_state_t* sock_state = sock_new(port_state, sock);
if (sock_state == NULL)
return -1;
if (sock_set_event(port_state, sock_state, ev) < 0) {
sock_delete(port_state, sock_state);
return -1;
}
port__update_events_if_polling(port_state);
return 0;
}
static inline int port__ctl_mod(port_state_t* port_state,
SOCKET sock,
struct epoll_event* ev) {
sock_state_t* sock_state = port_find_socket(port_state, sock);
if (sock_state == NULL)
return -1;
if (sock_set_event(port_state, sock_state, ev) < 0)
return -1;
port__update_events_if_polling(port_state);
return 0;
}
static inline int port__ctl_del(port_state_t* port_state, SOCKET sock) {
sock_state_t* sock_state = port_find_socket(port_state, sock);
if (sock_state == NULL)
return -1;
sock_delete(port_state, sock_state);
return 0;
}
static inline int port__ctl_op(port_state_t* port_state,
int op,
SOCKET sock,
struct epoll_event* ev) {
switch (op) {
case EPOLL_CTL_ADD:
return port__ctl_add(port_state, sock, ev);
case EPOLL_CTL_MOD:
return port__ctl_mod(port_state, sock, ev);
case EPOLL_CTL_DEL:
return port__ctl_del(port_state, sock);
default:
return_set_error(-1, ERROR_INVALID_PARAMETER);
}
}
int port_ctl(port_state_t* port_state,
int op,
SOCKET sock,
struct epoll_event* ev) {
int result;
EnterCriticalSection(&port_state->lock);
result = port__ctl_op(port_state, op, sock, ev);
LeaveCriticalSection(&port_state->lock);
return result;
}
int port_register_socket(port_state_t* port_state,
sock_state_t* sock_state,
SOCKET socket) {
if (tree_add(&port_state->sock_tree,
sock_state_to_tree_node(sock_state),
socket) < 0)
return_set_error(-1, ERROR_ALREADY_EXISTS);
return 0;
}
void port_unregister_socket(port_state_t* port_state,
sock_state_t* sock_state) {
tree_del(&port_state->sock_tree, sock_state_to_tree_node(sock_state));
}
sock_state_t* port_find_socket(port_state_t* port_state, SOCKET socket) {
tree_node_t* tree_node = tree_find(&port_state->sock_tree, socket);
if (tree_node == NULL)
return_set_error(NULL, ERROR_NOT_FOUND);
return sock_state_from_tree_node(tree_node);
}
void port_request_socket_update(port_state_t* port_state,
sock_state_t* sock_state) {
if (queue_is_enqueued(sock_state_to_queue_node(sock_state)))
return;
queue_append(&port_state->sock_update_queue,
sock_state_to_queue_node(sock_state));
}
void port_cancel_socket_update(port_state_t* port_state,
sock_state_t* sock_state) {
unused_var(port_state);
if (!queue_is_enqueued(sock_state_to_queue_node(sock_state)))
return;
queue_remove(sock_state_to_queue_node(sock_state));
}
void port_add_deleted_socket(port_state_t* port_state,
sock_state_t* sock_state) {
if (queue_is_enqueued(sock_state_to_queue_node(sock_state)))
return;
queue_append(&port_state->sock_deleted_queue,
sock_state_to_queue_node(sock_state));
}
void port_remove_deleted_socket(port_state_t* port_state,
sock_state_t* sock_state) {
unused_var(port_state);
if (!queue_is_enqueued(sock_state_to_queue_node(sock_state)))
return;
queue_remove(sock_state_to_queue_node(sock_state));
}
HANDLE port_get_iocp_handle(port_state_t* port_state) {
assert(port_state->iocp_handle != NULL);
return port_state->iocp_handle;
}
queue_t* port_get_poll_group_queue(port_state_t* port_state) {
return &port_state->poll_group_queue;
}
port_state_t* port_state_from_handle_tree_node(ts_tree_node_t* tree_node) {
return container_of(tree_node, port_state_t, handle_tree_node);
}
ts_tree_node_t* port_state_to_handle_tree_node(port_state_t* port_state) {
return &port_state->handle_tree_node;
}
void queue_init(queue_t* queue) {
queue_node_init(&queue->head);
}
void queue_node_init(queue_node_t* node) {
node->prev = node;
node->next = node;
}
static inline void queue__detach_node(queue_node_t* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
queue_node_t* queue_first(const queue_t* queue) {
return !queue_is_empty(queue) ? queue->head.next : NULL;
}
queue_node_t* queue_last(const queue_t* queue) {
return !queue_is_empty(queue) ? queue->head.prev : NULL;
}
void queue_prepend(queue_t* queue, queue_node_t* node) {
node->next = queue->head.next;
node->prev = &queue->head;
node->next->prev = node;
queue->head.next = node;
}
void queue_append(queue_t* queue, queue_node_t* node) {
node->next = &queue->head;
node->prev = queue->head.prev;
node->prev->next = node;
queue->head.prev = node;
}
void queue_move_to_start(queue_t* queue, queue_node_t* node) {
queue__detach_node(node);
queue_prepend(queue, node);
}
void queue_move_to_end(queue_t* queue, queue_node_t* node) {
queue__detach_node(node);
queue_append(queue, node);
}
void queue_remove(queue_node_t* node) {
queue__detach_node(node);
queue_node_init(node);
}
bool queue_is_empty(const queue_t* queue) {
return !queue_is_enqueued(&queue->head);
}
bool queue_is_enqueued(const queue_node_t* node) {
return node->prev != node;
}
#define REFLOCK__REF ((long) 0x00000001UL)
#define REFLOCK__REF_MASK ((long) 0x0fffffffUL)
#define REFLOCK__DESTROY ((long) 0x10000000UL)
#define REFLOCK__DESTROY_MASK ((long) 0xf0000000UL)
#define REFLOCK__POISON ((long) 0x300dead0UL)
static HANDLE reflock__keyed_event = NULL;
int reflock_global_init(void) {
NTSTATUS status = NtCreateKeyedEvent(
&reflock__keyed_event, KEYEDEVENT_ALL_ACCESS, NULL, 0);
if (status != STATUS_SUCCESS)
return_set_error(-1, RtlNtStatusToDosError(status));
return 0;
}
void reflock_init(reflock_t* reflock) {
reflock->state = 0;
}
static void reflock__signal_event(void* address) {
NTSTATUS status =
NtReleaseKeyedEvent(reflock__keyed_event, address, FALSE, NULL);
if (status != STATUS_SUCCESS)
abort();
}
static void reflock__await_event(void* address) {
NTSTATUS status =
NtWaitForKeyedEvent(reflock__keyed_event, address, FALSE, NULL);
if (status != STATUS_SUCCESS)
abort();
}
void reflock_ref(reflock_t* reflock) {
long state = InterlockedAdd(&reflock->state, REFLOCK__REF);
/* Verify that the counter didn't overflow and the lock isn't destroyed. */
assert((state & REFLOCK__DESTROY_MASK) == 0);
unused_var(state);
}
void reflock_unref(reflock_t* reflock) {
long state = InterlockedAdd(&reflock->state, -REFLOCK__REF);
/* Verify that the lock was referenced and not already destroyed. */
assert((state & REFLOCK__DESTROY_MASK & ~REFLOCK__DESTROY) == 0);
if (state == REFLOCK__DESTROY)
reflock__signal_event(reflock);
}
void reflock_unref_and_destroy(reflock_t* reflock) {
long state =
InterlockedAdd(&reflock->state, REFLOCK__DESTROY - REFLOCK__REF);
long ref_count = state & REFLOCK__REF_MASK;
/* Verify that the lock was referenced and not already destroyed. */
assert((state & REFLOCK__DESTROY_MASK) == REFLOCK__DESTROY);
if (ref_count != 0)
reflock__await_event(reflock);
state = InterlockedExchange(&reflock->state, REFLOCK__POISON);
assert(state == REFLOCK__DESTROY);
}
#define SOCK__KNOWN_EPOLL_EVENTS \
(EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDNORM | \
EPOLLRDBAND | EPOLLWRNORM | EPOLLWRBAND | EPOLLMSG | EPOLLRDHUP)
typedef enum sock__poll_status {
SOCK__POLL_IDLE = 0,
SOCK__POLL_PENDING,
SOCK__POLL_CANCELLED
} sock__poll_status_t;
typedef struct sock_state {
IO_STATUS_BLOCK io_status_block;
AFD_POLL_INFO poll_info;
queue_node_t queue_node;
tree_node_t tree_node;
poll_group_t* poll_group;
SOCKET base_socket;
epoll_data_t user_data;
uint32_t user_events;
uint32_t pending_events;
sock__poll_status_t poll_status;
bool delete_pending;
} sock_state_t;
static inline sock_state_t* sock__alloc(void) {
sock_state_t* sock_state = malloc(sizeof *sock_state);
if (sock_state == NULL)
return_set_error(NULL, ERROR_NOT_ENOUGH_MEMORY);
return sock_state;
}
static inline void sock__free(sock_state_t* sock_state) {
assert(sock_state != NULL);
free(sock_state);
}
static inline int sock__cancel_poll(sock_state_t* sock_state) {
assert(sock_state->poll_status == SOCK__POLL_PENDING);
if (afd_cancel_poll(poll_group_get_afd_device_handle(sock_state->poll_group),
&sock_state->io_status_block) < 0)
return -1;
sock_state->poll_status = SOCK__POLL_CANCELLED;
sock_state->pending_events = 0;
return 0;
}
sock_state_t* sock_new(port_state_t* port_state, SOCKET socket) {
SOCKET base_socket;
poll_group_t* poll_group;
sock_state_t* sock_state;
if (socket == 0 || socket == INVALID_SOCKET)
return_set_error(NULL, ERROR_INVALID_HANDLE);
base_socket = ws_get_base_socket(socket);
if (base_socket == INVALID_SOCKET)
return NULL;
poll_group = poll_group_acquire(port_state);
if (poll_group == NULL)
return NULL;
sock_state = sock__alloc();
if (sock_state == NULL)
goto err1;
memset(sock_state, 0, sizeof *sock_state);
sock_state->base_socket = base_socket;
sock_state->poll_group = poll_group;
tree_node_init(&sock_state->tree_node);
queue_node_init(&sock_state->queue_node);
if (port_register_socket(port_state, sock_state, socket) < 0)
goto err2;
return sock_state;
err2:
sock__free(sock_state);
err1:
poll_group_release(poll_group);
return NULL;
}
static int sock__delete(port_state_t* port_state,
sock_state_t* sock_state,
bool force) {
if (!sock_state->delete_pending) {
if (sock_state->poll_status == SOCK__POLL_PENDING)
sock__cancel_poll(sock_state);
port_cancel_socket_update(port_state, sock_state);
port_unregister_socket(port_state, sock_state);
sock_state->delete_pending = true;
}
/* If the poll request still needs to complete, the sock_state object can't
* be free()d yet. `sock_feed_event()` or `port_close()` will take care
* of this later. */
if (force || sock_state->poll_status == SOCK__POLL_IDLE) {
/* Free the sock_state now. */
port_remove_deleted_socket(port_state, sock_state);
poll_group_release(sock_state->poll_group);
sock__free(sock_state);
} else {
/* Free the socket later. */
port_add_deleted_socket(port_state, sock_state);
}
return 0;
}
void sock_delete(port_state_t* port_state, sock_state_t* sock_state) {
sock__delete(port_state, sock_state, false);
}
void sock_force_delete(port_state_t* port_state, sock_state_t* sock_state) {
sock__delete(port_state, sock_state, true);
}
int sock_set_event(port_state_t* port_state,
sock_state_t* sock_state,
const struct epoll_event* ev) {
/* EPOLLERR and EPOLLHUP are always reported, even when not requested by the
* caller. However they are disabled after a event has been reported for a
* socket for which the EPOLLONESHOT flag was set. */
uint32_t events = ev->events | EPOLLERR | EPOLLHUP;
sock_state->user_events = events;
sock_state->user_data = ev->data;
if ((events & SOCK__KNOWN_EPOLL_EVENTS & ~sock_state->pending_events) != 0)
port_request_socket_update(port_state, sock_state);
return 0;
}
static inline DWORD sock__epoll_events_to_afd_events(uint32_t epoll_events) {
/* Always monitor for AFD_POLL_LOCAL_CLOSE, which is triggered when the
* socket is closed with closesocket() or CloseHandle(). */
DWORD afd_events = AFD_POLL_LOCAL_CLOSE;
if (epoll_events & (EPOLLIN | EPOLLRDNORM))
afd_events |= AFD_POLL_RECEIVE | AFD_POLL_ACCEPT;
if (epoll_events & (EPOLLPRI | EPOLLRDBAND))
afd_events |= AFD_POLL_RECEIVE_EXPEDITED;
if (epoll_events & (EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND))
afd_events |= AFD_POLL_SEND;
if (epoll_events & (EPOLLIN | EPOLLRDNORM | EPOLLRDHUP))
afd_events |= AFD_POLL_DISCONNECT;
if (epoll_events & EPOLLHUP)
afd_events |= AFD_POLL_ABORT;
if (epoll_events & EPOLLERR)
afd_events |= AFD_POLL_CONNECT_FAIL;
return afd_events;
}
static inline uint32_t sock__afd_events_to_epoll_events(DWORD afd_events) {
uint32_t epoll_events = 0;
if (afd_events & (AFD_POLL_RECEIVE | AFD_POLL_ACCEPT))
epoll_events |= EPOLLIN | EPOLLRDNORM;
if (afd_events & AFD_POLL_RECEIVE_EXPEDITED)
epoll_events |= EPOLLPRI | EPOLLRDBAND;
if (afd_events & AFD_POLL_SEND)
epoll_events |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
if (afd_events & AFD_POLL_DISCONNECT)
epoll_events |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
if (afd_events & AFD_POLL_ABORT)
epoll_events |= EPOLLHUP;
if (afd_events & AFD_POLL_CONNECT_FAIL)
/* Linux reports all these events after connect() has failed. */
epoll_events |=
EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLRDNORM | EPOLLWRNORM | EPOLLRDHUP;
return epoll_events;
}
int sock_update(port_state_t* port_state, sock_state_t* sock_state) {
assert(!sock_state->delete_pending);
if ((sock_state->poll_status == SOCK__POLL_PENDING) &&
(sock_state->user_events & SOCK__KNOWN_EPOLL_EVENTS &
~sock_state->pending_events) == 0) {
/* All the events the user is interested in are already being monitored by
* the pending poll operation. It might spuriously complete because of an
* event that we're no longer interested in; when that happens we'll submit
* a new poll operation with the updated event mask. */
} else if (sock_state->poll_status == SOCK__POLL_PENDING) {
/* A poll operation is already pending, but it's not monitoring for all the
* events that the user is interested in. Therefore, cancel the pending
* poll operation; when we receive it's completion package, a new poll
* operation will be submitted with the correct event mask. */
if (sock__cancel_poll(sock_state) < 0)
return -1;
} else if (sock_state->poll_status == SOCK__POLL_CANCELLED) {
/* The poll operation has already been cancelled, we're still waiting for
* it to return. For now, there's nothing that needs to be done. */
} else if (sock_state->poll_status == SOCK__POLL_IDLE) {
/* No poll operation is pending; start one. */
sock_state->poll_info.Exclusive = FALSE;
sock_state->poll_info.NumberOfHandles = 1;
sock_state->poll_info.Timeout.QuadPart = INT64_MAX;
sock_state->poll_info.Handles[0].Handle = (HANDLE) sock_state->base_socket;
sock_state->poll_info.Handles[0].Status = 0;
sock_state->poll_info.Handles[0].Events =
sock__epoll_events_to_afd_events(sock_state->user_events);
if (afd_poll(poll_group_get_afd_device_handle(sock_state->poll_group),
&sock_state->poll_info,
&sock_state->io_status_block) < 0) {
switch (GetLastError()) {
case ERROR_IO_PENDING:
/* Overlapped poll operation in progress; this is expected. */
break;
case ERROR_INVALID_HANDLE:
/* Socket closed; it'll be dropped from the epoll set. */
return sock__delete(port_state, sock_state, false);
default:
/* Other errors are propagated to the caller. */
return_map_error(-1);
}
}
/* The poll request was successfully submitted. */
sock_state->poll_status = SOCK__POLL_PENDING;
sock_state->pending_events = sock_state->user_events;
} else {
/* Unreachable. */
assert(false);
}
port_cancel_socket_update(port_state, sock_state);
return 0;
}
int sock_feed_event(port_state_t* port_state,
IO_STATUS_BLOCK* io_status_block,
struct epoll_event* ev) {
sock_state_t* sock_state =
container_of(io_status_block, sock_state_t, io_status_block);
AFD_POLL_INFO* poll_info = &sock_state->poll_info;
uint32_t epoll_events = 0;
sock_state->poll_status = SOCK__POLL_IDLE;
sock_state->pending_events = 0;
if (sock_state->delete_pending) {
/* Socket has been deleted earlier and can now be freed. */
return sock__delete(port_state, sock_state, false);
} else if (io_status_block->Status == STATUS_CANCELLED) {
/* The poll request was cancelled by CancelIoEx. */
} else if (!NT_SUCCESS(io_status_block->Status)) {
/* The overlapped request itself failed in an unexpected way. */
epoll_events = EPOLLERR;
} else if (poll_info->NumberOfHandles < 1) {
/* This poll operation succeeded but didn't report any socket events. */
} else if (poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) {
/* The poll operation reported that the socket was closed. */
return sock__delete(port_state, sock_state, false);
} else {
/* Events related to our socket were reported. */
epoll_events =
sock__afd_events_to_epoll_events(poll_info->Handles[0].Events);
}
/* Requeue the socket so a new poll request will be submitted. */
port_request_socket_update(port_state, sock_state);
/* Filter out events that the user didn't ask for. */
epoll_events &= sock_state->user_events;
/* Return if there are no epoll events to report. */
if (epoll_events == 0)
return 0;
/* If the the socket has the EPOLLONESHOT flag set, unmonitor all events,
* even EPOLLERR and EPOLLHUP. But always keep looking for closed sockets. */
if (sock_state->user_events & EPOLLONESHOT)
sock_state->user_events = 0;
ev->data = sock_state->user_data;
ev->events = epoll_events;
return 1;
}
sock_state_t* sock_state_from_queue_node(queue_node_t* queue_node) {
return container_of(queue_node, sock_state_t, queue_node);
}
queue_node_t* sock_state_to_queue_node(sock_state_t* sock_state) {
return &sock_state->queue_node;
}
sock_state_t* sock_state_from_tree_node(tree_node_t* tree_node) {
return container_of(tree_node, sock_state_t, tree_node);
}
tree_node_t* sock_state_to_tree_node(sock_state_t* sock_state) {
return &sock_state->tree_node;
}
void ts_tree_init(ts_tree_t* ts_tree) {
tree_init(&ts_tree->tree);
InitializeSRWLock(&ts_tree->lock);
}
void ts_tree_node_init(ts_tree_node_t* node) {
tree_node_init(&node->tree_node);
reflock_init(&node->reflock);
}
int ts_tree_add(ts_tree_t* ts_tree, ts_tree_node_t* node, uintptr_t key) {
int r;
AcquireSRWLockExclusive(&ts_tree->lock);
r = tree_add(&ts_tree->tree, &node->tree_node, key);
ReleaseSRWLockExclusive(&ts_tree->lock);
return r;
}
static inline ts_tree_node_t* ts_tree__find_node(ts_tree_t* ts_tree,
uintptr_t key) {
tree_node_t* tree_node = tree_find(&ts_tree->tree, key);
if (tree_node == NULL)
return NULL;
return container_of(tree_node, ts_tree_node_t, tree_node);
}
ts_tree_node_t* ts_tree_del_and_ref(ts_tree_t* ts_tree, uintptr_t key) {
ts_tree_node_t* ts_tree_node;
AcquireSRWLockExclusive(&ts_tree->lock);
ts_tree_node = ts_tree__find_node(ts_tree, key);
if (ts_tree_node != NULL) {
tree_del(&ts_tree->tree, &ts_tree_node->tree_node);
reflock_ref(&ts_tree_node->reflock);
}
ReleaseSRWLockExclusive(&ts_tree->lock);
return ts_tree_node;
}
ts_tree_node_t* ts_tree_find_and_ref(ts_tree_t* ts_tree, uintptr_t key) {
ts_tree_node_t* ts_tree_node;
AcquireSRWLockShared(&ts_tree->lock);
ts_tree_node = ts_tree__find_node(ts_tree, key);
if (ts_tree_node != NULL)
reflock_ref(&ts_tree_node->reflock);
ReleaseSRWLockShared(&ts_tree->lock);
return ts_tree_node;
}
void ts_tree_node_unref(ts_tree_node_t* node) {
reflock_unref(&node->reflock);
}
void ts_tree_node_unref_and_destroy(ts_tree_node_t* node) {
reflock_unref_and_destroy(&node->reflock);
}
void tree_init(tree_t* tree) {
memset(tree, 0, sizeof *tree);
}
void tree_node_init(tree_node_t* node) {
memset(node, 0, sizeof *node);
}
#define TREE__ROTATE(cis, trans) \
tree_node_t* p = node; \
tree_node_t* q = node->trans; \
tree_node_t* parent = p->parent; \
\
if (parent) { \
if (parent->left == p) \
parent->left = q; \
else \
parent->right = q; \
} else { \
tree->root = q; \
} \
\
q->parent = parent; \
p->parent = q; \
p->trans = q->cis; \
if (p->trans) \
p->trans->parent = p; \
q->cis = p;
static inline void tree__rotate_left(tree_t* tree, tree_node_t* node) {
TREE__ROTATE(left, right)
}
static inline void tree__rotate_right(tree_t* tree, tree_node_t* node) {
TREE__ROTATE(right, left)
}
#define TREE__INSERT_OR_DESCEND(side) \
if (parent->side) { \
parent = parent->side; \
} else { \
parent->side = node; \
break; \
}
#define TREE__REBALANCE_AFTER_INSERT(cis, trans) \
tree_node_t* grandparent = parent->parent; \
tree_node_t* uncle = grandparent->trans; \
\
if (uncle && uncle->red) { \
parent->red = uncle->red = false; \
grandparent->red = true; \
node = grandparent; \
} else { \
if (node == parent->trans) { \
tree__rotate_##cis(tree, parent); \
node = parent; \
parent = node->parent; \
} \
parent->red = false; \
grandparent->red = true; \
tree__rotate_##trans(tree, grandparent); \
}
int tree_add(tree_t* tree, tree_node_t* node, uintptr_t key) {
tree_node_t* parent;
parent = tree->root;
if (parent) {
for (;;) {
if (key < parent->key) {
TREE__INSERT_OR_DESCEND(left)
} else if (key > parent->key) {
TREE__INSERT_OR_DESCEND(right)
} else {
return -1;
}
}
} else {
tree->root = node;
}
node->key = key;
node->left = node->right = NULL;
node->parent = parent;
node->red = true;
for (; parent && parent->red; parent = node->parent) {
if (parent == parent->parent->left) {
TREE__REBALANCE_AFTER_INSERT(left, right)
} else {
TREE__REBALANCE_AFTER_INSERT(right, left)
}
}
tree->root->red = false;
return 0;
}
#define TREE__REBALANCE_AFTER_REMOVE(cis, trans) \
tree_node_t* sibling = parent->trans; \
\
if (sibling->red) { \
sibling->red = false; \
parent->red = true; \
tree__rotate_##cis(tree, parent); \
sibling = parent->trans; \
} \
if ((sibling->left && sibling->left->red) || \
(sibling->right && sibling->right->red)) { \
if (!sibling->trans || !sibling->trans->red) { \
sibling->cis->red = false; \
sibling->red = true; \
tree__rotate_##trans(tree, sibling); \
sibling = parent->trans; \
} \
sibling->red = parent->red; \
parent->red = sibling->trans->red = false; \
tree__rotate_##cis(tree, parent); \
node = tree->root; \
break; \
} \
sibling->red = true;
void tree_del(tree_t* tree, tree_node_t* node) {
tree_node_t* parent = node->parent;
tree_node_t* left = node->left;
tree_node_t* right = node->right;
tree_node_t* next;
bool red;
if (!left) {
next = right;
} else if (!right) {
next = left;
} else {
next = right;
while (next->left)
next = next->left;
}
if (parent) {
if (parent->left == node)
parent->left = next;
else
parent->right = next;
} else {
tree->root = next;
}
if (left && right) {
red = next->red;
next->red = node->red;
next->left = left;
left->parent = next;
if (next != right) {
parent = next->parent;
next->parent = node->parent;
node = next->right;
parent->left = node;
next->right = right;
right->parent = next;
} else {
next->parent = parent;
parent = next;
node = next->right;
}
} else {
red = node->red;
node = next;
}
if (node)
node->parent = parent;
if (red)
return;
if (node && node->red) {
node->red = false;
return;
}
do {
if (node == tree->root)
break;
if (node == parent->left) {
TREE__REBALANCE_AFTER_REMOVE(left, right)
} else {
TREE__REBALANCE_AFTER_REMOVE(right, left)
}
node = parent;
parent = parent->parent;
} while (!node->red);
if (node)
node->red = false;
}
tree_node_t* tree_find(const tree_t* tree, uintptr_t key) {
tree_node_t* node = tree->root;
while (node) {
if (key < node->key)
node = node->left;
else if (key > node->key)
node = node->right;
else
return node;
}
return NULL;
}
tree_node_t* tree_root(const tree_t* tree) {
return tree->root;
}
#ifndef SIO_BSP_HANDLE_POLL
#define SIO_BSP_HANDLE_POLL 0x4800001D
#endif
#ifndef SIO_BASE_HANDLE
#define SIO_BASE_HANDLE 0x48000022
#endif
int ws_global_init(void) {
int r;
WSADATA wsa_data;
r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
if (r != 0)
return_set_error(-1, (DWORD) r);
return 0;
}
static inline SOCKET ws__ioctl_get_bsp_socket(SOCKET socket, DWORD ioctl) {
SOCKET bsp_socket;
DWORD bytes;
if (WSAIoctl(socket,
ioctl,
NULL,
0,
&bsp_socket,
sizeof bsp_socket,
&bytes,
NULL,
NULL) != SOCKET_ERROR)
return bsp_socket;
else
return INVALID_SOCKET;
}
SOCKET ws_get_base_socket(SOCKET socket) {
SOCKET base_socket;
DWORD error;
for (;;) {
base_socket = ws__ioctl_get_bsp_socket(socket, SIO_BASE_HANDLE);
if (base_socket != INVALID_SOCKET)
return base_socket;
error = GetLastError();
if (error == WSAENOTSOCK)
return_set_error(INVALID_SOCKET, error);
/* Even though Microsoft documentation clearly states that LSPs should
* never intercept the `SIO_BASE_HANDLE` ioctl [1], Komodia based LSPs do
* so anyway, breaking it, with the apparent intention of preventing LSP
* bypass [2]. Fortunately they don't handle `SIO_BSP_HANDLE_POLL`, which
* will at least let us obtain the socket associated with the next winsock
* protocol chain entry. If this succeeds, loop around and call
* `SIO_BASE_HANDLE` again with the returned BSP socket, to make sure that
* we unwrap all layers and retrieve the actual base socket.
* [1] https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls
* [2] https://www.komodia.com/newwiki/index.php?title=Komodia%27s_Redirector_bug_fixes#Version_2.2.2.6
*/
base_socket = ws__ioctl_get_bsp_socket(socket, SIO_BSP_HANDLE_POLL);
if (base_socket != INVALID_SOCKET && base_socket != socket)
socket = base_socket;
else
return_set_error(INVALID_SOCKET, error);
}
}
================================================
FILE: 3rd/compat-mingw/wepoll.h
================================================
/*
* wepoll - epoll for Windows
* https://github.com/piscisaureus/wepoll
*
* Copyright 2012-2020, Bert Belder <bertbelder@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef WEPOLL_H_
#define WEPOLL_H_
#ifndef WEPOLL_EXPORT
#define WEPOLL_EXPORT
#endif
#include <stdint.h>
enum EPOLL_EVENTS {
EPOLLIN = (int) (1U << 0),
EPOLLPRI = (int) (1U << 1),
EPOLLOUT = (int) (1U << 2),
EPOLLERR = (int) (1U << 3),
EPOLLHUP = (int) (1U << 4),
EPOLLRDNORM = (int) (1U << 6),
EPOLLRDBAND = (int) (1U << 7),
EPOLLWRNORM = (int) (1U << 8),
EPOLLWRBAND = (int) (1U << 9),
EPOLLMSG = (int) (1U << 10), /* Never reported. */
EPOLLRDHUP = (int) (1U << 13),
EPOLLONESHOT = (int) (1U << 31)
};
#define EPOLLIN (1U << 0)
#define EPOLLPRI (1U << 1)
#define EPOLLOUT (1U << 2)
#define EPOLLERR (1U << 3)
#define EPOLLHUP (1U << 4)
#define EPOLLRDNORM (1U << 6)
#define EPOLLRDBAND (1U << 7)
#define EPOLLWRNORM (1U << 8)
#define EPOLLWRBAND (1U << 9)
#define EPOLLMSG (1U << 10)
#define EPOLLRDHUP (1U << 13)
#define EPOLLONESHOT (1U << 31)
#define EPOLL_CTL_ADD 1
#define EPOLL_CTL_MOD 2
#define EPOLL_CTL_DEL 3
typedef void* HANDLE;
typedef uintptr_t SOCKET;
typedef union epoll_data {
void* ptr;
int fd;
uint32_t u32;
uint64_t u64;
SOCKET sock; /* Windows specific */
HANDLE hnd; /* Windows specific */
} epoll_data_t;
struct epoll_event {
uint32_t events; /* Epoll events and flags */
epoll_data_t data; /* User data variable */
};
#ifdef __cplusplus
extern "C" {
#endif
WEPOLL_EXPORT HANDLE epoll_create(int size);
WEPOLL_EXPORT HANDLE epoll_create1(int flags);
WEPOLL_EXPORT int epoll_close(HANDLE ephnd);
WEPOLL_EXPORT int epoll_ctl(HANDLE ephnd,
int op,
SOCKET sock,
struct epoll_event* event);
WEPOLL_EXPORT int epoll_wait(HANDLE ephnd,
struct epoll_event* events,
int maxevents,
int timeout);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* WEPOLL_H_ */
================================================
FILE: 3rd/lpeg/HISTORY
================================================
HISTORY for LPeg 1.1.0
* Changes from version 1.0.2 to 1.1.0
---------------------------------
+ accumulator capture
+ UTF-8 ranges
+ Larger limit for number of rules in a grammar
+ Larger limit for number of captures in a match
+ bug fixes
+ other small improvements
* Changes from version 1.0.1 to 1.0.2
---------------------------------
+ some bugs fixed
* Changes from version 0.12 to 1.0.1
---------------------------------
+ group "names" can be any Lua value
+ some bugs fixed
+ other small improvements
* Changes from version 0.11 to 0.12
---------------------------------
+ no "unsigned short" limit for pattern sizes
+ mathtime captures considered nullable
+ some bugs fixed
* Changes from version 0.10 to 0.11
-------------------------------
+ complete reimplementation of the code generator
+ new syntax for table captures
+ new functions in module 're'
+ other small improvements
* Changes from version 0.9 to 0.10
-------------------------------
+ backtrack stack has configurable size
+ better error messages
+ Notation for non-terminals in 're' back to A instead o <A>
+ experimental look-behind pattern
+ support for external extensions
+ works with Lua 5.2
+ consumes less C stack
- "and" predicates do not keep captures
* Changes from version 0.8 to 0.9
-------------------------------
+ The accumulator capture was replaced by a fold capture;
programs that used the old 'lpeg.Ca' will need small changes.
+ Some support for character classes from old C locales.
+ A new named-group capture.
* Changes from version 0.7 to 0.8
-------------------------------
+ New "match-time" capture.
+ New "argument capture" that allows passing arguments into the pattern.
+ Better documentation for 're'.
+ Several small improvements for 're'.
+ The 're' module has an incompatibility with previous versions:
now, any use of a non-terminal must be enclosed in angle brackets
(like <B>).
* Changes from version 0.6 to 0.7
-------------------------------
+ Several improvements in module 're':
- better documentation;
- support for most captures (all but accumulator);
- limited repetitions p{n,m}.
+ Small improvements in efficiency.
+ Several small bugs corrected (special thanks to Hans Hagen
and Taco Hoekwater).
* Changes from version 0.5 to 0.6
-------------------------------
+ Support for non-numeric indices in grammars.
+ Some bug fixes (thanks to the luatex team).
+ Some new optimizations; (thanks to Mike Pall).
+ A new page layout (thanks to Andre Carregal).
+ Minimal documentation for module 're'.
* Changes from version 0.4 to 0.5
-------------------------------
+ Several optimizations.
+ lpeg.P now accepts booleans.
+ Some new examples.
+ A proper license.
+ Several small improvements.
* Changes from version 0.3 to 0.4
-------------------------------
+ Static check for loops in repetitions and grammars.
+ Removed label option in captures.
+ The implementation of captures uses less memory.
* Changes from version 0.2 to 0.3
-------------------------------
+ User-defined patterns in Lua.
+ Several new captures.
* Changes from version 0.1 to 0.2
-------------------------------
+ Several small corrections.
+ Handles embedded zeros like any other character.
+ Capture "name" can be any Lua value.
+ Unlimited number of captures.
+ Match gets an optional initial position.
(end of HISTORY)
================================================
FILE: 3rd/lpeg/README.md
================================================
# LPeg - Parsing Expression Grammars For Lua
For more information,
see [Lpeg](//www.inf.puc-rio.br/~roberto/lpeg/).
================================================
FILE: 3rd/lpeg/lpcap.c
================================================
#include "lua.h"
#include "lauxlib.h"
#include "lpcap.h"
#include "lpprint.h"
#include "lptypes.h"
#define getfromktable(cs,v) lua_rawgeti((cs)->L, ktableidx((cs)->ptop), v)
#define pushluaval(cs) getfromktable(cs, (cs)->cap->idx)
#define skipclose(cs,head) \
if (isopencap(head)) { assert(isclosecap(cs->cap)); cs->cap++; }
/*
** Return the size of capture 'cap'. If it is an open capture, 'close'
** must be its corresponding close.
*/
static Index_t capsize (Capture *cap, Capture *close) {
if (isopencap(cap)) {
assert(isclosecap(close));
return close->index - cap->index;
}
else
return cap->siz - 1;
}
static Index_t closesize (CapState *cs, Capture *head) {
return capsize(head, cs->cap);
}
/*
** Put at the cache for Lua values the value indexed by 'v' in ktable
** of the running pattern (if it is not there yet); returns its index.
*/
static int updatecache (CapState *cs, int v) {
int idx = cs->ptop + 1; /* stack index of cache for Lua values */
if (v != cs->valuecached) { /* not there? */
getfromktable(cs, v); /* get value from 'ktable' */
lua_replace(cs->L, idx); /* put it at reserved stack position */
cs->valuecached = v; /* keep track of what is there */
}
return idx;
}
static int pushcapture (CapState *cs);
/*
** Goes back in a list of captures looking for an open capture
** corresponding to a close one.
*/
static Capture *findopen (Capture *cap) {
int n = 0; /* number of closes waiting an open */
for (;;) {
cap--;
if (isclosecap(cap)) n++; /* one more open to skip */
else if (isopencap(cap))
if (n-- == 0) return cap;
}
}
/*
** Go to the next capture at the same level.
*/
static void nextcap (CapState *cs) {
Capture *cap = cs->cap;
if (isopencap(cap)) { /* must look for a close? */
int n = 0; /* number of opens waiting a close */
for (;;) { /* look for corresponding close */
cap++;
if (isopencap(cap)) n++;
else if (isclosecap(cap))
if (n-- == 0) break;
}
cs->cap = cap + 1; /* + 1 to skip last close */
}
else {
Capture *next;
for (next = cap + 1; capinside(cap, next); next++)
; /* skip captures inside current one */
cs->cap = next;
}
}
/*
** Push on the Lua stack all values generated by nested captures inside
** the current capture. Returns number of values pushed. 'addextra'
** makes it push the entire match after all captured values. The
** entire match is pushed also if there are no other nested values,
** so the function never returns zero.
*/
static int pushnestedvalues (CapState *cs, int addextra) {
Capture *head = cs->cap++; /* original capture */
int n = 0; /* number of pushed subvalues */
/* repeat for all nested patterns */
while (capinside(head, cs->cap))
n += pushcapture(cs);
if (addextra || n == 0) { /* need extra? */
lua_pushlstring(cs->L, cs->s + head->index, closesize(cs, head));
n++;
}
skipclose(cs, head);
return n;
}
/*
** Push only the first value generated by nested captures
*/
static void pushonenestedvalue (CapState *cs) {
int n = pushnestedvalues(cs, 0);
if (n > 1)
lua_pop(cs->L, n - 1); /* pop extra values */
}
/*
** Checks whether group 'grp' is visible to 'ref', that is, 'grp' is
** not nested inside a full capture that does not contain 'ref'. (We
** only need to care for full captures because the search at 'findback'
** skips open-end blocks; so, if 'grp' is nested in a non-full capture,
** 'ref' is also inside it.) To check this, we search backward for the
** inner full capture enclosing 'grp'. A full capture cannot contain
** non-full captures, so a close capture means we cannot be inside a
** full capture anymore.
*/
static int capvisible (CapState *cs, Capture *grp, Capture *ref) {
Capture *cap = grp;
int i = MAXLOP; /* maximum distance for an 'open' */
while (i-- > 0 && cap-- > cs->ocap) {
if (isclosecap(cap))
return 1; /* can stop the search */
else if (grp->index - cap->index >= UCHAR_MAX)
return 1; /* can stop the search */
else if (capinside(cap, grp)) /* is 'grp' inside cap? */
return capinside(cap, ref); /* ok iff cap also contains 'ref' */
}
return 1; /* 'grp' is not inside any capture */
}
/*
** Try to find a named group capture with the name given at the top of
** the stack; goes backward from 'ref'.
*/
static Capture *findback (CapState *cs, Capture *ref) {
lua_State *L = cs->L;
Capture *cap = ref;
while (cap-- > cs->ocap) { /* repeat until end of list */
if (isclosecap(cap))
cap = findopen(cap); /* skip nested captures */
else if (capinside(cap, ref))
continue; /* enclosing captures are not visible to 'ref' */
if (captype(cap) == Cgroup && capvisible(cs, cap, ref)) {
getfromktable(cs, cap->idx); /* get group name */
if (lp_equal(L, -2, -1)) { /* right group? */
lua_pop(L, 2); /* remove reference name and group name */
return cap;
}
else lua_pop(L, 1); /* remove group name */
}
}
luaL_error(L, "back reference '%s' not found", lua_tostring(L, -1));
return NULL; /* to avoid warnings */
}
/*
** Back-reference capture. Return number of values pushed.
*/
static int backrefcap (CapState *cs) {
int n;
Capture *curr = cs->cap;
pushluaval(cs); /* reference name */
cs->cap = findback(cs, curr); /* find corresponding group */
n = pushnestedvalues(cs, 0); /* push group's values */
cs->cap = curr + 1;
return n;
}
/*
** Table capture: creates a new table and populates it with nested
** captures.
*/
static int tablecap (CapState *cs) {
lua_State *L = cs->L;
Capture *head = cs->cap++;
int n = 0;
lua_newtable(L);
while (capinside(head, cs->cap)) {
if (captype(cs->cap) == Cgroup && cs->cap->idx != 0) { /* named group? */
pushluaval(cs); /* push group name */
pushonenestedvalue(cs);
lua_settable(L, -3);
}
else { /* not a named group */
int i;
int k = pushcapture(cs);
for (i = k; i > 0; i--) /* store all values into table */
lua_rawseti(L, -(i + 1), n + i);
n += k;
}
}
skipclose(cs, head);
return 1; /* number of values pushed (only the table) */
}
/*
** Table-query capture
*/
static int querycap (CapState *cs) {
int idx = cs->cap->idx;
pushonenestedvalue(cs); /* get nested capture */
lua_gettable(cs->L, updatecache(cs, idx)); /* query cap. value at table */
if (!lua_isnil(cs->L, -1))
return 1;
else { /* no value */
lua_pop(cs->L, 1); /* remove nil */
return 0;
}
}
/*
** Fold capture
*/
static int foldcap (CapState *cs) {
int n;
lua_State *L = cs->L;
Capture *head = cs->cap++;
int idx = head->idx;
if (isclosecap(cs->cap) || /* no nested captures (large subject)? */
(n = pushcapture(cs)) == 0) /* nested captures with no values? */
return luaL_error(L, "no initial value for fold capture");
if (n > 1)
lua_pop(L, n - 1); /* leave only one result for accumulator */
while (capinside(head, cs->cap)) {
lua_pushvalue(L, updatecache(cs, idx)); /* get folding function */
lua_insert(L, -2); /* put it before accumulator */
n = pushcapture(cs); /* get next capture's values */
lua_call(L, n + 1, 1); /* call folding function */
}
skipclose(cs, head);
return 1; /* only accumulator left on the stack */
}
/*
** Function capture
*/
static int functioncap (CapState *cs) {
int n;
int top = lua_gettop(cs->L);
pushluaval(cs); /* push function */
n = pushnestedvalues(cs, 0); /* push nested captures */
lua_call(cs->L, n, LUA_MULTRET); /* call function */
return lua_gettop(cs->L) - top; /* return function's results */
}
/*
** Accumulator capture
*/
static int accumulatorcap (CapState *cs) {
lua_State *L = cs->L;
int n;
if (lua_gettop(L) < cs->firstcap)
luaL_error(L, "no previous value for accumulator capture");
pushluaval(cs); /* push function */
lua_insert(L, -2); /* previous value becomes first argument */
n = pushnestedvalues(cs, 0); /* push nested captures */
lua_call(L, n + 1, 1); /* call function */
return 0; /* did not add any extra value */
}
/*
** Select capture
*/
static int numcap (CapState *cs) {
int idx = cs->cap->idx; /* value to select */
if (idx == 0) { /* no values? */
nextcap(cs); /* skip entire capture */
return 0; /* no value produced */
}
else {
int n = pushnestedvalues(cs, 0);
if (n < idx) /* invalid index? */
return luaL_error(cs->L, "no capture '%d'", idx);
else {
lua_pushvalue(cs->L, -(n - idx + 1)); /* get selected capture */
lua_replace(cs->L, -(n + 1)); /* put it in place of 1st capture */
lua_pop(cs->L, n - 1); /* remove other captures */
return 1;
}
}
}
/*
** Return the stack index of the first runtime capture in the given
** list of captures (or zero if no runtime captures)
*/
int finddyncap (Capture *cap, Capture *last) {
for (; cap < last; cap++) {
if (cap->kind == Cruntime)
return cap->idx; /* stack position of first capture */
}
return 0; /* no dynamic captures in this segment */
}
/*
** Calls a runtime capture. Returns number of captures "removed" by the
** call, that is, those inside the group capture. Captures to be added
** are on the Lua stack.
*/
int runtimecap (CapState *cs, Capture *close, const char *s, int *rem) {
int n, id;
lua_State *L = cs->L;
int otop = lua_gettop(L);
Capture *open = findopen(close); /* get open group capture */
assert(captype(open) == Cgroup);
id = finddyncap(open, close); /* get first dynamic capture argument */
close->kind = Cclose; /* closes the group */
close->index = s - cs->s;
cs->cap = open; cs->valuecached = 0; /* prepare capture state */
luaL_checkstack(L, 4, "too many runtime captures");
pushluaval(cs); /* push function to be called */
lua_pushvalue(L, SUBJIDX); /* push original subject */
lua_pushinteger(L, s - cs->s + 1); /* push current position */
n = pushnestedvalues(cs, 0); /* push nested captures */
lua_call(L, n + 2, LUA_MULTRET); /* call dynamic function */
if (id > 0) { /* are there old dynamic captures to be removed? */
int i;
for (i = id; i <= otop; i++)
lua_remove(L, id); /* remove old dynamic captures */
*rem = otop - id + 1; /* total number of dynamic captures removed */
}
else
*rem = 0; /* no dynamic captures removed */
return close - open - 1; /* number of captures to be removed */
}
/*
** Auxiliary structure for substitution and string captures: keep
** information about nested captures for future use, avoiding to push
** string results into Lua
*/
typedef struct StrAux {
int isstring; /* whether capture is a string */
union {
Capture *cp; /* if not a string, respective capture */
struct { /* if it is a string... */
Index_t idx; /* starts here */
Index_t siz; /* with this size */
} s;
} u;
} StrAux;
#define MAXSTRCAPS 10
/*
** Collect values from current capture into array 'cps'. Current
** capture must be Cstring (first call) or Csimple (recursive calls).
** (In first call, fills %0 with whole match for Cstring.)
** Returns number of elements in the array that were filled.
*/
static int getstrcaps (CapState *cs, StrAux *cps, int n) {
int k = n++;
Capture *head = cs->cap++;
cps[k].isstring = 1; /* get string value */
cps[k].u.s.idx = head->index; /* starts here */
while (capinside(head, cs->cap)) {
if (n >= MAXSTRCAPS) /* too many captures? */
nextcap(cs); /* skip extra captures (will not need them) */
else if (captype(cs->cap) == Csimple) /* string? */
n = getstrcaps(cs, cps, n); /* put info. into array */
else {
cps[n].isstring = 0; /* not a string */
cps[n].u.cp = cs->cap; /* keep original capture */
nextcap(cs);
n++;
}
}
cps[k].u.s.siz = closesize(cs, head);
skipclose(cs, head);
return n;
}
/*
** add next capture value (which should be a string) to buffer 'b'
*/
static int addonestring (luaL_Buffer *b, CapState *cs, const char *what);
/*
** String capture: add result to buffer 'b' (instead of pushing
** it into the stack)
*/
static void stringcap (luaL_Buffer *b, CapState *cs) {
StrAux cps[MAXSTRCAPS];
int n;
size_t len, i;
const char *fmt; /* format string */
fmt = lua_tolstring(cs->L, updatecache(cs, cs->cap->idx), &len);
n = getstrcaps(cs, cps, 0) - 1; /* collect nested captures */
for (i = 0; i < len; i++) { /* traverse format string */
if (fmt[i] != '%') /* not an escape? */
luaL_addchar(b, fmt[i]); /* add it to buffer */
else if (fmt[++i] < '0' || fmt[i] > '9') /* not followed by a digit? */
luaL_addchar(b, fmt[i]); /* add to buffer */
else {
int l = fmt[i] - '0'; /* capture index */
if (l > n)
luaL_error(cs->L, "invalid capture index (%d)", l);
else if (cps[l].isstring)
luaL_addlstring(b, cs->s + cps[l].u.s.idx, cps[l].u.s.siz);
else {
Capture *curr = cs->cap;
cs->cap = cps[l].u.cp; /* go back to evaluate that nested capture */
if (!addonestring(b, cs, "capture"))
luaL_error(cs->L, "no values in capture index %d", l);
cs->cap = curr; /* continue from where it stopped */
}
}
}
}
/*
** Substitution capture: add result to buffer 'b'
*/
static void substcap (luaL_Buffer *b, CapState *cs) {
const char *curr = cs->s + cs->cap->index;
Capture *head = cs->cap++;
while (capinside(head, cs->cap)) {
Capture *cap = cs->cap;
const char *caps = cs->s + cap->index;
luaL_addlstring(b, curr, caps - curr); /* add text up to capture */
if (addonestring(b, cs, "replacement"))
curr = caps + capsize(cap, cs->cap - 1); /* continue after match */
else /* no capture value */
curr = caps; /* keep original text in final result */
}
/* add last piece of text */
luaL_addlstring(b, curr, cs->s + head->index + closesize(cs, head) - curr);
skipclose(cs, head);
}
/*
** Evaluates a capture and adds its first value to buffer 'b'; returns
** whether there was a value
*/
static int addonestring (luaL_Buffer *b, CapState *cs, const char *what) {
switch (captype(cs->cap)) {
case Cstring:
stringcap(b, cs); /* add capture directly to buffer */
return 1;
case Csubst:
substcap(b, cs); /* add capture directly to buffer */
return 1;
case Cacc: /* accumulator capture? */
return luaL_error(cs->L, "invalid context for an accumulator capture");
default: {
lua_State *L = cs->L;
int n = pushcapture(cs);
if (n > 0) {
if (n > 1) lua_pop(L, n - 1); /* only one result */
if (!lua_isstring(L, -1))
return luaL_error(L, "invalid %s value (a %s)",
what, luaL_typename(L, -1));
luaL_addvalue(b);
}
return n;
}
}
}
#if !defined(MAXRECLEVEL)
#define MAXRECLEVEL 200
#endif
/*
** Push all values of the current capture into the stack; returns
** number of values pushed
*/
static int pushcapture (CapState *cs) {
lua_State *L = cs->L;
int res;
luaL_checkstack(L, 4, "too many captures");
if (cs->reclevel++ > MAXRECLEVEL)
return luaL_error(L, "subcapture nesting too deep");
switch (captype(cs->cap)) {
case Cposition: {
lua_pushinteger(L, cs->cap->index + 1);
cs->cap++;
res = 1;
break;
}
case Cconst: {
pushluaval(cs);
cs->cap++;
res = 1;
break;
}
case Carg: {
int arg = (cs->cap++)->idx;
if (arg + FIXEDARGS > cs->ptop)
return luaL_error(L, "reference to absent extra argument #%d", arg);
lua_pushvalue(L, arg + FIXEDARGS);
res = 1;
break;
}
case Csimple: {
int k = pushnestedvalues(cs, 1);
lua_insert(L, -k); /* make whole match be first result */
res = k;
break;
}
case Cruntime: {
lua_pushvalue(L, (cs->cap++)->idx); /* value is in the stack */
res = 1;
break;
}
case Cstring: {
luaL_Buffer b;
luaL_buffinit(L, &b);
stringcap(&b, cs);
luaL_pushresult(&b);
res = 1;
break;
}
case Csubst: {
luaL_Buffer b;
luaL_buffinit(L, &b);
substcap(&b, cs);
luaL_pushresult(&b);
res = 1;
break;
}
case Cgroup: {
if (cs->cap->idx == 0) /* anonymous group? */
res = pushnestedvalues(cs, 0); /* add all nested values */
else { /* named group: add no values */
nextcap(cs); /* skip capture */
res = 0;
}
break;
}
case Cbackref: res = backrefcap(cs); break;
case Ctable: res = tablecap(cs); break;
case Cfunction: res = functioncap(cs); break;
case Cacc: res = accumulatorcap(cs); break;
case Cnum: res = numcap(cs); break;
case Cquery: res = querycap(cs); break;
case Cfold: res = foldcap(cs); break;
default: assert(0); res = 0;
}
cs->reclevel--;
return res;
}
/*
** Prepare a CapState structure and traverse the entire list of
** captures in the stack pushing its results. 's' is the subject
** string, 'r' is the final position of the match, and 'ptop'
** the index in the stack where some useful values were pushed.
** Returns the number of results pushed. (If the list produces no
** results, push the final position of the match.)
*/
int getcaptures (lua_State *L, const char *s, const char *r, int ptop) {
Capture *capture = (Capture *)lua_touserdata(L, caplistidx(ptop));
int n = 0;
/* printcaplist(capture); */
if (!isclosecap(capture)) { /* is there any capture? */
CapState cs;
cs.ocap = cs.cap = capture; cs.L = L; cs.reclevel = 0;
cs.s = s; cs.valuecached = 0; cs.ptop = ptop;
cs.firstcap = lua_gettop(L) + 1; /* where first value (if any) will go */
do { /* collect their values */
n += pushcapture(&cs);
} while (!isclosecap(cs.cap));
assert(lua_gettop(L) - cs.firstcap == n - 1);
}
if (n == 0) { /* no capture values? */
lua_pushinteger(L, r - s + 1); /* return only end position */
n = 1;
}
return n;
}
================================================
FILE: 3rd/lpeg/lpcap.h
================================================
#if !defined(lpcap_h)
#define lpcap_h
#include "lptypes.h"
/* kinds of captures */
typedef enum CapKind {
Cclose, /* not used in trees */
Cposition,
Cconst, /* ktable[key] is Lua constant */
Cbackref, /* ktable[key] is "name" of group to get capture */
Carg, /* 'key' is arg's number */
Csimple, /* next node is pattern */
Ctable, /* next node is pattern */
Cfunction, /* ktable[key] is function; next node is pattern */
Cacc, /* ktable[key] is function; next node is pattern */
Cquery, /* ktable[key] is table; next node is pattern */
Cstring, /* ktable[key] is string; next node is pattern */
Cnum, /* numbered capture; 'key' is number of value to return */
Csubst, /* substitution capture; next node is pattern */
Cfold, /* ktable[key] is function; next node is pattern */
Cruntime, /* not used in trees (is uses another type for tree) */
Cgroup /* ktable[key] is group's "name" */
} CapKind;
/*
** An unsigned integer large enough to index any subject entirely.
** It can be size_t, but that will double the size of the array
** of captures in a 64-bit machine.
*/
#if !defined(Index_t)
typedef uint Index_t;
#endif
#define MAXINDT (~(Index_t)0)
typedef struct Capture {
Index_t index; /* subject position */
unsigned short idx; /* extra info (group name, arg index, etc.) */
byte kind; /* kind of capture */
byte siz; /* size of full capture + 1 (0 = not a full capture) */
} Capture;
typedef struct CapState {
Capture *cap; /* current capture */
Capture *ocap; /* (original) capture list */
lua_State *L;
int ptop; /* stack index of last argument to 'match' */
int firstcap; /* stack index of first capture pushed in the stack */
const char *s; /* original string */
int valuecached; /* value stored in cache slot */
int reclevel; /* recursion level */
} CapState;
#define captype(cap) ((cap)->kind)
#define isclosecap(cap) (captype(cap) == Cclose)
#define isopencap(cap) ((cap)->siz == 0)
/* true if c2 is (any number of levels) inside c1 */
#define capinside(c1,c2) \
(isopencap(c1) ? !isclosecap(c2) \
: (c2)->index < (c1)->index + (c1)->siz - 1)
/**
** Maximum number of captures to visit when looking for an 'open'.
*/
#define MAXLOP 20
int runtimecap (CapState *cs, Capture *close, const char *s, int *rem);
int getcaptures (lua_State *L, const char *s, const char *r, int ptop);
int finddyncap (Capture *cap, Capture *last);
#endif
================================================
FILE: 3rd/lpeg/lpcode.c
================================================
#include <limits.h>
#include "lua.h"
#include "lauxlib.h"
#include "lptypes.h"
#include "lpcode.h"
#include "lpcset.h"
/* signals a "no-instruction */
#define NOINST -1
static const Charset fullset_ =
{{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
static const Charset *fullset = &fullset_;
/*
** {======================================================
** Analysis and some optimizations
** =======================================================
*/
/*
** A few basic operations on Charsets
*/
static void cs_complement (Charset *cs) {
loopset(i, cs->cs[i] = ~cs->cs[i]);
}
static int cs_disjoint (const Charset *cs1, const Charset *cs2) {
loopset(i, if ((cs1->cs[i] & cs2->cs[i]) != 0) return 0;)
return 1;
}
/*
** Visit a TCall node taking care to stop recursion. If node not yet
** visited, return 'f(sib2(tree))', otherwise return 'def' (default
** value)
*/
static int callrecursive (TTree *tree, int f (TTree *t), int def) {
int key = tree->key;
assert(tree->tag == TCall);
assert(sib2(tree)->tag == TRule);
if (key == 0) /* node already visited? */
return def; /* return default value */
else { /* first visit */
int result;
tree->key = 0; /* mark call as already visited */
result = f(sib2(tree)); /* go to called rule */
tree->key = key; /* restore tree */
return result;
}
}
/*
** Check whether a pattern tree has captures
*/
int hascaptures (TTree *tree) {
tailcall:
switch (tree->tag) {
case TCapture: case TRunTime:
return 1;
case TCall:
return callrecursive(tree, hascaptures, 0);
case TRule: /* do not follow siblings */
tree = sib1(tree); goto tailcall;
case TOpenCall: assert(0);
default: {
switch (numsiblings[tree->tag]) {
case 1: /* return hascaptures(sib1(tree)); */
tree = sib1(tree); goto tailcall;
case 2:
if (hascaptures(sib1(tree)))
return 1;
/* else return hascaptures(sib2(tree)); */
tree = sib2(tree); goto tailcall;
default: assert(numsiblings[tree->tag] == 0); return 0;
}
}
}
}
/*
** Checks how a pattern behaves regarding the empty string,
** in one of two different ways:
** A pattern is *nullable* if it can match without consuming any character;
** A pattern is *nofail* if it never fails for any string
** (including the empty string).
** The difference is only for predicates and run-time captures;
** for other patterns, the two properties are equivalent.
** (With predicates, &'a' is nullable but not nofail. Of course,
** nofail => nullable.)
** These functions are all convervative in the following way:
** p is nullable => nullable(p)
** nofail(p) => p cannot fail
** The function assumes that TOpenCall is not nullable;
** this will be checked again when the grammar is fixed.
** Run-time captures can do whatever they want, so the result
** is conservative.
*/
int checkaux (TTree *tree, int pred) {
tailcall:
switch (tree->tag) {
case TChar: case TSet: case TAny: case TUTFR:
case TFalse: case TOpenCall:
return 0; /* not nullable */
case TRep: case TTrue:
return 1; /* no fail */
case TNot: case TBehind: /* can match empty, but can fail */
if (pred == PEnofail) return 0;
else return 1; /* PEnullable */
case TAnd: /* can match empty; fail iff body does */
if (pred == PEnullable) return 1;
/* else return checkaux(sib1(tree), pred); */
tree = sib1(tree); goto tailcall;
case TRunTime: /* can fail; match empty iff body does */
if (pred == PEnofail) return 0;
/* else return checkaux(sib1(tree), pred); */
tree = sib1(tree); goto tailcall;
case TSeq:
if (!checkaux(sib1(tree), pred)) return 0;
/* else return checkaux(sib2(tree), pred); */
tree = sib2(tree); goto tailcall;
case TChoice:
if (checkaux(sib2(tree), pred)) return 1;
/* else return checkaux(sib1(tree), pred); */
tree = sib1(tree); goto tailcall;
case TCapture: case TGrammar: case TRule: case TXInfo:
/* return checkaux(sib1(tree), pred); */
tree = sib1(tree); goto tailcall;
case TCall: /* return checkaux(sib2(tree), pred); */
tree = sib2(tree); goto tailcall;
default: assert(0); return 0;
}
}
/*
** number of characters to match a pattern (or -1 if variable)
*/
int fixedlen (TTree *tree) {
int len = 0; /* to accumulate in tail calls */
tailcall:
switch (tree->tag) {
case TChar: case TSet: case TAny:
return len + 1;
case TUTFR:
return (tree->cap == sib1(tree)->cap) ? len + tree->cap : -1;
case TFalse: case TTrue: case TNot: case TAnd: case TBehind:
return len;
case TRep: case TRunTime: case TOpenCall:
return -1;
case TCapture: case TRule: case TGrammar: case TXInfo:
/* return fixedlen(sib1(tree)); */
tree = sib1(tree); goto tailcall;
case TCall: {
int n1 = callrecursive(tree, fixedlen, -1);
if (n1 < 0)
return -1;
else
return len + n1;
}
case TSeq: {
int n1 = fixedlen(sib1(tree));
if (n1 < 0)
return -1;
/* else return fixedlen(sib2(tree)) + len; */
len += n1; tree = sib2(tree); goto tailcall;
}
case TChoice: {
int n1 = fixedlen(sib1(tree));
int n2 = fixedlen(sib2(tree));
if (n1 != n2 || n1 < 0)
return -1;
else
return len + n1;
}
default: assert(0); return 0;
};
}
/*
** Computes the 'first set' of a pattern.
** The result is a conservative aproximation:
** match p ax -> x (for some x) ==> a belongs to first(p)
** or
** a not in first(p) ==> match p ax -> fail (for all x)
**
** The set 'follow' is the first set of what follows the
** pattern (full set if nothing follows it).
**
** The function returns 0 when this resulting set can be used for
** test instructions that avoid the pattern altogether.
** A non-zero return can happen for two reasons:
** 1) match p '' -> '' ==> return has bit 1 set
** (tests cannot be used because they would always fail for an empty input);
** 2) there is a match-time capture ==> return has bit 2 set
** (optimizations should not bypass match-time captures).
*/
static int getfirst (TTree *tree, const Charset *follow, Charset *firstset) {
tailcall:
switch (tree->tag) {
case TChar: case TSet: case TAny: case TFalse: {
tocharset(tree, firstset);
return 0;
}
case TUTFR: {
int c;
clearset(firstset->cs); /* erase all chars */
for (c = tree->key; c <= sib1(tree)->key; c++)
setchar(firstset->cs, c);
return 0;
}
case TTrue: {
loopset(i, firstset->cs[i] = follow->cs[i]);
return 1; /* accepts the empty string */
}
case TChoice: {
Charset csaux;
int e1 = getfirst(sib1(tree), follow, firstset);
int e2 = getfirst(sib2(tree), follow, &csaux);
loopset(i, firstset->cs[i] |= csaux.cs[i]);
return e1 | e2;
}
case TSeq: {
if (!nullable(sib1(tree))) {
/* when p1 is not nullable, p2 has nothing to contribute;
return getfirst(sib1(tree), fullset, firstset); */
tree = sib1(tree); follow = fullset; goto tailcall;
}
else { /* FIRST(p1 p2, fl) = FIRST(p1, FIRST(p2, fl)) */
Charset csaux;
int e2 = getfirst(sib2(tree), follow, &csaux);
int e1 = getfirst(sib1(tree), &csaux, firstset);
if (e1 == 0) return 0; /* 'e1' ensures that first can be used */
else if ((e1 | e2) & 2) /* one of the children has a matchtime? */
return 2; /* pattern has a matchtime capture */
else return e2; /* else depends on 'e2' */
}
}
case TRep: {
getfirst(sib1(tree), follow, firstset);
loopset(i, firstset->cs[i] |= follow->cs[i]);
return 1; /* accept the empty string */
}
case TCapture: case TGrammar: case TRule: case TXInfo: {
/* return getfirst(sib1(tree), follow, firstset); */
tree = sib1(tree); goto tailcall;
}
case TRunTime: { /* function invalidates any follow info. */
int e = getfirst(sib1(tree), fullset, firstset);
if (e) return 2; /* function is not "protected"? */
else return 0; /* pattern inside capture ensures first can be used */
}
case TCall: {
/* return getfirst(sib2(tree), follow, firstset); */
tree = sib2(tree); goto tailcall;
}
case TAnd: {
int e = getfirst(sib1(tree), follow, firstset);
loopset(i, firstset->cs[i] &= follow->cs[i]);
return e;
}
case TNot: {
if (tocharset(sib1(tree), firstset)) {
cs_complement(firstset);
return 1;
} /* else */
} /* FALLTHROUGH */
case TBehind: { /* instruction gives no new information */
/* call 'getfirst' only to check for math-time captures */
int e = getfirst(sib1(tree), follow, firstset);
loopset(i, firstset->cs[i] = follow->cs[i]); /* uses follow */
return e | 1; /* always can accept the empty string */
}
default: assert(0); return 0;
}
}
/*
** If 'headfail(tree)' true, then 'tree' can fail only depending on the
** next character of the subject.
*/
static int headfail (TTree *tree) {
tailcall:
switch (tree->tag) {
case TChar: case TSet: case TAny: case TFalse:
return 1;
case TTrue: case TRep: case TRunTime: case TNot:
case TBehind: case TUTFR:
return 0;
case TCapture: case TGrammar: case TRule: case TXInfo: case TAnd:
tree = sib1(tree); goto tailcall; /* return headfail(sib1(tree)); */
case TCall:
tree = sib2(tree); goto tailcall; /* return headfail(sib2(tree)); */
case TSeq:
if (!nofail(sib2(tree))) return 0;
/* else return headfail(sib1(tree)); */
tree = sib1(tree); goto tailcall;
case TChoice:
if (!headfail(sib1(tree))) return 0;
/* else return headfail(sib2(tree)); */
tree = sib2(tree); goto tailcall;
default: assert(0); return 0;
}
}
/*
** Check whether the code generation for the given tree can benefit
** from a follow set (to avoid computing the follow set when it is
** not needed)
*/
static int needfollow (TTree *tree) {
tailcall:
switch (tree->tag) {
case TChar: case TSet: case TAny: case TUTFR:
case TFalse: case TTrue: case TAnd: case TNot:
case TRunTime: case TGrammar: case TCall: case TBehind:
return 0;
case TChoice: case TRep:
return 1;
case TCapture:
tree = sib1(tree); goto tailcall;
case TSeq:
tree = sib2(tree); goto tailcall;
default: assert(0); return 0;
}
}
/* }====================================================== */
/*
** {======================================================
** Code generation
** =======================================================
*/
/*
** size of an instruction
*/
int sizei (const Instruction *i) {
switch((Opcode)i->i.code) {
case ISet: case ISpan: return 1 + i->i.aux2.set.size;
case ITestSet: return 2 + i->i.aux2.set.size;
case ITestChar: case ITestAny: case IChoice: case IJmp: case ICall:
case IOpenCall: case ICommit: case IPartialCommit: case IBackCommit:
case IUTFR:
return 2;
default: return 1;
}
}
/*
** state for the compiler
*/
typedef struct CompileState {
Pattern *p; /* pattern being compiled */
int ncode; /* next position in p->code to be filled */
lua_State *L;
} CompileState;
/*
** code generation is recursive; 'opt' indicates that the code is being
** generated as the last thing inside an optional pattern (so, if that
** code is optional too, it can reuse the 'IChoice' already in place for
** the outer pattern). 'tt' points to a previous test protecting this
** code (or NOINST). 'fl' is the follow set of the pattern.
*/
static void codegen (CompileState *compst, TTree *tree, int opt, int tt,
const Charset *fl);
static void finishrelcode (lua_State *L, Pattern *p, Instruction *block,
int size) {
if (block == NULL)
luaL_error(L, "not enough memory");
block->codesize = size;
p->code = (Instruction *)block + 1;
}
/*
** Initialize array 'p->code'
*/
static void newcode (lua_State *L, Pattern *p, int size) {
void *ud;
Instruction *block;
lua_Alloc f = lua_getallocf(L, &ud);
size++; /* slot for 'codesize' */
block = (Instruction*) f(ud, NULL, 0, size * sizeof(Instruction));
finishrelcode(L, p, block, size);
}
void freecode (lua_State *L, Pattern *p) {
if (p->code != NULL) {
void *ud;
lua_Alloc f = lua_getallocf(L, &ud);
uint osize = p->code[-1].codesize;
f(ud, p->code - 1, osize * sizeof(Instruction), 0); /* free block */
}
}
/*
** Assume that 'nsize' is not zero and that 'p->code' already exists.
*/
static void realloccode (lua_State *L, Pattern *p, int nsize) {
void *ud;
lua_Alloc f = lua_getallocf(L, &ud);
Instruction *block = p->code - 1;
uint osize = block->codesize;
nsize++; /* add the 'codesize' slot to size */
block = (Instruction*) f(ud, block, osize * sizeof(Instruction),
nsize * sizeof(Instruction));
finishrelcode(L, p, block, nsize);
}
/*
** Add space for an instruction with 'n' slots and return its index.
*/
static int nextinstruction (CompileState *compst, int n) {
int size = compst->p->code[-1].codesize - 1;
int ncode = compst->ncode;
if (ncode > size - n) {
uint nsize = size + (size >> 1) + n;
if (nsize >= INT_MAX)
luaL_error(compst->L, "pattern code too large");
realloccode(compst->L, compst->p, nsize);
}
compst->ncode = ncode + n;
return ncode;
}
#define getinstr(cs,i) ((cs)->p->code[i])
static int addinstruction (CompileState *compst, Opcode op, int aux) {
int i = nextinstruction(compst, 1);
getinstr(compst, i).i.code = op;
getinstr(compst, i).i.aux1 = aux;
return i;
}
/*
** Add an instruction followed by space for an offset (to be set later)
*/
static int addoffsetinst (CompileState *compst, Opcode op) {
int i = addinstruction(compst, op, 0); /* instruction */
addinstruction(compst, (Opcode)0, 0); /* open space for offset */
assert(op == ITestSet || sizei(&getinstr(compst, i)) == 2);
return i;
}
/*
** Set the offset of an instruction
*/
static void setoffset (CompileState *compst, int instruction, int offset) {
getinstr(compst, instruction + 1).offset = offset;
}
static void codeutfr (CompileState *compst, TTree *tree) {
int i = addoffsetinst(compst, IUTFR);
int to = sib1(tree)->u.n;
assert(sib1(tree)->tag == TXInfo);
getinstr(compst, i + 1).offset = tree->u.n;
getinstr(compst, i).i.aux1 = to & 0xff;
getinstr(compst, i).i.aux2.key = to >> 8;
}
/*
** Add a capture instruction:
** 'op' is the capture instruction; 'cap' the capture kind;
** 'key' the key into ktable; 'aux' is the optional capture offset
**
*/
static int addinstcap (CompileState *compst, Opcode op, int cap, int key,
int aux) {
int i = addinstruction(compst, op, joinkindoff(cap, aux));
getinstr(compst, i).i.aux2.key = key;
return i;
}
#define gethere(compst) ((compst)->ncode)
#define target(code,i) ((i) + code[i + 1].offset)
/*
** Patch 'instruction' to jump to 'target'
*/
static void jumptothere (CompileState *compst, int instruction, int target) {
if (instruction >= 0)
setoffset(compst, instruction, target - instruction);
}
/*
** Patch 'instruction' to jump to current position
*/
static void jumptohere (CompileState *compst, int instruction) {
jumptothere(compst, instruction, gethere(compst));
}
/*
** Code an IChar instruction, or IAny if there is an equivalent
** test dominating it
*/
static void codechar (CompileState *compst, int c, int tt) {
if (tt >= 0 && getinstr(compst, tt).i.code == ITestChar &&
getinstr(compst, tt).i.aux1 == c)
addinstruction(compst, IAny, 0);
else
addinstruction(compst, IChar, c);
}
/*
** Add a charset posfix to an instruction.
*/
static void addcharset (CompileState *compst, int inst, charsetinfo *info) {
int p;
Instruction *I = &getinstr(compst, inst);
byte *charset;
int isize = instsize(info->size); /* size in instructions */
int i;
I->i.aux2.set.offset = info->offset * 8; /* offset in bits */
I->i.aux2.set.size = isize;
I->i.aux1 = info->deflt;
p = nextinstruction(compst, isize); /* space for charset */
charset = getinstr(compst, p).buff; /* charset buffer */
for (i = 0; i < isize * (int)sizeof(Instruction); i++)
charset[i] = getbytefromcharset(info, i); /* copy the buffer */
}
/*
** Check whether charset 'info' is dominated by instruction 'p'
*/
static int cs_equal (Instruction *p, charsetinfo *info) {
if (p->i.code != ITestSet)
return 0;
else if (p->i.aux2.set.offset != info->offset * 8 ||
p->i.aux2.set.size != instsize(info->size) ||
p->i.aux1 != info->deflt)
return 0;
else {
int i;
for (i = 0; i < instsize(info->size) * (int)sizeof(Instruction); i++) {
if ((p + 2)->buff[i] != getbytefromcharset(info, i))
return 0;
}
}
return 1;
}
/*
** Code a char set, using IAny when instruction is dominated by an
** equivalent test.
*/
static void codecharset (CompileState *compst, TTree *tree, int tt) {
charsetinfo info;
tree2cset(tree, &info);
if (tt >= 0 && cs_equal(&getinstr(compst, tt), &info))
addinstruction(compst, IAny, 0);
else {
int i = addinstruction(compst, ISet, 0);
addcharset(compst, i, &info);
}
}
/*
** Code a test set, optimizing unit sets for ITestChar, "complete"
** sets for ITestAny, and empty sets for IJmp (always fails).
** 'e' is true iff test should accept the empty string. (Test
** instructions in the current VM never accept the empty string.)
*/
static int codetestset (CompileState *compst, Charset *cs, int e) {
if (e) return NOINST; /* no test */
else {
charsetinfo info;
Opcode op = charsettype(cs->cs, &info);
switch (op) {
case IFail: return addoffsetinst(compst, IJmp); /* always jump */
case IAny: return addoffsetinst(compst, ITestAny);
case IChar: {
int i = addoffsetinst(compst, ITestChar);
getinstr(compst, i).i.aux1 = info.offset;
return i;
}
default: { /* regular set */
int i = addoffsetinst(compst, ITestSet);
addcharset(compst, i, &info);
assert(op == ISet);
return i;
}
}
}
}
/*
** Find the final destination of a sequence of jumps
*/
static int finaltarget (Instruction *code, int i) {
while (code[i].i.code == IJmp)
i = target(code, i);
return i;
}
/*
** final label (after traversing any jumps)
*/
static int finallabel (Instruction *code, int i) {
return finaltarget(code, target(code, i));
}
/*
** <behind(p)> == behind n; <p> (where n = fixedlen(p))
*/
static void codebehind (CompileState *compst, TTree *tree) {
if (tree->u.n > 0)
addinstruction(compst, IBehind, tree->u.n);
codegen(compst, sib1(tree), 0, NOINST, fullset);
}
/*
** Choice; optimizations:
** - when p1 is headfail or when first(p1) and first(p2) are disjoint,
** than a character not in first(p1) cannot go to p1 and a character
** in first(p1) cannot go to p2, either because p1 will accept
** (headfail) or because it is not in first(p2) (disjoint).
** (The second case is not valid if p1 accepts the empty string,
** as then there is no character at all...)
** - when p2 is empty and opt is true; a IPartialCommit can reuse
** the Choice already active in the stack.
*/
static void codechoice (CompileState *compst, TTree *p1, TTree *p2, int opt,
const Charset *fl) {
int emptyp2 = (p2->tag == TTrue);
Charset cs1, cs2;
int e1 = getfirst(p1, fullset, &cs1);
if (headfail(p1) ||
(!e1 && (getfirst(p2, fl, &cs2), cs_disjoint(&cs1, &cs2)))) {
/* <p1 / p2> == test (fail(p1)) -> L1 ; p1 ; jmp L2; L1: p2; L2: */
int test = codetestset(compst, &cs1, 0);
int jmp = NOINST;
codegen(compst, p1, 0, test, fl);
if (!emptyp2)
jmp = addoffsetinst(compst, IJmp);
jumptohere(compst, test);
codegen(compst, p2, opt, NOINST, fl);
jumptohere(compst, jmp);
}
else if (opt && emptyp2) {
/* p1? == IPartialCommit; p1 */
jumptohere(compst, addoffsetinst(compst, IPartialCommit));
codegen(compst, p1, 1, NOINST, fullset);
}
else {
/* <p1 / p2> ==
test(first(p1)) -> L1; choice L1; <p1>; commit L2; L1: <p2>; L2: */
int pcommit;
int test = codetestset(compst, &cs1, e1);
int pchoice = addoffsetinst(compst, IChoice);
codegen(compst, p1, emptyp2, test, fullset);
pcommit = addoffsetinst(compst, ICommit);
jumptohere(compst, pchoice);
jumptohere(compst, test);
codegen(compst, p2, opt, NOINST, fl);
jumptohere(compst, pcommit);
}
}
/*
** And predicate
** optimization: fixedlen(p) = n ==> <&p> == <p>; behind n
** (valid only when 'p' has no captures)
*/
static void codeand (CompileState *compst, TTree *tree, int tt) {
int n = fixedlen(tree);
if (n >= 0 && n <= MAXBEHIND && !hascaptures(tree)) {
codegen(compst, tree, 0, tt, fullset);
if (n > 0)
addinstruction(compst, IBehind, n);
}
else { /* default: Choice L1; p1; BackCommit L2; L1: Fail; L2: */
int pcommit;
int pchoice = addoffsetinst(compst, IChoice);
codegen(compst, tree, 0, tt, fullset);
pcommit = addoffsetinst(compst, IBackCommit);
jumptohere(compst, pchoice);
addinstruction(compst, IFail, 0);
jumptohere(compst, pcommit);
}
}
/*
** Captures: if pattern has fixed (and not too big) length, and it
** has no nested captures, use a single IFullCapture instruction
** after the match; otherwise, enclose the pattern with OpenCapture -
** CloseCapture.
*/
static void codecapture (CompileState *compst, TTree *tree, int tt,
const Charset *fl) {
int len = fixedlen(sib1(tree));
if (len >= 0 && len <= MAXOFF && !hascaptures(sib1(tree))) {
codegen(compst, sib1(tree), 0, tt, fl);
addinstcap(compst, IFullCapture, tree->cap, tree->key, len);
}
else {
addinstcap(compst, IOpenCapture, tree->cap, tree->key, 0);
codegen(compst, sib1(tree), 0, tt, fl);
addinstcap(compst, ICloseCapture, Cclose, 0, 0);
}
}
static void coderuntime (CompileState *compst, TTree *tree, int tt) {
addinstcap(compst, IOpenCapture, Cgroup, tree->key, 0);
codegen(compst, sib1(tree), 0, tt, fullset);
addinstcap(compst, ICloseRunTime, Cclose, 0, 0);
}
/*
** Create a jump to 'test' and fix 'test' to jump to next instruction
*/
static void closeloop (CompileState *compst, int test) {
int jmp = addoffsetinst(compst, IJmp);
jumptohere(compst, test);
jumptothere(compst, jmp, test);
}
/*
** Try repetition of charsets:
** For an empty set, repetition of fail is a no-op;
** For any or char, code a tight loop;
** For generic charset, use a span instruction.
*/
static int coderepcharset (CompileState *compst, TTree *tree) {
switch (tree->tag) {
case TFalse: return 1; /* 'fail*' is a no-op */
case TAny: { /* L1: testany -> L2; any; jmp L1; L2: */
int test = addoffsetinst(compst, ITestAny);
addinstruction(compst, IAny, 0);
closeloop(compst, test);
return 1;
}
case TChar: { /* L1: testchar c -> L2; any; jmp L1; L2: */
int test = addoffsetinst(compst, ITestChar);
getinstr(compst, test).i.aux1 = tree->u.n;
addinstruction(compst, IAny, 0);
closeloop(compst, test);
return 1;
}
case TSet: { /* regular set */
charsetinfo info;
int i = addinstruction(compst, ISpan, 0);
tree2cset(tree, &info);
addcharset(compst, i, &info);
return 1;
}
default: return 0; /* not a charset */
}
}
/*
** Repetion; optimizations:
** When pattern is a charset, use special code.
** When pattern is head fail, or if it starts with characters that
** are disjoint from what follows the repetions, a simple test
** is enough (a fail inside the repetition would backtrack to fail
** again in the following pattern, so there is no need for a choice).
** When 'opt' is true, the repetion can reuse the Choice already
** active in the stack.
*/
static void coderep (CompileState *compst, TTree *tree, int opt,
const Charset *fl) {
if (!coderepcharset(compst, tree)) {
Charset st;
int e1 = getfirst(tree, fullset, &st);
if (headfail(tree) || (!e1 && cs_disjoint(&st, fl))) {
/* L1: test (fail(p1)) -> L2; <p>; jmp L1; L2: */
int test = codetestset(compst, &st, 0);
codegen(compst, tree, 0, test, fullset);
closeloop(compst, test);
}
else {
/* test(fail(p1)) -> L2; choice L2; L1: <p>; partialcommit L1; L2: */
/* or (if 'opt'): partialcommit L1; L1: <p>; partialcommit L1; */
int commit, l2;
int test = codetestset(compst, &st, e1);
int pchoice = NOINST;
if (opt)
jumptohere(compst, addoffsetinst(compst, IPartialCommit));
else
pchoice = addoffsetinst(compst, IChoice);
l2 = gethere(compst);
codegen(compst, tree, 0, NOINST, fullset);
commit = addoffsetinst(compst, IPartialCommit);
jumptothere(compst, commit, l2);
jumptohere(compst, pchoice);
jumptohere(compst, test);
}
}
}
/*
** Not predicate; optimizations:
** In any case, if first test fails, 'not' succeeds, so it can jump to
** the end. If pattern is headfail, that is all (it cannot fail
** in other parts); this case includes 'not' of simple sets. Otherwise,
** use the default code (a choice plus a failtwice).
*/
static void codenot (CompileState *compst, TTree *tree) {
Charset st;
int e = getfirst(tree, fullset, &st);
int test = codetestset(compst, &st, e);
if (headfail(tree)) /* test (fail(p1)) -> L1; fail; L1: */
addinstruction(compst, IFail, 0);
else {
/* test(fail(p))-> L1; choice L1; <p>; failtwice; L1: */
int pchoice = addoffsetinst(compst, IChoice);
codegen(compst, tree, 0, NOINST, fullset);
addinstruction(compst, IFailTwice, 0);
jumptohere(compst, pchoice);
}
jumptohere(compst, test);
}
/*
** change open calls to calls, using list 'positions' to find
** correct offsets; also optimize tail calls
*/
static void correctcalls (CompileState *compst, int *positions,
int from, int to) {
int i;
Instruction *code = compst->p->code;
for (i = from; i < to; i += sizei(&code[i])) {
if (code[i].i.code == IOpenCall) {
int n = code[i].i.aux2.key; /* rule number */
int rule = positions[n]; /* rule position */
assert(rule == from || code[rule - 1].i.code == IRet);
if (code[finaltarget(code, i + 2)].i.code == IRet) /* call; ret ? */
code[i].i.code = IJmp; /* tail call */
else
code[i].i.code = ICall;
jumptothere(compst, i, rule); /* call jumps to respective rule */
}
}
assert(i == to);
}
/*
** Code for a grammar:
** call L1; jmp L2; L1: rule 1; ret; rule 2; ret; ...; L2:
*/
static void codegrammar (CompileState *compst, TTree *grammar) {
int positions[MAXRULES];
int rulenumber = 0;
TTree *rule;
int firstcall = addoffsetinst(compst, ICall); /* call initial rule */
int jumptoend = addoffsetinst(compst, IJmp); /* jump to the end */
int start = gethere(compst); /* here starts the initial rule */
jumptohere(compst, firstcall);
for (rule = sib1(grammar); rule->tag == TRule; rule = sib2(rule)) {
TTree *r = sib1(rule);
assert(r->tag == TXInfo);
positions[rulenumber++] = gethere(compst); /* save rule position */
codegen(compst, sib1(r), 0, NOINST, fullset); /* code rule */
addinstruction(compst, IRet, 0);
}
assert(rule->tag == TTrue);
jumptohere(compst, jumptoend);
correctcalls(compst, positions, start, gethere(compst));
}
static void codecall (CompileState *compst, TTree *call) {
int c = addoffsetinst(compst, IOpenCall); /* to be corrected later */
assert(sib1(sib2(call))->tag == TXInfo);
getinstr(compst, c).i.aux2.key = sib1(sib2(call))->u.n; /* rule number */
}
/*
** Code first child of a sequence
** (second child is called in-place to allow tail call)
** Return 'tt' for second child
*/
static int codeseq1 (CompileState *compst, TTree *p1, TTree *p2,
int tt, const Charset *fl) {
if (needfollow(p1)) {
Charset fl1;
getfirst(p2, fl, &fl1); /* p1 follow is p2 first */
codegen(compst, p1, 0, tt, &fl1);
}
else /* use 'fullset' as follow */
codegen(compst, p1, 0, tt, fullset);
if (fixedlen(p1) != 0) /* can 'p1' consume anything? */
return NOINST; /* invalidate test */
else return tt; /* else 'tt' still protects sib2 */
}
/*
** Main code-generation function: dispatch to auxiliar functions
** according to kind of tree. ('needfollow' should return true
** only for consructions that use 'fl'.)
*/
static void codegen (CompileState *compst, TTree *tree, int opt, int tt,
const Charset *fl) {
tailcall:
switch (tree->tag) {
case TChar: codechar(compst, tree->u.n, tt); break;
case TAny: addinstruction(compst, IAny, 0); break;
case TSet: codecharset(compst, tree, tt); break;
case TTrue: break;
case TFalse: addinstruction(compst, IFail, 0); break;
case TUTFR: codeutfr(compst, tree); break;
case TChoice: codechoice(compst, sib1(tree), sib2(tree), opt, fl); break;
case TRep: coderep(compst, sib1(tree), opt, fl); break;
case TBehind: codebehind(compst, tree); break;
case TNot: codenot(compst, sib1(tree)); break;
case TAnd: codeand(compst, sib1(tree), tt); break;
case TCapture: codecapture(compst, tree, tt, fl); break;
case TRunTime: coderuntime(compst, tree, tt); break;
case TGrammar: codegrammar(compst, tree); break;
case TCall: codecall(compst, tree); break;
case TSeq: {
tt = codeseq1(compst, sib1(tree), sib2(tree), tt, fl); /* code 'p1' */
/* codegen(compst, p2, opt, tt, fl); */
tree = sib2(tree); goto tailcall;
}
default: assert(0);
}
}
/*
** Optimize jumps and other jump-like instructions.
** * Update labels of instructions with labels to their final
** destinations (e.g., choice L1; ... L1: jmp L2: becomes
** choice L2)
** * Jumps to other instructions that do jumps become those
** instructions (e.g., jump to return becomes a return; jump
** to commit becomes a commit)
*/
static void peephole (CompileState *compst) {
Instruction *code = compst->p->code;
int i;
for (i = 0; i < compst->ncode; i += sizei(&code[i])) {
redo:
switch (code[i].i.code) {
case IChoice: case ICall: case ICommit: case IPartialCommit:
case IBackCommit: case ITestChar: case ITestSet:
case ITestAny: { /* instructions with labels */
jumptothere(compst, i, finallabel(code, i)); /* optimize label */
break;
}
case IJmp: {
int ft = finaltarget(code, i);
switch (code[ft].i.code) { /* jumping to what? */
case IRet: case IFail: case IFailTwice:
case IEnd: { /* instructions with unconditional implicit jumps */
code[i] = code[ft]; /* jump becomes that instruction */
code[i + 1].i.code = IEmpty; /* 'no-op' for target position */
break;
}
case ICommit: case IPartialCommit:
case IBackCommit: { /* inst. with unconditional explicit jumps */
int fft = finallabel(code, ft);
code[i] = code[ft]; /* jump becomes that instruction... */
jumptothere(compst, i, fft); /* but must correct its offset */
goto redo; /* reoptimize its label */
}
default: {
jumptothere(compst, i, ft); /* optimize label */
break;
}
}
break;
}
default: break;
}
}
assert(code[i - 1].i.code == IEnd);
}
/*
** Compile a pattern. 'size' is the size of the pattern's tree,
** which gives a hint for the size of the final code.
*/
Instruction *compile (lua_State *L, Pattern *p, uint size) {
CompileState compst;
compst.p = p; compst.ncode = 0; compst.L = L;
newcode(L, p, size/2u + 2); /* set initial size */
codegen(&compst, p->tree, 0, NOINST, fullset);
addinstruction(&compst, IEnd, 0);
realloccode(L, p, compst.ncode); /* set final size */
peephole(&compst);
return p->code;
}
/* }====================================================== */
================================================
FILE: 3rd/lpeg/lpcode.h
================================================
#if !defined(lpcode_h)
#define lpcode_h
#include "lua.h"
#include "lptypes.h"
#include "lptree.h"
#include "lpvm.h"
int checkaux (TTree *tree, int pred);
int fixedlen (TTree *tree);
int hascaptures (TTree *tree);
int lp_gc (lua_State *L);
Instruction *compile (lua_State *L, Pattern *p, uint size);
void freecode (lua_State *L, Pattern *p);
int sizei (const Instruction *i);
#define PEnullable 0
#define PEnofail 1
/*
** nofail(t) implies that 't' cannot fail with any input
*/
#define nofail(t) checkaux(t, PEnofail)
/*
** (not nullable(t)) implies 't' cannot match without consuming
** something
*/
#define nullable(t) checkaux(t, PEnullable)
#endif
================================================
FILE: 3rd/lpeg/lpcset.c
================================================
#include "lptypes.h"
#include "lpcset.h"
/*
** Add to 'c' the index of the (only) bit set in byte 'b'
*/
static int onlybit (int c, int b) {
if ((b & 0xF0) != 0) { c += 4; b >>= 4; }
if ((b & 0x0C) != 0) { c += 2; b >>= 2; }
if ((b & 0x02) != 0) { c += 1; }
return c;
}
/*
** Check whether a charset is empty (returns IFail), singleton (IChar),
** full (IAny), or none of those (ISet). When singleton, 'info.offset'
** returns which character it is. When generic set, 'info' returns
** information about its range.
*/
Opcode charsettype (const byte *cs, charsetinfo *info) {
int low0, low1, high0, high1;
for (low1 = 0; low1 < CHARSETSIZE && cs[low1] == 0; low1++)
/* find lowest byte with a 1-bit */;
if (low1 == CHARSETSIZE)
return IFail; /* no characters in set */
for (high1 = CHARSETSIZE - 1; cs[high1] == 0; high1--)
/* find highest byte with a 1-bit; low1 is a sentinel */;
if (low1 == high1) { /* only one byte with 1-bits? */
int b = cs[low1];
if ((b & (b - 1)) == 0) { /* does byte has only one 1-bit? */
info->offset = onlybit(low1 * BITSPERCHAR, b); /* get that bit */
return IChar; /* single character */
}
}
for (low0 = 0; low0 < CHARSETSIZE && cs[low0] == 0xFF; low0++)
/* find lowest byte with a 0-bit */;
if (low0 == CHARSETSIZE)
return IAny; /* set has all bits set */
for (high0 = CHARSETSIZE - 1; cs[high0] == 0xFF; high0--)
/* find highest byte with a 0-bit; low0 is a sentinel */;
if (high1 - low1 <= high0 - low0) { /* range of 1s smaller than of 0s? */
info->offset = low1;
info->size = high1 - low1 + 1;
info->deflt = 0; /* all discharged bits were 0 */
}
else {
info->offset = low0;
info->size = high0 - low0 + 1;
info->deflt = 0xFF; /* all discharged bits were 1 */
}
info->cs = cs + info->offset;
return ISet;
}
/*
** Get a byte from a compact charset. If index is inside the charset
** range, get the byte from the supporting charset (correcting it
** by the offset). Otherwise, return the default for the set.
*/
byte getbytefromcharset (const charsetinfo *info, int index) {
if (index < info->size)
return info->cs[index];
else return info->deflt;
}
/*
** If 'tree' is a 'char' pattern (TSet, TChar, TAny, TFalse), convert it
** into a charset and return 1; else return 0.
*/
int tocharset (TTree *tree, Charset *cs) {
switch (tree->tag) {
case TChar: { /* only one char */
assert(0 <= tree->u.n && tree->u.n <= UCHAR_MAX);
clearset(cs->cs); /* erase all chars */
setchar(cs->cs, tree->u.n); /* add that one */
return 1;
}
case TAny: {
fillset(cs->cs, 0xFF); /* add all characters to the set */
return 1;
}
case TFalse: {
clearset(cs->cs); /* empty set */
return 1;
}
case TSet: { /* fill set */
int i;
fillset(cs->cs, tree->u.set.deflt);
for (i = 0; i < tree->u.set.size; i++)
cs->cs[tree->u.set.offset + i] = treebuffer(tree)[i];
return 1;
}
default: return 0;
}
}
void tree2cset (TTree *tree, charsetinfo *info) {
assert(tree->tag == TSet);
info->offset = tree->u.set.offset;
info->size = tree->u.set.size;
info->deflt = tree->u.set.deflt;
info->cs = treebuffer(tree);
}
================================================
FILE: 3rd/lpeg/lpcset.h
================================================
#if !defined(lpset_h)
#define lpset_h
#include "lpcset.h"
#include "lpcode.h"
#include "lptree.h"
/*
** Extra information for the result of 'charsettype'. When result is
** IChar, 'offset' is the character. When result is ISet, 'cs' is the
** supporting bit array (with offset included), 'offset' is the offset
** (in bytes), 'size' is the size (in bytes), and 'delt' is the default
** value for bytes outside the set.
*/
typedef struct {
const byte *cs;
int offset;
int size;
int deflt;
} charsetinfo;
int tocharset (TTree *tree, Charset *cs);
Opcode charsettype (const byte *cs, charsetinfo *info);
byte getbytefromcharset (const charsetinfo *info, int index);
void tree2cset (TTree *tree, charsetinfo *info);
#endif
================================================
FILE: 3rd/lpeg/lpeg.html
================================================
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"//www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="//www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>LPeg - Parsing Expression Grammars For Lua</title>
<link rel="stylesheet"
href="//www.inf.puc-rio.br/~roberto/lpeg/doc.css"
type="text/css"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo">
<a href="//www.inf.puc-rio.br/~roberto/lpeg/">
<img alt="LPeg logo" src="lpeg-128.gif"/></a>
</div>
<div id="product_name"><big><strong>LPeg</strong></big></div>
<div id="product_description">
Parsing Expression Grammars For Lua, version 1.1
</div>
</div> <!-- id="product" -->
<div id="main">
<div id="navigation">
<h1>LPeg</h1>
<ul>
<li><strong>Home</strong>
<ul>
<li><a href="#intro">Introduction</a></li>
<li><a href="#func">Functions</a></li>
<li><a href="#basic">Basic Constructions</a></li>
<li><a href="#grammar">Grammars</a></li>
<li><a href="#captures">Captures</a></li>
<li><a href="#ex">Some Examples</a></li>
<li><a href="re.html">The <code>re</code> Module</a></li>
<li><a href="#download">Download</a></li>
<li><a href="#license">License</a></li>
</ul>
</li>
</ul>
</div> <!-- id="navigation" -->
<div id="content">
<h2><a name="intro">Introduction</a></h2>
<p>
<em>LPeg</em> is a new pattern-matching library for Lua,
based on
<a href="//bford.info/packrat/">
Parsing Expression Grammars</a> (PEGs).
This text is a reference manual for the library.
For a more formal treatment of LPeg,
as well as some discussion about its implementation,
see
<a href="//www.inf.puc-rio.br/~roberto/docs/peg.pdf">
A Text Pattern-Matching Tool based on Parsing Expression Grammars</a>.
(You may also be interested in my
<a href="//vimeo.com/1485123">talk about LPeg</a>
given at the III Lua Workshop.)
</p>
<p>
Following the Snobol tradition,
LPeg defines patterns as first-class objects.
That is, patterns are regular Lua values
(represented by userdata).
The library offers several functions to create
and compose patterns.
With the use of metamethods,
several of these functions are provided as infix or prefix
operators.
On the one hand,
the result is usually much more verbose than the typical
encoding of patterns using the so called
<em>regular expressions</em>
(which typically are not regular expressions in the formal sense).
On the other hand,
first-class patterns allow much better documentation
(as it is easy to comment the code,
to break complex definitions in smaller parts, etc.)
and are extensible,
as we can define new functions to create and compose patterns.
</p>
<p>
For a quick glance of the library,
the following table summarizes its basic operations
for creating patterns:
</p>
<table border="1">
<tbody><tr><td><b>Operator</b></td><td><b>Description</b></td></tr>
<tr><td><a href="#op-p"><code>lpeg.P(string)</code></a></td>
<td>Matches <code>string</code> literally</td></tr>
<tr><td><a href="#op-p"><code>lpeg.P(n)</code></a></td>
<td>Matches exactly <code>n</code> characters</td></tr>
<tr><td><a href="#op-s"><code>lpeg.S(string)</code></a></td>
<td>Matches any character in <code>string</code> (Set)</td></tr>
<tr><td><a href="#op-r"><code>lpeg.R("<em>xy</em>")</code></a></td>
<td>Matches any character between <em>x</em> and <em>y</em> (Range)</td></tr>
<tr><td><a href="#op-utfR"><code>lpeg.utfR(cp1, cp2)</code></a></td>
<td>Matches an UTF-8 code point between <code>cp1</code> and
<code>cp2</code></td></tr>
<tr><td><a href="#op-pow"><code>patt^n</code></a></td>
<td>Matches at least <code>n</code> repetitions of <code>patt</code></td></tr>
<tr><td><a href="#op-pow"><code>patt^-n</code></a></td>
<td>Matches at most <code>n</code> repetitions of <code>patt</code></td></tr>
<tr><td><a href="#op-mul"><code>patt1 * patt2</code></a></td>
<td>Matches <code>patt1</code> followed by <code>patt2</code></td></tr>
<tr><td><a href="#op-add"><code>patt1 + patt2</code></a></td>
<td>Matches <code>patt1</code> or <code>patt2</code>
(ordered choice)</td></tr>
<tr><td><a href="#op-sub"><code>patt1 - patt2</code></a></td>
<td>Matches <code>patt1</code> if <code>patt2</code> does not match</td></tr>
<tr><td><a href="#op-unm"><code>-patt</code></a></td>
<td>Equivalent to <code>("" - patt)</code></td></tr>
<tr><td><a href="#op-len"><code>#patt</code></a></td>
<td>Matches <code>patt</code> but consumes no input</td></tr>
<tr><td><a href="#op-behind"><code>lpeg.B(patt)</code></a></td>
<td>Matches <code>patt</code> behind the current position,
consuming no input</td></tr>
</tbody></table>
<p>As a very simple example,
<code>lpeg.R("09")^1</code> creates a pattern that
matches a non-empty sequence of digits.
As a not so simple example,
<code>-lpeg.P(1)</code>
(which can be written as <code>lpeg.P(-1)</code>,
or simply <code>-1</code> for operations expecting a pattern)
matches an empty string only if it cannot match a single character;
so, it succeeds only at the end of the subject.
</p>
<p>
LPeg also offers the <a href="re.html"><code>re</code> module</a>,
which implements patterns following a regular-expression style
(e.g., <code>[09]+</code>).
(This module is 270 lines of Lua code,
and of course it uses LPeg to parse regular expressions and
translate them to regular LPeg patterns.)
</p>
<h2><a name="func">Functions</a></h2>
<h3><a name="f-match"></a><code>lpeg.match (pattern, subject [, init])</code></h3>
<p>
The matching function.
It attempts to match the given pattern against the subject string.
If the match succeeds,
returns the index in the subject of the first character after the match,
or the <a href="#captures">captured values</a>
(if the pattern captured any value).
</p>
<p>
An optional numeric argument <code>init</code> makes the match
start at that position in the subject string.
As in the Lua standard libraries,
a negative value counts from the end.
</p>
<p>
Unlike typical pattern-matching functions,
<code>match</code> works only in <em>anchored</em> mode;
that is, it tries to match the pattern with a prefix of
the given subject string (at position <code>init</code>),
not with an arbitrary substring of the subject.
So, if we want to find a pattern anywhere in a string,
we must either write a loop in Lua or write a pattern that
matches anywhere.
This second approach is easy and quite efficient;
see <a href="#ex">examples</a>.
</p>
<h3><a name="f-type"></a><code>lpeg.type (value)</code></h3>
<p>
If the given value is a pattern,
returns the string <code>"pattern"</code>.
Otherwise returns nil.
</p>
<h3><a name="f-version"></a><code>lpeg.version</code></h3>
<p>
A string (not a function) with the running version of LPeg.
</p>
<h3><a name="f-setstack"></a><code>lpeg.setmaxstack (max)</code></h3>
<p>
Sets a limit for the size of the backtrack stack used by LPeg to
track calls and choices.
(The default limit is 400.)
Most well-written patterns need little backtrack levels and
therefore you seldom need to change this limit;
before changing it you should try to rewrite your
pattern to avoid the need for extra space.
Nevertheless, a few useful patterns may overflow.
Also, with recursive grammars,
subjects with deep recursion may also need larger limits.
</p>
<h2><a name="basic">Basic Constructions</a></h2>
<p>
The following operations build patterns.
All operations that expect a pattern as an argument
may receive also strings, tables, numbers, booleans, or functions,
which are translated to patterns according to
the rules of function <a href="#op-p"><code>lpeg.P</code></a>.
</p>
<h3><a name="op-p"></a><code>lpeg.P (value)</code></h3>
<p>
Converts the given value into a proper pattern,
according to the following rules:
</p>
<ul>
<li><p>
If the argument is a pattern,
it is returned unmodified.
</p></li>
<li><p>
If the argument is a string,
it is translated to a pattern that matches the string literally.
</p></li>
<li><p>
If the argument is a non-negative number <em>n</em>,
the result is a pattern that matches exactly <em>n</em> characters.
</p></li>
<li><p>
If the argument is a negative number <em>-n</em>,
the result is a pattern that
succeeds only if the input string has less than <em>n</em> characters left:
<code>lpeg.P(-n)</code>
is equivalent to <code>-lpeg.P(n)</code>
(see the <a href="#op-unm">unary minus operation</a>).
</p></li>
<li><p>
If the argument is a boolean,
the result is a pattern that always succeeds or always fails
(according to the boolean value),
without consuming any input.
</p></li>
<li><p>
If the argument is a table,
it is interpreted as a grammar
(see <a href="#grammar">Grammars</a>).
</p></li>
<li><p>
If the argument is a function,
returns a pattern equivalent to a
<a href="#matchtime">match-time capture</a> over the empty string.
</p></li>
</ul>
<h3><a name="op-behind"></a><code>lpeg.B(patt)</code></h3>
<p>
Returns a pattern that
matches only if the input string at the current position
is preceded by <code>patt</code>.
Pattern <code>patt</code> must match only strings
with some fixed length,
and it cannot contain captures.
</p>
<p>
Like the <a href="#op-len">and predicate</a>,
this pattern never consumes any input,
independently of success or failure.
</p>
<h3><a name="op-r"></a><code>lpeg.R ({range})</code></h3>
<p>
Returns a pattern that matches any single character
belonging to one of the given <em>ranges</em>.
Each <code>range</code> is a string <em>xy</em> of length 2,
representing all characters with code
between the codes of <em>x</em> and <em>y</em>
(both inclusive).
</p>
<p>
As an example, the pattern
<code>lpeg.R("09")</code> matches any digit,
and <code>lpeg.R("az", "AZ")</code> matches any ASCII letter.
</p>
<h3><a name="op-s"></a><code>lpeg.S (string)</code></h3>
<p>
Returns a pattern that matches any single character that
appears in the given string.
(The <code>S</code> stands for <em>Set</em>.)
</p>
<p>
As an example, the pattern
<code>lpeg.S("+-*/")</code> matches any arithmetic operator.
</p>
<p>
Note that, if <code>s</code> is a character
(that is, a string of length 1),
then <code>lpeg.P(s)</code> is equivalent to <code>lpeg.S(s)</code>
which is equivalent to <code>lpeg.R(s..s)</code>.
Note also that both <code>lpeg.S("")</code> and <code>lpeg.R()</code>
are patterns that always fail.
</p>
<h3><a name="op-utfR"></a><code>lpeg.utfR (cp1, cp2)</code></h3>
<p>
Returns a pattern that matches a valid UTF-8 byte sequence
representing a code point in the range <code>[cp1, cp2]</code>.
The range is limited by the natural Unicode limit of 0x10FFFF,
but may include surrogates.
</p>
<h3><a name="op-v"></a><code>lpeg.V (v)</code></h3>
<p>
This operation creates a non-terminal (a <em>variable</em>)
for a grammar.
The created non-terminal refers to the rule indexed by <code>v</code>
in the enclosing grammar.
(See <a href="#grammar">Grammars</a> for details.)
</p>
<h3><a name="op-locale"></a><code>lpeg.locale ([table])</code></h3>
<p>
Returns a table with patterns for matching some character classes
according to the current locale.
The table has fields named
<code>alnum</code>,
<code>alpha</code>,
<code>cntrl</code>,
<code>digit</code>,
<code>graph</code>,
<code>lower</code>,
<code>print</code>,
<code>punct</code>,
<code>space</code>,
<code>upper</code>, and
<code>xdigit</code>,
each one containing a correspondent pattern.
Each pattern matches any single character that belongs to its class.
</p>
<p>
If called with an argument <code>table</code>,
then it creates those fields inside the given table and
returns that table.
</p>
<h3><a name="op-len"></a><code>#patt</code></h3>
<p>
Returns a pattern that
matches only if the input string matches <code>patt</code>,
but without consuming any input,
independently of success or failure.
(This pattern is called an <em>and predicate</em>
and it is equivalent to
<em>&patt</em> in the original PEG notation.)
</p>
<p>
This pattern never produces any capture.
</p>
<h3><a name="op-unm"></a><code>-patt</code></h3>
<p>
Returns a pattern that
matches only if the input string does not match <code>patt</code>.
It does not consume any input,
independently of success or failure.
(This pattern is equivalent to
<em>!patt</em> in the original PEG notation.)
</p>
<p>
As an example, the pattern
<code>-lpeg.P(1)</code> matches only the end of string.
</p>
<p>
This pattern never produces any captures,
because either <code>patt</code> fails
or <code>-patt</code> fails.
(A failing pattern never produces captures.)
</p>
<h3><a name="op-add"></a><code>patt1 + patt2</code></h3>
<p>
Returns a pattern equivalent to an <em>ordered choice</em>
of <code>patt1</code> and <code>patt2</code>.
(This is denoted by <em>patt1 / patt2</em> in the original PEG notation,
not to be confused with the <code>/</code> operation in LPeg.)
It matches either <code>patt1</code> or <code>patt2</code>,
with no backtracking once one of them succeeds.
The identity element for this operation is the pattern
<code>lpeg.P(false)</code>,
which always fails.
</p>
<p>
If both <code>patt1</code> and <code>patt2</code> are
character sets,
this operation is equivalent to set union.
</p>
<pre class="example">
lower = lpeg.R("az")
upper = lpeg.R("AZ")
letter = lower + upper
</pre>
<h3><a name="op-sub"></a><code>patt1 - patt2</code></h3>
<p>
Returns a pattern equivalent to <em>!patt2 patt1</em>
in the origial PEG notation.
This pattern asserts that the input does not match
<code>patt2</code> and then matches <code>patt1</code>.
</p>
<p>
When successful,
this pattern produces all captures from <code>patt1</code>.
It never produces any capture from <code>patt2</code>
(as either <code>patt2</code> fails or
<code>patt1 - patt2</code> fails).
</p>
<p>
If both <code>patt1</code> and <code>patt2</code> are
character sets,
this operation is equivalent to set difference.
Note that <code>-patt</code> is equivalent to <code>"" - patt</code>
(or <code>0 - patt</code>).
If <code>patt</code> is a character set,
<code>1 - patt</code> is its complement.
</p>
<h3><a name="op-mul"></a><code>patt1 * patt2</code></h3>
<p>
Returns a pattern that matches <code>patt1</code>
and then matches <code>patt2</code>,
starting where <code>patt1</code> finished.
The identity element for this operation is the
pattern <code>lpeg.P(true)</code>,
which always succeeds.
</p>
<p>
(LPeg uses the <code>*</code> operator
[instead of the more obvious <code>..</code>]
both because it has
the right priority and because in formal languages it is
common to use a dot for denoting concatenation.)
</p>
<h3><a name="op-pow"></a><code>patt^n</code></h3>
<p>
If <code>n</code> is nonnegative,
this pattern is
equivalent to <em>patt<sup>n</sup> patt*</em>:
It matches <code>n</code> or more occurrences of <code>patt</code>.
</p>
<p>
Otherwise, when <code>n</code> is negative,
this pattern is equivalent to <em>(patt?)<sup>-n</sup></em>:
It matches at most <code>|n|</code>
occurrences of <code>patt</code>.
</p>
<p>
In particular, <code>patt^0</code> is equivalent to <em>patt*</em>,
<code>patt^1</code> is equivalent to <em>patt+</em>,
and <code>patt^-1</code> is equivalent to <em>patt?</em>
in the original PEG notation.
</p>
<p>
In all cases,
the resulting pattern is greedy with no backtracking
(also called a <em>possessive</em> repetition).
That is, it matches only the longest possible sequence
of matches for <code>patt</code>.
</p>
<h2><a name="grammar">Grammars</a></h2>
<p>
With the use of Lua variables,
it is possible to define patterns incrementally,
with each new pattern using previously defined ones.
However, this technique does not allow the definition of
recursive patterns.
For recursive patterns,
we need real grammars.
</p>
<p>
LPeg represents grammars with tables,
where each entry is a rule.
</p>
<p>
The call <code>lpeg.V(v)</code>
creates a pattern that represents the nonterminal
(or <em>variable</em>) with index <code>v</code> in a grammar.
Because the grammar still does not exist when
this function is evaluated,
the result is an <em>open reference</em> to the respective rule.
</p>
<p>
A table is <em>fixed</em> when it is converted to a pattern
(either by calling <code>lpeg.P</code> or by using it wherein a
pattern is expected).
Then every open reference created by <code>lpeg.V(v)</code>
is corrected to refer to the rule indexed by <code>v</code> in the table.
</p>
<p>
When a table is fixed,
the result is a pattern that matches its <em>initial rule</em>.
The entry with index 1 in the table defines its initial rule.
If that entry is a string,
it is assumed to be the name of the initial rule.
Otherwise, LPeg assumes that the entry 1 itself is the initial rule.
</p>
<p>
As an example,
the following grammar matches strings of a's and b's that
have the same number of a's and b's:
</p>
<pre class="example">
equalcount = lpeg.P{
"S"; -- initial rule name
S = "a" * lpeg.V"B" + "b" * lpeg.V"A" + "",
A = "a" * lpeg.V"S" + "b" * lpeg.V"A" * lpeg.V"A",
B = "b" * lpeg.V"S" + "a" * lpeg.V"B" * lpeg.V"B",
} * -1
</pre>
<p>
It is equivalent to the following grammar in standard PEG notation:
</p>
<pre class="example">
S <- 'a' B / 'b' A / ''
A <- 'a' S / 'b' A A
B <- 'b' S / 'a' B B
</pre>
<h2><a name="captures">Captures</a></h2>
<p>
A <em>capture</em> is a pattern that produces values
(the so called <em>semantic information</em>)
according to what it matches.
LPeg offers several kinds of captures,
which produces values based on matches and combine these values to
produce new values.
Each capture may produce zero or more values.
</p>
<p>
The following table summarizes the basic captures:
</p>
<table border="1">
<tbody><tr><td><b>Operation</b></td><td><b>What it Produces</b></td></tr>
<tr><td><a href="#cap-c"><code>lpeg.C(patt)</code></a></td>
<td>the match for <code>patt</code> plus all captures
made by <code>patt</code></td></tr>
<tr><td><a href="#cap-arg"><code>lpeg.Carg(n)</code></a></td>
<td>the value of the n<sup>th</sup> extra argument to
<code>lpeg.match</code> (matches the empty string)</td></tr>
<tr><td><a href="#cap-b"><code>lpeg.Cb(key)</code></a></td>
<td>the values produced by the previous
group capture named <code>key</code>
(matches the empty string)</td></tr>
<tr><td><a href="#cap-cc"><code>lpeg.Cc(values)</code></a></td>
<td>the given values (matches the empty string)</td></tr>
<tr><td><a href="#cap-f"><code>lpeg.Cf(patt, func)</code></a></td>
<td>folding capture (<em>deprecated</em>)</td></tr>
<tr><td><a href="#cap-g"><code>lpeg.Cg(patt [, key])</code></a></td>
<td>the values produced by <code>patt</code>,
optionally tagged with <code>key</code></td></tr>
<tr><td><a href="#cap-p"><code>lpeg.Cp()</code></a></td>
<td>the current position (matches the empty string)</td></tr>
<tr><td><a href="#cap-s"><code>lpeg.Cs(patt)</code></a></td>
<td>the match for <code>patt</code>
with the values from nested captures replacing their matches</td></tr>
<tr><td><a href="#cap-t"><code>lpeg.Ct(patt)</code></a></td>
<td>a table with all captures from <code>patt</code></td></tr>
<tr><td><a href="#cap-string"><code>patt / string</code></a></td>
<td><code>string</code>, with some marks replaced by captures
of <code>patt</code></td></tr>
<tr><td><a href="#cap-num"><code>patt / number</code></a></td>
<td>the n-th value captured by <code>patt</code>,
or no value when <code>number</code> is zero.</td></tr>
<tr><td><a href="#cap-query"><code>patt / table</code></a></td>
<td><code>table[c]</code>, where <code>c</code> is the (first)
capture of <code>patt</code></td></tr>
<tr><td><a href="#cap-func"><code>patt / function</code></a></td>
<td>the returns of <code>function</code> applied to the captures
of <code>patt</code></td></tr>
<tr><td><a href="#cap-acc"><code>patt % function</code></a></td>
<td>produces no value;
it <em>accummulates</em> the captures from <code>patt</code>
into the previous capture through <code>function</code>
</td></tr>
<tr><td><a href="#matchtime"><code>lpeg.Cmt(patt, function)</code></a></td>
<td>the returns of <code>function</code> applied to the captures
of <code>patt</code>; the application is done at match time</td></tr>
</tbody></table>
<p>
A capture pattern produces its values only when it succeeds.
For instance,
the pattern <code>lpeg.C(lpeg.P"a"^-1)</code>
produces the empty string when there is no <code>"a"</code>
(because the pattern <code>"a"?</code> succeeds),
while the pattern <code>lpeg.C("a")^-1</code>
does not produce any value when there is no <code>"a"</code>
(because the pattern <code>"a"</code> fails).
A pattern inside a loop or inside a recursive structure
produces values for each match.
</p>
<p>
Usually,
LPeg does not specify when (and if) it evaluates its captures.
(As an example,
consider the pattern <code>lpeg.P"a" / func / 0</code>.
Because the "division" by 0 instructs LPeg to throw away the
results from the pattern,
it is not specified whether LPeg will call <code>func</code>.)
Therefore, captures should avoid side effects.
Moreover,
captures cannot affect the way a pattern matches a subject.
The only exception to this rule is the
so-called <a href="#matchtime"><em>match-time capture</em></a>.
When a match-time capture matches,
it forces the immediate evaluation of all its nested captures
and then calls its corresponding function,
which defines whether the match succeeds and also
what values are produced.
</p>
<h3><a name="cap-c"></a><code>lpeg.C (patt)</code></h3>
<p>
Creates a <em>simple capture</em>,
which captures the substring of the subject that matches <code>patt</code>.
The captured value is a string.
If <code>patt</code> has other captures,
their values are returned after this one.
</p>
<h3><a name="cap-arg"></a><code>lpeg.Carg (n)</code></h3>
<p>
Creates an <em>argument capture</em>.
This pattern matches the empty string and
produces the value given as the n<sup>th</sup> extra
argument given in the call to <code>lpeg.match</code>.
</p>
<h3><a name="cap-b"></a><code>lpeg.Cb (key)</code></h3>
<p>
Creates a <em>back capture</em>.
This pattern matches the empty string and
produces the values produced by the <em>most recent</em>
<a href="#cap-g">group capture</a> named <code>key</code>
(where <code>key</code> can be any Lua value).
</p>
<p>
<em>Most recent</em> means the last
<em>complete</em>
<em>outermost</em>
group capture with the given key.
A <em>Complete</em> capture means that the entire pattern
corresponding to the capture has matched;
in other words, the back capture is not nested inside the group.
An <em>Outermost</em> capture means that the capture is not inside
another complete capture that does not contain the back capture itself.
</p>
<p>
In the same way that LPeg does not specify when it evaluates captures,
it does not specify whether it reuses
values previously produced by the group
or re-evaluates them.
</p>
<h3><a name="cap-cc"></a><code>lpeg.Cc ([value, ...])</code></h3>
<p>
Creates a <em>constant capture</em>.
This pattern matches the empty string and
produces all given values as its captured values.
</p>
<h3><a name="cap-f"></a><code>lpeg.Cf (patt, func)</code></h3>
<p>
Creates a <em>fold capture</em>.
This construction is deprecated;
use an <a href="#cap-acc">accumulator pattern</a> instead.
In general, a fold like
<code>lpeg.Cf(p1 * p2^0, func)</code>
can be translated to
<code>(p1 * (p2 % func)^0)</code>.
<h3><a name="cap-g"></a><code>lpeg.Cg (patt [, key])</code></h3>
<p>
Creates a <em>group capture</em>.
It groups all values returned by <code>patt</code>
into a single capture.
The group may be anonymous (if no key is given)
or named with the given key
(which can be any non-nil Lua value).
</p>
<p>
An anonymous group serves to join values from several captures into
a single capture.
A named group has a different behavior.
In most situations, a named group returns no values at all.
Its values are only relevant for a following
<a href="#cap-b">back capture</a> or when used
inside a <a href="#cap-t">table capture</a>.
</p>
<h3><a name="cap-p"></a><code>lpeg.Cp ()</code></h3>
<p>
Creates a <em>position capture</em>.
It matches the empty string and
captures the position in the subject where the match occurs.
The captured value is a number.
</p>
<h3><a name="cap-s"></a><code>lpeg.Cs (patt)</code></h3>
<p>
Creates a <em>substitution capture</em>,
which captures the substring of the subject that matches <code>patt</code>,
with <em>substitutions</em>.
For any capture inside <code>patt</code> with a value,
the substring that matched the capture is replaced by the capture value
(which should be a string).
The final captured value is the string resulting from
all replacements.
</p>
<h3><a name="cap-t"></a><code>lpeg.Ct (patt)</code></h3>
<p>
Creates a <em>table capture</em>.
This capture returns a table with all values from all anonymous captures
made by <code>patt</code> inside this table in successive integer keys,
starting at 1.
Moreover,
for each named capture group created by <code>patt</code>,
the first value of the group is put into the table
with the group key as its key.
The captured value is only the table.
</p>
<h3><a name="cap-string"></a><code>patt / string</code></h3>
<p>
Creates a <em>string capture</em>.
It creates a capture string based on <code>string</code>.
The captured value is a copy of <code>string</code>,
except that the character <code>%</code> works as an escape character:
any sequence in <code>string</code> of the form <code>%<em>n</em></code>,
with <em>n</em> between 1 and 9,
stands for the match of the <em>n</em>-th capture in <code>patt</code>.
The sequence <code>%0</code> stands for the whole match.
The sequence <code>%%</code> stands for a single <code>%</code>.
</p>
<h3><a name="cap-num"></a><code>patt / number</code></h3>
<p>
Creates a <em>numbered capture</em>.
For a non-zero number,
the captured value is the n-th value
captured by <code>patt</code>.
When <code>number</code> is zero,
there are no captured values.
</p>
<h3><a name="cap-query"></a><code>patt / table</code></h3>
<p>
Creates a <em>query capture</em>.
It indexes the given table using as key the first value captured by
<code>patt</code>,
or the whole match if <code>patt</code> produced no value.
The value at that index is the final value of the capture.
If the table does not have that key,
there is no captured value.
</p>
<h3><a name="cap-func"></a><code>patt / function</code></h3>
<p>
Creates a <em>function capture</em>.
It calls the given function passing all captures made by
<code>patt</code> as arguments,
or the whole match if <code>patt</code> made no capture.
The values returned by the function
are the final values of the capture.
In particular,
if <code>function</code> returns no value,
there is no captured value.
</p>
<h3><a name="cap-acc"></a><code>patt % function</code></h3>
<p>
Creates an <em>accumulator capture</em>.
This pattern behaves similarly to a
<a href="#cap-func">function capture</a>,
with the following differences:
The last captured value before <code>patt</code>
is added as a first argument to the call;
the return of the function is adjusted to one single value;
that value replaces the last captured value.
Note that the capture itself produces no values;
it only changes the value of its previous capture.
</p>
<p>
As an example,
let us consider the problem of adding a list of numbers.
</p>
<pre class="example">
-- matches a numeral and captures its numerical value
number = lpeg.R"09"^1 / tonumber
-- auxiliary function to add two numbers
function add (acc, newvalue) return acc + newvalue end
-- matches a list of numbers, adding their values
sum = number * ("," * number % add)^0
-- example of use
print(sum:match("10,30,43")) --> 83
</pre>
<p>
First, the initial <code>number</code> captures a number;
that first capture will play the role of an accumulator.
Then, each time the sequence <code>comma-number</code>
matches inside the loop there is an accumulator capture:
It calls <code>add</code> with the current value of the
accumulator—which is the last captured value, created by the
first <code>number</code>— and the value of the new number,
and the result of the call (the sum of the two numbers)
replaces the value of the accumulator.
At the end of the match,
the accumulator with all sums is the final value.
</p>
<p>
As another example,
consider the following code fragment:
</p>
<pre class="example">
local name = lpeg.C(lpeg.R("az")^1)
local p = name * (lpeg.P("^") % string.upper)^-1
print(p:match("count")) --> count
print(p:match("count^")) --> COUNT
</pre>
<p>
In the match against <code>"count"</code>,
as there is no <code>"^"</code>,
the optional accumulator capture does not match;
so, the match results in its sole capture, a name.
In the match against <code>"count^"</code>,
the accumulator capture matches,
so the function <code>string.upper</code>
is called with the previous captured value (created by <code>name</code>)
plus the string <code>"^"</code>;
the function ignores its second argument and returns the first argument
changed to upper case;
that value then becomes the first and only
capture value created by the match.
</p>
<p>
Due to the nature of this capture,
you should avoid using it in places where it is not clear
what is the "previous" capture,
such as directly nested in a <a href="#cap-string">string capture</a>
or a <a href="#cap-num">numbered capture</a>.
(Note that these captures may not need to evaluate
all their subcaptures to compute their results.)
Moreover, due to implementation details,
you should not use this capture directly nested in a
<a href="#cap-s">substitution capture</a>.
You should also avoid a direct nesting of this capture inside
a <a href="#cap-f">folding capture</a> (deprecated),
as the folding will try to fold each individual accumulator capture.
A simple and effective way to avoid all these issues is
to enclose the whole accumulation composition
(including the capture that generates the initial value)
into an anonymous <a href="#cap-g">group capture</a>.
</p>
<h3><a name="matchtime"></a><code>lpeg.Cmt(patt, function)</code></h3>
<p>
Creates a <em>match-time capture</em>.
Unlike all other captures,
this one is evaluated immediately when a match occurs
(even if it is part of a larger pattern that fails later).
It forces the immediate evaluation of all its nested captures
and then calls <code>function</code>.
</p>
<p>
The given function gets as arguments the entire subject,
the current position (after the match of <code>patt</code>),
plus any capture values produced by <code>patt</code>.
</p>
<p>
The first value returned by <code>function</code>
defines how the match happens.
If the call returns a number,
the match succeeds
and the returned number becomes the new current position.
(Assuming a subject <em>s</em> and current position <em>i</em>,
the returned number must be in the range <em>[i, len(s) + 1]</em>.)
If the call returns <b>true</b>,
the match succeeds without consuming any input.
(So, to return <b>true</b> is equivalent to return <em>i</em>.)
If the call returns <b>false</b>, <b>nil</b>, or no value,
the match fails.
</p>
<p>
Any extra values returned by the function become the
values produced by the capture.
</p>
<h2><a name="ex">Some Examples</a></h2>
<h3>Using a Pattern</h3>
<p>
This example shows a very simple but complete program
that builds and uses a pattern:
</p>
<pre class="example">
local lpeg = require "lpeg"
-- matches a word followed by end-of-string
p = lpeg.R"az"^1 * -1
print(p:match("hello")) --> 6
print(lpeg.match(p, "hello")) --> 6
print(p:match("1 hello")) --> nil
</pre>
<p>
The pattern is simply a sequence of one or more lower-case letters
followed by the end of string (-1).
The program calls <code>match</code> both as a method
and as a function.
In both sucessful cases,
the match returns
the index of the first character after the match,
which is the string length plus one.
</p>
<h3>Name-value lists</h3>
<p>
This example parses a list of name-value pairs and returns a table
with those pairs:
</p>
<pre class="example">
lpeg.locale(lpeg) -- adds locale entries into 'lpeg' table
local space = lpeg.space^0
local name = lpeg.C(lpeg.alpha^1) * space
local sep = lpeg.S(",;") * space
local pair = name * "=" * space * name * sep^-1
local list = lpeg.Ct("") * (pair % rawset)^0
t = list:match("a=b, c = hi; next = pi")
--> { a = "b", c = "hi", next = "pi" }
</pre>
<p>
Each pair has the format <code>name = name</code> followed by
an optional separator (a comma or a semicolon).
The <code>list</code> pattern then <em>folds</em> these captures.
It starts with an empty table,
created by a table capture matching an empty string;
then for each a pair of names it applies <code>rawset</code>
over the accumulator (the table) and the capture values (the pair of names).
<code>rawset</code> returns the table itself,
so the accumulator is always the table.
</p>
<h3>Splitting a string</h3>
<p>
The following code builds a pattern that
splits a string using a given pattern
<code>sep</code> as a separator:
</p>
<pre class="example">
function split (s, sep)
sep = lpeg.P(sep)
local elem = lpeg.C((1 - sep)^0)
local p = elem * (sep * elem)^0
return lpeg.match(p, s)
end
</pre>
<p>
First the function ensures that <code>sep</code> is a proper pattern.
The pattern <code>elem</code> is a repetition of zero of more
arbitrary characters as long as there is not a match against
the separator.
It also captures its match.
The pattern <code>p</code> matches a list of elements separated
by <code>sep</code>.
</p>
<p>
If the split results in too many values,
it may overflow the maximum number of values
that can be returned by a Lua function.
To avoid this problem,
we can collect these values in a table:
</p>
<pre class="example">
function split (s, sep)
sep = lpeg.P(sep)
local elem = lpeg.C((1 - sep)^0)
local p = lpeg.Ct(elem * (sep * elem)^0) -- make a table capture
return lpeg.match(p, s)
end
</pre>
<h3>Searching for a pattern</h3>
<p>
The primitive <code>match</code> works only in anchored mode.
If we want to find a pattern anywhere in a string,
we must write a pattern that matches anywhere.
</p>
<p>
Because patterns are composable,
we can write a function that,
given any arbitrary pattern <code>p</code>,
returns a new pattern that searches for <code>p</code>
anywhere in a string.
There are several ways to do the search.
One way is like this:
</p>
<pre class="example">
function anywhere (p)
return lpeg.P{ p + 1 * lpeg.V(1) }
end
</pre>
<p>
This grammar has a straight reading:
its sole rule matches <code>p</code> or skips one character and tries again.
</p>
<p>
If we want to know where the pattern is in the string
(instead of knowing only that it is there somewhere),
we can add position captures to the pattern:
</p>
<pre class="example">
local Cp = lpeg.Cp()
function anywhere (p)
return lpeg.P{ Cp * p * Cp + 1 * lpeg.V(1) }
end
print(anywhere("world"):match("hello world!")) --> 7 12
</pre>
<p>
Another option for the search is like this:
</p>
<pre class="example">
local Cp = lpeg.Cp()
function anywhere (p)
return (1 - lpeg.P(p))^0 * Cp * p * Cp
end
</pre>
<p>
Again the pattern has a straight reading:
it skips as many characters as possible while not matching <code>p</code>,
and then matches <code>p</code> plus appropriate captures.
</p>
<p>
If we want to look for a pattern only at word boundaries,
we can use the following transformer:
</p>
<pre class="example">
local t = lpeg.locale()
function atwordboundary (p)
return lpeg.P{
[1] = p + t.alpha^0 * (1 - t.alpha)^1 * lpeg.V(1)
}
end
</pre>
<h3><a name="balanced"></a>Balanced parentheses</h3>
<p>
The following pattern matches only strings with balanced parentheses:
</p>
<pre class="example">
b = lpeg.P{ "(" * ((1 - lpeg.S"()") + lpeg.V(1))^0 * ")" }
</pre>
<p>
Reading the first (and only) rule of the given grammar,
we have that a balanced string is
an open parenthesis,
followed by zero or more repetitions of either
a non-parenthesis character or
a balanced string (<code>lpeg.V(1)</code>),
followed by a closing parenthesis.
</p>
<h3>Global substitution</h3>
<p>
The next example does a job somewhat similar to <code>string.gsub</code>.
It receives a pattern and a replacement value,
and substitutes the replacement value for all occurrences of the pattern
in a given string:
</p>
<pre class="example">
function gsub (s, patt, repl)
patt = lpeg.P(patt)
patt = lpeg.Cs((patt / repl + 1)^0)
return lpeg.match(patt, s)
end
</pre>
<p>
As in <code>string.gsub</code>,
the replacement value can be a string,
a function, or a table.
</p>
<h3><a name="CSV"></a>Comma-Separated Values (CSV)</h3>
<p>
This example breaks a string into comma-separated values,
returning all fields:
</p>
<pre class="example">
local field = '"' * lpeg.Cs(((lpeg.P(1) - '"') + lpeg.P'""' / '"')^0) * '"' +
lpeg.C((1 - lpeg.S',\n"')^0)
local record = field * (',' * field)^0 * (lpeg.P'\n' + -1)
function csv (s)
return lpeg.match(record, s)
end
</pre>
<p>
A field is either a quoted field
(which may contain any character except an individual quote,
which may be written as two quotes that are replaced by one)
or an unquoted field
(which cannot contain commas, newlines, or quotes).
A record is a list of fields separated by commas,
ending with a newline or the string end (-1).
</p>
<p>
As it is,
the previous pattern returns each field as a separated result.
If we add a table capture in the definition of <code>record</code>,
the pattern will return instead a single table
containing all fields:
</p>
<pre>
local record = lpeg.Ct(field * (',' * field)^0) * (lpeg.P'\n' + -1)
</pre>
<h3>Lua's long strings</h3>
<p>
A long string in Lua starts with the pattern <code>[=*[</code>
and ends at the first occurrence of <code>]=*]</code> with
exactly the same number of equal signs.
If the opening brackets are followed by a newline,
this newline is discarded
(that is, it is not part of the string).
</p>
<p>
To match a long string in Lua,
the pattern must capture the first repetition of equal signs and then,
whenever it finds a candidate for closing the string,
check whether it has the same number of equal signs.
</p>
<pre class="example">
equals = lpeg.P"="^0
open = "[" * lpeg.Cg(equals, "init") * "[" * lpeg.P"\n"^-1
close = "]" * lpeg.C(equals) * "]"
closeeq = lpeg.Cmt(close * lpeg.Cb("init"), function (s, i, a, b) return a == b end)
string = open * lpeg.C((lpeg.P(1) - closeeq)^0) * close / 1
</pre>
<p>
The <code>open</code> pattern matches <code>[=*[</code>,
capturing the repetitions of equal signs in a group named <code>init</code>;
it also discharges an optional newline, if present.
The <code>close</code> pattern matches <code>]=*]</code>,
also capturing the repetitions of equal signs.
The <code>closeeq</code> pattern first matches <code>close</code>;
then it uses a back capture to recover the capture made
by the previous <code>open</code>,
which is named <code>init</code>;
finally it uses a match-time capture to check
whether both captures are equal.
The <code>string</code> pattern starts with an <code>open</code>,
then it goes as far as possible until matching <code>closeeq</code>,
and then matches the final <code>close</code>.
The final numbered capture simply discards
the capture made by <code>close</code>.
</p>
<h3>Arithmetic expressions</h3>
<p>
This example is a complete parser and evaluator for simple
arithmetic expressions.
We write it in two styles.
The first approach first builds a syntax tree and then
traverses this tree to compute the expression value:
</p>
<pre class="example">
-- Lexical Elements
local Space = lpeg.S(" \n\t")^0
local Number = lpeg.C(lpeg.P"-"^-1 * lpeg.R("09")^1) * Space
local TermOp = lpeg.C(lpeg.S("+-")) * Space
local FactorOp = lpeg.C(lpeg.S("*/")) * Space
local Open = "(" * Space
local Close = ")" * Space
-- Grammar
local Exp, Term, Factor = lpeg.V"Exp", lpeg.V"Term", lpeg.V"Factor"
G = lpeg.P{ Exp,
Exp = lpeg.Ct(Term * (TermOp * Term)^0);
Term = lpeg.Ct(Factor * (FactorOp * Factor)^0);
Factor = Number + Open * Exp * Close;
}
G = Space * G * -1
-- Evaluator
function eval (x)
if type(x) == "string" then
return tonumber(x)
else
local op1 = eval(x[1])
for i = 2, #x, 2 do
local op = x[i]
local op2 = eval(x[i + 1])
if (op == "+") then op1 = op1 + op2
elseif (op == "-") then op1 = op1 - op2
elseif (op == "*") then op1 = op1 * op2
elseif (op == "/") then op1 = op1 / op2
end
end
return op1
end
end
-- Parser/Evaluator
function evalExp (s)
local t = lpeg.match(G, s)
if not t then error("syntax error", 2) end
return eval(t)
end
-- small example
print(evalExp"3 + 5*9 / (1+1) - 12") --> 13.5
</pre>
<p>
The second style computes the expression value on the fly,
without building the syntax tree.
The following grammar takes this approach.
(It assumes the same lexical elements as before.)
</p>
<pre class="example">
-- Auxiliary function
function eval (v1, op, v2)
if (op == "+") then return v1 + v2
elseif (op == "-") then return v1 - v2
elseif (op == "*") then return v1 * v2
elseif (op == "/") then return v1 / v2
end
end
-- Grammar
local V = lpeg.V
G = lpeg.P{ "Exp",
Exp = V"Term" * (TermOp * V"Term" % eval)^0;
Term = V"Factor" * (FactorOp * V"Factor" % eval)^0;
Factor = Number / tonumber + Open * V"Exp" * Close;
}
-- small example
print(lpeg.match(G, "3 + 5*9 / (1+1) - 12")) --> 13.5
</pre>
<p>
Note the use of the accumulator capture.
To compute the value of an expression,
the accumulator starts with the value of the first term,
and then applies <code>eval</code> over
the accumulator, the operator,
and the new term for each repetition.
</p>
<h2><a name="download"></a>Download</h2>
<p>LPeg
<a href="//www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.1.0.tar.gz">source code</a>.</p>
<p>
Probably, the easiest way to install LPeg is with
<a href="//luarocks.org/">LuaRocks</a>.
If you have LuaRocks installed,
the following command is all you need to install LPeg:
<pre>$ luarocks install lpeg</pre>
<h2><a name="license">License<
gitextract_nfy1fgz2/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ └── readme-first.md
│ └── workflows/
│ └── build-release.yml
├── .gitignore
├── .gitmodules
├── 3rd/
│ ├── compat-mingw/
│ │ ├── arpa/
│ │ │ └── inet.h
│ │ ├── compat.c
│ │ ├── compat.h
│ │ ├── dlfcn.c
│ │ ├── dlfcn.h
│ │ ├── netdb.h
│ │ ├── netinet/
│ │ │ ├── in.h
│ │ │ └── tcp.h
│ │ ├── sys/
│ │ │ ├── epoll.h
│ │ │ ├── file.h
│ │ │ └── socket.h
│ │ ├── unistd.c
│ │ ├── unistd.h
│ │ ├── wepoll.c
│ │ └── wepoll.h
│ ├── lpeg/
│ │ ├── HISTORY
│ │ ├── README.md
│ │ ├── lpcap.c
│ │ ├── lpcap.h
│ │ ├── lpcode.c
│ │ ├── lpcode.h
│ │ ├── lpcset.c
│ │ ├── lpcset.h
│ │ ├── lpeg.html
│ │ ├── lpprint.c
│ │ ├── lpprint.h
│ │ ├── lptree.c
│ │ ├── lptree.h
│ │ ├── lptypes.h
│ │ ├── lpvm.c
│ │ ├── lpvm.h
│ │ ├── makefile
│ │ ├── re.html
│ │ ├── re.lua
│ │ └── test.lua
│ ├── lua/
│ │ ├── README
│ │ ├── README.md
│ │ ├── lapi.c
│ │ ├── lapi.h
│ │ ├── lauxlib.c
│ │ ├── lauxlib.h
│ │ ├── lbaselib.c
│ │ ├── lcode.c
│ │ ├── lcode.h
│ │ ├── lcorolib.c
│ │ ├── lctype.c
│ │ ├── lctype.h
│ │ ├── ldblib.c
│ │ ├── ldebug.c
│ │ ├── ldebug.h
│ │ ├── ldo.c
│ │ ├── ldo.h
│ │ ├── ldump.c
│ │ ├── lfunc.c
│ │ ├── lfunc.h
│ │ ├── lgc.c
│ │ ├── lgc.h
│ │ ├── linit.c
│ │ ├── liolib.c
│ │ ├── ljumptab.h
│ │ ├── llex.c
│ │ ├── llex.h
│ │ ├── llimits.h
│ │ ├── lmathlib.c
│ │ ├── lmem.c
│ │ ├── lmem.h
│ │ ├── loadlib.c
│ │ ├── lobject.c
│ │ ├── lobject.h
│ │ ├── lopcodes.c
│ │ ├── lopcodes.h
│ │ ├── lopnames.h
│ │ ├── loslib.c
│ │ ├── lparser.c
│ │ ├── lparser.h
│ │ ├── lprefix.h
│ │ ├── lstate.c
│ │ ├── lstate.h
│ │ ├── lstring.c
│ │ ├── lstring.h
│ │ ├── lstrlib.c
│ │ ├── ltable.c
│ │ ├── ltable.h
│ │ ├── ltablib.c
│ │ ├── ltests.c
│ │ ├── ltests.h
│ │ ├── ltm.c
│ │ ├── ltm.h
│ │ ├── lua.c
│ │ ├── lua.h
│ │ ├── lua.hpp
│ │ ├── luac.c
│ │ ├── luaconf.h
│ │ ├── lualib.h
│ │ ├── lundump.c
│ │ ├── lundump.h
│ │ ├── lutf8lib.c
│ │ ├── lvm.c
│ │ ├── lvm.h
│ │ ├── lzio.c
│ │ ├── lzio.h
│ │ ├── makefile
│ │ └── onelua.c
│ └── lua-md5/
│ ├── README
│ ├── compat-5.2.c
│ ├── compat-5.2.h
│ ├── md5.c
│ ├── md5.h
│ └── md5lib.c
├── HISTORY.md
├── LICENSE
├── Makefile
├── README.md
├── examples/
│ ├── abort.lua
│ ├── agent.lua
│ ├── checkdeadloop.lua
│ ├── client.lua
│ ├── cluster1.lua
│ ├── cluster2.lua
│ ├── clustername.lua
│ ├── config
│ ├── config.c1
│ ├── config.c2
│ ├── config.handle
│ ├── config.login
│ ├── config.mc
│ ├── config.mongodb
│ ├── config.mysql
│ ├── config.path
│ ├── config.userlog
│ ├── config_log
│ ├── globallog.lua
│ ├── injectlaunch.lua
│ ├── login/
│ │ ├── client.lua
│ │ ├── gated.lua
│ │ ├── logind.lua
│ │ ├── main.lua
│ │ └── msgagent.lua
│ ├── main.lua
│ ├── main_log.lua
│ ├── main_mongodb.lua
│ ├── main_mysql.lua
│ ├── preload.lua
│ ├── proto.lua
│ ├── protoloader.lua
│ ├── share.lua
│ ├── simpledb.lua
│ ├── simplemonitor.lua
│ ├── simpleweb.lua
│ ├── simplewebsocket.lua
│ ├── userlog.lua
│ └── watchdog.lua
├── lualib/
│ ├── compat10/
│ │ ├── cluster.lua
│ │ ├── crypt.lua
│ │ ├── datacenter.lua
│ │ ├── dns.lua
│ │ ├── memory.lua
│ │ ├── mongo.lua
│ │ ├── mqueue.lua
│ │ ├── multicast.lua
│ │ ├── mysql.lua
│ │ ├── netpack.lua
│ │ ├── profile.lua
│ │ ├── redis.lua
│ │ ├── sharedata.lua
│ │ ├── sharemap.lua
│ │ ├── snax.lua
│ │ ├── socket.lua
│ │ ├── socketchannel.lua
│ │ ├── socketdriver.lua
│ │ └── stm.lua
│ ├── http/
│ │ ├── httpc.lua
│ │ ├── httpd.lua
│ │ ├── internal.lua
│ │ ├── sockethelper.lua
│ │ ├── tlshelper.lua
│ │ ├── url.lua
│ │ └── websocket.lua
│ ├── loader.lua
│ ├── md5.lua
│ ├── skynet/
│ │ ├── cluster.lua
│ │ ├── coroutine.lua
│ │ ├── datacenter.lua
│ │ ├── datasheet/
│ │ │ ├── builder.lua
│ │ │ ├── dump.lua
│ │ │ └── init.lua
│ │ ├── db/
│ │ │ ├── mongo/
│ │ │ │ └── transaction.lua
│ │ │ ├── mongo.lua
│ │ │ ├── mysql.lua
│ │ │ ├── redis/
│ │ │ │ ├── cluster.lua
│ │ │ │ └── crc16.lua
│ │ │ └── redis.lua
│ │ ├── debug.lua
│ │ ├── dns.lua
│ │ ├── harbor.lua
│ │ ├── inject.lua
│ │ ├── injectcode.lua
│ │ ├── manager.lua
│ │ ├── mqueue.lua
│ │ ├── multicast.lua
│ │ ├── queue.lua
│ │ ├── remotedebug.lua
│ │ ├── require.lua
│ │ ├── service.lua
│ │ ├── sharedata/
│ │ │ └── corelib.lua
│ │ ├── sharedata.lua
│ │ ├── sharemap.lua
│ │ ├── sharetable.lua
│ │ ├── snax.lua
│ │ ├── socket.lua
│ │ └── socketchannel.lua
│ ├── skynet.lua
│ ├── snax/
│ │ ├── gateserver.lua
│ │ ├── hotfix.lua
│ │ ├── interface.lua
│ │ ├── loginserver.lua
│ │ └── msgserver.lua
│ ├── sproto.lua
│ ├── sprotoloader.lua
│ └── sprotoparser.lua
├── lualib-src/
│ ├── lsha1.c
│ ├── ltls.c
│ ├── lua-bson.c
│ ├── lua-clientsocket.c
│ ├── lua-cluster.c
│ ├── lua-crypt.c
│ ├── lua-datasheet.c
│ ├── lua-debugchannel.c
│ ├── lua-memory.c
│ ├── lua-mongo.c
│ ├── lua-multicast.c
│ ├── lua-netpack.c
│ ├── lua-seri.c
│ ├── lua-seri.h
│ ├── lua-sharedata.c
│ ├── lua-sharetable.c
│ ├── lua-skynet.c
│ ├── lua-socket.c
│ ├── lua-stm.c
│ └── sproto/
│ ├── README
│ ├── README.md
│ ├── lsproto.c
│ ├── msvcint.h
│ ├── sproto.c
│ └── sproto.h
├── mingw.mk
├── platform.mk
├── service/
│ ├── bootstrap.lua
│ ├── cdummy.lua
│ ├── clusteragent.lua
│ ├── clusterd.lua
│ ├── clusterproxy.lua
│ ├── clustersender.lua
│ ├── cmaster.lua
│ ├── cmemory.lua
│ ├── console.lua
│ ├── cslave.lua
│ ├── datacenterd.lua
│ ├── dbg.lua
│ ├── debug_agent.lua
│ ├── debug_console.lua
│ ├── gate.lua
│ ├── launcher.lua
│ ├── multicastd.lua
│ ├── service_cell.lua
│ ├── service_mgr.lua
│ ├── service_provider.lua
│ ├── sharedatad.lua
│ └── snaxd.lua
├── service-src/
│ ├── databuffer.h
│ ├── hashid.h
│ ├── service_gate.c
│ ├── service_harbor.c
│ ├── service_logger.c
│ └── service_snlua.c
├── skynet-src/
│ ├── atomic.h
│ ├── malloc_hook.c
│ ├── malloc_hook.h
│ ├── mem_info.c
│ ├── mem_info.h
│ ├── rwlock.h
│ ├── skynet.h
│ ├── skynet_daemon.c
│ ├── skynet_daemon.h
│ ├── skynet_env.c
│ ├── skynet_env.h
│ ├── skynet_error.c
│ ├── skynet_handle.c
│ ├── skynet_handle.h
│ ├── skynet_harbor.c
│ ├── skynet_harbor.h
│ ├── skynet_imp.h
│ ├── skynet_log.c
│ ├── skynet_log.h
│ ├── skynet_main.c
│ ├── skynet_malloc.h
│ ├── skynet_module.c
│ ├── skynet_module.h
│ ├── skynet_monitor.c
│ ├── skynet_monitor.h
│ ├── skynet_mq.c
│ ├── skynet_mq.h
│ ├── skynet_server.c
│ ├── skynet_server.h
│ ├── skynet_socket.c
│ ├── skynet_socket.h
│ ├── skynet_start.c
│ ├── skynet_timer.c
│ ├── skynet_timer.h
│ ├── socket_buffer.h
│ ├── socket_epoll.h
│ ├── socket_info.h
│ ├── socket_kqueue.h
│ ├── socket_poll.h
│ ├── socket_server.c
│ ├── socket_server.h
│ └── spinlock.h
└── test/
├── pingserver.lua
├── sharemap.sp
├── testbson.lua
├── testcoroutine.lua
├── testcrypt.lua
├── testdatacenter.lua
├── testdatasheet.lua
├── testdeadcall.lua
├── testdeadloop.lua
├── testdns.lua
├── testecho.lua
├── testendless.lua
├── testhandle.lua
├── testharborlink.lua
├── testhttp.lua
├── testmemlimit.lua
├── testmongodb.lua
├── testmulticast.lua
├── testmulticast2.lua
├── testmysql.lua
├── testoverload.lua
├── testping.lua
├── testpipeline.lua
├── testqueue.lua
├── testredis.lua
├── testredis2.lua
├── testrediscluster.lua
├── testresponse.lua
├── testselect.lua
├── testservice/
│ ├── init.lua
│ └── kvdb.lua
├── testsha.lua
├── testsharetable.lua
├── testsm.lua
├── testsocket.lua
├── teststm.lua
├── testterm.lua
├── testtimeout.lua
├── testtimer.lua
├── testtobeclosed.lua
├── testudp.lua
└── time.lua
Showing preview only (215K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3043 symbols across 129 files)
FILE: 3rd/compat-mingw/unistd.c
function set_errno_from_wsa_error (line 13) | static void set_errno_from_wsa_error(int wsa_error) {
function init_winsock (line 69) | static int init_winsock(void) {
function cleanup_winsock (line 81) | static void cleanup_winsock(void) {
function auto_init_winsock (line 89) | __attribute__((constructor))
function auto_cleanup_winsock (line 95) | __attribute__((destructor))
function LONGLONG (line 100) | static LONGLONG get_cpu_freq() {
function kill (line 106) | int kill(pid_t pid, int exit_code) {
function usleep (line 113) | void usleep(size_t us) {
function sleep (line 129) | void sleep(size_t sec) {
function clock_gettime (line 133) | int clock_gettime(int what, struct timespec* ti) {
function flock (line 184) | int flock(int fd, int flag) {
function fcntl (line 189) | int fcntl(int fd, int cmd, long arg) {
function sigfillset (line 201) | void sigfillset(int* flag) {
function sigemptyset (line 205) | int sigemptyset(int* set) {
function sigaction (line 210) | void sigaction(int flag, struct sigaction* action, void* param) {
function socket_keepalive (line 214) | static void socket_keepalive(int fd) {
function pipe (line 222) | int pipe(int fd[2]) {
function write (line 281) | int write(int fd, const void* ptr, unsigned int sz) {
function read (line 296) | int read(int fd, void* buffer, unsigned int sz) {
function compat_recv (line 320) | int compat_recv(SOCKET s, char *buf, int len, int flags) {
function close (line 349) | int close(int fd) {
function daemon (line 354) | int daemon(int a, int b) {
FILE: 3rd/compat-mingw/unistd.h
type timespec (line 80) | struct timespec
type sigaction (line 85) | struct sigaction {
type sigaction (line 93) | struct sigaction
FILE: 3rd/compat-mingw/wepoll.c
type EPOLL_EVENTS (line 38) | enum EPOLL_EVENTS {
type SOCKET (line 71) | typedef uintptr_t SOCKET;
type epoll_data_t (line 73) | typedef union epoll_data {
type epoll_event (line 82) | struct epoll_event {
type epoll_event (line 99) | struct epoll_event
type epoll_event (line 102) | struct epoll_event
type LONG (line 143) | typedef LONG NTSTATUS;
type NTSTATUS (line 144) | typedef NTSTATUS* PNTSTATUS;
type IO_STATUS_BLOCK (line 166) | typedef struct _IO_STATUS_BLOCK {
type UNICODE_STRING (line 175) | typedef struct _UNICODE_STRING {
type OBJECT_ATTRIBUTES (line 184) | typedef struct _OBJECT_ATTRIBUTES {
type AFD_POLL_HANDLE_INFO (line 282) | typedef struct _AFD_POLL_HANDLE_INFO {
type AFD_POLL_INFO (line 288) | typedef struct _AFD_POLL_INFO {
function afd_create_device_handle (line 328) | int afd_create_device_handle(HANDLE iocp_handle,
function afd_poll (line 366) | int afd_poll(HANDLE afd_device_handle,
function afd_cancel_poll (line 394) | int afd_cancel_poll(HANDLE afd_device_handle,
type port_state_t (line 419) | typedef struct port_state port_state_t;
type queue_t (line 420) | typedef struct queue queue_t;
type sock_state_t (line 421) | typedef struct sock_state sock_state_t;
type ts_tree_node_t (line 422) | typedef struct ts_tree_node ts_tree_node_t;
type epoll_event (line 429) | struct epoll_event
type epoll_event (line 436) | struct epoll_event
type reflock_t (line 482) | typedef struct reflock {
type tree_t (line 499) | typedef struct tree tree_t;
type tree_node_t (line 500) | typedef struct tree_node tree_node_t;
type tree_t (line 502) | typedef struct tree {
type tree_node_t (line 506) | typedef struct tree_node {
type ts_tree_t (line 523) | typedef struct ts_tree {
type ts_tree_node_t (line 528) | typedef struct ts_tree_node {
function epoll_global_init (line 550) | int epoll_global_init(void) {
function HANDLE (line 555) | static HANDLE epoll__create(void) {
function HANDLE (line 577) | HANDLE epoll_create(int size) {
function HANDLE (line 584) | HANDLE epoll_create1(int flags) {
function epoll_close (line 591) | int epoll_close(HANDLE ephnd) {
function epoll_ctl (line 616) | int epoll_ctl(HANDLE ephnd, int op, SOCKET sock, struct epoll_event* ev) {
function epoll_wait (line 648) | int epoll_wait(HANDLE ephnd,
function errno_t (line 788) | static errno_t err__map_win_error_to_errno(DWORD error) {
function err_map_win_error (line 799) | void err_map_win_error(void) {
function err_set_win_error (line 803) | void err_set_win_error(DWORD error) {
function err_check_handle (line 808) | int err_check_handle(HANDLE handle) {
function BOOL (line 842) | static BOOL CALLBACK init__once_callback(INIT_ONCE* once,
function init (line 858) | int init(void) {
type FARPROC (line 879) | typedef FARPROC nt__fn_ptr_cast_t;
function nt_global_init (line 887) | int nt_global_init(void) {
type poll_group_t (line 908) | typedef struct poll_group poll_group_t;
type queue_node_t (line 910) | typedef struct queue_node queue_node_t;
type queue_node_t (line 922) | typedef struct queue_node {
type queue_t (line 927) | typedef struct queue {
type poll_group_t (line 948) | typedef struct poll_group {
function poll_group_t (line 955) | static poll_group_t* poll_group__new(port_state_t* port_state) {
function poll_group_delete (line 979) | void poll_group_delete(poll_group_t* poll_group) {
function poll_group_t (line 986) | poll_group_t* poll_group_from_queue_node(queue_node_t* queue_node) {
function HANDLE (line 990) | HANDLE poll_group_get_afd_device_handle(poll_group_t* poll_group) {
function poll_group_t (line 994) | poll_group_t* poll_group_acquire(port_state_t* port_state) {
function poll_group_release (line 1014) | void poll_group_release(poll_group_t* poll_group) {
type epoll_event (line 1035) | struct epoll_event
type epoll_event (line 1041) | struct epoll_event
type port_state_t (line 1053) | typedef struct port_state {
function port_state_t (line 1064) | static inline port_state_t* port__alloc(void) {
function port__free (line 1072) | static inline void port__free(port_state_t* port) {
function HANDLE (line 1077) | static inline HANDLE port__create_iocp(void) {
function port_state_t (line 1086) | port_state_t* port_new(HANDLE* iocp_handle_out) {
function port__close_iocp (line 1117) | static inline int port__close_iocp(port_state_t* port_state) {
function port_close (line 1127) | int port_close(port_state_t* port_state) {
function port_delete (line 1137) | int port_delete(port_state_t* port_state) {
function port__update_events (line 1168) | static int port__update_events(port_state_t* port_state) {
function port__update_events_if_polling (line 1186) | static inline void port__update_events_if_polling(port_state_t* port_sta...
function port__feed_events (line 1191) | static inline int port__feed_events(port_state_t* port_state,
function port__poll (line 1209) | static inline int port__poll(port_state_t* port_state,
function port_wait (line 1241) | int port_wait(port_state_t* port_state,
function port__ctl_add (line 1319) | static inline int port__ctl_add(port_state_t* port_state,
function port__ctl_mod (line 1336) | static inline int port__ctl_mod(port_state_t* port_state,
function port__ctl_del (line 1351) | static inline int port__ctl_del(port_state_t* port_state, SOCKET sock) {
function port__ctl_op (line 1361) | static inline int port__ctl_op(port_state_t* port_state,
function port_ctl (line 1377) | int port_ctl(port_state_t* port_state,
function port_register_socket (line 1390) | int port_register_socket(port_state_t* port_state,
function port_unregister_socket (line 1400) | void port_unregister_socket(port_state_t* port_state,
function sock_state_t (line 1405) | sock_state_t* port_find_socket(port_state_t* port_state, SOCKET socket) {
function port_request_socket_update (line 1412) | void port_request_socket_update(port_state_t* port_state,
function port_cancel_socket_update (line 1420) | void port_cancel_socket_update(port_state_t* port_state,
function port_add_deleted_socket (line 1428) | void port_add_deleted_socket(port_state_t* port_state,
function port_remove_deleted_socket (line 1436) | void port_remove_deleted_socket(port_state_t* port_state,
function HANDLE (line 1444) | HANDLE port_get_iocp_handle(port_state_t* port_state) {
function queue_t (line 1449) | queue_t* port_get_poll_group_queue(port_state_t* port_state) {
function port_state_t (line 1453) | port_state_t* port_state_from_handle_tree_node(ts_tree_node_t* tree_node) {
function ts_tree_node_t (line 1457) | ts_tree_node_t* port_state_to_handle_tree_node(port_state_t* port_state) {
function queue_init (line 1461) | void queue_init(queue_t* queue) {
function queue_node_init (line 1465) | void queue_node_init(queue_node_t* node) {
function queue__detach_node (line 1470) | static inline void queue__detach_node(queue_node_t* node) {
function queue_node_t (line 1475) | queue_node_t* queue_first(const queue_t* queue) {
function queue_node_t (line 1479) | queue_node_t* queue_last(const queue_t* queue) {
function queue_prepend (line 1483) | void queue_prepend(queue_t* queue, queue_node_t* node) {
function queue_append (line 1490) | void queue_append(queue_t* queue, queue_node_t* node) {
function queue_move_to_start (line 1497) | void queue_move_to_start(queue_t* queue, queue_node_t* node) {
function queue_move_to_end (line 1502) | void queue_move_to_end(queue_t* queue, queue_node_t* node) {
function queue_remove (line 1507) | void queue_remove(queue_node_t* node) {
function queue_is_empty (line 1512) | bool queue_is_empty(const queue_t* queue) {
function queue_is_enqueued (line 1516) | bool queue_is_enqueued(const queue_node_t* node) {
function reflock_global_init (line 1528) | int reflock_global_init(void) {
function reflock_init (line 1536) | void reflock_init(reflock_t* reflock) {
function reflock__signal_event (line 1540) | static void reflock__signal_event(void* address) {
function reflock__await_event (line 1547) | static void reflock__await_event(void* address) {
function reflock_ref (line 1554) | void reflock_ref(reflock_t* reflock) {
function reflock_unref (line 1562) | void reflock_unref(reflock_t* reflock) {
function reflock_unref_and_destroy (line 1572) | void reflock_unref_and_destroy(reflock_t* reflock) {
type sock__poll_status_t (line 1591) | typedef enum sock__poll_status {
type sock_state_t (line 1597) | typedef struct sock_state {
function sock_state_t (line 1611) | static inline sock_state_t* sock__alloc(void) {
function sock__free (line 1618) | static inline void sock__free(sock_state_t* sock_state) {
function sock__cancel_poll (line 1623) | static inline int sock__cancel_poll(sock_state_t* sock_state) {
function sock_state_t (line 1635) | sock_state_t* sock_new(port_state_t* port_state, SOCKET socket) {
function sock__delete (line 1676) | static int sock__delete(port_state_t* port_state,
function sock_delete (line 1705) | void sock_delete(port_state_t* port_state, sock_state_t* sock_state) {
function sock_force_delete (line 1709) | void sock_force_delete(port_state_t* port_state, sock_state_t* sock_stat...
function sock_set_event (line 1713) | int sock_set_event(port_state_t* port_state,
function DWORD (line 1730) | static inline DWORD sock__epoll_events_to_afd_events(uint32_t epoll_even...
function sock__afd_events_to_epoll_events (line 1751) | static inline uint32_t sock__afd_events_to_epoll_events(DWORD afd_events) {
function sock_update (line 1772) | int sock_update(port_state_t* port_state, sock_state_t* sock_state) {
function sock_feed_event (line 1834) | int sock_feed_event(port_state_t* port_state,
function sock_state_t (line 1889) | sock_state_t* sock_state_from_queue_node(queue_node_t* queue_node) {
function queue_node_t (line 1893) | queue_node_t* sock_state_to_queue_node(sock_state_t* sock_state) {
function sock_state_t (line 1897) | sock_state_t* sock_state_from_tree_node(tree_node_t* tree_node) {
function tree_node_t (line 1901) | tree_node_t* sock_state_to_tree_node(sock_state_t* sock_state) {
function ts_tree_init (line 1905) | void ts_tree_init(ts_tree_t* ts_tree) {
function ts_tree_node_init (line 1910) | void ts_tree_node_init(ts_tree_node_t* node) {
function ts_tree_add (line 1915) | int ts_tree_add(ts_tree_t* ts_tree, ts_tree_node_t* node, uintptr_t key) {
function ts_tree_node_t (line 1925) | static inline ts_tree_node_t* ts_tree__find_node(ts_tree_t* ts_tree,
function ts_tree_node_t (line 1934) | ts_tree_node_t* ts_tree_del_and_ref(ts_tree_t* ts_tree, uintptr_t key) {
function ts_tree_node_t (line 1950) | ts_tree_node_t* ts_tree_find_and_ref(ts_tree_t* ts_tree, uintptr_t key) {
function ts_tree_node_unref (line 1964) | void ts_tree_node_unref(ts_tree_node_t* node) {
function ts_tree_node_unref_and_destroy (line 1968) | void ts_tree_node_unref_and_destroy(ts_tree_node_t* node) {
function tree_init (line 1972) | void tree_init(tree_t* tree) {
function tree_node_init (line 1976) | void tree_node_init(tree_node_t* node) {
function tree__rotate_left (line 2001) | static inline void tree__rotate_left(tree_t* tree, tree_node_t* node) {
function tree__rotate_right (line 2005) | static inline void tree__rotate_right(tree_t* tree, tree_node_t* node) {
function tree_add (line 2036) | int tree_add(tree_t* tree, tree_node_t* node, uintptr_t key) {
function tree_del (line 2096) | void tree_del(tree_t* tree, tree_node_t* node) {
function tree_node_t (line 2169) | tree_node_t* tree_find(const tree_t* tree, uintptr_t key) {
function tree_node_t (line 2182) | tree_node_t* tree_root(const tree_t* tree) {
function ws_global_init (line 2194) | int ws_global_init(void) {
function SOCKET (line 2205) | static inline SOCKET ws__ioctl_get_bsp_socket(SOCKET socket, DWORD ioctl) {
function SOCKET (line 2223) | SOCKET ws_get_base_socket(SOCKET socket) {
FILE: 3rd/compat-mingw/wepoll.h
type EPOLL_EVENTS (line 41) | enum EPOLL_EVENTS {
type SOCKET (line 74) | typedef uintptr_t SOCKET;
type epoll_data_t (line 76) | typedef union epoll_data {
type epoll_event (line 85) | struct epoll_event {
type epoll_event (line 102) | struct epoll_event
type epoll_event (line 105) | struct epoll_event
FILE: 3rd/lpeg/lpcap.c
function Index_t (line 24) | static Index_t capsize (Capture *cap, Capture *close) {
function Index_t (line 34) | static Index_t closesize (CapState *cs, Capture *head) {
function updatecache (line 43) | static int updatecache (CapState *cs, int v) {
function Capture (line 61) | static Capture *findopen (Capture *cap) {
function nextcap (line 75) | static void nextcap (CapState *cs) {
function pushnestedvalues (line 103) | static int pushnestedvalues (CapState *cs, int addextra) {
function pushonenestedvalue (line 121) | static void pushonenestedvalue (CapState *cs) {
function capvisible (line 138) | static int capvisible (CapState *cs, Capture *grp, Capture *ref) {
function Capture (line 157) | static Capture *findback (CapState *cs, Capture *ref) {
function backrefcap (line 182) | static int backrefcap (CapState *cs) {
function tablecap (line 197) | static int tablecap (CapState *cs) {
function querycap (line 224) | static int querycap (CapState *cs) {
function foldcap (line 240) | static int foldcap (CapState *cs) {
function functioncap (line 264) | static int functioncap (CapState *cs) {
function accumulatorcap (line 277) | static int accumulatorcap (CapState *cs) {
function numcap (line 293) | static int numcap (CapState *cs) {
function finddyncap (line 317) | int finddyncap (Capture *cap, Capture *last) {
function runtimecap (line 331) | int runtimecap (CapState *cs, Capture *close, const char *s, int *rem) {
type StrAux (line 364) | typedef struct StrAux {
function getstrcaps (line 383) | static int getstrcaps (CapState *cs, StrAux *cps, int n) {
function stringcap (line 416) | static void stringcap (luaL_Buffer *b, CapState *cs) {
function substcap (line 449) | static void substcap (luaL_Buffer *b, CapState *cs) {
function addonestring (line 471) | static int addonestring (luaL_Buffer *b, CapState *cs, const char *what) {
function pushcapture (line 506) | static int pushcapture (CapState *cs) {
function getcaptures (line 591) | int getcaptures (lua_State *L, const char *s, const char *r, int ptop) {
FILE: 3rd/lpeg/lpcap.h
type CapKind (line 10) | typedef enum CapKind {
type uint (line 36) | typedef uint Index_t;
type Capture (line 42) | typedef struct Capture {
type CapState (line 50) | typedef struct CapState {
FILE: 3rd/lpeg/lpcode.c
function cs_complement (line 37) | static void cs_complement (Charset *cs) {
function cs_disjoint (line 41) | static int cs_disjoint (const Charset *cs1, const Charset *cs2) {
function callrecursive (line 52) | static int callrecursive (TTree *tree, int f (TTree *t), int def) {
function hascaptures (line 71) | int hascaptures (TTree *tree) {
function checkaux (line 115) | int checkaux (TTree *tree, int pred) {
function fixedlen (line 155) | int fixedlen (TTree *tree) {
function getfirst (line 215) | static int getfirst (TTree *tree, const Charset *follow, Charset *firsts...
function headfail (line 300) | static int headfail (TTree *tree) {
function needfollow (line 330) | static int needfollow (TTree *tree) {
function sizei (line 361) | int sizei (const Instruction *i) {
type CompileState (line 377) | typedef struct CompileState {
function finishrelcode (line 395) | static void finishrelcode (lua_State *L, Pattern *p, Instruction *block,
function newcode (line 407) | static void newcode (lua_State *L, Pattern *p, int size) {
function freecode (line 417) | void freecode (lua_State *L, Pattern *p) {
function realloccode (line 430) | static void realloccode (lua_State *L, Pattern *p, int nsize) {
function nextinstruction (line 445) | static int nextinstruction (CompileState *compst, int n) {
function addinstruction (line 462) | static int addinstruction (CompileState *compst, Opcode op, int aux) {
function addoffsetinst (line 473) | static int addoffsetinst (CompileState *compst, Opcode op) {
function setoffset (line 484) | static void setoffset (CompileState *compst, int instruction, int offset) {
function codeutfr (line 489) | static void codeutfr (CompileState *compst, TTree *tree) {
function addinstcap (line 505) | static int addinstcap (CompileState *compst, Opcode op, int cap, int key,
function jumptothere (line 521) | static void jumptothere (CompileState *compst, int instruction, int targ...
function jumptohere (line 530) | static void jumptohere (CompileState *compst, int instruction) {
function codechar (line 539) | static void codechar (CompileState *compst, int c, int tt) {
function addcharset (line 551) | static void addcharset (CompileState *compst, int inst, charsetinfo *inf...
function cs_equal (line 570) | static int cs_equal (Instruction *p, charsetinfo *info) {
function codecharset (line 592) | static void codecharset (CompileState *compst, TTree *tree, int tt) {
function codetestset (line 610) | static int codetestset (CompileState *compst, Charset *cs, int e) {
function finaltarget (line 637) | static int finaltarget (Instruction *code, int i) {
function finallabel (line 647) | static int finallabel (Instruction *code, int i) {
function codebehind (line 655) | static void codebehind (CompileState *compst, TTree *tree) {
function codechoice (line 673) | static void codechoice (CompileState *compst, TTree *p1, TTree *p2, int ...
function codeand (line 716) | static void codeand (CompileState *compst, TTree *tree, int tt) {
function codecapture (line 741) | static void codecapture (CompileState *compst, TTree *tree, int tt,
function coderuntime (line 756) | static void coderuntime (CompileState *compst, TTree *tree, int tt) {
function closeloop (line 766) | static void closeloop (CompileState *compst, int test) {
function coderepcharset (line 779) | static int coderepcharset (CompileState *compst, TTree *tree) {
function coderep (line 817) | static void coderep (CompileState *compst, TTree *tree, int opt,
function codenot (line 856) | static void codenot (CompileState *compst, TTree *tree) {
function correctcalls (line 877) | static void correctcalls (CompileState *compst, int *positions,
function codegrammar (line 901) | static void codegrammar (CompileState *compst, TTree *grammar) {
function codecall (line 922) | static void codecall (CompileState *compst, TTree *call) {
function codeseq1 (line 934) | static int codeseq1 (CompileState *compst, TTree *p1, TTree *p2,
function codegen (line 954) | static void codegen (CompileState *compst, TTree *tree, int opt, int tt,
function peephole (line 992) | static void peephole (CompileState *compst) {
function Instruction (line 1038) | Instruction *compile (lua_State *L, Pattern *p, uint size) {
FILE: 3rd/lpeg/lpcset.c
function onlybit (line 9) | static int onlybit (int c, int b) {
function Opcode (line 23) | Opcode charsettype (const byte *cs, charsetinfo *info) {
function byte (line 64) | byte getbytefromcharset (const charsetinfo *info, int index) {
function tocharset (line 75) | int tocharset (TTree *tree, Charset *cs) {
function tree2cset (line 103) | void tree2cset (TTree *tree, charsetinfo *info) {
FILE: 3rd/lpeg/lpcset.h
type charsetinfo (line 17) | typedef struct {
FILE: 3rd/lpeg/lpprint.c
function printcharset (line 21) | void printcharset (const byte *st) {
function printIcharset (line 36) | static void printIcharset (const Instruction *inst, const byte *buff) {
function printTcharset (line 49) | static void printTcharset (TTree *tree) {
function printjmp (line 70) | static void printjmp (const Instruction *op, const Instruction *p) {
function printinst (line 75) | void printinst (const Instruction *op, const Instruction *p) {
function printpatt (line 140) | void printpatt (Instruction *p) {
function printcap (line 150) | static void printcap (Capture *cap, int ident) {
function Capture (line 160) | static Capture *printcap2close (Capture *cap, int ident) {
function printcaplist (line 173) | void printcaplist (Capture *cap) {
function printtree (line 205) | void printtree (TTree *tree, int ident) {
function printktable (line 276) | void printktable (lua_State *L, int idx) {
FILE: 3rd/lpeg/lptree.c
function fixonecall (line 51) | static void fixonecall (lua_State *L, int postable, TTree *g, TTree *t) {
function correctassociativity (line 75) | static void correctassociativity (TTree *tree) {
function finalfix (line 97) | static void finalfix (lua_State *L, int postable, TTree *g, TTree *t) {
function newktable (line 144) | static void newktable (lua_State *L, int n) {
function addtoktable (line 156) | static int addtoktable (lua_State *L, int idx) {
function ktablelen (line 179) | static int ktablelen (lua_State *L, int idx) {
function concattable (line 191) | static int concattable (lua_State *L, int idx1, int idx2) {
function correctkeys (line 211) | static void correctkeys (TTree *tree, int n) {
function joinktables (line 242) | static void joinktables (lua_State *L, int p1, TTree *t2, int p2) {
function copyktable (line 273) | static void copyktable (lua_State *L, int idx) {
function mergektable (line 284) | static void mergektable (lua_State *L, int idx, TTree *stree) {
function addtonewktable (line 299) | static int addtonewktable (lua_State *L, int p, int idx) {
function testpattern (line 318) | static int testpattern (lua_State *L, int idx) {
function Pattern (line 332) | static Pattern *getpattern (lua_State *L, int idx) {
function getsize (line 337) | static int getsize (lua_State *L, int idx) {
function TTree (line 342) | static TTree *gettree (lua_State *L, int idx, int *len) {
function TTree (line 355) | static TTree *newtree (lua_State *L, int len) {
function TTree (line 367) | static TTree *newleaf (lua_State *L, int tag) {
function TTree (line 378) | static TTree *newcharset (lua_State *L, byte *cs) {
function TTree (line 413) | static TTree *seqaux (TTree *tree, TTree *sib, int sibsize) {
function fillseq (line 425) | static void fillseq (TTree *tree, int tag, int n, const char *s) {
function TTree (line 443) | static TTree *numtree (lua_State *L, int n) {
function TTree (line 465) | static TTree *getpatt (lua_State *L, int idx, int *len) {
function TTree (line 514) | static TTree *newroot1sib (lua_State *L, int tag) {
function TTree (line 529) | static TTree *newroot2sib (lua_State *L, int tag) {
function lp_P (line 543) | static int lp_P (lua_State *L) {
function lp_seq (line 556) | static int lp_seq (lua_State *L) {
function lp_choice (line 575) | static int lp_choice (lua_State *L) {
function lp_star (line 596) | static int lp_star (lua_State *L) {
function lp_and (line 632) | static int lp_and (lua_State *L) {
function lp_not (line 641) | static int lp_not (lua_State *L) {
function lp_sub (line 651) | static int lp_sub (lua_State *L) {
function lp_set (line 673) | static int lp_set (lua_State *L) {
function lp_range (line 687) | static int lp_range (lua_State *L) {
function codeutftree (line 710) | static void codeutftree (lua_State *L, TTree *t, lua_Unsigned cpu, int a...
function lp_utfr (line 734) | static int lp_utfr (lua_State *L) {
function lp_behind (line 760) | static int lp_behind (lua_State *L) {
function lp_V (line 776) | static int lp_V (lua_State *L) {
function capture_aux (line 789) | static int capture_aux (lua_State *L, int cap, int labelidx) {
function TTree (line 801) | static TTree *auxemptycap (TTree *tree, int cap) {
function TTree (line 812) | static TTree *newemptycap (lua_State *L, int cap, int key) {
function TTree (line 822) | static TTree *newemptycapkey (lua_State *L, int cap, int idx) {
function lp_divcapture (line 833) | static int lp_divcapture (lua_State *L) {
function lp_acccapture (line 853) | static int lp_acccapture (lua_State *L) {
function lp_substcapture (line 858) | static int lp_substcapture (lua_State *L) {
function lp_tablecapture (line 863) | static int lp_tablecapture (lua_State *L) {
function lp_groupcapture (line 868) | static int lp_groupcapture (lua_State *L) {
function lp_foldcapture (line 876) | static int lp_foldcapture (lua_State *L) {
function lp_simplecapture (line 882) | static int lp_simplecapture (lua_State *L) {
function lp_poscapture (line 887) | static int lp_poscapture (lua_State *L) {
function lp_argcapture (line 893) | static int lp_argcapture (lua_State *L) {
function lp_backref (line 901) | static int lp_backref (lua_State *L) {
function lp_constcapture (line 911) | static int lp_constcapture (lua_State *L) {
function lp_matchtime (line 939) | static int lp_matchtime (lua_State *L) {
function getfirstrule (line 961) | static void getfirstrule (lua_State *L, int arg, int postab) {
function collectrules (line 990) | static int collectrules (lua_State *L, int arg, int *totalsize) {
function buildgrammar (line 1019) | static void buildgrammar (lua_State *L, TTree *grammar, int frule, int n) {
function checkloops (line 1043) | static int checkloops (TTree *tree) {
function verifyerror (line 1068) | static int verifyerror (lua_State *L, unsigned short *passed, int npasse...
function verifyrule (line 1093) | static int verifyrule (lua_State *L, TTree *tree, unsigned short *passed,
function verifygrammar (line 1136) | static void verifygrammar (lua_State *L, TTree *grammar) {
function initialrulename (line 1160) | static void initialrulename (lua_State *L, TTree *grammar, int frule) {
function TTree (line 1170) | static TTree *newgrammar (lua_State *L, int arg) {
function Instruction (line 1193) | static Instruction *prepcompile (lua_State *L, Pattern *p, int idx) {
function lp_printtree (line 1201) | static int lp_printtree (lua_State *L) {
function lp_printcode (line 1215) | static int lp_printcode (lua_State *L) {
function initposition (line 1229) | static size_t initposition (lua_State *L, size_t len) {
function lp_match (line 1247) | static int lp_match (lua_State *L) {
function lp_setmax (line 1279) | static int lp_setmax (lua_State *L) {
function lp_type (line 1288) | static int lp_type (lua_State *L) {
function lp_gc (line 1297) | int lp_gc (lua_State *L) {
function createcat (line 1308) | static void createcat (lua_State *L, const char *catname, int (catf) (in...
function lp_locale (line 1319) | static int lp_locale (lua_State *L) {
type luaL_Reg (line 1343) | struct luaL_Reg
type luaL_Reg (line 1371) | struct luaL_Reg
function luaopen_lpeg (line 1386) | int luaopen_lpeg (lua_State *L) {
FILE: 3rd/lpeg/lptree.h
type TTag (line 12) | typedef enum TTag {
type TTree (line 48) | typedef struct TTree {
type Pattern (line 73) | typedef struct Pattern {
FILE: 3rd/lpeg/lptypes.h
type lua_Unsigned (line 40) | typedef size_t lua_Unsigned;
type byte (line 84) | typedef unsigned char byte;
type uint (line 86) | typedef unsigned int uint;
type Charset (line 95) | typedef struct Charset {
FILE: 3rd/lpeg/lpvm.c
function charinset (line 26) | int charinset (const Instruction *i, const byte *buff, uint c) {
type Stack (line 72) | typedef struct Stack {
function Capture (line 96) | static Capture *growcap (lua_State *L, Capture *capture, int *capsize,
function Stack (line 121) | static Stack *doublestack (lua_State *L, Stack **stacklimit, int ptop) {
function resdyncaptures (line 148) | static int resdyncaptures (lua_State *L, int fr, int curr, int limit) {
function adddyncaptures (line 172) | static void adddyncaptures (Index_t index, Capture *capture, int n, int ...
function removedyncap (line 191) | static int removedyncap (lua_State *L, Capture *capture,
function Capture (line 208) | static Capture *findopen (Capture *cap, Index_t currindex) {
FILE: 3rd/lpeg/lpvm.h
type Opcode (line 16) | typedef enum Opcode {
type Instruction (line 51) | typedef union Instruction {
FILE: 3rd/lua-md5/compat-5.2.c
function luaL_setfuncs (line 9) | void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
FILE: 3rd/lua-md5/md5.c
type WORD32 (line 17) | typedef uint32_t WORD32;
type WORD32 (line 19) | typedef unsigned int WORD32;
function word32tobytes (line 68) | static void word32tobytes (const WORD32 *input, char *output) {
function inic_digest (line 80) | static void inic_digest(WORD32 *d) {
function digest (line 89) | static void digest(const WORD32 *m, WORD32 *d) {
function bytestoword32 (line 150) | static void bytestoword32 (WORD32 *x, const char *pt) {
function put_length (line 163) | static void put_length(WORD32 *x, long len) {
function converte (line 176) | static int converte (WORD32 *x, const char *pt, int num, int old_status) {
function md5 (line 195) | void md5 (const char *message, long len, char *output) {
FILE: 3rd/lua-md5/md5lib.c
function lmd5 (line 24) | static int lmd5 (lua_State *L) {
function ex_or (line 41) | static int ex_or (lua_State *L) {
function checkseed (line 54) | static void checkseed (lua_State *L) {
function initblock (line 67) | static int initblock (lua_State *L, const char *seed, int lseed, char *b...
function codestream (line 79) | static void codestream (lua_State *L, const char *msg, size_t lmsg,
function decodestream (line 96) | static void decodestream (lua_State *L, const char *cypher, size_t lcypher,
function crypt (line 123) | static int crypt (lua_State *L) {
function decrypt (line 153) | static int decrypt (lua_State *L) {
function set_info (line 173) | static void set_info (lua_State *L) {
type luaL_Reg (line 186) | struct luaL_Reg
function luaopen_md5_core (line 195) | int luaopen_md5_core (lua_State *L) {
FILE: 3rd/lua/lapi.c
function TValue (line 58) | static TValue *index2value (lua_State *L, int idx) {
function StkId (line 93) | static StkId index2stack (lua_State *L, int idx) {
function LUA_API (line 109) | LUA_API int lua_checkstack (lua_State *L, int n) {
function LUA_API (line 126) | LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
function LUA_API (line 142) | LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
function LUA_API (line 152) | LUA_API lua_Number lua_version (lua_State *L) {
function LUA_API (line 167) | LUA_API int lua_absindex (lua_State *L, int idx) {
function LUA_API (line 174) | LUA_API int lua_gettop (lua_State *L) {
function LUA_API (line 179) | LUA_API void lua_settop (lua_State *L, int idx) {
function LUA_API (line 206) | LUA_API void lua_closeslot (lua_State *L, int idx) {
function reverse (line 224) | static void reverse (lua_State *L, StkId from, StkId to) {
function LUA_API (line 238) | LUA_API void lua_rotate (lua_State *L, int idx, int n) {
function LUA_API (line 253) | LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
function LUA_API (line 268) | LUA_API void lua_pushvalue (lua_State *L, int idx) {
function LUA_API (line 282) | LUA_API int lua_type (lua_State *L, int idx) {
function LUA_API (line 288) | LUA_API const char *lua_typename (lua_State *L, int t) {
function LUA_API (line 295) | LUA_API int lua_iscfunction (lua_State *L, int idx) {
function LUA_API (line 301) | LUA_API int lua_isinteger (lua_State *L, int idx) {
function LUA_API (line 307) | LUA_API int lua_isnumber (lua_State *L, int idx) {
function LUA_API (line 314) | LUA_API int lua_isstring (lua_State *L, int idx) {
function LUA_API (line 320) | LUA_API int lua_isuserdata (lua_State *L, int idx) {
function LUA_API (line 326) | LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
function LUA_API (line 333) | LUA_API void lua_arith (lua_State *L, int op) {
function LUA_API (line 349) | LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
function LUA_API (line 381) | LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
function LUA_API (line 389) | LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
function LUA_API (line 399) | LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
function LUA_API (line 409) | LUA_API int lua_toboolean (lua_State *L, int idx) {
function LUA_API (line 415) | LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
function LUA_API (line 437) | LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) {
function LUA_API (line 455) | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
function l_sinline (line 464) | l_sinline void *touserdata (const TValue *o) {
function LUA_API (line 473) | LUA_API void *lua_touserdata (lua_State *L, int idx) {
function LUA_API (line 479) | LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
function LUA_API (line 492) | LUA_API const void *lua_topointer (lua_State *L, int idx) {
function LUA_API (line 514) | LUA_API void lua_pushnil (lua_State *L) {
function LUA_API (line 522) | LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
function LUA_API (line 530) | LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
function LUA_API (line 543) | LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t...
function LUA_API (line 555) | LUA_API const char *lua_pushexternalstring (lua_State *L,
function LUA_API (line 570) | LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
function LUA_API (line 587) | LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
function LUA_API (line 598) | LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
function LUA_API (line 609) | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
function LUA_API (line 636) | LUA_API void lua_pushboolean (lua_State *L, int b) {
function LUA_API (line 647) | LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
function LUA_API (line 655) | LUA_API int lua_pushthread (lua_State *L) {
function auxgetstr (line 670) | static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
function getGlobalTable (line 691) | static void getGlobalTable (lua_State *L, TValue *gt) {
function LUA_API (line 699) | LUA_API int lua_getglobal (lua_State *L, const char *name) {
function LUA_API (line 707) | LUA_API int lua_gettable (lua_State *L, int idx) {
function LUA_API (line 721) | LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
function LUA_API (line 727) | LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
function finishrawget (line 744) | static int finishrawget (lua_State *L, lu_byte tag) {
function l_sinline (line 753) | l_sinline Table *gettable (lua_State *L, int idx) {
function LUA_API (line 760) | LUA_API int lua_rawget (lua_State *L, int idx) {
function LUA_API (line 772) | LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
function LUA_API (line 782) | LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
function LUA_API (line 792) | LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
function LUA_API (line 805) | LUA_API int lua_getmetatable (lua_State *L, int objindex) {
function LUA_API (line 832) | LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) {
function auxsetstr (line 859) | static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
function LUA_API (line 878) | LUA_API void lua_setglobal (lua_State *L, const char *name) {
function LUA_API (line 886) | LUA_API void lua_settable (lua_State *L, int idx) {
function LUA_API (line 902) | LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
function LUA_API (line 908) | LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
function aux_rawset (line 927) | static void aux_rawset (lua_State *L, int idx, TValue *key, int n) {
function LUA_API (line 940) | LUA_API void lua_rawset (lua_State *L, int idx) {
function LUA_API (line 945) | LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
function LUA_API (line 952) | LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
function LUA_API (line 964) | LUA_API int lua_setmetatable (lua_State *L, int objindex) {
function LUA_API (line 1006) | LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) {
function LUA_API (line 1039) | LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
type CallS (line 1065) | struct CallS { /* data to 'f_call' */
function f_call (line 1071) | static void f_call (lua_State *L, void *ud) {
function LUA_API (line 1078) | LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
function set_env (line 1121) | static void set_env (lua_State *L, LClosure *f) {
function LUA_API (line 1132) | LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
function LUA_API (line 1148) | LUA_API void lua_clonefunction (lua_State *L, const void * fp) {
function LUA_API (line 1162) | LUA_API void lua_sharefunction (lua_State *L, int index) {
function LUA_API (line 1170) | LUA_API void lua_sharestring (lua_State *L, int index) {
function LUA_API (line 1178) | LUA_API void lua_clonetable(lua_State *L, const void * tp) {
function LUA_API (line 1194) | LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int s...
function LUA_API (line 1208) | LUA_API int lua_status (lua_State *L) {
function LUA_API (line 1216) | LUA_API int lua_gc (lua_State *L, int what, ...) {
function LUA_API (line 1298) | LUA_API int lua_error (lua_State *L) {
function LUA_API (line 1313) | LUA_API int lua_next (lua_State *L, int idx) {
function LUA_API (line 1329) | LUA_API void lua_toclose (lua_State *L, int idx) {
function LUA_API (line 1340) | LUA_API void lua_concat (lua_State *L, int n) {
function LUA_API (line 1355) | LUA_API void lua_len (lua_State *L, int idx) {
function LUA_API (line 1365) | LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
function LUA_API (line 1375) | LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
function lua_setwarnf (line 1383) | void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) {
function lua_warning (line 1391) | void lua_warning (lua_State *L, const char *msg, int tocont) {
function LUA_API (line 1399) | LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
function LUA_API (line 1440) | LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
function LUA_API (line 1454) | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
function UpVal (line 1473) | static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
function LUA_API (line 1487) | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
function LUA_API (line 1509) | LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
FILE: 3rd/lua/lauxlib.c
function findfield (line 47) | static int findfield (lua_State *L, int objidx, int level) {
function pushglobalfuncname (line 74) | static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
function pushfuncname (line 96) | static void pushfuncname (lua_State *L, lua_Debug *ar) {
function lastlevel (line 112) | static int lastlevel (lua_State *L) {
function LUALIB_API (line 127) | LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
function LUALIB_API (line 171) | LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extrams...
function LUALIB_API (line 197) | LUALIB_API int luaL_typeerror (lua_State *L, int arg, const char *tname) {
function tag_error (line 211) | static void tag_error (lua_State *L, int arg, int tag) {
function LUALIB_API (line 220) | LUALIB_API void luaL_where (lua_State *L, int level) {
function LUALIB_API (line 238) | LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
function LUALIB_API (line 249) | LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fnam...
function LUALIB_API (line 291) | LUALIB_API int luaL_execresult (lua_State *L, int stat) {
function LUALIB_API (line 317) | LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
function LUALIB_API (line 330) | LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
function LUALIB_API (line 336) | LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
function LUALIB_API (line 351) | LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tnam...
function LUALIB_API (line 366) | LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
function LUALIB_API (line 386) | LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *ms...
function LUALIB_API (line 396) | LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) {
function LUALIB_API (line 402) | LUALIB_API void luaL_checkany (lua_State *L, int arg) {
function LUALIB_API (line 408) | LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t ...
function LUALIB_API (line 415) | LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
function LUALIB_API (line 426) | LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
function LUALIB_API (line 435) | LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number ...
function interror (line 440) | static void interror (lua_State *L, int arg) {
function LUALIB_API (line 448) | LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
function LUALIB_API (line 458) | LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg,
type UBox (line 473) | typedef struct UBox {
function boxgc (line 503) | static int boxgc (lua_State *L) {
function newbox (line 516) | static void newbox (lua_State *L) {
function newbuffsize (line 546) | static size_t newbuffsize (luaL_Buffer *B, size_t sz) {
function LUALIB_API (line 592) | LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
function LUALIB_API (line 597) | LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
function LUALIB_API (line 606) | LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
function LUALIB_API (line 611) | LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
function LUALIB_API (line 635) | LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
function LUALIB_API (line 650) | LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
function LUALIB_API (line 661) | LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
function LUALIB_API (line 670) | LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t...
function LUALIB_API (line 689) | LUALIB_API int luaL_ref (lua_State *L, int t) {
function LUALIB_API (line 716) | LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
type LoadF (line 736) | typedef struct LoadF {
function errfile (line 761) | static int errfile (lua_State *L, const char *what, int fnameindex) {
function skipBOM (line 779) | static int skipBOM (FILE *f) {
function skipcomment (line 795) | static int skipcomment (FILE *f, int *cp) {
function LUALIB_API (line 808) | LUALIB_API int luaL_loadfilex_ (lua_State *L, const char *filename,
type LoadS (line 851) | typedef struct LoadS {
function LUALIB_API (line 867) | LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t ...
function LUALIB_API (line 876) | LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
function LUALIB_API (line 884) | LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *eve...
function LUALIB_API (line 900) | LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
function LUALIB_API (line 910) | LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
function LUALIB_API (line 922) | LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *le...
function LUALIB_API (line 965) | LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
function LUALIB_API (line 986) | LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fnam...
function LUALIB_API (line 1006) | LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
function LUALIB_API (line 1026) | LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
function LUALIB_API (line 1039) | LUALIB_API const char *luaL_gsub (lua_State *L, const char *s,
function panic (line 1064) | static int panic (lua_State *L) {
function checkcontrol (line 1089) | static int checkcontrol (lua_State *L, const char *message, int tocont) {
function warnfoff (line 1102) | static void warnfoff (void *ud, const char *message, int tocont) {
function warnfcont (line 1111) | static void warnfcont (void *ud, const char *message, int tocont) {
function warnfon (line 1123) | static void warnfon (void *ud, const char *message, int tocont) {
function luai_makeseed (line 1155) | static unsigned int luai_makeseed (void) {
function luaL_makeseed (line 1174) | LUALIB_API unsigned int luaL_makeseed (lua_State *L) {
function LUALIB_API (line 1184) | LUALIB_API lua_State *(luaL_newstate) (void) {
function LUALIB_API (line 1194) | LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t...
type codecache (line 1208) | struct codecache {
type codecache (line 1213) | struct codecache
function lua_State (line 1215) | static lua_State *
function clearcache (line 1221) | static void
function init (line 1232) | static void
function LUALIB_API (line 1237) | LUALIB_API void
function cache_level (line 1291) | static int cache_level(lua_State *L) {
function cache_mode (line 1301) | static int cache_mode(lua_State *L) {
function LUALIB_API (line 1328) | LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
function cache_clear (line 1373) | static int
function LUAMOD_API (line 1380) | LUAMOD_API int luaopen_cache(lua_State *L) {
FILE: 3rd/lua/lauxlib.h
type luaL_Buffer (line 23) | typedef struct luaL_Buffer luaL_Buffer;
type luaL_Reg (line 38) | typedef struct luaL_Reg {
type luaL_Buffer (line 187) | struct luaL_Buffer {
type luaL_Stream (line 241) | typedef struct luaL_Stream {
FILE: 3rd/lua/lbaselib.c
function luaB_print (line 25) | static int luaB_print (lua_State *L) {
function luaB_warn (line 46) | static int luaB_warn (lua_State *L) {
function luaB_tonumber (line 83) | static int luaB_tonumber (lua_State *L) {
function luaB_error (line 116) | static int luaB_error (lua_State *L) {
function luaB_getmetatable (line 128) | static int luaB_getmetatable (lua_State *L) {
function luaB_setmetatable (line 139) | static int luaB_setmetatable (lua_State *L) {
function luaB_rawequal (line 151) | static int luaB_rawequal (lua_State *L) {
function luaB_rawlen (line 159) | static int luaB_rawlen (lua_State *L) {
function luaB_rawget (line 168) | static int luaB_rawget (lua_State *L) {
function luaB_rawset (line 176) | static int luaB_rawset (lua_State *L) {
function pushmode (line 186) | static int pushmode (lua_State *L, int oldmode) {
function luaB_collectgarbage (line 201) | static int luaB_collectgarbage (lua_State *L) {
function luaB_type (line 260) | static int luaB_type (lua_State *L) {
function luaB_next (line 268) | static int luaB_next (lua_State *L) {
function pairscont (line 280) | static int pairscont (lua_State *L, int status, lua_KContext k) {
function luaB_pairs (line 285) | static int luaB_pairs (lua_State *L) {
function ipairsaux (line 304) | static int ipairsaux (lua_State *L) {
function luaB_ipairs (line 316) | static int luaB_ipairs (lua_State *L) {
function load_aux (line 325) | static int load_aux (lua_State *L, int status, int envidx) {
function luaB_loadfile (line 350) | static int luaB_loadfile (lua_State *L) {
function luaB_load (line 397) | static int luaB_load (lua_State *L) {
function dofilecont (line 419) | static int dofilecont (lua_State *L, int d1, lua_KContext d2) {
function luaB_dofile (line 425) | static int luaB_dofile (lua_State *L) {
function luaB_assert (line 435) | static int luaB_assert (lua_State *L) {
function luaB_select (line 448) | static int luaB_select (lua_State *L) {
function finishpcall (line 471) | static int finishpcall (lua_State *L, int status, lua_KContext extra) {
function luaB_pcall (line 482) | static int luaB_pcall (lua_State *L) {
function luaB_xpcall (line 497) | static int luaB_xpcall (lua_State *L) {
function luaB_tostring (line 509) | static int luaB_tostring (lua_State *L) {
function LUAMOD_API (line 547) | LUAMOD_API int luaopen_base (lua_State *L) {
FILE: 3rd/lua/lcode.c
function l_noret (line 43) | l_noret luaK_semerror (LexState *ls, const char *fmt, ...) {
function tonumeral (line 57) | static int tonumeral (const expdesc *e, TValue *v) {
function TValue (line 75) | static TValue *const2val (FuncState *fs, const expdesc *e) {
function luaK_exp2const (line 85) | int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) {
function Instruction (line 117) | static Instruction *previousinstruction (FuncState *fs) {
function luaK_nil (line 132) | void luaK_nil (FuncState *fs, int from, int n) {
function getjump (line 155) | static int getjump (FuncState *fs, int pc) {
function fixjump (line 168) | static void fixjump (FuncState *fs, int pc, int dest) {
function luaK_concat (line 182) | void luaK_concat (FuncState *fs, int *l1, int l2) {
function luaK_jump (line 200) | int luaK_jump (FuncState *fs) {
function luaK_ret (line 208) | void luaK_ret (FuncState *fs, int first, int nret) {
function condjump (line 224) | static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int ...
function luaK_getlabel (line 234) | int luaK_getlabel (FuncState *fs) {
function Instruction (line 245) | static Instruction *getjumpcontrol (FuncState *fs, int pc) {
function patchtestreg (line 261) | static int patchtestreg (FuncState *fs, int node, int reg) {
function removevalues (line 279) | static void removevalues (FuncState *fs, int list) {
function patchlistaux (line 290) | static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
function luaK_patchlist (line 308) | void luaK_patchlist (FuncState *fs, int list, int target) {
function luaK_patchtohere (line 314) | void luaK_patchtohere (FuncState *fs, int list) {
function savelineinfo (line 331) | static void savelineinfo (FuncState *fs, Proto *f, int line) {
function removelastlineinfo (line 355) | static void removelastlineinfo (FuncState *fs) {
function removelastinstruction (line 374) | static void removelastinstruction (FuncState *fs) {
function luaK_code (line 384) | int luaK_code (FuncState *fs, Instruction i) {
function luaK_codeABCk (line 399) | int luaK_codeABCk (FuncState *fs, OpCode o, int A, int B, int C, int k) {
function luaK_codevABCk (line 407) | int luaK_codevABCk (FuncState *fs, OpCode o, int A, int B, int C, int k) {
function luaK_codeABx (line 418) | int luaK_codeABx (FuncState *fs, OpCode o, int A, int Bc) {
function codeAsBx (line 428) | static int codeAsBx (FuncState *fs, OpCode o, int A, int Bc) {
function codesJ (line 439) | static int codesJ (FuncState *fs, OpCode o, int sj, int k) {
function codeextraarg (line 450) | static int codeextraarg (FuncState *fs, int A) {
function luaK_codek (line 461) | static int luaK_codek (FuncState *fs, int reg, int k) {
function luaK_checkstack (line 476) | void luaK_checkstack (FuncState *fs, int n) {
function luaK_reserveregs (line 488) | void luaK_reserveregs (FuncState *fs, int n) {
function freereg (line 499) | static void freereg (FuncState *fs, int reg) {
function freeregs (line 510) | static void freeregs (FuncState *fs, int r1, int r2) {
function freeexp (line 525) | static void freeexp (FuncState *fs, expdesc *e) {
function freeexps (line 535) | static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
function addk (line 545) | static int addk (FuncState *fs, Proto *f, TValue *v) {
function k2proto (line 565) | static int k2proto (FuncState *fs, TValue *key, TValue *v) {
function stringK (line 589) | static int stringK (FuncState *fs, TString *s) {
function luaK_intK (line 599) | static int luaK_intK (FuncState *fs, lua_Integer n) {
function luaK_numberK (line 617) | static int luaK_numberK (FuncState *fs, lua_Number r) {
function boolF (line 645) | static int boolF (FuncState *fs) {
function boolT (line 655) | static int boolT (FuncState *fs) {
function nilK (line 665) | static int nilK (FuncState *fs) {
function fitsC (line 679) | static int fitsC (lua_Integer i) {
function fitsBx (line 687) | static int fitsBx (lua_Integer i) {
function luaK_int (line 692) | void luaK_int (FuncState *fs, int reg, lua_Integer i) {
function luaK_float (line 700) | static void luaK_float (FuncState *fs, int reg, lua_Number f) {
function luaK_codecheckglobal (line 715) | void luaK_codecheckglobal (FuncState *fs, expdesc *var, int k, int line) {
function const2exp (line 728) | static void const2exp (TValue *v, expdesc *e) {
function luaK_setreturns (line 757) | void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
function str2K (line 774) | static int str2K (FuncState *fs, expdesc *e) {
function luaK_setoneret (line 792) | void luaK_setoneret (FuncState *fs, expdesc *e) {
function luaK_vapar2local (line 808) | void luaK_vapar2local (FuncState *fs, expdesc *var) {
function luaK_dischargevars (line 819) | void luaK_dischargevars (FuncState *fs, expdesc *e) {
function discharge2reg (line 882) | static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
function discharge2anyreg (line 937) | static void discharge2anyreg (FuncState *fs, expdesc *e) {
function code_loadbool (line 945) | static int code_loadbool (FuncState *fs, int A, OpCode op) {
function need_value (line 955) | static int need_value (FuncState *fs, int list) {
function exp2reg (line 971) | static void exp2reg (FuncState *fs, expdesc *e, int reg) {
function luaK_exp2nextreg (line 999) | void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
function luaK_exp2anyreg (line 1011) | int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
function luaK_exp2anyregup (line 1033) | void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
function luaK_exp2val (line 1043) | void luaK_exp2val (FuncState *fs, expdesc *e) {
function luaK_exp2K (line 1055) | static int luaK_exp2K (FuncState *fs, expdesc *e) {
function exp2RK (line 1085) | static int exp2RK (FuncState *fs, expdesc *e) {
function codeABRK (line 1095) | static void codeABRK (FuncState *fs, OpCode o, int A, int B,
function luaK_storevar (line 1105) | void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
function negatecondition (line 1146) | static void negatecondition (FuncState *fs, expdesc *e) {
function jumponcond (line 1160) | static int jumponcond (FuncState *fs, expdesc *e, int cond) {
function luaK_goiftrue (line 1178) | void luaK_goiftrue (FuncState *fs, expdesc *e) {
function luaK_goiffalse (line 1205) | static void luaK_goiffalse (FuncState *fs, expdesc *e) {
function codenot (line 1231) | static void codenot (FuncState *fs, expdesc *e) {
function isKstr (line 1265) | static int isKstr (FuncState *fs, expdesc *e) {
function isKint (line 1273) | static int isKint (expdesc *e) {
function isCint (line 1282) | static int isCint (expdesc *e) {
function isSCint (line 1291) | static int isSCint (expdesc *e) {
function isSCnumber (line 1300) | static int isSCnumber (expdesc *e, int *pi, int *isfloat) {
function luaK_self (line 1321) | void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
function fillidxk (line 1345) | static void fillidxk (expdesc *t, int idx, expkind k) {
function luaK_indexed (line 1357) | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
function validop (line 1399) | static int validop (int op, TValue *v1, TValue *v2) {
function constfolding (line 1418) | static int constfolding (FuncState *fs, int op, expdesc *e1,
function l_sinline (line 1442) | l_sinline OpCode binopr2op (BinOpr opr, BinOpr baser, OpCode base) {
function l_sinline (line 1453) | l_sinline OpCode unopr2op (UnOpr opr) {
function l_sinline (line 1462) | l_sinline TMS binopr2TM (BinOpr opr) {
function codeunexpval (line 1473) | static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
function finishbinexpval (line 1488) | static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
function codebinexpval (line 1506) | static void codebinexpval (FuncState *fs, BinOpr opr,
function codebini (line 1521) | static void codebini (FuncState *fs, OpCode op,
function codebinK (line 1533) | static void codebinK (FuncState *fs, BinOpr opr,
function finishbinexpneg (line 1545) | static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2,
function swapexps (line 1564) | static void swapexps (expdesc *e1, expdesc *e2) {
function codebinNoK (line 1572) | static void codebinNoK (FuncState *fs, BinOpr opr,
function codearith (line 1584) | static void codearith (FuncState *fs, BinOpr opr,
function codecommutative (line 1598) | static void codecommutative (FuncState *fs, BinOpr op,
function codebitwise (line 1616) | static void codebitwise (FuncState *fs, BinOpr opr,
function codeorder (line 1634) | static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *...
function codeeq (line 1666) | static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
function luaK_prefix (line 1697) | void luaK_prefix (FuncState *fs, UnOpr opr, expdesc *e, int line) {
function luaK_infix (line 1718) | void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
function codeconcat (line 1767) | static void codeconcat (FuncState *fs, expdesc *e1, expdesc *e2, int lin...
function luaK_posfix (line 1787) | void luaK_posfix (FuncState *fs, BinOpr opr,
function luaK_fixline (line 1868) | void luaK_fixline (FuncState *fs, int line) {
function luaK_settablesize (line 1874) | void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hs...
function luaK_setlist (line 1892) | void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
function finaltarget (line 1911) | static int finaltarget (Instruction *code, int i) {
function luaK_finish (line 1929) | void luaK_finish (FuncState *fs) {
FILE: 3rd/lua/lcode.h
type BinOpr (line 26) | typedef enum BinOpr {
type UnOpr (line 51) | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR ...
FILE: 3rd/lua/lcorolib.c
function lua_State (line 22) | static lua_State *getco (lua_State *L) {
function auxresume (line 33) | static int auxresume (lua_State *L, lua_State *co, int narg) {
function luaB_coresume (line 57) | static int luaB_coresume (lua_State *L) {
function luaB_auxwrap (line 74) | static int luaB_auxwrap (lua_State *L) {
function luaB_cocreate (line 96) | static int luaB_cocreate (lua_State *L) {
function luaB_cowrap (line 106) | static int luaB_cowrap (lua_State *L) {
function luaB_yield (line 113) | static int luaB_yield (lua_State *L) {
function auxstatus (line 128) | static int auxstatus (lua_State *L, lua_State *co) {
function luaB_costatus (line 150) | static int luaB_costatus (lua_State *L) {
function lua_State (line 157) | static lua_State *getoptco (lua_State *L) {
function luaB_yieldable (line 162) | static int luaB_yieldable (lua_State *L) {
function luaB_corunning (line 169) | static int luaB_corunning (lua_State *L) {
function luaB_close (line 176) | static int luaB_close (lua_State *L) {
function LUAMOD_API (line 221) | LUAMOD_API int luaopen_coroutine (lua_State *L) {
FILE: 3rd/lua/ldblib.c
function checkstack (line 36) | static void checkstack (lua_State *L, lua_State *L1, int n) {
function db_getregistry (line 42) | static int db_getregistry (lua_State *L) {
function db_getmetatable (line 48) | static int db_getmetatable (lua_State *L) {
function db_setmetatable (line 57) | static int db_setmetatable (lua_State *L) {
function db_getuservalue (line 66) | static int db_getuservalue (lua_State *L) {
function db_setuservalue (line 78) | static int db_setuservalue (lua_State *L) {
function lua_State (line 95) | static lua_State *getthread (lua_State *L, int *arg) {
function settabss (line 112) | static void settabss (lua_State *L, const char *k, const char *v) {
function settabsi (line 117) | static void settabsi (lua_State *L, const char *k, int v) {
function settabsb (line 122) | static void settabsb (lua_State *L, const char *k, int v) {
function treatstackoption (line 135) | static void treatstackoption (lua_State *L, lua_State *L1, const char *f...
function db_getinfo (line 150) | static int db_getinfo (lua_State *L) {
function db_getlocal (line 206) | static int db_getlocal (lua_State *L) {
function db_setlocal (line 237) | static int db_setlocal (lua_State *L) {
function auxupvalue (line 261) | static int auxupvalue (lua_State *L, int get) {
function db_getupvalue (line 273) | static int db_getupvalue (lua_State *L) {
function db_setupvalue (line 278) | static int db_setupvalue (lua_State *L) {
function db_upvalueid (line 301) | static int db_upvalueid (lua_State *L) {
function db_upvaluejoin (line 311) | static int db_upvaluejoin (lua_State *L) {
function hookf (line 326) | static void hookf (lua_State *L, lua_Debug *ar) {
function makemask (line 345) | static int makemask (const char *smask, int count) {
function db_sethook (line 368) | static int db_sethook (lua_State *L) {
function db_gethook (line 398) | static int db_gethook (lua_State *L) {
function db_debug (line 423) | static int db_debug (lua_State *L) {
function db_traceback (line 438) | static int db_traceback (lua_State *L) {
function LUAMOD_API (line 473) | LUAMOD_API int luaopen_debug (lua_State *L) {
FILE: 3rd/lua/ldebug.c
function currentpc (line 43) | static int currentpc (CallInfo *ci) {
function getbaseline (line 62) | static int getbaseline (const Proto *f, int pc, int *basepc) {
function luaG_getfuncline (line 85) | int luaG_getfuncline (const Proto *f, int pc) {
function getcurrentline (line 100) | static int getcurrentline (CallInfo *ci) {
function settraps (line 116) | static void settraps (CallInfo *ci) {
function LUA_API (line 133) | LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int cou...
function LUA_API (line 147) | LUA_API lua_Hook lua_gethook (lua_State *L) {
function LUA_API (line 152) | LUA_API int lua_gethookmask (lua_State *L) {
function LUA_API (line 157) | LUA_API int lua_gethookcount (lua_State *L) {
function LUA_API (line 162) | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
function LUA_API (line 222) | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int...
function LUA_API (line 244) | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int...
function funcinfo (line 259) | static void funcinfo (lua_Debug *ar, Closure *cl) {
function nextline (line 284) | static int nextline (const Proto *p, int currentline, int pc) {
function collectvalidlines (line 292) | static void collectvalidlines (lua_State *L, Closure *f) {
function auxgetinfo (line 331) | static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
function LUA_API (line 395) | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
function filterpc (line 433) | static int filterpc (int pc, int jmptarget) {
function findsetreg (line 443) | static int findsetreg (const Proto *p, int lastpc, int reg) {
function rname (line 539) | static void rname (const Proto *p, int pc, int c, const char **name) {
function instack (line 685) | static int instack (CallInfo *ci, const TValue *o) {
function l_noret (line 746) | static l_noret typeerror (lua_State *L, const TValue *o, const char *op,
function l_noret (line 757) | l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
function l_noret (line 767) | l_noret luaG_callerror (lua_State *L, const TValue *o) {
function l_noret (line 776) | l_noret luaG_forerror (lua_State *L, const TValue *o, const char *what) {
function l_noret (line 782) | l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *...
function l_noret (line 788) | l_noret luaG_opinterror (lua_State *L, const TValue *p1,
function l_noret (line 799) | l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p...
function l_noret (line 807) | l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p...
function l_noret (line 817) | l_noret luaG_errnnil (lua_State *L, LClosure *cl, int k) {
function l_noret (line 840) | l_noret luaG_errormsg (lua_State *L) {
function l_noret (line 857) | l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
function changedline (line 881) | static int changedline (const Proto *p, int oldpc, int newpc) {
function luaG_tracecall (line 910) | int luaG_tracecall (lua_State *L) {
function luaG_traceexec (line 936) | int luaG_traceexec (lua_State *L, const Instruction *pc) {
FILE: 3rd/lua/ldo.c
type lua_longjmp (line 61) | typedef struct lua_longjmp {
function LUAI_TRY (line 81) | static void LUAI_TRY (lua_State *L, lua_longjmp *c, Pfunc f, void *ud) {
function luaD_seterrorobj (line 112) | void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) {
function l_noret (line 125) | l_noret luaD_throw (lua_State *L, TStatus errcode) {
function l_noret (line 150) | l_noret luaD_throwbaselevel (lua_State *L, TStatus errcode) {
function TStatus (line 160) | TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
function l_noret (line 215) | l_noret luaD_errerr (lua_State *L) {
function luaD_checkminstack (line 228) | int luaD_checkminstack (lua_State *L) {
function relstack (line 252) | static void relstack (lua_State *L) {
function correctstack (line 269) | static void correctstack (lua_State *L, StkId oldstack) {
function relstack (line 291) | static void relstack (lua_State *L) { UNUSED(L); }
function correctstack (line 297) | static void correctstack (lua_State *L, StkId oldstack) {
function luaD_reallocstack (line 322) | int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
function luaD_growstack (line 353) | int luaD_growstack (lua_State *L, int n, int raiseerror) {
function stackinuse (line 387) | static int stackinuse (lua_State *L) {
function luaD_shrinkstack (line 411) | void luaD_shrinkstack (lua_State *L) {
function luaD_inctop (line 426) | void luaD_inctop (lua_State *L) {
function luaD_hook (line 439) | void luaD_hook (lua_State *L, int event, int line,
function luaD_hookcall (line 476) | void luaD_hookcall (lua_State *L, CallInfo *ci) {
function rethook (line 494) | static void rethook (lua_State *L, CallInfo *ci, int nres) {
function tryfuncTM (line 523) | static unsigned tryfuncTM (lua_State *L, StkId func, unsigned status) {
function l_sinline (line 540) | l_sinline void genmoveresults (lua_State *L, StkId res, int nres,
function l_sinline (line 561) | l_sinline void moveresults (lua_State *L, StkId res, int nres,
function luaD_poscall (line 605) | void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
function l_sinline (line 628) | l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, unsigned sta...
function l_sinline (line 642) | l_sinline int precallC (lua_State *L, StkId func, unsigned status,
function luaD_pretailcall (line 669) | int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
function CallInfo (line 715) | CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
function l_sinline (line 757) | l_sinline void ccall (lua_State *L, StkId func, int nResults, l_uint32 i...
function luaD_call (line 775) | void luaD_call (lua_State *L, StkId func, int nResults) {
function luaD_callnoyield (line 783) | void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
function TStatus (line 804) | static TStatus finishpcallk (lua_State *L, CallInfo *ci) {
function finishCcall (line 837) | static void finishCcall (lua_State *L, CallInfo *ci) {
function unroll (line 866) | static void unroll (lua_State *L, void *ud) {
function CallInfo (line 884) | static CallInfo *findpcall (lua_State *L) {
function resume_error (line 899) | static int resume_error (lua_State *L, const char *msg, int narg) {
function resume (line 916) | static void resume (lua_State *L, void *ud) {
function TStatus (line 955) | static TStatus precover (lua_State *L, TStatus status) {
function LUA_API (line 966) | LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
function LUA_API (line 1001) | LUA_API int lua_isyieldable (lua_State *L) {
function LUA_API (line 1006) | LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
type CloseP (line 1040) | struct CloseP {
function closepaux (line 1049) | static void closepaux (lua_State *L, void *ud) {
function TStatus (line 1059) | TStatus luaD_closeprotected (lua_State *L, ptrdiff_t level, TStatus stat...
function TStatus (line 1081) | TStatus luaD_pcall (lua_State *L, Pfunc func, void *u, ptrdiff_t old_top,
type SParser (line 1105) | struct SParser { /* data to 'f_parser' */
function checkmode (line 1114) | static void checkmode (lua_State *L, const char *mode, const char *x) {
function f_parser (line 1123) | static void f_parser (lua_State *L, void *ud) {
function TStatus (line 1145) | TStatus luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
FILE: 3rd/lua/ldump.c
type DumpState (line 26) | typedef struct {
function dumpBlock (line 52) | static void dumpBlock (DumpState *D, const void *b, size_t size) {
function dumpAlign (line 66) | static void dumpAlign (DumpState *D, unsigned align) {
function dumpByte (line 80) | static void dumpByte (DumpState *D, int y) {
function dumpVarint (line 95) | static void dumpVarint (DumpState *D, lua_Unsigned x) {
function dumpSize (line 105) | static void dumpSize (DumpState *D, size_t sz) {
function dumpInt (line 110) | static void dumpInt (DumpState *D, int x) {
function dumpNumber (line 116) | static void dumpNumber (DumpState *D, lua_Number x) {
function dumpInteger (line 127) | static void dumpInteger (DumpState *D, lua_Integer x) {
function dumpString (line 143) | static void dumpString (DumpState *D, TString *ts) {
function dumpCode (line 171) | static void dumpCode (DumpState *D, const Proto *f) {
function dumpConstants (line 181) | static void dumpConstants (DumpState *D, const Proto *f) {
function dumpProtos (line 207) | static void dumpProtos (DumpState *D, const Proto *f) {
function dumpUpvalues (line 216) | static void dumpUpvalues (DumpState *D, const Proto *f) {
function dumpDebug (line 227) | static void dumpDebug (DumpState *D, const Proto *f) {
function dumpFunction (line 254) | static void dumpFunction (DumpState *D, const Proto *f) {
function dumpHeader (line 273) | static void dumpHeader (DumpState *D) {
function luaU_dump (line 288) | int luaU_dump (lua_State *L, const Proto *f, lua_Writer w, void *data,
FILE: 3rd/lua/lfunc.c
function CClosure (line 28) | CClosure *luaF_newCclosure (lua_State *L, int nupvals) {
function LClosure (line 36) | LClosure *luaF_newLclosure (lua_State *L, int nupvals) {
function luaF_initupvals (line 49) | void luaF_initupvals (lua_State *L, LClosure *cl) {
function UpVal (line 66) | static UpVal *newupval (lua_State *L, StkId level, UpVal **prev) {
function UpVal (line 88) | UpVal *luaF_findupval (lua_State *L, StkId level) {
function callclosemethod (line 108) | static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int...
function checkclosemth (line 128) | static void checkclosemth (lua_State *L, StkId level) {
function prepcallclosemth (line 146) | static void prepcallclosemth (lua_State *L, StkId level, TStatus status,
function luaF_newtbcupval (line 173) | void luaF_newtbcupval (lua_State *L, StkId level) {
function luaF_unlinkupval (line 187) | void luaF_unlinkupval (UpVal *uv) {
function luaF_closeupval (line 198) | void luaF_closeupval (lua_State *L, StkId level) {
function poptbclist (line 217) | static void poptbclist (lua_State *L) {
function StkId (line 231) | StkId luaF_close (lua_State *L, StkId level, TStatus status, int yy) {
function Proto (line 244) | Proto *luaF_newproto (lua_State *L) {
function lu_mem (line 271) | lu_mem luaF_protosize (Proto *p) {
function luaF_freeproto (line 286) | void luaF_freeproto (lua_State *L, Proto *f) {
function luaF_shareproto (line 316) | void luaF_shareproto (Proto *f) {
FILE: 3rd/lua/lgc.c
function l_mem (line 113) | static l_mem objsize (GCObject *o) {
function GCObject (line 163) | static GCObject **getgclist (GCObject *o) {
function linkgclist_ (line 186) | static void linkgclist_ (GCObject *o, GCObject **pnext, GCObject **list) {
function clearkey (line 209) | static void clearkey (Node *n) {
function iscleared (line 223) | static int iscleared (global_State *g, const GCObject *o) {
function luaC_barrier_ (line 246) | void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
function luaC_barrierback_ (line 268) | void luaC_barrierback_ (lua_State *L, GCObject *o) {
function luaC_fix (line 282) | void luaC_fix (lua_State *L, GCObject *o) {
function GCObject (line 297) | GCObject *luaC_newobjdt (lua_State *L, lu_byte tt, size_t sz, size_t off...
function GCObject (line 312) | GCObject *luaC_newobj (lua_State *L, lu_byte tt, size_t sz) {
function reallymarkobject (line 339) | static void reallymarkobject (global_State *g, GCObject *o) {
function markmt (line 378) | static void markmt (global_State *g) {
function markbeingfnz (line 388) | static void markbeingfnz (global_State *g) {
function remarkupvals (line 406) | static void remarkupvals (global_State *g) {
function cleargraylists (line 429) | static void cleargraylists (global_State *g) {
function restartcollection (line 440) | static void restartcollection (global_State *g) {
function genlink (line 470) | static void genlink (global_State *g, GCObject *o) {
function traverseweakvalue (line 487) | static void traverseweakvalue (global_State *g, Table *h) {
function traversearray (line 514) | static int traversearray (global_State *g, Table *h) {
function traverseephemeron (line 541) | static int traverseephemeron (global_State *g, Table *h, int inv) {
function traversestrongtable (line 576) | static void traversestrongtable (global_State *g, Table *h) {
function getmode (line 595) | static int getmode (global_State *g, Table *h) {
function l_mem (line 608) | static l_mem traversetable (global_State *g, Table *h) {
function l_mem (line 631) | static l_mem traverseudata (global_State *g, Udata *u) {
function l_mem (line 646) | static l_mem traverseproto (global_State *g, Proto *f) {
function l_mem (line 661) | static l_mem traverseCclosure (global_State *g, CClosure *cl) {
function l_mem (line 672) | static l_mem traverseLclosure (global_State *g, LClosure *cl) {
function l_mem (line 695) | static l_mem traversethread (global_State *g, lua_State *th) {
function l_mem (line 727) | static l_mem propagatemark (global_State *g) {
function propagateall (line 743) | static void propagateall (global_State *g) {
function convergeephemerons (line 755) | static void convergeephemerons (global_State *g) {
function clearbykeys (line 789) | static void clearbykeys (global_State *g, GCObject *l) {
function clearbyvalues (line 808) | static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) {
function freeupval (line 829) | static void freeupval (lua_State *L, UpVal *uv) {
function freeobj (line 836) | static void freeobj (lua_State *L, GCObject *o) {
function GCObject (line 892) | static GCObject **sweeplist (lua_State *L, GCObject **p, l_mem countin) {
function GCObject (line 917) | static GCObject **sweeptolive (lua_State *L, GCObject **p) {
function checkSizes (line 937) | static void checkSizes (lua_State *L, global_State *g) {
function GCObject (line 949) | static GCObject *udata2finalize (global_State *g) {
function dothecall (line 964) | static void dothecall (lua_State *L, void *ud) {
function GCTM (line 970) | static void GCTM (lua_State *L) {
function callallpendingfinalizers (line 1001) | static void callallpendingfinalizers (lua_State *L) {
function GCObject (line 1011) | static GCObject **findlast (GCObject **p) {
function separatetobefnz (line 1025) | static void separatetobefnz (global_State *g, int all) {
function checkpointer (line 1048) | static void checkpointer (GCObject **p, GCObject *o) {
function correctpointers (line 1058) | static void correctpointers (global_State *g, GCObject *o) {
function luaC_checkfinalizer (line 1070) | void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
function setpause (line 1124) | static void setpause (global_State *g) {
function sweep2old (line 1138) | static void sweep2old (lua_State *L, GCObject **p) {
function GCObject (line 1176) | static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p,
function GCObject (line 1233) | static GCObject **correctgraylist (GCObject **p) {
function correctgraylists (line 1266) | static void correctgraylists (global_State *g) {
function markold (line 1282) | static void markold (global_State *g, GCObject *from, GCObject *to) {
function finishgencycle (line 1298) | static void finishgencycle (lua_State *L, global_State *g) {
function minor2inc (line 1312) | static void minor2inc (lua_State *L, global_State *g, lu_byte kind) {
function checkminormajor (line 1329) | static int checkminormajor (global_State *g) {
function youngcollection (line 1341) | static void youngcollection (lua_State *L, global_State *g) {
function atomic2gen (line 1395) | static void atomic2gen (lua_State *L, global_State *g) {
function setminordebt (line 1423) | static void setminordebt (global_State *g) {
function entergen (line 1434) | static void entergen (lua_State *L, global_State *g) {
function luaC_changemode (line 1446) | void luaC_changemode (lua_State *L, int newmode) {
function fullgen (line 1464) | static void fullgen (lua_State *L, global_State *g) {
function checkmajorminor (line 1477) | static int checkmajorminor (lua_State *L, global_State *g) {
function entersweep (line 1510) | static void entersweep (lua_State *L) {
function deletelist (line 1522) | static void deletelist (lua_State *L, GCObject *p, GCObject *limit) {
function luaC_freeallobjects (line 1535) | void luaC_freeallobjects (lua_State *L) {
function atomic (line 1549) | static void atomic (lua_State *L) {
function sweepstep (line 1594) | static void sweepstep (lua_State *L, global_State *g,
function l_mem (line 1623) | static l_mem singlestep (lua_State *L, int fast) {
function luaC_runtilstate (line 1700) | void luaC_runtilstate (lua_State *L, int state, int fast) {
function incstep (line 1716) | static void incstep (lua_State *L, global_State *g) {
function luaC_step (line 1746) | void luaC_step (lua_State *L) {
function fullinc (line 1776) | static void fullinc (lua_State *L, global_State *g) {
function luaC_fullgc (line 1792) | void luaC_fullgc (lua_State *L, int isemergency) {
FILE: 3rd/lua/linit.c
function LUALIB_API (line 46) | LUALIB_API void luaL_openselectedlibs (lua_State *L, int load, int prelo...
FILE: 3rd/lua/liolib.c
function l_checkmode (line 39) | static int l_checkmode (const char *mode) {
type luaL_Stream (line 154) | typedef luaL_Stream LStream;
function io_type (line 162) | static int io_type (lua_State *L) {
function f_tostring (line 176) | static int f_tostring (lua_State *L) {
function FILE (line 186) | static FILE *tofile (lua_State *L) {
function LStream (line 200) | static LStream *newprefile (lua_State *L) {
function aux_close (line 213) | static int aux_close (lua_State *L) {
function f_close (line 221) | static int f_close (lua_State *L) {
function io_close (line 227) | static int io_close (lua_State *L) {
function f_gc (line 234) | static int f_gc (lua_State *L) {
function io_fclose (line 245) | static int io_fclose (lua_State *L) {
function LStream (line 252) | static LStream *newfile (lua_State *L) {
function opencheck (line 260) | static void opencheck (lua_State *L, const char *fname, const char *mode) {
function io_open (line 268) | static int io_open (lua_State *L) {
function io_pclose (line 283) | static int io_pclose (lua_State *L) {
function io_popen (line 290) | static int io_popen (lua_State *L) {
function io_tmpfile (line 302) | static int io_tmpfile (lua_State *L) {
function FILE (line 310) | static FILE *getiofile (lua_State *L, const char *findex) {
function g_iofile (line 320) | static int g_iofile (lua_State *L, const char *f, const char *mode) {
function io_input (line 337) | static int io_input (lua_State *L) {
function io_output (line 342) | static int io_output (lua_State *L) {
function aux_lines (line 365) | static void aux_lines (lua_State *L, int toclose) {
function f_lines (line 376) | static int f_lines (lua_State *L) {
function io_lines (line 388) | static int io_lines (lua_State *L) {
type RN (line 429) | typedef struct {
function nextc (line 440) | static int nextc (RN *rn) {
function test2 (line 456) | static int test2 (RN *rn, const char *set) {
function readdigits (line 466) | static int readdigits (RN *rn, int hex) {
function read_number (line 479) | static int read_number (lua_State *L, FILE *f) {
function test_eof (line 513) | static int test_eof (lua_State *L, FILE *f) {
function read_line (line 521) | static int read_line (lua_State *L, FILE *f, int chop) {
function read_all (line 542) | static void read_all (lua_State *L, FILE *f) {
function read_chars (line 555) | static int read_chars (lua_State *L, FILE *f, size_t n) {
function g_read (line 568) | static int g_read (lua_State *L, FILE *f, int first) {
function io_read (line 619) | static int io_read (lua_State *L) {
function f_read (line 624) | static int f_read (lua_State *L) {
function io_readline (line 632) | static int io_readline (lua_State *L) {
function g_write (line 663) | static int g_write (lua_State *L, FILE *f, int arg) {
function io_write (line 690) | static int io_write (lua_State *L) {
function f_write (line 695) | static int f_write (lua_State *L) {
function f_seek (line 702) | static int f_seek (lua_State *L) {
function f_setvbuf (line 722) | static int f_setvbuf (lua_State *L) {
function aux_flush (line 735) | static int aux_flush (lua_State *L, FILE *f) {
function f_flush (line 741) | static int f_flush (lua_State *L) {
function io_flush (line 746) | static int io_flush (lua_State *L) {
function createmeta (line 797) | static void createmeta (lua_State *L) {
function io_noclose (line 810) | static int io_noclose (lua_State *L) {
function createstdfile (line 819) | static void createstdfile (lua_State *L, FILE *f, const char *k,
function LUAMOD_API (line 832) | LUAMOD_API int luaopen_io (lua_State *L) {
FILE: 3rd/lua/llex.c
function save (line 62) | static void save (LexState *ls, int c) {
function luaX_init (line 75) | void luaX_init (lua_State *L) {
function l_noret (line 116) | static l_noret lexerror (LexState *ls, const char *msg, int token) {
function l_noret (line 124) | l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
function TString (line 135) | static TString *anchorstr (LexState *ls, TString *ts) {
function TString (line 156) | TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
function inclinenumber (line 165) | static void inclinenumber (LexState *ls) {
function luaX_setinput (line 176) | void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
function check_next1 (line 208) | static int check_next1 (LexState *ls, int c) {
function check_next2 (line 221) | static int check_next2 (LexState *ls, const char *set) {
function read_numeral (line 244) | static int read_numeral (LexState *ls, SemInfo *seminfo) {
function skip_sep (line 282) | static size_t skip_sep (LexState *ls) {
function read_long_string (line 297) | static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) {
function esccheck (line 336) | static void esccheck (LexState *ls, int c, const char *msg) {
function gethexa (line 345) | static int gethexa (LexState *ls) {
function readhexaesc (line 352) | static int readhexaesc (LexState *ls) {
function l_uint32 (line 365) | static l_uint32 readutf8esc (LexState *ls) {
function utf8esc (line 383) | static void utf8esc (LexState *ls) {
function readdecesc (line 391) | static int readdecesc (LexState *ls) {
function read_string (line 404) | static void read_string (LexState *ls, int del, SemInfo *seminfo) {
function llex (line 467) | static int llex (LexState *ls, SemInfo *seminfo) {
function luaX_next (line 588) | void luaX_next (LexState *ls) {
function luaX_lookahead (line 599) | int luaX_lookahead (LexState *ls) {
FILE: 3rd/lua/llex.h
type RESERVED (line 32) | enum RESERVED {
type SemInfo (line 49) | typedef union {
type Token (line 56) | typedef struct Token {
type LexState (line 64) | typedef struct LexState {
FILE: 3rd/lua/llimits.h
type LUAI_MEM (line 27) | typedef LUAI_MEM l_mem;
type LUAI_UMEM (line 28) | typedef LUAI_UMEM lu_mem;
type l_mem (line 30) | typedef ptrdiff_t l_mem;
type lu_mem (line 31) | typedef size_t lu_mem;
type l_mem (line 33) | typedef long l_mem;
type lu_mem (line 34) | typedef unsigned long lu_mem;
type lu_byte (line 42) | typedef unsigned char lu_byte;
type ls_byte (line 43) | typedef signed char ls_byte;
type lu_byte (line 47) | typedef lu_byte TStatus;
type LUAI_UACNUMBER (line 95) | typedef LUAI_UACNUMBER l_uacNumber;
type LUAI_UACINT (line 96) | typedef LUAI_UACINT l_uacInt;
type l_uint32 (line 225) | typedef unsigned int l_uint32;
type l_uint32 (line 227) | typedef unsigned long l_uint32;
FILE: 3rd/lua/lmathlib.c
function math_abs (line 30) | static int math_abs (lua_State *L) {
function math_sin (line 42) | static int math_sin (lua_State *L) {
function math_cos (line 48) | static int math_cos (lua_State *L) {
function math_tan (line 54) | static int math_tan (lua_State *L) {
function math_asin (line 60) | static int math_asin (lua_State *L) {
function math_acos (line 66) | static int math_acos (lua_State *L) {
function math_atan (line 72) | static int math_atan (lua_State *L) {
function math_toint (line 80) | static int math_toint (lua_State *L) {
function pushnumint (line 93) | static void pushnumint (lua_State *L, lua_Number d) {
function math_floor (line 102) | static int math_floor (lua_State *L) {
function math_ceil (line 113) | static int math_ceil (lua_State *L) {
function math_fmod (line 124) | static int math_fmod (lua_State *L) {
function math_modf (line 146) | static int math_modf (lua_State *L) {
function math_sqrt (line 163) | static int math_sqrt (lua_State *L) {
function math_ult (line 169) | static int math_ult (lua_State *L) {
function math_log (line 177) | static int math_log (lua_State *L) {
function math_exp (line 199) | static int math_exp (lua_State *L) {
function math_deg (line 205) | static int math_deg (lua_State *L) {
function math_rad (line 211) | static int math_rad (lua_State *L) {
function math_frexp (line 217) | static int math_frexp (lua_State *L) {
function math_ldexp (line 226) | static int math_ldexp (lua_State *L) {
function math_min (line 234) | static int math_min (lua_State *L) {
function math_max (line 248) | static int math_max (lua_State *L) {
function math_type (line 262) | static int math_type (lua_State *L) {
function Rand64 (line 344) | static Rand64 rotl (Rand64 x, int n) {
function Rand64 (line 348) | static Rand64 nextrand (Rand64 *state) {
function lua_Number (line 379) | static lua_Number I2d (Rand64 x) {
type Rand64 (line 400) | typedef struct Rand64 {
function Rand64 (line 421) | static Rand64 packI (l_uint32 h, l_uint32 l) {
function Rand64 (line 429) | static Rand64 Ishl (Rand64 i, int n) {
function Ixor (line 435) | static void Ixor (Rand64 *i1, Rand64 i2) {
function Rand64 (line 441) | static Rand64 Iadd (Rand64 i1, Rand64 i2) {
function Rand64 (line 449) | static Rand64 times5 (Rand64 i) {
function Rand64 (line 454) | static Rand64 times9 (Rand64 i) {
function Rand64 (line 459) | static Rand64 rotl (Rand64 i, int n) {
function Rand64 (line 466) | static Rand64 rotl1 (Rand64 i, int n) {
function Rand64 (line 476) | static Rand64 nextrand (Rand64 *state) {
function lua_Number (line 506) | static lua_Number I2d (Rand64 x) {
function lua_Number (line 529) | static lua_Number I2d (Rand64 x) {
function lua_Unsigned (line 539) | static lua_Unsigned I2UInt (Rand64 x) {
function Rand64 (line 544) | static Rand64 Int2I (lua_Unsigned n) {
type RanState (line 554) | typedef struct {
function lua_Unsigned (line 569) | static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n,
function math_random (line 582) | static int math_random (lua_State *L) {
function setseed (line 617) | static void setseed (lua_State *L, Rand64 *state,
function math_randomseed (line 631) | static int math_randomseed (lua_State *L) {
function setrandfunc (line 657) | static void setrandfunc (lua_State *L) {
function math_cosh (line 674) | static int math_cosh (lua_State *L) {
function math_sinh (line 679) | static int math_sinh (lua_State *L) {
function math_tanh (line 684) | static int math_tanh (lua_State *L) {
function math_pow (line 689) | static int math_pow (lua_State *L) {
function math_log10 (line 696) | static int math_log10 (lua_State *L) {
function LUAMOD_API (line 752) | LUAMOD_API int luaopen_math (lua_State *L) {
FILE: 3rd/lua/lmem.c
function l_noret (line 142) | l_noret luaM_toobig (lua_State *L) {
function luaM_free_ (line 150) | void luaM_free_ (lua_State *L, void *block, size_t osize) {
FILE: 3rd/lua/loadlib.c
function lsys_unloadlib (line 104) | static void lsys_unloadlib (void *lib) {
function lua_CFunction (line 117) | static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
function setprogdir (line 153) | static void setprogdir (lua_State *L) {
function pusherror (line 170) | static void pusherror (lua_State *L) {
function lsys_unloadlib (line 180) | static void lsys_unloadlib (void *lib) {
function lua_CFunction (line 193) | static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
function lsys_unloadlib (line 216) | static void lsys_unloadlib (void *lib) {
function lua_CFunction (line 228) | static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
function noenv (line 261) | static int noenv (lua_State *L) {
function setpath (line 274) | static void setpath (lua_State *L, const char *fieldname,
function createlibstr (line 347) | static void createlibstr (lua_State *L, void *plib) {
function addtoclib (line 359) | static void addtoclib (lua_State *L, const char *path, void *plib) {
function lookforfunc (line 384) | static int lookforfunc (lua_State *L, const char *path, const char *sym) {
function ll_loadlib (line 405) | static int ll_loadlib (lua_State *L) {
function readable (line 428) | static int readable (const char *filename) {
function pusherrornotfound (line 465) | static void pusherrornotfound (lua_State *L, const char *path) {
function ll_searchpath (line 502) | static int ll_searchpath (lua_State *L) {
function checkload (line 528) | static int checkload (lua_State *L, int stat, const char *filename) {
function searcher_Lua (line 539) | static int searcher_Lua (lua_State *L) {
function loadfunc (line 556) | static int loadfunc (lua_State *L, const char *filename, const char *mod...
function searcher_C (line 574) | static int searcher_C (lua_State *L) {
function searcher_Croot (line 582) | static int searcher_Croot (lua_State *L) {
function searcher_preload (line 604) | static int searcher_preload (lua_State *L) {
function findloader (line 618) | static void findloader (lua_State *L, const char *name) {
function ll_require (line 650) | static int ll_require (lua_State *L) {
function createsearcherstable (line 703) | static void createsearcherstable (lua_State *L) {
function LUAMOD_API (line 724) | LUAMOD_API int luaopen_package (lua_State *L) {
FILE: 3rd/lua/lobject.c
function lu_byte (line 37) | lu_byte luaO_ceillog2 (unsigned int x) {
function lu_byte (line 62) | lu_byte luaO_codeparam (unsigned int p) {
function l_mem (line 89) | l_mem luaO_applyparam (lu_byte p, l_mem x) {
function lua_Integer (line 115) | static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
function lua_Number (line 135) | static lua_Number numarith (lua_State *L, int op, lua_Number v1,
function luaO_rawarith (line 151) | int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue ...
function luaO_arith (line 188) | void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
function lu_byte (line 197) | lu_byte luaO_hexavalue (int c) {
function isneg (line 204) | static int isneg (const char **s) {
function lua_Number (line 228) | static lua_Number lua_strx2number (const char *s, char **endptr) {
function luaO_str2num (line 371) | size_t luaO_str2num (const char *s, TValue *o) {
function luaO_utf8esc (line 386) | int luaO_utf8esc (char *buff, l_uint32 x) {
function tostringbuffFloat (line 427) | static int tostringbuffFloat (lua_Number n, char *buff) {
function luaO_tostringbuff (line 449) | unsigned luaO_tostringbuff (const TValue *obj, char *buff) {
function luaO_tostring (line 464) | void luaO_tostring (lua_State *L, TValue *obj) {
type BuffFS (line 490) | typedef struct BuffFS {
function initbuff (line 500) | static void initbuff (lua_State *L, BuffFS *buff) {
function pushbuff (line 513) | static void pushbuff (lua_State *L, void *ud) {
function addstr2buff (line 549) | static void addstr2buff (BuffFS *buff, const char *str, size_t slen) {
function addnum2buff (line 585) | static void addnum2buff (BuffFS *buff, TValue *num) {
function luaO_chunkid (line 682) | void luaO_chunkid (char *out, const char *source, size_t srclen) {
FILE: 3rd/lua/lobject.h
type Value (line 49) | typedef union Value {
type TValue (line 67) | typedef struct TValue {
type StackValue (line 148) | typedef union StackValue {
type StackValue (line 158) | typedef StackValue *StkId;
type StkIdRel (line 165) | typedef union {
type GCObject (line 305) | typedef struct GCObject {
type TString (line 405) | typedef struct TString {
type UValue (line 482) | typedef union UValue {
type Udata (line 492) | typedef struct Udata {
type Udata0 (line 511) | typedef struct Udata0 {
type l_uint32 (line 543) | typedef l_uint32 Instruction;
type Upvaldesc (line 549) | typedef struct Upvaldesc {
type LocVar (line 561) | typedef struct LocVar {
type AbsLineInfo (line 578) | typedef struct AbsLineInfo {
type Proto (line 603) | typedef struct Proto {
type UpVal (line 680) | typedef struct UpVal {
type CClosure (line 700) | typedef struct CClosure {
type LClosure (line 707) | typedef struct LClosure {
type Closure (line 714) | typedef union Closure {
type Node (line 752) | typedef union Node {
type Table (line 777) | typedef struct Table {
FILE: 3rd/lua/lopcodes.c
function luaP_isOT (line 117) | int luaP_isOT (Instruction i) {
function luaP_isIT (line 131) | int luaP_isIT (Instruction i) {
FILE: 3rd/lua/lopcodes.h
type OpMode (line 36) | enum OpMode {iABC, ivABC, iABx, iAsBx, iAx, isJ}
type OpCode (line 231) | typedef enum {
FILE: 3rd/lua/loslib.c
function os_execute (line 143) | static int os_execute (lua_State *L) {
function os_remove (line 157) | static int os_remove (lua_State *L) {
function os_rename (line 164) | static int os_rename (lua_State *L) {
function os_tmpname (line 172) | static int os_tmpname (lua_State *L) {
function os_getenv (line 183) | static int os_getenv (lua_State *L) {
function os_clock (line 189) | static int os_clock (lua_State *L) {
function setfield (line 212) | static void setfield (lua_State *L, const char *key, int value, int delt...
function setboolfield (line 222) | static void setboolfield (lua_State *L, const char *key, int value) {
function setallfields (line 233) | static void setallfields (lua_State *L, struct tm *stm) {
function getboolfield (line 246) | static int getboolfield (lua_State *L, const char *key) {
function getfield (line 254) | static int getfield (lua_State *L, const char *key, int d, int delta) {
function time_t (line 294) | static time_t l_checktime (lua_State *L, int arg) {
function os_date (line 305) | static int os_date (lua_State *L) {
function os_time (line 348) | static int os_time (lua_State *L) {
function os_difftime (line 374) | static int os_difftime (lua_State *L) {
function os_setlocale (line 384) | static int os_setlocale (lua_State *L) {
function os_exit (line 396) | static int os_exit (lua_State *L) {
function LUAMOD_API (line 428) | LUAMOD_API int luaopen_os (lua_State *L) {
FILE: 3rd/lua/lparser.c
type BlockCnt (line 49) | typedef struct BlockCnt {
function l_noret (line 68) | static l_noret error_expected (LexState *ls, int token) {
function l_noret (line 74) | static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
function luaY_checklimit (line 87) | void luaY_checklimit (FuncState *fs, int v, int l, const char *what) {
function testnext (line 95) | static int testnext (LexState *ls, int c) {
function check (line 107) | static void check (LexState *ls, int c) {
function checknext (line 116) | static void checknext (LexState *ls, int c) {
function check_match (line 130) | static void check_match (LexState *ls, int what, int who, int where) {
function TString (line 143) | static TString *str_checkname (LexState *ls) {
function init_exp (line 152) | static void init_exp (expdesc *e, expkind k, int i) {
function codestring (line 159) | static void codestring (expdesc *e, TString *s) {
function codename (line 166) | static void codename (LexState *ls, expdesc *e) {
function registerlocalvar (line 175) | static short registerlocalvar (LexState *ls, FuncState *fs,
function new_varkind (line 194) | static int new_varkind (LexState *ls, TString *name, lu_byte kind) {
function new_localvar (line 211) | static int new_localvar (LexState *ls, TString *name) {
function Vardesc (line 226) | static Vardesc *getlocalvardesc (FuncState *fs, int vidx) {
function lu_byte (line 236) | static lu_byte reglevel (FuncState *fs, int nvar) {
function lu_byte (line 250) | lu_byte luaY_nvarstack (FuncState *fs) {
function LocVar (line 258) | static LocVar *localdebuginfo (FuncState *fs, int vidx) {
function init_var (line 273) | static void init_var (FuncState *fs, expdesc *e, int vidx) {
function check_readonly (line 286) | static void check_readonly (LexState *ls, expdesc *e) {
function adjustlocalvars (line 328) | static void adjustlocalvars (LexState *ls, int nvars) {
function removevars (line 346) | static void removevars (FuncState *fs, int tolevel) {
function searchupvalue (line 360) | static int searchupvalue (FuncState *fs, TString *name) {
function Upvaldesc (line 370) | static Upvaldesc *allocupvalue (FuncState *fs) {
function newupvalue (line 382) | static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
function searchvar (line 414) | static int searchvar (FuncState *fs, TString *n, expdesc *var) {
function markupval (line 451) | static void markupval (FuncState *fs, int level) {
function marktobeclosed (line 463) | static void marktobeclosed (FuncState *fs) {
function singlevaraux (line 476) | static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int b...
function buildglobal (line 502) | static void buildglobal (LexState *ls, TString *varname, expdesc *var) {
function buildvar (line 520) | static void buildvar (LexState *ls, TString *varname, expdesc *var) {
function singlevar (line 538) | static void singlevar (LexState *ls, expdesc *var) {
function adjust_assign (line 547) | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *...
function l_noret (line 580) | static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) {
function closegoto (line 597) | static void closegoto (LexState *ls, int g, Labeldesc *label, int bup) {
function Labeldesc (line 626) | static Labeldesc *findlabel (LexState *ls, TString *name, int ilb) {
function newlabelentry (line 640) | static int newlabelentry (LexState *ls, Labellist *l, TString *name,
function newgotoentry (line 663) | static int newgotoentry (LexState *ls, TString *name, int line) {
function createlabel (line 678) | static void createlabel (LexState *ls, TString *name, int line, int last) {
function solvegotos (line 696) | static void solvegotos (FuncState *fs, BlockCnt *bl) {
function enterblock (line 720) | static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
function l_noret (line 737) | static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
function leaveblock (line 745) | static void leaveblock (FuncState *fs) {
function Proto (line 768) | static Proto *addprototype (LexState *ls) {
function codeclosure (line 792) | static void codeclosure (LexState *ls, expdesc *v) {
function open_func (line 799) | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
function close_func (line 830) | static void close_func (LexState *ls) {
function block_follow (line 864) | static int block_follow (LexState *ls, int withuntil) {
function statlist (line 875) | static void statlist (LexState *ls) {
function fieldsel (line 887) | static void fieldsel (LexState *ls, expdesc *v) {
function yindex (line 898) | static void yindex (LexState *ls, expdesc *v) {
type ConsControl (line 913) | typedef struct ConsControl {
function recfield (line 936) | static void recfield (LexState *ls, ConsControl *cc) {
function closelistfield (line 955) | static void closelistfield (FuncState *fs, ConsControl *cc) {
function lastlistfield (line 967) | static void lastlistfield (FuncState *fs, ConsControl *cc) {
function listfield (line 983) | static void listfield (LexState *ls, ConsControl *cc) {
function field (line 990) | static void field (LexState *ls, ConsControl *cc) {
function maxtostore (line 1017) | static int maxtostore (FuncState *fs) {
function constructor (line 1028) | static void constructor (LexState *ls, expdesc *t) {
function setvararg (line 1059) | static void setvararg (FuncState *fs) {
function parlist (line 1065) | static void parlist (LexState *ls) {
function body (line 1103) | static void body (LexState *ls, expdesc *e, int ismethod, int line) {
function explist (line 1125) | static int explist (LexState *ls, expdesc *v) {
function funcargs (line 1138) | static void funcargs (LexState *ls, expdesc *f) {
function primaryexp (line 1195) | static void primaryexp (LexState *ls, expdesc *v) {
function suffixedexp (line 1217) | static void suffixedexp (LexState *ls, expdesc *v) {
function simpleexp (line 1254) | static void simpleexp (LexState *ls, expdesc *v) {
function UnOpr (line 1309) | static UnOpr getunopr (int op) {
function BinOpr (line 1320) | static BinOpr getbinopr (int op) {
function BinOpr (line 1374) | static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
function expr (line 1404) | static void expr (LexState *ls, expdesc *v) {
function block (line 1419) | static void block (LexState *ls) {
type LHS_assign (line 1433) | struct LHS_assign {
function check_conflict (line 1445) | static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc...
function storevartop (line 1484) | static void storevartop (FuncState *fs, expdesc *var) {
function restassign (line 1498) | static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) {
function cond (line 1528) | static int cond (LexState *ls) {
function gotostat (line 1538) | static void gotostat (LexState *ls, int line) {
function breakstat (line 1547) | static void breakstat (LexState *ls, int line) {
function checkrepeated (line 1565) | static void checkrepeated (LexState *ls, TString *name) {
function labelstat (line 1573) | static void labelstat (LexState *ls, TString *name, int line) {
function whilestat (line 1583) | static void whilestat (LexState *ls, int line) {
function repeatstat (line 1602) | static void repeatstat (LexState *ls, int line) {
function exp1 (line 1632) | static void exp1 (LexState *ls) {
function fixforjump (line 1645) | static void fixforjump (FuncState *fs, int pc, int dest, int back) {
function forbody (line 1659) | static void forbody (LexState *ls, int base, int line, int nvars, int is...
function fornum (line 1685) | static void fornum (LexState *ls, TString *varname, int line) {
function forlist (line 1707) | static void forlist (LexState *ls, TString *indexname) {
function forstat (line 1734) | static void forstat (LexState *ls, int line) {
function test_then_block (line 1752) | static void test_then_block (LexState *ls, int *escapelist) {
function ifstat (line 1767) | static void ifstat (LexState *ls, int line) {
function localfunc (line 1781) | static void localfunc (LexState *ls) {
function lu_byte (line 1793) | static lu_byte getvarattribute (LexState *ls, lu_byte df) {
function checktoclose (line 1810) | static void checktoclose (FuncState *fs, int level) {
function localstat (line 1818) | static void localstat (LexState *ls) {
function lu_byte (line 1862) | static lu_byte getglobalattribute (LexState *ls, lu_byte df) {
function checkglobal (line 1876) | static void checkglobal (LexState *ls, TString *varname, int line) {
function initglobal (line 1894) | static void initglobal (LexState *ls, int nvars, int firstidx, int n,
function globalnames (line 1915) | static void globalnames (LexState *ls, lu_byte defkind) {
function globalstat (line 1931) | static void globalstat (LexState *ls) {
function globalfunc (line 1947) | static void globalfunc (LexState *ls, int line) {
function globalstatfunc (line 1962) | static void globalstatfunc (LexState *ls, int line) {
function funcname (line 1972) | static int funcname (LexState *ls, expdesc *v) {
function funcstat (line 1986) | static void funcstat (LexState *ls, int line) {
function exprstat (line 1999) | static void exprstat (LexState *ls) {
function retstat (line 2017) | static void retstat (LexState *ls) {
function statement (line 2049) | static void statement (LexState *ls) {
function mainfunc (line 2150) | static void mainfunc (LexState *ls, FuncState *fs) {
function LClosure (line 2168) | LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
FILE: 3rd/lua/lparser.h
type expkind (line 25) | typedef enum {
type expdesc (line 78) | typedef struct expdesc {
type Vardesc (line 118) | typedef union Vardesc {
type Labeldesc (line 132) | typedef struct Labeldesc {
type Labellist (line 142) | typedef struct Labellist {
type Dyndata (line 150) | typedef struct Dyndata {
type BlockCnt (line 162) | struct BlockCnt
type FuncState (line 166) | typedef struct FuncState {
FILE: 3rd/lua/lstate.c
function luaE_setdebt (line 61) | void luaE_setdebt (global_State *g, l_mem debt) {
function CallInfo (line 71) | CallInfo *luaE_extendCI (lua_State *L) {
function freeCI (line 88) | static void freeCI (lua_State *L) {
function luaE_shrinkCI (line 104) | void luaE_shrinkCI (lua_State *L) {
function luaE_checkcstack (line 131) | void luaE_checkcstack (lua_State *L) {
function LUAI_FUNC (line 139) | LUAI_FUNC void luaE_incCstack (lua_State *L) {
function resetCI (line 146) | static void resetCI (lua_State *L) {
function stack_init (line 158) | static void stack_init (lua_State *L1, lua_State *L) {
function freestack (line 172) | static void freestack (lua_State *L) {
function init_registry (line 186) | static void init_registry (lua_State *L, global_State *g) {
function f_luaopen (line 207) | static void f_luaopen (lua_State *L, void *ud) {
function preinit_thread (line 225) | static void preinit_thread (lua_State *L, global_State *g) {
function lu_mem (line 246) | lu_mem luaE_threadsize (lua_State *L) {
function close_state (line 255) | static void close_state (lua_State *L) {
function LUA_API (line 273) | LUA_API lua_State *lua_newthread (lua_State *L) {
function luaE_freethread (line 300) | void luaE_freethread (lua_State *L, lua_State *L1) {
function TStatus (line 310) | TStatus luaE_resetthread (lua_State *L, TStatus status) {
function LUA_API (line 324) | LUA_API int lua_closethread (lua_State *L, lua_State *from) {
function LUA_API (line 336) | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud, unsigned seed) {
function LUA_API (line 391) | LUA_API void lua_close (lua_State *L) {
function luaE_warning (line 398) | void luaE_warning (lua_State *L, const char *msg, int tocont) {
function luaE_warnerror (line 408) | void luaE_warnerror (lua_State *L, const char *where) {
FILE: 3rd/lua/lstate.h
type CallInfo (line 14) | typedef struct CallInfo CallInfo;
type lua_longjmp (line 122) | struct lua_longjmp
type stringtable (line 167) | typedef struct stringtable {
type CallInfo (line 187) | struct CallInfo {
type lua_State (line 285) | struct lua_State {
type LX (line 318) | typedef struct LX {
type global_State (line 327) | typedef struct global_State {
type TString (line 396) | struct TString
type Udata (line 397) | struct Udata
type Table (line 399) | struct Table
type Proto (line 400) | struct Proto
type lua_State (line 401) | struct lua_State
type UpVal (line 402) | struct UpVal
FILE: 3rd/lua/lstring.c
function luaS_eqstr (line 46) | int luaS_eqstr (TString *a, TString *b) {
function luaS_eqshrstr (line 54) | int luaS_eqshrstr (TString *a, TString *b) {
function luaS_share (line 68) | void luaS_share (TString *ts) {
function luaS_hash (line 77) | static unsigned luaS_hash (const char *str, size_t l, unsigned seed) {
function luaS_hashlongstr (line 85) | unsigned luaS_hashlongstr (TString *ts) {
function tablerehash (line 96) | static void tablerehash (TString **vect, int osize, int nsize) {
function luaS_resize (line 119) | void luaS_resize (lua_State *L, int nsize) {
function luaS_clearcache (line 144) | void luaS_clearcache (global_State *g) {
function luaS_init (line 157) | void luaS_init (lua_State *L) {
function luaS_sizelngstr (line 173) | size_t luaS_sizelngstr (size_t len, int kind) {
function TString (line 191) | static TString *createstrobj (lua_State *L, size_t totalsize, lu_byte tag,
function TString (line 204) | TString *luaS_createlngstrobj (lua_State *L, size_t l) {
function luaS_remove (line 215) | void luaS_remove (lua_State *L, TString *ts) {
function growstrtab (line 225) | static void growstrtab (lua_State *L, stringtable *tb) {
function TString (line 239) | static TString *internshrstr (lua_State *L, const char *str, size_t l) {
function TString (line 274) | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
function TString (line 294) | TString *luaS_new (lua_State *L, const char *str) {
function Udata (line 311) | Udata *luaS_newudata (lua_State *L, size_t s, unsigned short nuvalue) {
type NewExt (line 328) | struct NewExt {
function f_newext (line 336) | static void f_newext (lua_State *L, void *ud) {
function TString (line 343) | TString *luaS_newextlstr (lua_State *L,
function TString (line 369) | TString *luaS_normstr (lua_State *L, TString *ts) {
FILE: 3rd/lua/lstrlib.c
function str_len (line 40) | static int str_len (lua_State *L) {
function posrelatI (line 56) | static size_t posrelatI (lua_Integer pos, size_t len) {
function getendpos (line 72) | static size_t getendpos (lua_State *L, int arg, lua_Integer def,
function str_sub (line 85) | static int str_sub (lua_State *L) {
function str_reverse (line 97) | static int str_reverse (lua_State *L) {
function str_lower (line 109) | static int str_lower (lua_State *L) {
function str_upper (line 122) | static int str_upper (lua_State *L) {
function str_rep (line 139) | static int str_rep (lua_State *L) {
function str_byte (line 166) | static int str_byte (lua_State *L) {
function str_char (line 184) | static int str_char (lua_State *L) {
type str_Writer (line 205) | struct str_Writer {
function writer (line 211) | static int writer (lua_State *L, const void *b, size_t size, void *ud) {
function str_dump (line 227) | static int str_dump (lua_State *L) {
function tonum (line 259) | static int tonum (lua_State *L, int arg) {
function trymt (line 279) | static void trymt (lua_State *L, const char *mtkey, const char *opname) {
function arith (line 290) | static int arith (lua_State *L, int op, const char *mtname) {
function arith_add (line 299) | static int arith_add (lua_State *L) {
function arith_sub (line 303) | static int arith_sub (lua_State *L) {
function arith_mul (line 307) | static int arith_mul (lua_State *L) {
function arith_mod (line 311) | static int arith_mod (lua_State *L) {
function arith_pow (line 315) | static int arith_pow (lua_State *L) {
function arith_div (line 319) | static int arith_div (lua_State *L) {
function arith_idiv (line 323) | static int arith_idiv (lua_State *L) {
function arith_unm (line 327) | static int arith_unm (lua_State *L) {
type MatchState (line 360) | typedef struct MatchState {
function check_capture (line 388) | static int check_capture (MatchState *ms, int l) {
function capture_to_close (line 397) | static int capture_to_close (MatchState *ms) {
function match_class (line 429) | static int match_class (int c, int cl) {
function matchbracketclass (line 449) | static int matchbracketclass (int c, const char *p, const char *ec) {
function singlematch (line 472) | static int singlematch (MatchState *ms, const char *s, const char *p,
function get_onecapture (line 704) | static ptrdiff_t get_onecapture (MatchState *ms, int i, const char *s,
function push_onecapture (line 728) | static void push_onecapture (MatchState *ms, int i, const char *s,
function push_captures (line 738) | static int push_captures (MatchState *ms, const char *s, const char *e) {
function nospecials (line 749) | static int nospecials (const char *p, size_t l) {
function prepstate (line 760) | static void prepstate (MatchState *ms, lua_State *L,
function reprepstate (line 770) | static void reprepstate (MatchState *ms) {
function str_find_aux (line 776) | static int str_find_aux (lua_State *L, int find) {
function str_find (line 822) | static int str_find (lua_State *L) {
function str_match (line 827) | static int str_match (lua_State *L) {
type GMatchState (line 833) | typedef struct GMatchState {
function gmatch_aux (line 841) | static int gmatch_aux (lua_State *L) {
function gmatch (line 857) | static int gmatch (lua_State *L) {
function add_s (line 874) | static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
function add_value (line 909) | static int add_value (MatchState *ms, luaL_Buffer *b, const char *s,
function str_gsub (line 945) | static int str_gsub (lua_State *L) {
function lua_Number (line 1020) | static lua_Number adddigit (char *buff, unsigned n, lua_Number x) {
function num2straux (line 1028) | static int num2straux (char *buff, unsigned sz, lua_Number x) {
function lua_number2strx (line 1060) | static int lua_number2strx (lua_State *L, char *buff, unsigned sz,
function addquoted (line 1126) | static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
function quotefloat (line 1155) | static int quotefloat (lua_State *L, char *buff, lua_Number n) {
function addliteral (line 1179) | static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
function checkformat (line 1229) | static void checkformat (lua_State *L, const char *form, const char *flags,
function addlenmod (line 1267) | static void addlenmod (char *form, const char *lenmod) {
function str_format (line 1277) | static int str_format (lua_State *L) {
type Header (line 1422) | typedef struct Header {
type KOption (line 1432) | typedef enum KOption {
function digit (line 1451) | static int digit (int c) { return '0' <= c && c <= '9'; }
function getnum (line 1453) | static size_t getnum (const char **fmt, size_t df) {
function getnumlimit (line 1470) | static unsigned getnumlimit (Header *h, const char **fmt, size_t df) {
function initheader (line 1482) | static void initheader (lua_State *L, Header *h) {
function KOption (line 1492) | static KOption getoption (Header *h, const char **fmt, size_t *size) {
function KOption (line 1545) | static KOption getdetails (Header *h, size_t totalsize, const char **fmt,
function packint (line 1578) | static void packint (luaL_Buffer *b, lua_Unsigned n,
function copywithendian (line 1599) | static void copywithendian (char *dest, const char *src,
function str_pack (line 1611) | static int str_pack (lua_State *L) {
function str_packsize (line 1717) | static int str_packsize (lua_State *L) {
function lua_Integer (line 1746) | static lua_Integer unpackint (lua_State *L, const char *str,
function str_unpack (line 1772) | static int str_unpack (lua_State *L) {
function createmetatable (line 1872) | static void createmetatable (lua_State *L) {
function LUAMOD_API (line 1889) | LUAMOD_API int luaopen_string (lua_State *L) {
FILE: 3rd/lua/ltable.c
type Limbox_aux (line 55) | typedef struct { Node *dummy; Node follows_pNode; } Limbox_aux;
type Limbox (line 57) | typedef union {
function Node (line 145) | static Node *hashint (const Table *t, lua_Integer i) {
function l_hashfloat (line 168) | static unsigned l_hashfloat (lua_Number n) {
function Node (line 188) | static Node *mainpositionTV (const Table *t, const TValue *key) {
function l_sinline (line 226) | l_sinline Node *mainpositionfromnode (const Table *t, Node *nd) {
function equalkey (line 252) | static int equalkey (const TValue *k1, const Node *n2, int deadok) {
function TValue (line 294) | static const TValue *getgeneric (Table *t, const TValue *key, int deadok) {
function checkrange (line 313) | static unsigned checkrange (lua_Integer k, unsigned limit) {
function keyinarray (line 336) | static unsigned keyinarray (Table *t, const TValue *key) {
function findindex (line 346) | static unsigned findindex (lua_State *L, Table *t, TValue *key,
function luaH_next (line 364) | int luaH_next (lua_State *L, Table *t, StkId key) {
function sizehash (line 391) | static size_t sizehash (Table *t) {
function freehash (line 396) | static void freehash (lua_State *L, Table *t) {
type Counters (line 424) | typedef struct {
function computesizes (line 449) | static unsigned computesizes (Counters *ct) {
function countint (line 473) | static void countint (lua_Integer key, Counters *ct) {
function l_sinline (line 482) | l_sinline int arraykeyisempty (const Table *t, unsigned key) {
function numusearray (line 491) | static void numusearray (const Table *t, Counters *ct) {
function numusehash (line 524) | static void numusehash (const Table *t, Counters *ct) {
function concretesize (line 547) | static size_t concretesize (unsigned int size) {
function Value (line 566) | static Value *resizearray (lua_State *L , Table *t,
function setnodevector (line 605) | static void setnodevector (lua_State *L, Table *t, unsigned size) {
function reinserthash (line 640) | static void reinserthash (lua_State *L, Table *ot, Table *t) {
function exchangehashpart (line 662) | static void exchangehashpart (Table *t1, Table *t2) {
function reinsertOldSlice (line 679) | static void reinsertOldSlice (Table *t, unsigned oldasize,
function clearNewSlice (line 697) | static void clearNewSlice (Table *t, unsigned oldasize, unsigned newasiz...
function luaH_resize (line 719) | void luaH_resize (lua_State *L, Table *t, unsigned newasize,
function luaH_resizearray (line 754) | void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
function rehash (line 765) | static void rehash (lua_State *L, Table *t, const TValue *ek) {
function Table (line 802) | Table *luaH_new (lua_State *L) {
function lu_mem (line 814) | lu_mem luaH_size (Table *t) {
function luaH_free (line 825) | void luaH_free (lua_State *L, Table *t) {
function Node (line 832) | static Node *getfreepos (Table *t) {
function insertkey (line 862) | static int insertkey (Table *t, const TValue *key, TValue *value) {
function newcheckedkey (line 905) | static void newcheckedkey (Table *t, const TValue *key, TValue *value) {
function luaH_newkey (line 917) | static void luaH_newkey (lua_State *L, Table *t, const TValue *key,
function TValue (line 934) | static const TValue *getintfromhash (Table *t, lua_Integer key) {
function hashkeyisempty (line 950) | static int hashkeyisempty (Table *t, lua_Unsigned key) {
function lu_byte (line 956) | static lu_byte finishnodeget (const TValue *val, TValue *res) {
function lu_byte (line 964) | lu_byte luaH_getint (Table *t, lua_Integer key, TValue *res) {
function TValue (line 980) | const TValue *luaH_Hgetshortstr (Table *t, TString *key) {
function lu_byte (line 996) | lu_byte luaH_getshortstr (Table *t, TString *key, TValue *res) {
function TValue (line 1001) | static const TValue *Hgetlongstr (Table *t, TString *key) {
function TValue (line 1009) | static const TValue *Hgetstr (Table *t, TString *key) {
function lu_byte (line 1017) | lu_byte luaH_getstr (Table *t, TString *key, TValue *res) {
function lu_byte (line 1025) | lu_byte luaH_get (Table *t, const TValue *key, TValue *res) {
function retpsetcode (line 1054) | static int retpsetcode (Table *t, const TValue *slot) {
function finishnodeset (line 1062) | static int finishnodeset (Table *t, const TValue *slot, TValue *val) {
function rawfinishnodeset (line 1072) | static int rawfinishnodeset (const TValue *slot, TValue *val) {
function luaH_psetint (line 1082) | int luaH_psetint (Table *t, lua_Integer key, TValue *val) {
function psetint (line 1088) | static int psetint (Table *t, lua_Integer key, TValue *val) {
function luaH_psetshortstr (line 1103) | int luaH_psetshortstr (Table *t, TString *key, TValue *val) {
function luaH_psetstr (line 1129) | int luaH_psetstr (Table *t, TString *key, TValue *val) {
function luaH_pset (line 1137) | int luaH_pset (Table *t, const TValue *key, TValue *val) {
function luaH_finishset (line 1159) | void luaH_finishset (lua_State *L, Table *t, const TValue *key,
function luaH_set (line 1202) | void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) {
function luaH_setint (line 1213) | void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
function lua_Unsigned (line 1248) | static lua_Unsigned hash_search (lua_State *L, Table *t, unsigned asize) {
function binsearch (line 1280) | static unsigned int binsearch (Table *array, unsigned int i, unsigned in...
function lua_Unsigned (line 1292) | static lua_Unsigned newhint (Table *t, unsigned hint) {
function lua_Unsigned (line 1310) | lua_Unsigned luaH_getn (lua_State *L, Table *t) {
function Node (line 1360) | Node *luaH_mainposition (const Table *t, const TValue *key) {
FILE: 3rd/lua/ltablib.c
function checkfield (line 37) | static int checkfield (lua_State *L, const char *key, int n) {
function checktab (line 47) | static void checktab (lua_State *L, int arg, int what) {
function tcreate (line 62) | static int tcreate (lua_State *L) {
function tinsert (line 72) | static int tinsert (lua_State *L) {
function tremove (line 102) | static int tremove (lua_State *L) {
function tmove (line 126) | static int tmove (lua_State *L) {
function addfield (line 158) | static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) {
function tconcat (line 167) | static int tconcat (lua_State *L) {
function tpack (line 192) | static int tpack (lua_State *L) {
function tunpack (line 205) | static int tunpack (lua_State *L) {
type IdxT (line 238) | typedef unsigned int IdxT;
function set2 (line 261) | static void set2 (lua_State *L, IdxT i, IdxT j) {
function sort_comp (line 271) | static int sort_comp (lua_State *L, int a, int b) {
function IdxT (line 294) | static IdxT partition (lua_State *L, IdxT lo, IdxT up) {
function IdxT (line 330) | static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) {
function auxsort (line 341) | static void auxsort (lua_State *L, IdxT lo, IdxT up, unsigned rnd) {
function sort (line 394) | static int sort (lua_State *L) {
function LUAMOD_API (line 422) | LUAMOD_API int luaopen_table (lua_State *L) {
FILE: 3rd/lua/ltests.c
function setnameval (line 53) | static void setnameval (lua_State *L, const char *name, int val) {
function pushobject (line 59) | static void pushobject (lua_State *L, const TValue *o) {
function badexit (line 65) | static void badexit (const char *fmt, const char *s1, const char *s2) {
function tpanic (line 75) | static int tpanic (lua_State *L) {
function warnf (line 95) | static void warnf (void *ud, const char *msg, int tocont) {
type memHeader (line 167) | typedef union memHeader {
function freeblock (line 196) | static void freeblock (Memcontrol *mc, memHeader *block) {
function testobjref1 (line 297) | static int testobjref1 (global_State *g, GCObject *f, GCObject *t) {
function printobj (line 314) | static void printobj (global_State *g, GCObject *o) {
function lua_printobj (line 324) | void lua_printobj (lua_State *L, struct GCObject *o) {
function lua_printvalue (line 329) | void lua_printvalue (TValue *v) {
function testobjref (line 368) | static int testobjref (global_State *g, GCObject *f, GCObject *t) {
function checkobjref (line 381) | static void checkobjref (global_State *g, GCObject *f, GCObject *t) {
function checkvalref (line 395) | static void checkvalref (global_State *g, GCObject *f, const TValue *t) {
function checktable (line 400) | static void checktable (global_State *g, Table *h) {
function checkudata (line 423) | static void checkudata (global_State *g, Udata *u) {
function checkproto (line 432) | static void checkproto (global_State *g, Proto *f) {
function checkCclosure (line 449) | static void checkCclosure (global_State *g, CClosure *cl) {
function checkLclosure (line 457) | static void checkLclosure (global_State *g, LClosure *cl) {
function lua_checkpc (line 472) | static int lua_checkpc (CallInfo *ci) {
function check_stack (line 483) | static void check_stack (global_State *g, lua_State *L1) {
function checkrefs (line 505) | static void checkrefs (global_State *g, GCObject *o) {
function checkobject (line 557) | static void checkobject (global_State *g, GCObject *o, int maybedead,
function l_mem (line 580) | static l_mem checkgraylist (global_State *g, GCObject *o) {
function l_mem (line 609) | static l_mem checkgrays (global_State *g) {
function incifingray (line 626) | static void incifingray (global_State *g, GCObject *o, l_mem *count) {
function l_mem (line 643) | static l_mem checklist (global_State *g, int maybedead, int tof,
function lua_checkmemory (line 671) | int lua_checkmemory (lua_State *L) {
function luaI_printcode (line 763) | void luaI_printcode (Proto *pt, int size) {
function luaI_printinst (line 773) | void luaI_printinst (Proto *pt, int pc) {
function listcode (line 780) | static int listcode (lua_State *L) {
function printcode (line 799) | static int printcode (lua_State *L) {
function listk (line 815) | static int listk (lua_State *L) {
function listabslineinfo (line 830) | static int listabslineinfo (lua_State *L) {
function listlocals (line 848) | static int listlocals (lua_State *L) {
function lua_printstack (line 865) | void lua_printstack (lua_State *L) {
function lua_printallstack (line 878) | int lua_printallstack (lua_State *L) {
function get_limits (line 900) | static int get_limits (lua_State *L) {
function get_sizes (line 911) | static int get_sizes (lua_State *L) {
function mem_query (line 922) | static int mem_query (lua_State *L) {
function alloc_count (line 949) | static int alloc_count (lua_State *L) {
function alloc_failnext (line 958) | static int alloc_failnext (lua_State *L) {
function settrick (line 965) | static int settrick (lua_State *L) {
function gc_color (line 974) | static int gc_color (lua_State *L) {
function gc_age (line 990) | static int gc_age (lua_State *L) {
function gc_printobj (line 1006) | static int gc_printobj (lua_State *L) {
function gc_state (line 1025) | static int gc_state (lua_State *L) {
function luai_tracegctest (line 1051) | void luai_tracegctest (lua_State *L, int first) {
function tracegc (line 1067) | static int tracegc (lua_State *L) {
function hash_query (line 1078) | static int hash_query (lua_State *L) {
function stacklevel (line 1098) | static int stacklevel (lua_State *L) {
function table_query (line 1109) | static int table_query (lua_State *L) {
function gc_query (line 1151) | static int gc_query (lua_State *L) {
function test_codeparam (line 1165) | static int test_codeparam (lua_State *L) {
function test_applyparam (line 1172) | static int test_applyparam (lua_State *L) {
function string_query (line 1180) | static int string_query (lua_State *L) {
function getreftable (line 1202) | static int getreftable (lua_State *L) {
function tref (line 1210) | static int tref (lua_State *L) {
function getref (line 1222) | static int getref (lua_State *L) {
function unref (line 1231) | static int unref (lua_State *L) {
function upvalue (line 1241) | static int upvalue (lua_State *L) {
function newuserdata (line 1258) | static int newuserdata (lua_State *L) {
function pushuserdata (line 1267) | static int pushuserdata (lua_State *L) {
function udataval (line 1274) | static int udataval (lua_State *L) {
function doonnewstack (line 1280) | static int doonnewstack (lua_State *L) {
function s2d (line 1292) | static int s2d (lua_State *L) {
function d2s (line 1298) | static int d2s (lua_State *L) {
function num2int (line 1305) | static int num2int (lua_State *L) {
function makeseed (line 1311) | static int makeseed (lua_State *L) {
function newstate (line 1317) | static int newstate (lua_State *L) {
function lua_State (line 1331) | static lua_State *getstate (lua_State *L) {
function loadlib (line 1338) | static int loadlib (lua_State *L) {
function closestate (line 1352) | static int closestate (lua_State *L) {
function doremote (line 1358) | static int doremote (lua_State *L) {
function log2_aux (line 1383) | static int log2_aux (lua_State *L) {
type Aux (line 1390) | struct Aux { jmp_buf jb; const char *paniccode; lua_State *L; }
function panicback (line 1395) | static int panicback (lua_State *L) {
function checkpanic (line 1406) | static int checkpanic (lua_State *L) {
function externKstr (line 1435) | static int externKstr (lua_State *L) {
function externstr (line 1448) | static int externstr (lua_State *L) {
function skip (line 1479) | static void skip (const char **pc) {
function getnum_aux (line 1489) | static int getnum_aux (lua_State *L, lua_State *L1, const char **pc) {
function getindex_aux (line 1544) | static int getindex_aux (lua_State *L, lua_State *L1, const char **pc) {
function regcodes (line 1567) | static void regcodes (lua_State *L) {
function runC (line 1596) | static int runC (lua_State *L, lua_State *L1, const char *pc) {
function testC (line 2002) | static int testC (lua_State *L) {
function Cfunc (line 2021) | static int Cfunc (lua_State *L) {
function Cfunck (line 2026) | static int Cfunck (lua_State *L, int status, lua_KContext ctx) {
function makeCfunc (line 2035) | static int makeCfunc (lua_State *L) {
function Chook (line 2054) | static void Chook (lua_State *L, lua_Debug *ar) {
function sethookaux (line 2071) | static void sethookaux (lua_State *L, int mask, int count, const char *s...
function sethook (line 2090) | static int sethook (lua_State *L) {
function coresume (line 2108) | static int coresume (lua_State *L) {
function nonblock (line 2133) | static int nonblock (lua_State *L) {
type luaL_Reg (line 2147) | struct luaL_Reg
function checkfinalmem (line 2202) | static void checkfinalmem (void) {
function luaB_opentests (line 2208) | int luaB_opentests (lua_State *L) {
FILE: 3rd/lua/ltests.h
type Memcontrol (line 52) | typedef struct Memcontrol {
type GCObject (line 83) | struct GCObject
type GCObject (line 84) | struct GCObject
type TValue (line 90) | struct TValue
type TValue (line 91) | struct TValue
type L_EXTRA (line 102) | struct L_EXTRA { int lock; int *plock; }
FILE: 3rd/lua/ltm.c
function luaT_init (line 38) | void luaT_init (lua_State *L) {
function TValue (line 60) | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
function TValue (line 71) | const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
function luaT_callTM (line 103) | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
function lu_byte (line 119) | lu_byte luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
function callbinTM (line 138) | static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
function luaT_trybinTM (line 150) | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
function luaT_tryconcatTM (line 173) | void luaT_tryconcatTM (lua_State *L) {
function luaT_trybinassocTM (line 180) | void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2,
function luaT_trybiniTM (line 189) | void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2,
function luaT_callorderTM (line 200) | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
function luaT_callorderiTM (line 210) | int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
function createvarargtab (line 231) | static void createvarargtab (lua_State *L, StkId f, int n) {
function buildhiddenargs (line 255) | static void buildhiddenargs (lua_State *L, CallInfo *ci, const Proto *p,
function luaT_adjustvarargs (line 272) | void luaT_adjustvarargs (lua_State *L, CallInfo *ci, const Proto *p) {
function luaT_getvararg (line 292) | void luaT_getvararg (CallInfo *ci, StkId ra, TValue *rc) {
function getnumargs (line 321) | static int getnumargs (lua_State *L, CallInfo *ci, Table *h) {
function luaT_getvarargs (line 338) | void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted,
FILE: 3rd/lua/ltm.h
type TMS (line 18) | typedef enum {
type CallInfo (line 98) | struct CallInfo
type CallInfo (line 101) | struct CallInfo
FILE: 3rd/lua/lua.c
function setsignal (line 46) | static void setsignal (int sig, void (*handler)(int)) {
function lstop (line 64) | static void lstop (lua_State *L, lua_Debug *ar) {
function laction (line 77) | static void laction (int i) {
function print_usage (line 84) | static void print_usage (const char *badoption) {
function l_message (line 111) | static void l_message (const char *pname, const char *msg) {
function report (line 121) | static int report (lua_State *L, int status) {
function msghandler (line 136) | static int msghandler (lua_State *L) {
function docall (line 155) | static int docall (lua_State *L, int narg, int nres) {
function print_version (line 169) | static void print_version (void) {
function createargtable (line 185) | static void createargtable (lua_State *L, char **argv, int argc, int scr...
function dochunk (line 197) | static int dochunk (lua_State *L, int status) {
function dofile (line 203) | static int dofile (lua_State *L, const char *name) {
function dostring (line 208) | static int dostring (lua_State *L, const char *s, const char *name) {
function dolibrary (line 218) | static int dolibrary (lua_State *L, char *globname) {
function pushargs (line 245) | static int pushargs (lua_State *L) {
function handle_script (line 258) | static int handle_script (lua_State *L, char **argv) {
function collectargs (line 287) | static int collectargs (char **argv, int *first) {
function runargs (line 350) | static int runargs (lua_State *L, char **argv, int n) {
function handle_luainit (line 377) | static int handle_luainit (lua_State *L) {
function lua_saveline (line 481) | static void lua_saveline (const char *line) {
function lua_freeline (line 488) | static void lua_freeline (char *line) {
function lua_initreadline (line 500) | static void lua_initreadline (lua_State *L) {
function incomplete (line 553) | static int incomplete (lua_State *L, int status) {
function pushline (line 567) | static int pushline (lua_State *L, int firstline) {
function addreturn (line 588) | static int addreturn (lua_State *L) {
function checklocal (line 600) | static void checklocal (const char *line) {
function multiline (line 617) | static int multiline (lua_State *L) {
function loadline (line 640) | static int loadline (lua_State *L) {
function l_print (line 660) | static void l_print (lua_State *L) {
function doREPL (line 677) | static void doREPL (lua_State *L) {
function pmain (line 704) | static int pmain (lua_State *L) {
function main (line 749) | int main (int argc, char **argv) {
FILE: 3rd/lua/lua.h
type lua_State (line 56) | typedef struct lua_State lua_State;
type LUA_NUMBER (line 90) | typedef LUA_NUMBER lua_Number;
type LUA_INTEGER (line 94) | typedef LUA_INTEGER lua_Integer;
type LUA_UNSIGNED (line 97) | typedef LUA_UNSIGNED lua_Unsigned;
type LUA_KCONTEXT (line 100) | typedef LUA_KCONTEXT lua_KContext;
type lua_Debug (line 137) | typedef struct lua_Debug lua_Debug;
type lua_Debug (line 491) | struct lua_Debug {
FILE: 3rd/lua/luac.c
function fatal (line 43) | static void fatal(const char* message)
function cannot (line 49) | static void cannot(const char* what)
function usage (line 55) | static void usage(const char* message)
function doargs (line 77) | static int doargs(int argc, char* argv[])
function Proto (line 144) | static const Proto* combine(lua_State* L, int n)
function writer (line 163) | static int writer(lua_State* L, const void* p, size_t size, void* u)
function pmain (line 169) | static int pmain(lua_State* L)
function main (line 197) | int main(int argc, char* argv[])
function PrintString (line 221) | static void PrintString(const TString* ts)
function PrintType (line 266) | static void PrintType(const Proto* f, int i)
function PrintConstant (line 295) | static void PrintConstant(const Proto* f, int i)
function PrintCode (line 335) | static void PrintCode(const Proto* f)
function PrintHeader (line 678) | static void PrintHeader(const Proto* f)
function PrintDebug (line 698) | static void PrintDebug(const Proto* f)
function PrintFunction (line 726) | static void PrintFunction(const Proto* f, int full)
FILE: 3rd/lua/lundump.c
type LoadState (line 34) | typedef struct {
function l_noret (line 45) | static l_noret error (LoadState *S, const char *why) {
function loadBlock (line 57) | static void loadBlock (LoadState *S, void *b, size_t size) {
function loadAlign (line 64) | static void loadAlign (LoadState *S, unsigned align) {
function lu_byte (line 88) | static lu_byte loadByte (LoadState *S) {
function lua_Unsigned (line 97) | static lua_Unsigned loadVarint (LoadState *S, lua_Unsigned limit) {
function loadSize (line 111) | static size_t loadSize (LoadState *S) {
function loadInt (line 116) | static int loadInt (LoadState *S) {
function lua_Number (line 122) | static lua_Number loadNumber (LoadState *S) {
function lua_Integer (line 129) | static lua_Integer loadInteger (LoadState *S) {
function loadString (line 145) | static void loadString (LoadState *S, Proto *p, TString **sl) {
function loadCode (line 187) | static void loadCode (LoadState *S, Proto *f) {
function loadConstants (line 205) | static void loadConstants (LoadState *S, Proto *f) {
function loadProtos (line 247) | static void loadProtos (LoadState *S, Proto *f) {
function loadUpvalues (line 268) | static void loadUpvalues (LoadState *S, Proto *f) {
function loadDebug (line 283) | static void loadDebug (LoadState *S, Proto *f) {
function loadFunction (line 326) | static void loadFunction (LoadState *S, Proto *f) {
function checkliteral (line 344) | static void checkliteral (LoadState *S, const char *s, const char *msg) {
function l_noret (line 353) | static l_noret numerror (LoadState *S, const char *what, const char *tna...
function checknumsize (line 359) | static void checknumsize (LoadState *S, int size, const char *tname) {
function checknumformat (line 365) | static void checknumformat (LoadState *S, int eq, const char *tname) {
function checkHeader (line 377) | static void checkHeader (LoadState *S) {
function LClosure (line 395) | LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name, int fixed) {
FILE: 3rd/lua/lutf8lib.c
function lua_Integer (line 38) | static lua_Integer u_posrelat (lua_Integer pos, size_t len) {
function utflen (line 87) | static int utflen (lua_State *L) {
function codepoint (line 117) | static int codepoint (lua_State *L) {
function pushutfchar (line 146) | static void pushutfchar (lua_State *L, int arg) {
function utfchar (line 156) | static int utfchar (lua_State *L) {
function byteoffset (line 178) | static int byteoffset (lua_State *L) {
function iter_aux (line 228) | static int iter_aux (lua_State *L, int strict) {
function iter_auxstrict (line 249) | static int iter_auxstrict (lua_State *L) {
function iter_auxlax (line 253) | static int iter_auxlax (lua_State *L) {
function iter_codes (line 258) | static int iter_codes (lua_State *L) {
function LUAMOD_API (line 285) | LUAMOD_API int luaopen_utf8 (lua_State *L) {
FILE: 3rd/lua/lvm.c
function l_strton (line 91) | static int l_strton (const TValue *obj, TValue *result) {
function luaV_tonumber_ (line 108) | int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
function luaV_flttointeger (line 126) | int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode) {
function luaV_tointegerns (line 142) | int luaV_tointegerns (const TValue *obj, lua_Integer *p, F2Imod mode) {
function luaV_tointeger (line 157) | int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode) {
function forlimit (line 181) | static int forlimit (lua_State *L, lua_Integer init, const TValue *lim,
function forprep (line 214) | static int forprep (lua_State *L, StkId ra) {
function floatforloop (line 273) | static int floatforloop (StkId ra) {
function lu_byte (line 291) | lu_byte luaV_finishget (lua_State *L, const TValue *t, TValue *key,
function luaV_finishset (line 334) | void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
function l_strcmp (line 393) | static int l_strcmp (const TString *ts1, const TString *ts2) {
function l_sinline (line 428) | l_sinline int LTintfloat (lua_Integer i, lua_Number f) {
function l_sinline (line 445) | l_sinline int LEintfloat (lua_Integer i, lua_Number f) {
function l_sinline (line 462) | l_sinline int LTfloatint (lua_Number f, lua_Integer i) {
function l_sinline (line 479) | l_sinline int LEfloatint (lua_Number f, lua_Integer i) {
function l_sinline (line 495) | l_sinline int LTnum (const TValue *l, const TValue *r) {
function l_sinline (line 517) | l_sinline int LEnum (const TValue *l, const TValue *r) {
function lessthanothers (line 539) | static int lessthanothers (lua_State *L, const TValue *l, const TValue *...
function luaV_lessthan (line 551) | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
function lessequalothers (line 561) | static int lessequalothers (lua_State *L, const TValue *l, const TValue ...
function luaV_lessequal (line 573) | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
function luaV_equalobj (line 584) | int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
function copy2buff (line 670) | static void copy2buff (StkId top, int n, char *buff) {
function luaV_concat (line 686) | void luaV_concat (lua_State *L, int total) {
function luaV_objlen (line 733) | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
function lua_Integer (line 768) | lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) {
function lua_Integer (line 788) | lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) {
function lua_Number (line 806) | lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) {
function lua_Integer (line 820) | lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
function pushclosure (line 836) | static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
function luaV_finishOp (line 857) | void luaV_finishOp (lua_State *L) {
function luaV_execute (line 1200) | void luaV_execute (lua_State *L, CallInfo *ci) {
FILE: 3rd/lua/lvm.h
type F2Imod (line 43) | typedef enum {
FILE: 3rd/lua/lzio.c
function luaZ_fill (line 24) | int luaZ_fill (ZIO *z) {
function luaZ_init (line 39) | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
function checkbuffer (line 50) | static int checkbuffer (ZIO *z) {
function luaZ_read (line 63) | size_t luaZ_read (ZIO *z, void *b, size_t n) {
FILE: 3rd/lua/lzio.h
type ZIO (line 18) | typedef struct Zio ZIO;
type Mbuffer (line 23) | typedef struct Mbuffer {
type Zio (line 56) | struct Zio {
FILE: lualib-src/lsha1.c
type SHA1_CTX (line 91) | typedef struct {
function SHA1_Transform (line 124) | static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
function sat_SHA1_Init (line 177) | static void sat_SHA1_Init(SHA1_CTX* context)
function sat_SHA1_Update (line 190) | static void sat_SHA1_Update(SHA1_CTX* context, const uint8_t* data, cons...
function sat_SHA1_Final (line 219) | static void sat_SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST...
function lsha1 (line 249) | int
function xor_key (line 265) | static inline void
function LUAMOD_API (line 274) | LUAMOD_API int
FILE: lualib-src/ltls.c
type tls_context (line 16) | struct tls_context {
type ssl_ctx (line 24) | struct ssl_ctx {
function _init_bio (line 34) | static void
function _init_client_context (line 57) | static void
function _init_server_context (line 64) | static void
type tls_context (line 71) | struct tls_context
type tls_context (line 73) | struct tls_context
type tls_context (line 73) | struct tls_context
type ssl_ctx (line 83) | struct ssl_ctx
type ssl_ctx (line 85) | struct ssl_ctx
type ssl_ctx (line 85) | struct ssl_ctx
function _ltls_context_finished (line 92) | static int
function _ltls_context_close (line 100) | static int
function _bio_read (line 113) | static int
function _bio_write (line 143) | static void
function _ltls_context_handshake (line 162) | static int
function _ltls_context_read (line 204) | static int
function _ltls_context_write (line 243) | static int
function _lset_ext_host_name (line 270) | static int
function _lctx_gc (line 280) | static int
function _lctx_cert (line 290) | static int
function _lctx_ciphers (line 319) | static int
function lnew_ctx (line 334) | static int
function lnew_tls (line 362) | static int
function luaopen_ltls_c (line 402) | int
function ltls_init_constructor (line 418) | static int
function ltls_init_destructor (line 434) | static int
function luaopen_ltls_init_c (line 450) | int
FILE: lualib-src/lua-bson.c
type bson (line 46) | struct bson {
type bson_reader (line 53) | struct bson_reader {
function get_length (line 58) | static inline int32_t
function bson_destroy (line 65) | static inline void
function bson_create (line 72) | static inline void
function bson_reserve (line 79) | static inline void
function check_reader (line 95) | static inline void
function read_byte (line 102) | static inline int
function read_int32 (line 113) | static inline int32_t
function read_int64 (line 123) | static inline int64_t
function lua_Number (line 135) | static inline lua_Number
type bson_reader (line 152) | struct bson_reader
type bson_reader (line 161) | struct bson_reader
function write_byte (line 178) | static inline void
function write_int32 (line 184) | static inline void
function write_length (line 194) | static inline void
function utf8_copy (line 205) | static int
function write_string (line 232) | static void
function reserve_length (line 251) | static inline int
function write_int64 (line 259) | static inline void
function write_double (line 269) | static inline void
function append_key (line 283) | static inline void
function is_32bit (line 289) | static inline int
function append_number (line 294) | static void
type bson (line 312) | struct bson
function write_binary (line 314) | static void
function append_one (line 323) | static void
function bson_numstr (line 434) | static inline int
function pack_array (line 444) | static void
function pack_dict_data (line 460) | static void
function pack_simple_dict (line 479) | static void
function pack_meta_dict (line 491) | static void
function is_rawarray (line 514) | static bool
function append_table (line 529) | static void
function pack_ordered_dict (line 557) | static void
function ltostring (line 577) | static int
function llen (line 585) | static int
function make_object (line 592) | static void
function unpack_dict (line 602) | static void
function lmakeindex (line 744) | static int
function replace_object (line 829) | static void
function lreplace (line 865) | static int
function ldecode (line 915) | static int
function bson_meta (line 930) | static void
function encode_bson (line 950) | static int
function lencode (line 964) | static int
function lto_lightuserdata (line 982) | static int
function encode_bson_byorder (line 989) | static int
function lencode_order (line 1001) | static int
function ldate (line 1022) | static int
function lint64 (line 1035) | static int
function ltimestamp (line 1048) | static int
function lregex (line 1069) | static int
function lbinary (line 1090) | static int
function lsubtype (line 1105) | static int
function ltype (line 1196) | static int
function typeclosure (line 1231) | static void
function init_oid_header (line 1260) | static void
function hextoint (line 1289) | static inline int
function lobjectid (line 1300) | static int
function LUAMOD_API (line 1332) | LUAMOD_API int
FILE: lualib-src/lua-clientsocket.c
function lconnect (line 24) | static int
function lclose (line 49) | static int
function block_send (line 57) | static void
function lsend (line 75) | static int
type socket_buffer (line 96) | struct socket_buffer {
function lrecv (line 101) | static int
function lusleep (line 122) | static int
type queue (line 133) | struct queue {
type queue (line 142) | struct queue
function lreadstdin (line 170) | static int
function lshutdown (line 188) | static int
function LUAMOD_API (line 222) | LUAMOD_API int
FILE: lualib-src/lua-cluster.c
function fill_uint32 (line 25) | static void
function fill_header (line 33) | static void
function packreq_number (line 83) | static int
function packreq_string (line 108) | static int
function packreq_multi (line 146) | static void
function packrequest (line 171) | static int
function lpackrequest (line 206) | static int
function lpackpush (line 211) | static int
function lpacktrace (line 216) | static int
function unpack_uint32 (line 242) | static inline uint32_t
function return_buffer (line 247) | static void
function unpackreq_number (line 255) | static int
function unpackmreq_number (line 275) | static int
function unpackmreq_part (line 293) | static int
function unpacktrace (line 308) | static int
function unpackreq_string (line 314) | static int
function unpackmreq_string (line 336) | static int
function lunpackrequest (line 357) | static int
function lpackresponse (line 417) | static int
function lunpackresponse (line 494) | static int
function lappend (line 539) | static int
function lconcat (line 558) | static int
function lisname (line 591) | static int
function lnodename (line 601) | static int
function LUAMOD_API (line 618) | LUAMOD_API int
FILE: lualib-src/lua-crypt.c
function des_main_ks (line 251) | static void
function des_crypt (line 320) | static void
function lrandomkey (line 344) | static int
function padding_mode_table (line 360) | static void
function padding_add_iso7816_4 (line 379) | static void
function padding_remove_iso7816_4 (line 385) | static int
function padding_add_pkcs7 (line 402) | static void
function padding_remove_pkcs7 (line 408) | static int
function check_padding_mode (line 430) | static inline void
function add_padding (line 436) | static void
function remove_padding (line 445) | static int
function des_key (line 451) | static void
function ldesencode (line 461) | static int
function ldesdecode (line 487) | static int
function Hash (line 520) | static void
function lhashkey (line 543) | static int
function ltohex (line 553) | static int
function lfromhex (line 574) | static int
function digest_md5 (line 628) | static void
function hmac (line 667) | static void
function hmac_md5 (line 685) | static void
function read64 (line 708) | static void
function pushqword (line 725) | static int
function lhmac64 (line 741) | static int
function lhmac64_md5 (line 756) | static int
function lhmac_hash (line 769) | static int
function mul_mod_p (line 795) | static inline uint64_t
function pow_mod_p (line 817) | static inline uint64_t
function powmodp (line 831) | static uint64_t
function push64 (line 838) | static void
function ldhsecret (line 853) | static int
function ldhexchange (line 870) | static int
function lb64encode (line 892) | static int
function b64index (line 935) | static inline int
function lb64decode (line 948) | static int
function lxor_str (line 1014) | static int
function LUAMOD_API (line 1038) | LUAMOD_API int
function LUAMOD_API (line 1075) | LUAMOD_API int
FILE: lualib-src/lua-datasheet.c
type proxy (line 19) | struct proxy {
type document (line 24) | struct document {
type table (line 32) | struct table {
type table (line 40) | struct table
type document (line 41) | struct document
type table (line 45) | struct table
function create_proxy (line 48) | static void
function clear_table (line 83) | static void
function update_cache (line 101) | static void
function lupdate (line 156) | static int
function getuint32 (line 171) | static inline uint32_t
function getfloat (line 186) | static inline float
function pushvalue (line 203) | static void
function copytable (line 229) | static void
function lnew (line 252) | static int
function copyfromdata (line 265) | static void
function lindex (line 280) | static int
function lnext (line 287) | static int
function lpairs (line 299) | static int
function llen (line 308) | static int
function new_weak_table (line 315) | static void
function gen_metatable (line 326) | static void
function lstringpointer (line 350) | static int
function LUAMOD_API (line 357) | LUAMOD_API int
FILE: lualib-src/lua-debugchannel.c
type command (line 13) | struct command {
type channel (line 18) | struct channel {
type channel (line 25) | struct channel
type channel (line 27) | struct channel
type channel (line 35) | struct channel
type channel (line 36) | struct channel
type channel (line 37) | struct channel
function if (line 38) | SPIN_LOCK(c)
type channel (line 47) | struct channel
type channel (line 48) | struct channel
type command (line 56) | struct command
type command (line 60) | struct command
function SPIN_DESTROY (line 64) | SPIN_UNLOCK(c)
function channel_write (line 91) | static void
type channel_box (line 107) | struct channel_box {
function lread (line 111) | static int
function lwrite (line 123) | static int
function lrelease (line 132) | static int
type channel (line 144) | struct channel
type channel (line 145) | struct channel
type channel_box (line 155) | struct channel_box
function lcreate (line 172) | static int
function lconnect (line 179) | static int
function lua_State (line 197) | static lua_State *getthread (lua_State *L, int *arg) {
function hookf (line 212) | static void hookf (lua_State *L, lua_Debug *ar) {
function makemask (line 234) | static int makemask (const char *smask, int count) {
function db_sethook (line 243) | static int db_sethook (lua_State *L) {
function LUAMOD_API (line 273) | LUAMOD_API int
FILE: lualib-src/lua-memory.c
function ltotal (line 8) | static int
function lblock (line 16) | static int
function ldumpinfo (line 24) | static int
function ljestat (line 35) | static int
function lmallctl (line 55) | static int
function ldump (line 62) | static int
function lcurrent (line 69) | static int
function ldumpheap (line 75) | static int
function lprofactive (line 81) | static int
function LUAMOD_API (line 95) | LUAMOD_API int
FILE: lualib-src/lua-mongo.c
type msg_flags_t (line 16) | typedef enum {
type connection (line 24) | struct connection {
type response (line 29) | struct response {
type buffer (line 36) | struct buffer {
function little_endian (line 43) | static inline uint32_t
function get_length (line 55) | static inline uint32_t
function buffer_destroy (line 65) | static inline void
function buffer_create (line 72) | static inline void
function buffer_reserve (line 79) | static inline void
function write_int32 (line 95) | static inline void
function write_int8 (line 105) | static inline void
function reserve_length (line 129) | static inline int
function write_length (line 137) | static inline void
type header_t (line 146) | struct header_t {
function unpack_reply (line 160) | static int
function reply_length (line 213) | static int
function op_msg (line 227) | static int
function LUAMOD_API (line 262) | LUAMOD_API int
FILE: lualib-src/lua-multicast.c
type mc_package (line 12) | struct mc_package {
function pack (line 18) | static int
function mc_packlocal (line 37) | static int
function mc_packremote (line 53) | static int
function mc_unpacklocal (line 71) | static int
function mc_bindrefer (line 90) | static int
function mc_closelocal (line 109) | static int
function mc_remote (line 129) | static int
function mc_nextid (line 140) | static int
function LUAMOD_API (line 150) | LUAMOD_API int
FILE: lualib-src/lua-netpack.c
type netpack (line 31) | struct netpack {
type uncomplete (line 37) | struct uncomplete {
type queue (line 44) | struct queue {
function clear_list (line 52) | static void
function lclear (line 62) | static int
function hash_fd (line 85) | static inline int
type uncomplete (line 93) | struct uncomplete
type queue (line 94) | struct queue
type uncomplete (line 98) | struct uncomplete
type uncomplete (line 105) | struct uncomplete
type queue (line 117) | struct queue
type queue (line 119) | struct queue
type queue (line 121) | struct queue
function expand_queue (line 134) | static void
function push_data (line 151) | static void
type uncomplete (line 170) | struct uncomplete
type queue (line 172) | struct queue
type uncomplete (line 174) | struct uncomplete
type uncomplete (line 174) | struct uncomplete
function read_size (line 183) | static inline int
function push_more (line 189) | static void
function close_uncomplete (line 218) | static void
function filter_data_ (line 228) | static int
function filter_data (line 310) | static inline int
function pushstring (line 319) | static void
function lfilter (line 338) | static int
function lpop (line 400) | static int
function write_size (line 434) | static inline void
function lpack (line 440) | static int
function ltostring (line 458) | static int
function LUAMOD_API (line 471) | LUAMOD_API int
FILE: lualib-src/lua-seri.c
type block (line 40) | struct block {
type write_block (line 45) | struct write_block {
type read_block (line 52) | struct read_block {
type block (line 58) | struct block
type block (line 60) | struct block
type block (line 60) | struct block
function wb_push (line 65) | inline static void
function wb_init (line 87) | static void
function wb_free (line 96) | static void
function rball_init (line 111) | static void
type read_block (line 119) | struct read_block
function wb_nil (line 130) | static inline void
function wb_boolean (line 136) | static inline void
function wb_integer (line 142) | static inline void
function wb_real (line 176) | static inline void
function wb_pointer (line 183) | static inline void
function wb_string (line 190) | static inline void
type write_block (line 215) | struct write_block
function wb_table_array (line 217) | static int
function wb_table_hash (line 239) | static void
function wb_table_metapairs (line 259) | static int
function wb_table (line 285) | static int
function pack_one (line 303) | static void
function pack_from (line 352) | static void
function invalid_stream_line (line 361) | static inline void
function lua_Integer (line 369) | static lua_Integer
function get_real (line 412) | static double
type read_block (line 423) | struct read_block
function get_buffer (line 433) | static void
type read_block (line 442) | struct read_block
function unpack_table (line 444) | static void
function push_value (line 477) | static void
function unpack_one (line 533) | static void
function seri (line 544) | static void
function luaseri_unpack (line 565) | int
function LUAMOD_API (line 609) | LUAMOD_API int
FILE: lualib-src/lua-sharedata.c
type table (line 21) | struct table
type table (line 26) | struct table
type node (line 31) | struct node {
type state (line 41) | struct state {
type table (line 47) | struct table {
type context (line 56) | struct context {
type ctrl (line 62) | struct ctrl {
function countsize (line 67) | static int
function calchash (line 91) | static uint32_t
function stringindex (line 102) | static int
function setvalue (line 124) | static void
function setarray (line 181) | static void
function ishashkey (line 191) | static int
function fillnocolliding (line 212) | static void
function fillcolliding (line 237) | static void
function convtable (line 277) | static int
function delete_tbl (line 329) | static void
function pconv (line 348) | static int
function convert_stringmap (line 379) | static void
function lnewconf (line 406) | static int
type table (line 459) | struct table
type table (line 461) | struct table
function ldeleteconf (line 468) | static int
function pushvalue (line 476) | static void
type node (line 503) | struct node
type table (line 504) | struct table
type node (line 507) | struct node
function lindexconf (line 534) | static int
function pushkey (line 572) | static void
function pushfirsthash (line 583) | static int
function lnextkey (line 593) | static int
function llen (line 652) | static int
function lhashlen (line 659) | static int
function releaseobj (line 666) | static int
function lboxconf (line 678) | static int
function lmarkdirty (line 696) | static int
function lisdirty (line 704) | static int
function lgetref (line 714) | static int
function lincref (line 723) | static int
function ldecref (line 733) | static int
function lneedupdate (line 743) | static int
function lupdate (line 754) | static int
function LUAMOD_API (line 771) | LUAMOD_API int
FILE: lualib-src/lua-sharetable.c
function mark_shared (line 11) | static void
function lis_sharedtable (line 59) | static int
function make_matrix (line 70) | static int
function clone_table (line 80) | static int
function lco_stackvalues (line 87) | static int
type state_ud (line 113) | struct state_ud {
function close_state (line 117) | static int
function get_matrix (line 127) | static int
function get_size (line 138) | static int
function box_state (line 153) | static int
function load_matrixfile (line 172) | static int
function matrix_from_file (line 193) | static int
function LUAMOD_API (line 243) | LUAMOD_API int
function LUAMOD_API (line 259) | LUAMOD_API int
FILE: lualib-src/lua-skynet.c
function get_time (line 25) | static int64_t
function traceback (line 38) | static int
type callback_context (line 49) | struct callback_context {
function _cb (line 53) | static int
function forward_cb (line 90) | static int
function clear_last_context (line 97) | static void
function _cb_pre (line 106) | static int
function _forward_pre (line 114) | static int
function lcallback (line 122) | static int
function lcommand (line 141) | static int
function laddresscommand (line 159) | static int
function lintcommand (line 191) | static int
function lgenid (line 228) | static int
function send_message (line 245) | static int
function lsend (line 316) | static int
function lredirect (line 331) | static int
function lerror (line 337) | static int
function ltostring (line 365) | static int
function lharbor (line 376) | static int
function lpackstring (line 388) | static int
function ltrash (line 398) | static int
function lnow (line 418) | static int
function lhpc (line 425) | static int
type source_info (line 433) | struct source_info {
function ltrace (line 444) | static int
function LUAMOD_API (line 498) | LUAMOD_API int
FILE: lualib-src/lua-socket.c
type buffer_node (line 29) | struct buffer_node {
type socket_buffer (line 35) | struct socket_buffer {
function lfreepool (line 42) | static int
function lnewpool (line 57) | static int
function lnewbuffer (line 75) | static int
function lpushbuffer (line 103) | static int
function return_free_node (line 156) | static void
function pop_lstring (line 175) | static void
function lheader (line 217) | static int
function lpopbuffer (line 241) | static int
function lclearbuffer (line 264) | static int
function lreadall (line 281) | static int
function ldrop (line 300) | static int
function check_sep (line 308) | static bool
function lreadline (line 332) | static int
function lstr2p (line 371) | static int
function lunpack (line 390) | static int
function lconnect (line 452) | static int
function lclose (line 469) | static int
function lshutdown (line 477) | static int
function llisten (line 485) | static int
function count_size (line 506) | static size_t
function concat_table (line 520) | static void
function get_buffer (line 542) | static void
function lsend (line 587) | static int
function lsendlow (line 599) | static int
function lbind (line 611) | static int
function lstart (line 620) | static int
function lpause (line 628) | static int
function lnodelay (line 636) | static int
function ludp (line 644) | static int
function ludp_connect (line 664) | static int
function ludp_dial (line 684) | static int
function ludp_listen (line 702) | static int
function ludp_send (line 722) | static int
function ludp_address (line 737) | static int
function getinfo (line 763) | static void
function linfo (line 821) | static int
function lresolve (line 836) | static int
function LUAMOD_API (line 864) | LUAMOD_API int
FILE: lualib-src/lua-stm.c
type stm_object (line 14) | struct stm_object {
type stm_copy (line 20) | struct stm_copy {
type stm_copy (line 27) | struct stm_copy
type stm_copy (line 29) | struct stm_copy
type stm_object (line 37) | struct stm_object
type stm_object (line 39) | struct stm_object
function stm_releasecopy (line 47) | static void
function stm_release (line 57) | static void
function stm_releasereader (line 73) | static void
function stm_grab (line 85) | static void
type stm_copy (line 93) | struct stm_copy
type stm_object (line 94) | struct stm_object
type stm_copy (line 96) | struct stm_copy
function stm_update (line 106) | static void
type boxstm (line 119) | struct boxstm {
function lcopy (line 123) | static int
function lnewwriter (line 131) | static int
function ldeletewriter (line 151) | static int
function lupdate (line 160) | static int
type boxreader (line 178) | struct boxreader {
function lnewreader (line 183) | static int
function ldeletereader (line 194) | static int
function lread (line 205) | static int
function LUAMOD_API (line 237) | LUAMOD_API int
FILE: lualib-src/sproto/lsproto.c
function LUALIB_API (line 24) | LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
function lua_tointegerx (line 48) | static int64_t lua_tointegerx(lua_State *L, int idx, int *isnum) {
function lua_absindex (line 59) | static int lua_absindex (lua_State *L, int idx) {
function lua_geti (line 67) | static void
function lua_seti (line 74) | static void
function tointegerx (line 85) | static int64_t
function tobooleanx (line 99) | static int
function tobooleanx (line 118) | static int
function lnewproto (line 135) | static int
function ldeleteproto (line 148) | static int
function lquerytype (line 158) | static int
type encode_ud (line 175) | struct encode_ud {
function next_list (line 188) | static int
function get_encodefield (line 207) | static int
type sproto_arg (line 280) | struct sproto_arg
function encode_one (line 282) | static int
function encode (line 372) | static int
function lencode (line 426) | static int
type decode_ud (line 465) | struct decode_ud {
function decode (line 476) | static int
function ldecode (line 633) | static int
function ldumpproto (line 666) | static int
function lpack (line 682) | static int
function lunpack (line 703) | static int
function pushfunction_withbuffer (line 722) | static void
function lprotocol (line 730) | static int
type sproto (line 780) | struct sproto
function lsaveproto (line 782) | static int
function lloadproto (line 794) | static int
function push_default (line 811) | static void
function encode_default (line 845) | static int
function ldefault (line 866) | static int
function LUAMOD_API (line 894) | LUAMOD_API int
FILE: lualib-src/sproto/sproto.c
type field (line 16) | struct field {
type sproto_type (line 26) | struct sproto_type {
type protocol (line 34) | struct protocol {
type chunk (line 41) | struct chunk {
type pool (line 45) | struct pool {
type sproto (line 51) | struct sproto {
function pool_init (line 59) | static void
function pool_release (line 66) | static void
type pool (line 77) | struct pool
type chunk (line 78) | struct chunk
type chunk (line 78) | struct chunk
type pool (line 87) | struct pool
function toword (line 114) | static inline int
function todword (line 119) | static inline uint32_t
function count_array (line 124) | static int
function struct_field (line 145) | static int
type sproto (line 176) | struct sproto
function calc_pow (line 184) | static int
type sproto (line 197) | struct sproto
type field (line 197) | struct field
type sproto (line 297) | struct sproto
type sproto_type (line 297) | struct sproto_type
type field (line 330) | struct field
type field (line 333) | struct field
type sproto (line 363) | struct sproto
type protocol (line 363) | struct protocol
type sproto (line 424) | struct sproto
type sproto (line 425) | struct sproto
type sproto (line 473) | struct sproto
type pool (line 475) | struct pool
type sproto (line 476) | struct sproto
function sproto_release (line 490) | void
type field (line 498) | struct field
function sproto_dump (line 523) | void
function sproto_prototag (line 573) | int
type protocol (line 584) | struct protocol
type sproto (line 585) | struct sproto
type sproto_type (line 602) | struct sproto_type
type sproto (line 603) | struct sproto
type protocol (line 604) | struct protocol
function sproto_protoresponse (line 615) | int
type sproto (line 622) | struct sproto
type protocol (line 623) | struct protocol
type sproto_type (line 630) | struct sproto_type
type sproto (line 631) | struct sproto
type sproto_type (line 642) | struct sproto_type
type field (line 646) | struct field
type sproto_type (line 647) | struct sproto_type
type field (line 659) | struct field
function fill_size (line 677) | static inline int
function encode_integer (line 686) | static int
function encode_uint64 (line 697) | static int
function encode_object (line 735) | static int
function uint32_to_uint64 (line 752) | static inline void
type sproto_arg (line 768) | struct sproto_arg
type sproto_arg (line 857) | struct sproto_arg
function encode_array (line 886) | static int
function sproto_encode (line 943) | int
function decode_array_object (line 1058) | static int
function expand64 (line 1082) | static inline uint64_t
function decode_empty_array (line 1091) | static int
function decode_array (line 1100) | static int
function sproto_decode (line 1163) | int
function pack_seg (line 1279) | static int
function write_ff (line 1317) | static inline void
function sproto_pack (line 1330) | int
function sproto_unpack (line 1385) | int
FILE: lualib-src/sproto/sproto.h
type sproto (line 6) | struct sproto
type sproto_type (line 7) | struct sproto_type
type sproto (line 30) | struct sproto
type sproto (line 31) | struct sproto
type sproto (line 33) | struct sproto
type sproto (line 34) | struct sproto
type sproto_type (line 36) | struct sproto_type
type sproto (line 36) | struct sproto
type sproto (line 37) | struct sproto
type sproto_type (line 39) | struct sproto_type
type sproto (line 39) | struct sproto
type sproto_arg (line 44) | struct sproto_arg {
type sproto_arg (line 61) | struct sproto_arg
type sproto_type (line 63) | struct sproto_type
type sproto_type (line 64) | struct sproto_type
type sproto (line 67) | struct sproto
type sproto_type (line 68) | struct sproto_type
FILE: service-src/databuffer.h
type message (line 10) | struct message {
type databuffer (line 16) | struct databuffer {
type messagepool_list (line 24) | struct messagepool_list {
type messagepool (line 29) | struct messagepool {
function messagepool_free (line 36) | static void
function _return_message (line 48) | static inline void
function databuffer_read (line 64) | static void
function databuffer_push (line 91) | static void
function databuffer_readheader (line 125) | static int
function databuffer_reset (line 146) | static inline void
function databuffer_clear (line 151) | static void
FILE: service-src/hashid.h
type hashid_node (line 8) | struct hashid_node {
type hashid (line 13) | struct hashid {
function hashid_init (line 21) | static void
function hashid_clear (line 41) | static void
function hashid_lookup (line 52) | static int
function hashid_remove (line 64) | static int
function hashid_insert (line 91) | static int
function hashid_full (line 115) | static inline int
FILE: service-src/service_gate.c
type connection (line 15) | struct connection {
type gate (line 23) | struct gate {
type gate (line 37) | struct gate
type gate (line 39) | struct gate
function gate_release (line 45) | void
function _parm (line 64) | static void
function _forward_agent (line 78) | static void
function _ctrl (line 88) | static void
function _report (line 153) | static void
function _forward (line 168) | static void
function dispatch_message (line 194) | static void
function dispatch_socket_message (line 216) | static void
function _cb (line 280) | static int
function start_listen (line 314) | static int
function gate_init (line 343) | int
FILE: service-src/service_harbor.c
type remote_message_header (line 34) | struct remote_message_header {
type harbor_msg (line 40) | struct harbor_msg {
type harbor_msg_queue (line 46) | struct harbor_msg_queue {
type keyvalue (line 53) | struct keyvalue {
type hashmap (line 61) | struct hashmap {
type slave (line 71) | struct slave {
type harbor (line 81) | struct harbor {
function push_queue_msg (line 91) | static void
function push_queue (line 112) | static void
type harbor_msg (line 121) | struct harbor_msg
type harbor_msg_queue (line 122) | struct harbor_msg_queue
type harbor_msg (line 126) | struct harbor_msg
type harbor_msg_queue (line 131) | struct harbor_msg_queue
type harbor_msg_queue (line 133) | struct harbor_msg_queue
type harbor_msg (line 137) | struct harbor_msg
function release_queue (line 142) | static void
type keyvalue (line 154) | struct keyvalue
type hashmap (line 155) | struct hashmap
type keyvalue (line 158) | struct keyvalue
type keyvalue (line 190) | struct keyvalue
type hashmap (line 191) | struct hashmap
type keyvalue (line 194) | struct keyvalue
type keyvalue (line 195) | struct keyvalue
type hashmap (line 206) | struct hashmap
type hashmap (line 208) | struct hashmap
type hashmap (line 208) | struct hashmap
function hash_delete (line 213) | static void
function close_harbor (line 230) | static void
function report_harbor_down (line 244) | static void
type harbor (line 252) | struct harbor
type harbor (line 254) | struct harbor
function close_all_remotes (line 261) | static void
function harbor_release (line 271) | void
function to_bigendian (line 278) | static inline void
function header_to_message (line 286) | static inline void
function from_bigendian (line 293) | static inline uint32_t
function message_to_header (line 303) | static inline void
function forward_local_messsage (line 312) | static void
function send_remote (line 332) | static void
function dispatch_name_queue (line 354) | static void
function dispatch_queue (line 399) | static void
function push_socket_data (line 418) | static void
function update_name (line 512) | static void
function remote_send_handle (line 526) | static int
function remote_send_name (line 565) | static int
function handshake (line 590) | static void
function harbor_command (line 602) | static void
function harbor_id (line 654) | static int
function mainloop (line 666) | static int
function harbor_init (line 731) | int
FILE: service-src/service_logger.c
type logger (line 9) | struct logger {
type logger (line 16) | struct logger
type logger (line 18) | struct logger
function logger_release (line 26) | void
function timestring (line 37) | static int
function logger_cb (line 47) | static int
function logger_init (line 72) | int
FILE: service-src/service_snlua.c
type snlua (line 26) | struct snlua {
function cleardummy (line 43) | static int
function codecache (line 48) | static int
function signal_hook (line 63) | static void
function switchL (line 76) | static void
function lua_resumeX (line 84) | static int
function get_time (line 99) | static double
function diff_time (line 123) | static inline double
function auxresume (line 139) | static int auxresume (lua_State *L, lua_State *co, int narg) {
function timing_enable (line 162) | static int
function timing_total (line 175) | static double
function timing_resume (line 184) | static int
function luaB_coresume (line 216) | static int luaB_coresume (lua_State *L) {
function luaB_auxwrap (line 231) | static int luaB_auxwrap (lua_State *L) {
function luaB_cocreate (line 248) | static int luaB_cocreate (lua_State *L) {
function luaB_cowrap (line 257) | static int luaB_cowrap (lua_State *L) {
function lstart (line 267) | static int
function lstop (line 297) | static int
function init_profile (line 329) | static int
function traceback (line 357) | static int
function report_launcher_error (line 368) | static void
type skynet_context (line 375) | struct skynet_context
function init_cb (line 383) | static int
function launch_cb (line 456) | static int
function snlua_init (line 469) | int
type snlua (line 484) | struct snlua
function global_seed (line 502) | static unsigned
type snlua (line 516) | struct snlua
type snlua (line 518) | struct snlua
function snlua_release (line 528) | void
function snlua_signal (line 534) | void
FILE: skynet-src/atomic.h
function ATOM_CAS (line 46) | static inline int
function ATOM_CAS_SIZET (line 51) | static inline int
function ATOM_CAS_ULONG (line 56) | static inline int
function ATOM_CAS_POINTER (line 61) | static inline int
FILE: skynet-src/malloc_hook.c
type mem_data (line 19) | struct mem_data {
type mem_data (line 24) | struct mem_data
type mem_cookie (line 26) | struct mem_cookie {
type mem_data (line 38) | struct mem_data
type mem_data (line 41) | struct mem_data
type mem_data (line 44) | struct mem_data
function update_xmalloc_stat_alloc (line 56) | inline static void
function update_xmalloc_stat_free (line 65) | inline static void
type mem_cookie (line 74) | struct mem_cookie
type mem_cookie (line 74) | struct mem_cookie
function get_cookie_size (line 87) | inline static uint32_t
type mem_cookie (line 97) | struct mem_cookie
type mem_cookie (line 97) | struct mem_cookie
function malloc_oom (line 111) | static void malloc_oom(size_t size) {
function memory_info_dump (line 118) | void
function mallctl_bool (line 123) | bool
function mallctl_cmd (line 135) | int
function mallctl_int64 (line 140) | size_t
function mallctl_opt (line 153) | int
function skynet_free (line 191) | void
function alignment_cookie_size (line 206) | static inline uint32_t
function skynet_posix_memalign (line 237) | int
function memory_info_dump (line 252) | void
function mallctl_int64 (line 257) | size_t
function mallctl_opt (line 263) | int
function mallctl_bool (line 269) | bool
function mallctl_cmd (line 275) | int
function malloc_used_memory (line 283) | size_t
function malloc_memory_block (line 296) | size_t
function dump_c_mem (line 309) | void
function dump_mem_lua (line 346) | int
function malloc_current_memory (line 363) | size_t
function skynet_debug_memory (line 375) | void
FILE: skynet-src/mem_info.c
function meminfo_init (line 5) | void
function atomic_meminfo_init (line 10) | void
function meminfo_alloc (line 18) | void
function atomic_meminfo_alloc (line 24) | void
function meminfo_free (line 30) | void
function atomic_meminfo_free (line 36) | void
function meminfo_merge (line 42) | void
function atomic_meminfo_merge (line 50) | void
FILE: skynet-src/mem_info.h
type MemInfo (line 11) | typedef struct {
type AtomicMemInfo (line 18) | typedef struct {
FILE: skynet-src/rwlock.h
type rwlock (line 8) | struct rwlock {
function rwlock_init (line 13) | static inline void
function rwlock_rlock (line 19) | static inline void
function rwlock_wlock (line 32) | static inline void
function rwlock_wunlock (line 38) | static inline void
function rwlock_runlock (line 43) | static inline void
type rwlock (line 55) | struct rwlock {
function rwlock_init (line 59) | static inline void
function rwlock_rlock (line 64) | static inline void
function rwlock_wlock (line 69) | static inline void
function rwlock_wunlock (line 74) | static inline void
function rwlock_runlock (line 79) | static inline void
FILE: skynet-src/skynet.h
type skynet_context (line 27) | struct skynet_context
type skynet_context (line 29) | struct skynet_context
type skynet_context (line 30) | struct skynet_context
type skynet_context (line 31) | struct skynet_context
type skynet_context (line 32) | struct skynet_context
type skynet_context (line 33) | struct skynet_context
type skynet_context (line 35) | struct skynet_context
type skynet_context (line 37) | struct skynet_context
type skynet_context (line 38) | struct skynet_context
FILE: skynet-src/skynet_daemon.c
function check_pid (line 12) | static int
function write_pid (line 31) | static int
function redirect_fds (line 68) | static int
function daemon_init (line 93) | int
function daemon_exit (line 123) | int
FILE: skynet-src/skynet_env.c
type skynet_env (line 11) | struct skynet_env {
type skynet_env (line 16) | struct skynet_env
function skynet_setenv (line 33) | void
function skynet_env_init (line 47) | void
FILE: skynet-src/skynet_error.c
function log_try_vasprintf (line 13) | static int
function skynet_error (line 32) | void
FILE: skynet-src/skynet_handle.c
type handle_name (line 15) | struct handle_name {
type handle_storage (line 20) | struct handle_storage {
type handle_storage (line 33) | struct handle_storage
function skynet_handle_register (line 35) | uint32_t
function skynet_handle_retire (line 76) | int
function skynet_handle_retireall (line 115) | void
type skynet_context (line 139) | struct skynet_context
type handle_storage (line 141) | struct handle_storage
type skynet_context (line 142) | struct skynet_context
type skynet_context (line 147) | struct skynet_context
function skynet_handle_findname (line 158) | uint32_t
function _insert_name_before (line 188) | static void
type handle_storage (line 215) | struct handle_storage
type handle_name (line 220) | struct handle_name
function skynet_handle_init (line 249) | void
FILE: skynet-src/skynet_handle.h
type skynet_context (line 10) | struct skynet_context
type skynet_context (line 12) | struct skynet_context
type skynet_context (line 14) | struct skynet_context
FILE: skynet-src/skynet_harbor.c
type skynet_context (line 11) | struct skynet_context
function invalid_type (line 14) | static inline int
function skynet_harbor_send (line 19) | void
function skynet_harbor_message_isremote (line 25) | int
function skynet_harbor_init (line 32) | void
function skynet_harbor_start (line 37) | void
function skynet_harbor_exit (line 45) | void
FILE: skynet-src/skynet_harbor.h
type remote_name (line 10) | struct remote_name {
type remote_message (line 15) | struct remote_message {
type remote_message (line 22) | struct remote_message
FILE: skynet-src/skynet_imp.h
type skynet_config (line 6) | struct skynet_config {
type skynet_config (line 23) | struct skynet_config
FILE: skynet-src/skynet_log.c
function FILE (line 8) | FILE *
function skynet_log_close (line 30) | void
function log_blob (line 37) | static void
function log_socket (line 46) | static void
function skynet_log_output (line 66) | void
FILE: skynet-src/skynet_log.h
type skynet_context (line 10) | struct skynet_context
type skynet_context (line 11) | struct skynet_context
FILE: skynet-src/skynet_main.c
function optint (line 20) | static int
function optboolean (line 32) | static int
function _init_env (line 55) | static void
function sigign (line 81) | int sigign() {
function main (line 121) | int
FILE: skynet-src/skynet_module.c
type modules (line 16) | struct modules {
type modules (line 23) | struct modules
type modules (line 26) | struct modules
type skynet_module (line 66) | struct skynet_module
type skynet_module (line 78) | struct skynet_module
function open_sym (line 93) | static int
type skynet_module (line 103) | struct skynet_module
type skynet_module (line 105) | struct skynet_module
type skynet_module (line 134) | struct skynet_module
function skynet_module_instance_init (line 142) | int
function skynet_module_instance_release (line 147) | void
function skynet_module_instance_signal (line 154) | void
function skynet_module_init (line 161) | void
FILE: skynet-src/skynet_module.h
type skynet_context (line 4) | struct skynet_context
type skynet_context (line 7) | struct skynet_context
type skynet_module (line 11) | struct skynet_module {
type skynet_module (line 20) | struct skynet_module
type skynet_module (line 21) | struct skynet_module
type skynet_module (line 22) | struct skynet_module
type skynet_context (line 22) | struct skynet_context
type skynet_module (line 23) | struct skynet_module
type skynet_module (line 24) | struct skynet_module
FILE: skynet-src/skynet_monitor.c
type skynet_monitor (line 11) | struct skynet_monitor {
type skynet_monitor (line 18) | struct skynet_monitor
type skynet_monitor (line 20) | struct skynet_monitor
function skynet_monitor_delete (line 25) | void
function skynet_monitor_trigger (line 30) | void
function skynet_monitor_check (line 37) | void
FILE: skynet-src/skynet_monitor.h
type skynet_monitor (line 6) | struct skynet_monitor
type skynet_monitor (line 8) | struct skynet_monitor
type skynet_monitor (line 9) | struct skynet_monitor
type skynet_monitor (line 10) | struct skynet_monitor
type skynet_monitor (line 11) | struct skynet_monitor
FILE: skynet-src/skynet_mq.c
type message_queue (line 21) | struct message_queue {
type global_queue (line 35) | struct global_queue {
type global_queue (line 41) | struct global_queue
function skynet_globalmq_push (line 43) | void
type message_queue (line 58) | struct message_queue
type global_queue (line 60) | struct global_queue
type message_queue (line 77) | struct message_queue
type message_queue (line 79) | struct message_queue
type skynet_message (line 92) | struct skynet_message
function _release (line 98) | static void
function skynet_mq_handle (line 106) | uint32_t
function skynet_mq_length (line 111) | int
function skynet_mq_overload (line 127) | int
function skynet_mq_pop (line 137) | int
function expand_queue (line 174) | static void
function skynet_mq_push (line 189) | void
function skynet_mq_init (line 211) | void
function skynet_mq_mark_release (line 219) | void
function _drop_queue (line 230) | static void
function skynet_mq_release (line 239) | void
FILE: skynet-src/skynet_mq.h
type skynet_message (line 7) | struct skynet_message {
type message_queue (line 18) | struct message_queue
type message_queue (line 20) | struct message_queue
type message_queue (line 21) | struct message_queue
type message_queue (line 23) | struct message_queue
type message_queue (line 24) | struct message_queue
type skynet_message (line 26) | struct skynet_message
type message_queue (line 28) | struct message_queue
type message_queue (line 29) | struct message_queue
type message_queue (line 32) | struct message_queue
type skynet_message (line 32) | struct skynet_message
type message_queue (line 33) | struct message_queue
type skynet_message (line 33) | struct skynet_message
type message_queue (line 36) | struct message_queue
type message_queue (line 37) | struct message_queue
FILE: skynet-src/skynet_server.c
type skynet_context (line 42) | struct skynet_context {
type skynet_node (line 63) | struct skynet_node {
type skynet_node (line 71) | struct skynet_node
function skynet_context_total (line 73) | int
function context_inc (line 78) | static void
function context_dec (line 83) | static void
function skynet_current_handle (line 88) | uint32_t
function id_to_hex (line 99) | static void
type drop_t (line 110) | struct drop_t {
function drop_message (line 114) | static void
function skynet_context_new (line 124) | uint32_t
function skynet_context_newsession (line 180) | int
function skynet_context_grab (line 191) | void
function skynet_context_reserve (line 196) | void
function delete_context (line 204) | static void
function skynet_context_release (line 217) | void
function skynet_context_push (line 224) | int
function skynet_context_endless (line 236) | void
function skynet_isremote (line 246) | int
function dispatch_message (line 255) | static void
function skynet_context_dispatchall (line 282) | void
type message_queue (line 292) | struct message_queue
type skynet_monitor (line 293) | struct skynet_monitor
type message_queue (line 293) | struct message_queue
type skynet_context (line 302) | struct skynet_context
type drop_t (line 304) | struct drop_t
type skynet_message (line 310) | struct skynet_message
type message_queue (line 337) | struct message_queue
function copy_name (line 349) | static void
function skynet_queryname (line 360) | uint32_t
function handle_exit (line 372) | static void
type command_func (line 388) | struct command_func {
type skynet_context (line 394) | struct skynet_context
type skynet_context (line 404) | struct skynet_context
type skynet_context (line 417) | struct skynet_context
type skynet_context (line 429) | struct skynet_context
type skynet_context (line 450) | struct skynet_context
function tohandle (line 455) | static uint32_t
type skynet_context (line 470) | struct skynet_context
type skynet_context (line 479) | struct skynet_context
type skynet_context (line 496) | struct skynet_context
type skynet_context (line 501) | struct skynet_context
type skynet_context (line 519) | struct skynet_context
type skynet_context (line 526) | struct skynet_context
type skynet_context (line 532) | struct skynet_context
type skynet_context (line 549) | struct skynet_context
type skynet_context (line 580) | struct skynet_context
type skynet_context (line 584) | struct skynet_context
type skynet_context (line 603) | struct skynet_context
type skynet_context (line 607) | struct skynet_context
type skynet_context (line 622) | struct skynet_context
type skynet_context (line 626) | struct skynet_context
type command_func (line 641) | struct command_func
type skynet_context (line 662) | struct skynet_context
type command_func (line 663) | struct command_func
function _filter_args (line 674) | static void
function skynet_send (line 695) | int
function skynet_sendname (line 741) | int
function skynet_context_handle (line 781) | uint32_t
function skynet_callback (line 786) | void
function skynet_context_send (line 792) | void
function skynet_globalinit (line 803) | void
function skynet_globalexit (line 816) | void
function skynet_initthread (line 821) | void
function skynet_profile_enable (line 827) | void
FILE: skynet-src/skynet_server.h
type skynet_context (line 7) | struct skynet_context
type skynet_message (line 8) | struct skynet_message
type skynet_monitor (line 9) | struct skynet_monitor
type skynet_context (line 12) | struct skynet_context
type skynet_context (line 13) | struct skynet_context
type skynet_context (line 14) | struct skynet_context
type skynet_context (line 15) | struct skynet_context
type skynet_message (line 16) | struct skynet_message
type skynet_context (line 17) | struct skynet_context
type skynet_context (line 18) | struct skynet_context
type message_queue (line 19) | struct message_queue
type skynet_monitor (line 19) | struct skynet_monitor
type message_queue (line 19) | struct message_queue
type skynet_context (line 21) | struct skynet_context
FILE: skynet-src/skynet_socket.c
type socket_server (line 14) | struct socket_server
function skynet_socket_init (line 16) | void
function skynet_socket_exit (line 21) | void
function skynet_socket_free (line 26) | void
function skynet_socket_updatetime (line 32) | void
function forward_message (line 38) | static void
function skynet_socket_poll (line 78) | int
function skynet_socket_sendbuffer (line 119) | int
function skynet_socket_sendbuffer_lowpriority (line 124) | int
function skynet_socket_listen (line 129) | int
function skynet_socket_connect (line 135) | int
function skynet_socket_bind (line 141) | int
function skynet_socket_close (line 147) | void
function skynet_socket_shutdown (line 153) | void
function skynet_socket_start (line 159) | void
function skynet_socket_pause (line 165) | void
function skynet_socket_nodelay (line 172) | void
function skynet_socket_udp (line 177) | int
function skynet_socket_udp_dial (line 183) | int
function skynet_socket_udp_listen (line 189) | int
function skynet_socket_udp_connect (line 195) | int
function skynet_socket_udp_sendbuffer (line 200) | int
type skynet_socket_message (line 206) | struct skynet_socket_message
type socket_message (line 210) | struct socket_message
type socket_info (line 218) | struct socket_info
FILE: skynet-src/skynet_socket.h
type skynet_context (line 7) | struct skynet_context
type skynet_socket_message (line 17) | struct skynet_socket_message {
type skynet_context (line 30) | struct skynet_context
type socket_sendbuffer (line 30) | struct socket_sendbuffer
type skynet_context (line 31) | struct skynet_context
type socket_sendbuffer (line 31) | struct socket_sen
Condensed preview — 363 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,603K chars).
[
{
"path": ".github/ISSUE_TEMPLATE/readme-first.md",
"chars": 436,
"preview": "---\nname: Readme First\nabout: Issues is bug report only\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\nThe **Issues** is for b"
},
{
"path": ".github/workflows/build-release.yml",
"chars": 4856,
"preview": "name: Build and Release Skynet\n\non:\n push:\n branches: [ master ]\n tags: [ 'v*' ]\n\npermissions:\n contents: write\n"
},
{
"path": ".gitignore",
"chars": 182,
"preview": "*.o\n*.a\n/skynet\n/skynet.pid\n3rd/lua/lua\n3rd/lua/luac\n3rd/lua/all\n/cservice\n/luaclib\n*.so\n*.dSYM\n.DS_Store\n.vscode\n3rd/lu"
},
{
"path": ".gitmodules",
"chars": 96,
"preview": "[submodule \"3rd/jemalloc\"]\n\tpath = 3rd/jemalloc\n\turl = https://github.com/jemalloc/jemalloc.git\n"
},
{
"path": "3rd/compat-mingw/arpa/inet.h",
"chars": 12,
"preview": "#pragma once"
},
{
"path": "3rd/compat-mingw/compat.c",
"chars": 80,
"preview": "#include \"compat.h\"\n\n#include \"dlfcn.c\"\n#include \"unistd.c\"\n#include \"wepoll.c\"\n"
},
{
"path": "3rd/compat-mingw/compat.h",
"chars": 53,
"preview": "#pragma once\n\n#include \"unistd.h\"\n#include \"dlfcn.h\"\n"
},
{
"path": "3rd/compat-mingw/dlfcn.c",
"chars": 524,
"preview": "#include \"dlfcn.h\"\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n\nvoid *dlopen(const char *path, int flag) {\n retu"
},
{
"path": "3rd/compat-mingw/dlfcn.h",
"chars": 151,
"preview": "#pragma once\n\nenum { RTLD_NOW, RTLD_GLOBAL };\n\nvoid *dlopen(const char *path, int flag);\nconst char *dlerror();\nvoid *dl"
},
{
"path": "3rd/compat-mingw/netdb.h",
"chars": 35,
"preview": "#pragma once\n\n#include <ws2tcpip.h>"
},
{
"path": "3rd/compat-mingw/netinet/in.h",
"chars": 13,
"preview": "#pragma once\n"
},
{
"path": "3rd/compat-mingw/netinet/tcp.h",
"chars": 13,
"preview": "#pragma once\n"
},
{
"path": "3rd/compat-mingw/sys/epoll.h",
"chars": 33,
"preview": "#pragma once\n\n#include \"wepoll.h\""
},
{
"path": "3rd/compat-mingw/sys/file.h",
"chars": 12,
"preview": "#pragma once"
},
{
"path": "3rd/compat-mingw/sys/socket.h",
"chars": 284,
"preview": "#pragma once\n\n#define _WINSOCK_DEPRECATED_NO_WARNINGS\n#define WIN32_LEAN_AND_MEAN\n\n#undef FD_SETSIZE\n#define FD_SETSIZE "
},
{
"path": "3rd/compat-mingw/unistd.c",
"chars": 9789,
"preview": "#include \"unistd.h\"\n\n#define _WINSOCK_DEPRECATED_NO_WARNINGS\n#define WIN32_LEAN_AND_MEAN\n#include <winsock2.h>\n#include "
},
{
"path": "3rd/compat-mingw/unistd.h",
"chars": 2328,
"preview": "#pragma once\n\n#include <assert.h>\n#include <stdio.h>\n#include <time.h>\n#include <process.h>\n#include <io.h>\n#include <as"
},
{
"path": "3rd/compat-mingw/wepoll.c",
"chars": 69998,
"preview": "/*\n * wepoll - epoll for Windows\n * https://github.com/piscisaureus/wepoll\n *\n * Copyright 2012-2020, Bert Belder <bertb"
},
{
"path": "3rd/compat-mingw/wepoll.h",
"chars": 3471,
"preview": "/*\n * wepoll - epoll for Windows\n * https://github.com/piscisaureus/wepoll\n *\n * Copyright 2012-2020, Bert Belder <bertb"
},
{
"path": "3rd/lpeg/HISTORY",
"chars": 3501,
"preview": "HISTORY for LPeg 1.1.0\n\n* Changes from version 1.0.2 to 1.1.0\n ---------------------------------\n + accumulator captur"
},
{
"path": "3rd/lpeg/README.md",
"chars": 117,
"preview": "# LPeg - Parsing Expression Grammars For Lua\n\nFor more information,\nsee [Lpeg](//www.inf.puc-rio.br/~roberto/lpeg/).\n"
},
{
"path": "3rd/lpeg/lpcap.c",
"chars": 18186,
"preview": "\n#include \"lua.h\"\n#include \"lauxlib.h\"\n\n#include \"lpcap.h\"\n#include \"lpprint.h\"\n#include \"lptypes.h\"\n\n\n#define getfromkt"
},
{
"path": "3rd/lpeg/lpcap.h",
"chars": 2482,
"preview": "\n#if !defined(lpcap_h)\n#define lpcap_h\n\n\n#include \"lptypes.h\"\n\n\n/* kinds of captures */\ntypedef enum CapKind {\n Cclose,"
},
{
"path": "3rd/lpeg/lpcode.c",
"chars": 32628,
"preview": "\n#include <limits.h>\n\n\n#include \"lua.h\"\n#include \"lauxlib.h\"\n\n#include \"lptypes.h\"\n#include \"lpcode.h\"\n#include \"lpcset."
},
{
"path": "3rd/lpeg/lpcode.h",
"chars": 675,
"preview": "\n#if !defined(lpcode_h)\n#define lpcode_h\n\n#include \"lua.h\"\n\n#include \"lptypes.h\"\n#include \"lptree.h\"\n#include \"lpvm.h\"\n\n"
},
{
"path": "3rd/lpeg/lpcset.c",
"chars": 3280,
"preview": "\n#include \"lptypes.h\"\n#include \"lpcset.h\"\n\n\n/*\n** Add to 'c' the index of the (only) bit set in byte 'b'\n*/\nstatic int o"
},
{
"path": "3rd/lpeg/lpcset.h",
"chars": 736,
"preview": "\n#if !defined(lpset_h)\n#define lpset_h\n\n#include \"lpcset.h\"\n#include \"lpcode.h\"\n#include \"lptree.h\"\n\n\n/*\n** Extra inform"
},
{
"path": "3rd/lpeg/lpeg.html",
"chars": 43617,
"preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n \"//www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns="
},
{
"path": "3rd/lpeg/lpprint.c",
"chars": 7161,
"preview": "\n#include <ctype.h>\n#include <limits.h>\n#include <stdio.h>\n\n\n#include \"lptypes.h\"\n#include \"lpprint.h\"\n#include \"lpcode."
},
{
"path": "3rd/lpeg/lpprint.h",
"chars": 641,
"preview": "\n#if !defined(lpprint_h)\n#define lpprint_h\n\n\n#include \"lptree.h\"\n#include \"lpvm.h\"\n\n\n#if defined(LPEG_DEBUG)\n\nvoid print"
},
{
"path": "3rd/lpeg/lptree.c",
"chars": 39406,
"preview": "\n#include <ctype.h>\n#include <limits.h>\n#include <string.h>\n\n\n#include \"lua.h\"\n#include \"lauxlib.h\"\n\n#include \"lptypes.h"
},
{
"path": "3rd/lpeg/lptree.h",
"chars": 2451,
"preview": "\n#if !defined(lptree_h)\n#define lptree_h\n\n\n#include \"lptypes.h\"\n\n\n/*\n** types of trees\n*/\ntypedef enum TTag {\n TChar = "
},
{
"path": "3rd/lpeg/lptypes.h",
"chars": 2981,
"preview": "/*\n** LPeg - PEG pattern matching for Lua\n** Copyright 2007-2023, Lua.org & PUC-Rio (see 'lpeg.html' for license)\n** wr"
},
{
"path": "3rd/lpeg/lpvm.c",
"chars": 14895,
"preview": "\n#include <limits.h>\n#include <string.h>\n\n\n#include \"lua.h\"\n#include \"lauxlib.h\"\n\n#include \"lpcap.h\"\n#include \"lptypes.h"
},
{
"path": "3rd/lpeg/lpvm.h",
"chars": 2344,
"preview": "\n#if !defined(lpvm_h)\n#define lpvm_h\n\n#include \"lpcap.h\"\n\n\n/*\n** About Character sets in instructions: a set is a bit ma"
},
{
"path": "3rd/lpeg/makefile",
"chars": 1315,
"preview": "LIBNAME = lpeg\nLUADIR = ../lua/\n\nCOPT = -O2 -DNDEBUG\n# COPT = -O0 -DLPEG_DEBUG -g\n\nCWARNS = -Wall -Wextra -pedantic \\\n\t-"
},
{
"path": "3rd/lpeg/re.html",
"chars": 14016,
"preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n \"//www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html>\n<head"
},
{
"path": "3rd/lpeg/re.lua",
"chars": 6562,
"preview": "--\n-- Copyright 2007-2023, Lua.org & PUC-Rio (see 'lpeg.html' for license)\n-- written by Roberto Ierusalimschy\n--\n\n-- i"
},
{
"path": "3rd/lpeg/test.lua",
"chars": 50659,
"preview": "#!/usr/bin/env lua\n\n-- require\"strict\" -- just to be pedantic\n\nlocal m = require\"lpeg\"\n\n\n-- for general use\nlocal a, "
},
{
"path": "3rd/lua/README",
"chars": 206,
"preview": "This is a modify version of lua 5.5 .\n\nFor detail ,\n Shared Proto : http://lua-users.org/lists/lua-l/2014-03/msg00489.h"
},
{
"path": "3rd/lua/README.md",
"chars": 442,
"preview": "# Lua\n\nThis is the repository of Lua development code, as seen by the Lua team. It contains the full history of all comm"
},
{
"path": "3rd/lua/lapi.c",
"chars": 37993,
"preview": "/*\n** $Id: lapi.c $\n** Lua API\n** See Copyright Notice in lua.h\n*/\n\n#define lapi_c\n#define LUA_CORE\n\n#include \"lprefix.h"
},
{
"path": "3rd/lua/lapi.h",
"chars": 1635,
"preview": "/*\n** $Id: lapi.h $\n** Auxiliary functions from Lua API\n** See Copyright Notice in lua.h\n*/\n\n#ifndef lapi_h\n#define lapi"
},
{
"path": "3rd/lua/lauxlib.c",
"chars": 39641,
"preview": "/*\n** $Id: lauxlib.c $\n** Auxiliary functions for building Lua libraries\n** See Copyright Notice in lua.h\n*/\n\n#define la"
},
{
"path": "3rd/lua/lauxlib.h",
"chars": 8774,
"preview": "/*\n** $Id: lauxlib.h $\n** Auxiliary functions for building Lua libraries\n** See Copyright Notice in lua.h\n*/\n\n\n#ifndef l"
},
{
"path": "3rd/lua/lbaselib.c",
"chars": 15833,
"preview": "/*\n** $Id: lbaselib.c $\n** Basic library\n** See Copyright Notice in lua.h\n*/\n\n#define lbaselib_c\n#define LUA_LIB\n\n#inclu"
},
{
"path": "3rd/lua/lcode.c",
"chars": 57186,
"preview": "/*\n** $Id: lcode.c $\n** Code generator for Lua\n** See Copyright Notice in lua.h\n*/\n\n#define lcode_c\n#define LUA_CORE\n\n#i"
},
{
"path": "3rd/lua/lcode.h",
"chars": 3901,
"preview": "/*\n** $Id: lcode.h $\n** Code generator for Lua\n** See Copyright Notice in lua.h\n*/\n\n#ifndef lcode_h\n#define lcode_h\n\n#in"
},
{
"path": "3rd/lua/lcorolib.c",
"chars": 5270,
"preview": "/*\n** $Id: lcorolib.c $\n** Coroutine Library\n** See Copyright Notice in lua.h\n*/\n\n#define lcorolib_c\n#define LUA_LIB\n\n#i"
},
{
"path": "3rd/lua/lctype.c",
"chars": 2461,
"preview": "/*\n** $Id: lctype.c $\n** 'ctype' functions for Lua\n** See Copyright Notice in lua.h\n*/\n\n#define lctype_c\n#define LUA_COR"
},
{
"path": "3rd/lua/lctype.h",
"chars": 2115,
"preview": "/*\n** $Id: lctype.h $\n** 'ctype' functions for Lua\n** See Copyright Notice in lua.h\n*/\n\n#ifndef lctype_h\n#define lctype_"
},
{
"path": "3rd/lua/ldblib.c",
"chars": 13211,
"preview": "/*\n** $Id: ldblib.c $\n** Interface from Lua to its debug API\n** See Copyright Notice in lua.h\n*/\n\n#define ldblib_c\n#defi"
},
{
"path": "3rd/lua/ldebug.c",
"chars": 30012,
"preview": "/*\n** $Id: ldebug.c $\n** Debug Interface\n** See Copyright Notice in lua.h\n*/\n\n#define ldebug_c\n#define LUA_CORE\n\n#includ"
},
{
"path": "3rd/lua/ldebug.h",
"chars": 2283,
"preview": "/*\n** $Id: ldebug.h $\n** Auxiliary functions from Debug Interface module\n** See Copyright Notice in lua.h\n*/\n\n#ifndef ld"
},
{
"path": "3rd/lua/ldo.c",
"chars": 39308,
"preview": "/*\n** $Id: ldo.c $\n** Stack and Call structure of Lua\n** See Copyright Notice in lua.h\n*/\n\n#define ldo_c\n#define LUA_COR"
},
{
"path": "3rd/lua/ldo.h",
"chars": 3617,
"preview": "/*\n** $Id: ldo.h $\n** Stack and Call structure of Lua\n** See Copyright Notice in lua.h\n*/\n\n#ifndef ldo_h\n#define ldo_h\n\n"
},
{
"path": "3rd/lua/ldump.c",
"chars": 7900,
"preview": "/*\n** $Id: ldump.c $\n** save precompiled Lua chunks\n** See Copyright Notice in lua.h\n*/\n\n#define ldump_c\n#define LUA_COR"
},
{
"path": "3rd/lua/lfunc.c",
"chars": 9639,
"preview": "/*\n** $Id: lfunc.c $\n** Auxiliary functions to manipulate prototypes and closures\n** See Copyright Notice in lua.h\n*/\n\n#"
},
{
"path": "3rd/lua/lfunc.h",
"chars": 1744,
"preview": "/*\n** $Id: lfunc.h $\n** Auxiliary functions to manipulate prototypes and closures\n** See Copyright Notice in lua.h\n*/\n\n#"
},
{
"path": "3rd/lua/lgc.c",
"chars": 58111,
"preview": "/*\n** $Id: lgc.c $\n** Garbage Collector\n** See Copyright Notice in lua.h\n*/\n\n#define lgc_c\n#define LUA_CORE\n\n#include \"l"
},
{
"path": "3rd/lua/lgc.h",
"chars": 9202,
"preview": "/*\n** $Id: lgc.h $\n** Garbage Collector\n** See Copyright Notice in lua.h\n*/\n\n#ifndef lgc_h\n#define lgc_h\n\n\n#include <std"
},
{
"path": "3rd/lua/linit.c",
"chars": 1529,
"preview": "/*\n** $Id: linit.c $\n** Initialization of libraries for lua.c and other clients\n** See Copyright Notice in lua.h\n*/\n\n\n#d"
},
{
"path": "3rd/lua/liolib.c",
"chars": 22402,
"preview": "/*\n** $Id: liolib.c $\n** Standard I/O (and system) library\n** See Copyright Notice in lua.h\n*/\n\n#define liolib_c\n#define"
},
{
"path": "3rd/lua/ljumptab.h",
"chars": 1694,
"preview": "/*\n** $Id: ljumptab.h $\n** Jump Table for the Lua interpreter\n** See Copyright Notice in lua.h\n*/\n\n\n#undef vmdispatch\n#u"
},
{
"path": "3rd/lua/llex.c",
"chars": 17852,
"preview": "/*\n** $Id: llex.c $\n** Lexical Analyzer\n** See Copyright Notice in lua.h\n*/\n\n#define llex_c\n#define LUA_CORE\n\n#include \""
},
{
"path": "3rd/lua/llex.h",
"chars": 2535,
"preview": "/*\n** $Id: llex.h $\n** Lexical Analyzer\n** See Copyright Notice in lua.h\n*/\n\n#ifndef llex_h\n#define llex_h\n\n#include <li"
},
{
"path": "3rd/lua/llimits.h",
"chars": 9780,
"preview": "/*\n** $Id: llimits.h $\n** Limits, basic types, and some other 'installation-dependent' definitions\n** See Copyright Noti"
},
{
"path": "3rd/lua/lmathlib.c",
"chars": 19049,
"preview": "/*\n** $Id: lmathlib.c $\n** Standard mathematical library\n** See Copyright Notice in lua.h\n*/\n\n#define lmathlib_c\n#define"
},
{
"path": "3rd/lua/lmem.c",
"chars": 6245,
"preview": "/*\n** $Id: lmem.c $\n** Interface to Memory Manager\n** See Copyright Notice in lua.h\n*/\n\n#define lmem_c\n#define LUA_CORE\n"
},
{
"path": "3rd/lua/lmem.h",
"chars": 3435,
"preview": "/*\n** $Id: lmem.h $\n** Interface to Memory Manager\n** See Copyright Notice in lua.h\n*/\n\n#ifndef lmem_h\n#define lmem_h\n\n\n"
},
{
"path": "3rd/lua/loadlib.c",
"chars": 22892,
"preview": "/*\n** $Id: loadlib.c $\n** Dynamic library loader for Lua\n** See Copyright Notice in lua.h\n**\n** This module contains an "
},
{
"path": "3rd/lua/lobject.c",
"chars": 24091,
"preview": "/*\n** $Id: lobject.c $\n** Some generic functions over Lua objects\n** See Copyright Notice in lua.h\n*/\n\n#define lobject_c"
},
{
"path": "3rd/lua/lobject.h",
"chars": 24536,
"preview": "/*\n** $Id: lobject.h $\n** Type definitions for Lua objects\n** See Copyright Notice in lua.h\n*/\n\n\n#ifndef lobject_h\n#defi"
},
{
"path": "3rd/lua/lopcodes.c",
"chars": 4981,
"preview": "/*\n** $Id: lopcodes.c $\n** Opcodes for Lua virtual machine\n** See Copyright Notice in lua.h\n*/\n\n#define lopcodes_c\n#defi"
},
{
"path": "3rd/lua/lopcodes.h",
"chars": 14170,
"preview": "/*\n** $Id: lopcodes.h $\n** Opcodes for Lua virtual machine\n** See Copyright Notice in lua.h\n*/\n\n#ifndef lopcodes_h\n#defi"
},
{
"path": "3rd/lua/lopnames.h",
"chars": 1169,
"preview": "/*\n** $Id: lopnames.h $\n** Opcode names\n** See Copyright Notice in lua.h\n*/\n\n#if !defined(lopnames_h)\n#define lopnames_h"
},
{
"path": "3rd/lua/loslib.c",
"chars": 11861,
"preview": "/*\n** $Id: loslib.c $\n** Standard Operating System library\n** See Copyright Notice in lua.h\n*/\n\n#define loslib_c\n#define"
},
{
"path": "3rd/lua/lparser.c",
"chars": 65665,
"preview": "/*\n** $Id: lparser.c $\n** Lua Parser\n** See Copyright Notice in lua.h\n*/\n\n#define lparser_c\n#define LUA_CORE\n\n#include \""
},
{
"path": "3rd/lua/lparser.h",
"chars": 7070,
"preview": "/*\n** $Id: lparser.h $\n** Lua Parser\n** See Copyright Notice in lua.h\n*/\n\n#ifndef lparser_h\n#define lparser_h\n\n#include "
},
{
"path": "3rd/lua/lprefix.h",
"chars": 828,
"preview": "/*\n** $Id: lprefix.h $\n** Definitions for Lua code that must come before any other header file\n** See Copyright Notice i"
},
{
"path": "3rd/lua/lstate.c",
"chars": 11078,
"preview": "/*\n** $Id: lstate.c $\n** Global State\n** See Copyright Notice in lua.h\n*/\n\n#define lstate_c\n#define LUA_CORE\n\n#include \""
},
{
"path": "3rd/lua/lstate.h",
"chars": 15948,
"preview": "/*\n** $Id: lstate.h $\n** Global State\n** See Copyright Notice in lua.h\n*/\n\n#ifndef lstate_h\n#define lstate_h\n\n#include \""
},
{
"path": "3rd/lua/lstring.c",
"chars": 10245,
"preview": "/*\n** $Id: lstring.c $\n** String table (keeps all strings handled by Lua)\n** See Copyright Notice in lua.h\n*/\n\n#define l"
},
{
"path": "3rd/lua/lstring.h",
"chars": 2285,
"preview": "/*\n** $Id: lstring.h $\n** String table (keep all strings handled by Lua)\n** See Copyright Notice in lua.h\n*/\n\n#ifndef ls"
},
{
"path": "3rd/lua/lstrlib.c",
"chars": 58129,
"preview": "/*\n** $Id: lstrlib.c $\n** Standard library for string operations and pattern-matching\n** See Copyright Notice in lua.h\n*"
},
{
"path": "3rd/lua/ltable.c",
"chars": 43591,
"preview": "/*\n** $Id: ltable.c $\n** Lua tables (hash)\n** See Copyright Notice in lua.h\n*/\n\n#define ltable_c\n#define LUA_CORE\n\n#incl"
},
{
"path": "3rd/lua/ltable.h",
"chars": 6449,
"preview": "/*\n** $Id: ltable.h $\n** Lua tables (hash)\n** See Copyright Notice in lua.h\n*/\n\n#ifndef ltable_h\n#define ltable_h\n\n#incl"
},
{
"path": "3rd/lua/ltablib.c",
"chars": 13162,
"preview": "/*\n** $Id: ltablib.c $\n** Library for Table Manipulation\n** See Copyright Notice in lua.h\n*/\n\n#define ltablib_c\n#define "
},
{
"path": "3rd/lua/ltests.c",
"chars": 59092,
"preview": "/*\n** $Id: ltests.c $\n** Internal Module for Debugging of the Lua Implementation\n** See Copyright Notice in lua.h\n*/\n\n#d"
},
{
"path": "3rd/lua/ltests.h",
"chars": 3588,
"preview": "/*\n** $Id: ltests.h $\n** Internal Header for Debugging of the Lua Implementation\n** See Copyright Notice in lua.h\n*/\n\n#i"
},
{
"path": "3rd/lua/ltm.c",
"chars": 11413,
"preview": "/*\n** $Id: ltm.c $\n** Tag methods\n** See Copyright Notice in lua.h\n*/\n\n#define ltm_c\n#define LUA_CORE\n\n#include \"lprefix"
},
{
"path": "3rd/lua/ltm.h",
"chars": 3091,
"preview": "/*\n** $Id: ltm.h $\n** Tag methods\n** See Copyright Notice in lua.h\n*/\n\n#ifndef ltm_h\n#define ltm_h\n\n\n#include \"lobject.h"
},
{
"path": "3rd/lua/lua.c",
"chars": 22900,
"preview": "/*\n** $Id: lua.c $\n** Lua stand-alone interpreter\n** See Copyright Notice in lua.h\n*/\n\n#define lua_c\n\n#include \"lprefix."
},
{
"path": "3rd/lua/lua.h",
"chars": 16924,
"preview": "/*\n** $Id: lua.h $\n** Lua - A Scripting Language\n** Lua.org, PUC-Rio, Brazil (www.lua.org)\n** See Copyright Notice at th"
},
{
"path": "3rd/lua/lua.hpp",
"chars": 218,
"preview": "// lua.hpp\n// Lua header files for C++\n// 'extern \"C\" not supplied automatically in lua.h and other headers\n// because L"
},
{
"path": "3rd/lua/luac.c",
"chars": 15412,
"preview": "/*\n** $Id: luac.c $\n** Lua compiler (saves bytecodes to files; also lists bytecodes)\n** See Copyright Notice in lua.h\n*/"
},
{
"path": "3rd/lua/luaconf.h",
"chars": 20002,
"preview": "/*\n** $Id: luaconf.h $\n** Configuration file for Lua\n** See Copyright Notice in lua.h\n*/\n\n\n#ifndef luaconf_h\n#define lua"
},
{
"path": "3rd/lua/lualib.h",
"chars": 1706,
"preview": "/*\n** $Id: lualib.h $\n** Lua standard libraries\n** See Copyright Notice in lua.h\n*/\n\n\n#ifndef lualib_h\n#define lualib_h\n"
},
{
"path": "3rd/lua/lundump.c",
"chars": 11028,
"preview": "/*\n** $Id: lundump.c $\n** load precompiled Lua chunks\n** See Copyright Notice in lua.h\n*/\n\n#define lundump_c\n#define LUA"
},
{
"path": "3rd/lua/lundump.h",
"chars": 903,
"preview": "/*\n** $Id: lundump.h $\n** load precompiled Lua chunks\n** See Copyright Notice in lua.h\n*/\n\n#ifndef lundump_h\n#define lun"
},
{
"path": "3rd/lua/lutf8lib.c",
"chars": 8440,
"preview": "/*\n** $Id: lutf8lib.c $\n** Standard library for UTF-8 manipulation\n** See Copyright Notice in lua.h\n*/\n\n#define lutf8lib"
},
{
"path": "3rd/lua/lvm.c",
"chars": 61556,
"preview": "/*\n** $Id: lvm.c $\n** Lua virtual machine\n** See Copyright Notice in lua.h\n*/\n\n#define lvm_c\n#define LUA_CORE\n\n#include "
},
{
"path": "3rd/lua/lvm.h",
"chars": 4115,
"preview": "/*\n** $Id: lvm.h $\n** Lua virtual machine\n** See Copyright Notice in lua.h\n*/\n\n#ifndef lvm_h\n#define lvm_h\n\n\n#include \"l"
},
{
"path": "3rd/lua/lzio.c",
"chars": 1809,
"preview": "/*\n** $Id: lzio.c $\n** Buffered streams\n** See Copyright Notice in lua.h\n*/\n\n#define lzio_c\n#define LUA_CORE\n\n#include \""
},
{
"path": "3rd/lua/lzio.h",
"chars": 1503,
"preview": "/*\n** $Id: lzio.h $\n** Buffered streams\n** See Copyright Notice in lua.h\n*/\n\n\n#ifndef lzio_h\n#define lzio_h\n\n#include \"l"
},
{
"path": "3rd/lua/makefile",
"chars": 7756,
"preview": "# Makefile for building Lua\n# See ../doc/readme.html for installation and customization instructions.\n\n# == CHANGE THE S"
},
{
"path": "3rd/lua/onelua.c",
"chars": 2475,
"preview": "/*\n** Lua core, libraries, and interpreter in a single file.\n** Compiling just this file generates a complete Lua stand-"
},
{
"path": "3rd/lua-md5/README",
"chars": 369,
"preview": "MD5 - Cryptographic Library for Lua\nCopyright 2003 PUC-Rio\nhttp://www.keplerproject.org/md5\n\nMD5 offers basic cryptograp"
},
{
"path": "3rd/lua-md5/compat-5.2.c",
"chars": 706,
"preview": "#include \"lua.h\"\n#include \"lauxlib.h\"\n#include \"compat-5.2.h\"\n\n#if !defined LUA_VERSION_NUM || LUA_VERSION_NUM==501\n/*\n*"
},
{
"path": "3rd/lua-md5/compat-5.2.h",
"chars": 349,
"preview": "#if !defined LUA_VERSION_NUM\n/* Lua 5.0 */\n#define luaL_Reg luaL_reg\n\n#define luaL_addchar(B,c) \\\n ((void)((B)->p < ((B"
},
{
"path": "3rd/lua-md5/md5.c",
"chars": 6416,
"preview": "/**\n* $Id: md5.c,v 1.2 2008/03/24 20:59:12 mascarenhas Exp $\n* Hash function MD5\n* @author Marcela Ozorio Suarez, Ro"
},
{
"path": "3rd/lua-md5/md5.h",
"chars": 305,
"preview": "/**\n* $Id: md5.h,v 1.2 2006/03/03 15:04:49 tomas Exp $\n* Cryptographic module for Lua.\n* @author Roberto Ierusalimsc"
},
{
"path": "3rd/lua-md5/md5lib.c",
"chars": 5335,
"preview": "/**\n* $Id: md5lib.c,v 1.10 2008/05/12 20:51:27 carregal Exp $\n* Cryptographic and Hash functions for Lua\n* @author R"
},
{
"path": "HISTORY.md",
"chars": 14043,
"preview": "v1.8.0 (2025-1-14)\n-----------\n* Update Lua to 5.4.7\n* service sessions can be rewind\n* Improve: udp (ipv6 support)\n* Im"
},
{
"path": "LICENSE",
"chars": 1085,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2012-2025 codingnow.com\n\nPermission is hereby granted, free of charge, to any perso"
},
{
"path": "Makefile",
"chars": 3874,
"preview": "include platform.mk\n\nLUA_CLIB_PATH ?= luaclib\nCSERVICE_PATH ?= cservice\n\nSKYNET_BUILD_PATH ?= .\n\nCFLAGS = -g -O2 -Wall -"
},
{
"path": "README.md",
"chars": 1660,
"preview": "## \n\nSkynet is a multi-user Lua framework s"
},
{
"path": "examples/abort.lua",
"chars": 96,
"preview": "local skynet = require \"skynet\"\nrequire \"skynet.manager\"\t-- import skynet.abort\n\nskynet.abort()\n"
},
{
"path": "examples/agent.lua",
"chars": 2212,
"preview": "local skynet = require \"skynet\"\nlocal socket = require \"skynet.socket\"\nlocal sproto = require \"sproto\"\nlocal sprotoloade"
},
{
"path": "examples/checkdeadloop.lua",
"chars": 581,
"preview": "local skynet = require \"skynet\"\n\nlocal list = {}\n\nlocal function timeout_check(ti)\n\tif not next(list) then\n\t\treturn\n\tend"
},
{
"path": "examples/client.lua",
"chars": 2100,
"preview": "package.cpath = \"luaclib/?.so\"\npackage.path = \"lualib/?.lua;examples/?.lua\"\n\nif _VERSION ~= \"Lua 5.4\" then\n\terror \"Use l"
},
{
"path": "examples/cluster1.lua",
"chars": 729,
"preview": "local skynet = require \"skynet\"\nlocal cluster = require \"skynet.cluster\"\nlocal snax = require \"skynet.snax\"\n\nskynet.star"
},
{
"path": "examples/cluster2.lua",
"chars": 1004,
"preview": "local skynet = require \"skynet\"\nlocal cluster = require \"skynet.cluster\"\n\nskynet.start(function()\n\tlocal proxy = cluster"
},
{
"path": "examples/clustername.lua",
"chars": 145,
"preview": "__nowaiting = true\t-- If you turn this flag off, cluster.call would block when node name is absent\n\ndb = \"127.0.0.1:2528"
},
{
"path": "examples/config",
"chars": 416,
"preview": "include \"config.path\"\n\n-- preload = \"./examples/preload.lua\"\t-- run preload.lua before every lua service run\nthread = 8\n"
},
{
"path": "examples/config.c1",
"chars": 344,
"preview": "thread = 8\nlogger = nil\nharbor = 0\nstart = \"cluster1\"\nbootstrap = \"snlua bootstrap\"\t-- The service for bootstrap\nluaserv"
},
{
"path": "examples/config.c2",
"chars": 293,
"preview": "thread = 8\nlogger = nil\nharbor = 0\nstart = \"cluster2\"\nbootstrap = \"snlua bootstrap\"\t-- The service for bootstrap\nluaserv"
},
{
"path": "examples/config.handle",
"chars": 232,
"preview": "include \"config.path\"\n\nthread = 8\nlogger = \"skynet.log\"\nlogpath = \".\"\nharbor = 0\nstart = \"testhandle\"\t-- main script\nboo"
},
{
"path": "examples/config.login",
"chars": 221,
"preview": "thread = 8\nlogger = nil\nharbor = 0\nstart = \"main\"\nbootstrap = \"snlua bootstrap\"\t-- The service for bootstrap\nluaservice "
},
{
"path": "examples/config.mc",
"chars": 509,
"preview": "root = \"./\"\nthread = 8\nlogger = nil\nharbor = 2\naddress = \"127.0.0.1:2527\"\nmaster = \"127.0.0.1:2013\"\nstart = \"testmultica"
},
{
"path": "examples/config.mongodb",
"chars": 365,
"preview": "root = \"./\"\nthread = 8\nlogger = nil\nharbor = 0\nstart = \"main_mongodb\"\t-- main script\nbootstrap = \"snlua bootstrap\"\t-- Th"
},
{
"path": "examples/config.mysql",
"chars": 363,
"preview": "root = \"./\"\nthread = 8\nlogger = nil\nharbor = 0\nstart = \"main_mysql\"\t-- main script\nbootstrap = \"snlua bootstrap\"\t-- The "
},
{
"path": "examples/config.path",
"chars": 305,
"preview": "root = \"./\"\nluaservice = root..\"service/?.lua;\"..root..\"test/?.lua;\"..root..\"examples/?.lua;\"..root..\"test/?/init.lua\"\nl"
},
{
"path": "examples/config.userlog",
"chars": 515,
"preview": "root = \"./\"\nthread = 8\nlogger = \"userlog\"\nlogservice = \"snlua\"\nlogpath = \".\"\nharbor = 0\nstart = \"main\"\t-- main script\nbo"
},
{
"path": "examples/config_log",
"chars": 245,
"preview": "thread = 8\nmqueue = 256\ncpath = \"./cservice/?.so\"\nlogger = nil\nharbor = 2\naddress = \"127.0.0.1:2527\"\nmaster = \"127.0.0.1"
},
{
"path": "examples/globallog.lua",
"chars": 275,
"preview": "local skynet = require \"skynet\"\nrequire \"skynet.manager\"\t-- import skynet.register\n\nskynet.start(function()\n\tskynet.disp"
},
{
"path": "examples/injectlaunch.lua",
"chars": 584,
"preview": "if not _P then\n\tprint[[\nThis file is examples to show how to inject code into lua service.\nIt is used to inject into lau"
},
{
"path": "examples/login/client.lua",
"chars": 3921,
"preview": "package.cpath = \"luaclib/?.so\"\n\nlocal socket = require \"client.socket\"\nlocal crypt = require \"client.crypt\"\n\nif _VERSION"
},
{
"path": "examples/login/gated.lua",
"chars": 2208,
"preview": "local msgserver = require \"snax.msgserver\"\nlocal crypt = require \"skynet.crypt\"\nlocal skynet = require \"skynet\"\n\nlocal l"
},
{
"path": "examples/login/logind.lua",
"chars": 1663,
"preview": "local login = require \"snax.loginserver\"\nlocal crypt = require \"skynet.crypt\"\nlocal skynet = require \"skynet\"\n\nlocal ser"
},
{
"path": "examples/login/main.lua",
"chars": 265,
"preview": "local skynet = require \"skynet\"\n\nskynet.start(function()\n\tlocal loginserver = skynet.newservice(\"logind\")\n\tlocal gate = "
},
{
"path": "examples/login/msgagent.lua",
"chars": 1165,
"preview": "local skynet = require \"skynet\"\n\nskynet.register_protocol {\n\tname = \"client\",\n\tid = skynet.PTYPE_CLIENT,\n\tunpack = skyne"
},
{
"path": "examples/main.lua",
"chars": 601,
"preview": "local skynet = require \"skynet\"\nlocal sprotoloader = require \"sprotoloader\"\n\nlocal max_client = 64\n\nskynet.start(functio"
},
{
"path": "examples/main_log.lua",
"chars": 382,
"preview": "local skynet = require \"skynet\"\nlocal harbor = require \"skynet.harbor\"\nrequire \"skynet.manager\"\t-- import skynet.monitor"
},
{
"path": "examples/main_mongodb.lua",
"chars": 236,
"preview": "local skynet = require \"skynet\"\n\n\nskynet.start(function()\n\tprint(\"Main Server start\")\n\tlocal console = skynet.newservice"
},
{
"path": "examples/main_mysql.lua",
"chars": 183,
"preview": "local skynet = require \"skynet\"\n\n\nskynet.start(function()\n\tprint(\"Main Server start\")\n\tlocal console = skynet.newservice"
},
{
"path": "examples/preload.lua",
"chars": 95,
"preview": "-- This file will execute before every lua service start\n-- See config\n\nprint(\"PRELOAD\", ...)\n\n"
},
{
"path": "examples/proto.lua",
"chars": 474,
"preview": "local sprotoparser = require \"sprotoparser\"\n\nlocal proto = {}\n\nproto.c2s = sprotoparser.parse [[\n.package {\n\ttype 0 : in"
},
{
"path": "examples/protoloader.lua",
"chars": 433,
"preview": "-- module proto as examples/proto.lua\npackage.path = \"./examples/?.lua;\" .. package.path\n\nlocal skynet = require \"skynet"
},
{
"path": "examples/share.lua",
"chars": 1709,
"preview": "local skynet = require \"skynet\"\nlocal sharedata = require \"skynet.sharedata\"\n\nlocal mode = ...\n\nif mode == \"host\" then\n\n"
},
{
"path": "examples/simpledb.lua",
"chars": 838,
"preview": "local skynet = require \"skynet\"\nrequire \"skynet.manager\"\t-- import skynet.register\nlocal db = {}\n\nlocal command = {}\n\nfu"
},
{
"path": "examples/simplemonitor.lua",
"chars": 838,
"preview": "local skynet = require \"skynet\"\n\n-- It's a simple service exit monitor, you can do something more when a service exit.\n\n"
},
{
"path": "examples/simpleweb.lua",
"chars": 3362,
"preview": "local skynet = require \"skynet\"\nlocal socket = require \"skynet.socket\"\nlocal httpd = require \"http.httpd\"\nlocal sockethe"
},
{
"path": "examples/simplewebsocket.lua",
"chars": 2952,
"preview": "local skynet = require \"skynet\"\nlocal socket = require \"skynet.socket\"\nlocal service = require \"skynet.service\"\nlocal we"
},
{
"path": "examples/userlog.lua",
"chars": 541,
"preview": "local skynet = require \"skynet\"\nrequire \"skynet.manager\"\n\n-- register protocol text before skynet.start would be better."
},
{
"path": "examples/watchdog.lua",
"chars": 1259,
"preview": "local skynet = require \"skynet\"\n\nlocal CMD = {}\nlocal SOCKET = {}\nlocal gate\nlocal agent = {}\n\nfunction SOCKET.open(fd, "
},
{
"path": "lualib/compat10/cluster.lua",
"chars": 31,
"preview": "return require \"skynet.cluster\""
},
{
"path": "lualib/compat10/crypt.lua",
"chars": 29,
"preview": "return require \"skynet.crypt\""
},
{
"path": "lualib/compat10/datacenter.lua",
"chars": 34,
"preview": "return require \"skynet.datacenter\""
},
{
"path": "lualib/compat10/dns.lua",
"chars": 27,
"preview": "return require \"skynet.dns\""
},
{
"path": "lualib/compat10/memory.lua",
"chars": 30,
"preview": "return require \"skynet.memory\""
},
{
"path": "lualib/compat10/mongo.lua",
"chars": 32,
"preview": "return require \"skynet.db.mongo\""
},
{
"path": "lualib/compat10/mqueue.lua",
"chars": 30,
"preview": "return require \"skynet.mqueue\""
},
{
"path": "lualib/compat10/multicast.lua",
"chars": 33,
"preview": "return require \"skynet.multicast\""
},
{
"path": "lualib/compat10/mysql.lua",
"chars": 32,
"preview": "return require \"skynet.db.mysql\""
},
{
"path": "lualib/compat10/netpack.lua",
"chars": 31,
"preview": "return require \"skynet.netpack\""
},
{
"path": "lualib/compat10/profile.lua",
"chars": 31,
"preview": "return require \"skynet.profile\""
},
{
"path": "lualib/compat10/redis.lua",
"chars": 32,
"preview": "return require \"skynet.db.redis\""
},
{
"path": "lualib/compat10/sharedata.lua",
"chars": 33,
"preview": "return require \"skynet.sharedata\""
},
{
"path": "lualib/compat10/sharemap.lua",
"chars": 32,
"preview": "return require \"skynet.sharemap\""
},
{
"path": "lualib/compat10/snax.lua",
"chars": 28,
"preview": "return require \"skynet.snax\""
},
{
"path": "lualib/compat10/socket.lua",
"chars": 30,
"preview": "return require \"skynet.socket\""
},
{
"path": "lualib/compat10/socketchannel.lua",
"chars": 37,
"preview": "return require \"skynet.socketchannel\""
},
{
"path": "lualib/compat10/socketdriver.lua",
"chars": 36,
"preview": "return require \"skynet.socketdriver\""
},
{
"path": "lualib/compat10/stm.lua",
"chars": 27,
"preview": "return require \"skynet.stm\""
},
{
"path": "lualib/http/httpc.lua",
"chars": 4941,
"preview": "local skynet = require \"skynet\"\nlocal socket = require \"http.sockethelper\"\nlocal internal = require \"http.internal\"\nloca"
},
{
"path": "lualib/http/httpd.lua",
"chars": 3798,
"preview": "local internal = require \"http.internal\"\n\nlocal string = string\nlocal type = type\nlocal assert = assert\nlocal tonumber ="
},
{
"path": "lualib/http/internal.lua",
"chars": 7983,
"preview": "local table = table\nlocal type = type\nlocal string = string\nlocal tonumber = tonumber\nlocal pcall = pcall\nlocal assert ="
},
{
"path": "lualib/http/sockethelper.lua",
"chars": 2624,
"preview": "local socket = require \"skynet.socket\"\nlocal skynet = require \"skynet\"\n\nlocal coroutine = coroutine\nlocal error = error\n"
},
{
"path": "lualib/http/tlshelper.lua",
"chars": 2440,
"preview": "local socket = require \"http.sockethelper\"\nlocal c = require \"ltls.c\"\n\nlocal tlshelper = {}\n\nfunction tlshelper.init_req"
},
{
"path": "lualib/http/url.lua",
"chars": 634,
"preview": "local url = {}\n\nlocal function decode_func(c)\n\treturn string.char(tonumber(c, 16))\nend\n\nlocal function decode(str)\n\tloca"
},
{
"path": "lualib/http/websocket.lua",
"chars": 16950,
"preview": "local internal = require \"http.internal\"\nlocal socket = require \"skynet.socket\"\nlocal crypt = require \"skynet.crypt\"\nloc"
},
{
"path": "lualib/loader.lua",
"chars": 1027,
"preview": "local args = {}\nfor word in string.gmatch(..., \"%S+\") do\n\ttable.insert(args, word)\nend\n\nSERVICE_NAME = args[1]\n\nlocal ma"
},
{
"path": "lualib/md5.lua",
"chars": 1054,
"preview": "----------------------------------------------------------------------------\n-- Modify version from https://github.com/k"
},
{
"path": "lualib/skynet/cluster.lua",
"chars": 2965,
"preview": "local skynet = require \"skynet\"\n\nlocal clusterd\nlocal cluster = {}\nlocal sender = {}\nlocal task_queue = {}\n\nlocal functi"
},
{
"path": "lualib/skynet/coroutine.lua",
"chars": 3123,
"preview": "-- You should use this module (skynet.coroutine) instead of origin lua coroutine in skynet framework\n\nlocal coroutine = "
},
{
"path": "lualib/skynet/datacenter.lua",
"chars": 343,
"preview": "local skynet = require \"skynet\"\n\nlocal datacenter = {}\n\nfunction datacenter.get(...)\n\treturn skynet.call(\"DATACENTER\", \""
},
{
"path": "lualib/skynet/datasheet/builder.lua",
"chars": 4493,
"preview": "local skynet = require \"skynet\"\nlocal dump = require \"skynet.datasheet.dump\"\nlocal core = require \"skynet.datasheet.core"
},
{
"path": "lualib/skynet/datasheet/dump.lua",
"chars": 6547,
"preview": "--[[ file format\ndocument :\n int32 strtbloffset\n int32 n\n int32*n index table\n table*n\n strings\n\ntable:\n int32 arr"
},
{
"path": "lualib/skynet/datasheet/init.lua",
"chars": 1487,
"preview": "local skynet = require \"skynet\"\nlocal service = require \"skynet.service\"\nlocal core = require \"skynet.datasheet.core\"\n\nl"
},
{
"path": "lualib/skynet/db/mongo/transaction.lua",
"chars": 7831,
"preview": "--[[\nmongo会话事务接口支持子模块,可根据需要引入:\nlocal mongo = require \"mongo\"\nmongo.enable(\"transaction\")\n]]\nlocal bson = require \"bson\"\n"
},
{
"path": "lualib/skynet/db/mongo.lua",
"chars": 26633,
"preview": "local bson = require \"bson\"\n\nrequire \"skynet.socket\"\n\nlocal socketchannel\t= require \"skynet.socketchannel\"\nlocal skynet "
},
{
"path": "lualib/skynet/db/mysql.lua",
"chars": 29978,
"preview": "-- Copyright (C) 2012 Yichun Zhang (agentzh)\n-- Copyright (C) 2014 Chang Feng\n-- This file is modified version from http"
},
{
"path": "lualib/skynet/db/redis/cluster.lua",
"chars": 12698,
"preview": "-- a simple redis-cluster client\n-- rewrite from https://github.com/antirez/redis-rb-cluster\n\nlocal skynet = require \"sk"
},
{
"path": "lualib/skynet/db/redis/crc16.lua",
"chars": 2687,
"preview": "--/*\n-- This is the CRC16 algorithm used by Redis Cluster to hash keys.\n-- Implementation according to CCITT standards.\n"
},
{
"path": "lualib/skynet/db/redis.lua",
"chars": 6877,
"preview": "local socketchannel = require \"skynet.socketchannel\"\n\nlocal tostring = tostring\nlocal tonumber = tonumber\nlocal table = "
},
{
"path": "lualib/skynet/debug.lua",
"chars": 3382,
"preview": "local table = table\nlocal extern_dbgcmd = {}\n\nlocal function init(skynet, export)\n\tlocal internal_info_func\n\n\tfunction s"
},
{
"path": "lualib/skynet/dns.lua",
"chars": 11998,
"preview": "--[[\n\tlua dns resolver library\n\tSee https://github.com/xjdrew/levent/blob/master/levent/dns.lua for more detail\n\n-- res"
},
{
"path": "lualib/skynet/harbor.lua",
"chars": 528,
"preview": "local skynet = require \"skynet\"\n\nlocal harbor = {}\n\nfunction harbor.globalname(name, handle)\n\thandle = handle or skynet."
},
{
"path": "lualib/skynet/inject.lua",
"chars": 1445,
"preview": "local function getupvaluetable(u, func, unique)\n\tlocal i = 1\n\twhile true do\n\t\tlocal name, value = debug.getupvalue(func,"
}
]
// ... and 163 more files (download for full content)
About this extraction
This page contains the full source code of the cloudwu/skynet GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 363 files (2.3 MB), approximately 622.9k tokens, and a symbol index with 3043 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.