Skip to content

Instantly share code, notes, and snippets.


Dave Lee kastiglione

View GitHub Profile
View call_callback.swift
// Given an imported C function, that uses a context pointer and a C callback function:
// func for_each(_ x: X, context: UnsafeMutableRawPointer!, callback: @convention(c) (UnsafeMutableRawPointer?, Element) -> Void)
// When is it safe to use this pattern?
// Example with two captured variables.
typealias Context = (Type1, Type2)
var context = (capture1, capture2)
for_each(x, context: &context) { context, element in
kastiglione /
Last active May 4, 2020
Change files to be transparently compressed
set -euo pipefail
hfs-compress() {
local files=("$@")
local filepath perms temppath
for filepath in "${files[@]}"; do
perms=$(stat -f %p "$filepath")

Debugging the Swift Toolchain

Use these steps to debug components of the Swift toolchain. This allows you to see Swift's source code from the debugger – instead of disassembly. The debugger can also provide some variable names and values. This has been initially tested with libswiftCore.dylib.

These instructions were updated as of Swift 5.2.1.


addbranch() {
local branch=$1
git config --add remote.origin.fetch "+refs/heads/${branch}:refs/remotes/origin/${branch}"
git fetch
git checkout "$branch"
kastiglione /
Last active Feb 4, 2020
Using Swift and LLVM headers in SwiftPM

Recently, we wanted call swift-demangle from code, but calling out to the process frequently was a bit too slow, and meant parsing the output of -tree-only, since we wanted to access module and class names, for example.

Fortunately there's libswiftDemangle.dylib for this, but it's a C++ API. Compiling against it requires #includeing headers from both Swift and LLVM.

Using CMake, both Swift and LLVM can easily be added as dependencies, but we build this project with SwiftPM. To build with SwiftPM, we imported the necessary headers. Roughly, here are the steps to determine which specific Swift

kastiglione /
Last active Jul 30, 2019
Build & Run iPhone simulator code outside of Xcode
set -e
_xcrun() {
DEVELOPER_DIR=/Applications/ \
xcrun -sdk iphonesimulator \
View CombineNotifications.swift
func observeNotifications(name: NSNotification.Name) -> AnyPublisher<Notification, Never> {
return Publishers.Deferred<AnyPublisher<Notification, Never>> {
var observer: NSObjectProtocol?
return AnyPublisher { subscriber in
observer = NotificationCenter.default.addObserver(forName: name, object: nil, queue: nil) { notification in
_ = subscriber.receive(notification)
.handleEvents(receiveCancel: {
if let observer = observer {
#!/usr/bin/env python3
import argparse
import ast
import astor
import os
import re
import sys
kastiglione /
Last active May 17, 2019
Simplifications to writing Python lldb commands as of Xcode 10.2
## Python commands before
def my_command(debugger, input, ctx, result, _):
# do stuff
def __lldb_init_module(debugger, _):
kastiglione /
Last active Apr 5, 2019
Prolog predicates to detangle Swift symbols and USRs
swift_demangle(Symbol, Name) :-
Command = ['swift-demangle', '-compact', Symbol],
process_create(path(xcrun), Command, [stdout(pipe(Out))]),
read_string(Out, "\n", "", _, Name),
usr_symbol(USR, Symbol) :-