1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-23 05:32:13 +03:00

Refactor build scripts

This commit is contained in:
Tae Won Ha 2020-08-21 08:59:40 +02:00
parent aac853f2a8
commit 13ed1e28a8
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
291 changed files with 59319 additions and 5321 deletions

View File

@ -1,6 +1,2 @@
# included as Framework
github "qvacua/CocoaFontAwesome" "master"
github "sparkle-project/Sparkle" == 1.23.0
# included directly
github "sindresorhus/github-markdown-css" == 4.0.0

View File

@ -5,6 +5,30 @@
import AppKit
public extension NSAttributedString {
func draw(at point: CGPoint, angle: CGFloat) {
var translation = AffineTransform.identity
var rotation = AffineTransform.identity
translation.translate(x: point.x, y: point.y)
rotation.rotate(byRadians: angle)
(translation as NSAffineTransform).concat()
(rotation as NSAffineTransform).concat()
self.draw(at: CGPoint.zero)
rotation.invert()
translation.invert()
(rotation as NSAffineTransform).concat()
(translation as NSAffineTransform).concat()
}
var wholeRange: NSRange { NSRange(location: 0, length: self.length) }
}
public extension NSColor {
static var random: NSColor {

View File

@ -33,7 +33,8 @@ class CellAttributesCollectionTest: XCTestCase {
let defaultAttrs = CellAttributes(
fontTrait: [], foreground: 10, background: 20, special: 30, reverse: true
)
self.cellAttributesCollection.set(attributes: defaultAttrs, for: 0)
self.cellAttributesCollection
.set(attributes: defaultAttrs, for: CellAttributesCollection.defaultAttributesId)
var attrs = CellAttributes(
fontTrait: [], foreground: -1, background: 2, special: 3, reverse: true
@ -41,7 +42,7 @@ class CellAttributesCollectionTest: XCTestCase {
self.cellAttributesCollection.set(attributes: attrs, for: 1)
expect(self.cellAttributesCollection.attributes(of: 1))
.to(equal(CellAttributes(
fontTrait: [], foreground: 10, background: 2, special: 3, reverse: true
fontTrait: [], foreground: 20, background: 2, special: 3, reverse: true
)))
attrs = CellAttributes(
@ -50,7 +51,7 @@ class CellAttributesCollectionTest: XCTestCase {
self.cellAttributesCollection.set(attributes: attrs, for: 1)
expect(self.cellAttributesCollection.attributes(of: 1))
.to(equal(CellAttributes(
fontTrait: [], foreground: 1, background: 20, special: 3, reverse: true
fontTrait: [], foreground: 1, background: 10, special: 3, reverse: true
)))
attrs = CellAttributes(
@ -59,7 +60,7 @@ class CellAttributesCollectionTest: XCTestCase {
self.cellAttributesCollection.set(attributes: attrs, for: 1)
expect(self.cellAttributesCollection.attributes(of: 1))
.to(equal(CellAttributes(
fontTrait: [], foreground: 1, background: 20, special: 30, reverse: true
fontTrait: [], foreground: 1, background: 10, special: 30, reverse: true
)))
}

View File

@ -343,7 +343,7 @@ class TypesetterWithoutLigaturesTest: XCTestCase {
let run = runs[0]
expect(run.font).to(equalFont(fira))
expect(run.glyphs).to(equal([134, 1021, 1021, 1171, 134]))
expect(run.glyphs).to(equal([139, 1059, 1059, 1228, 139]))
expect(run.positions).to(equal(
(1..<6).map {
CGPoint(x: offset.x + CGFloat($0) * firaWidth, y: offset.y)
@ -619,7 +619,9 @@ class TypesetterWithLigaturesTest: XCTestCase {
expect(run.font).to(equalFont(fira))
// Ligatures of popular monospace fonts like Fira Code seem to be composed
// of multiple characters with the same advance as other normal characters.
expect(run.glyphs).to(equal([1742, 1742, 1054, 134]))
// The glyph codes may change from version to version of Fira Code.
// Check using http://mathew-kurian.github.io/CharacterMap/.
expect(run.glyphs).to(equal([1142, 1141, 1743, 139]))
expect(run.positions).to(equal(
(0..<4).map {
CGPoint(x: offset.x + CGFloat($0) * firaWidth, y: offset.y)

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Workspace">
</FileRef>
<FileRef
location = "group:Commons">
</FileRef>

View File

@ -37,6 +37,15 @@
"version": "0.1.7"
}
},
{
"package": "MaterialIcons",
"repositoryURL": "https://github.com/qvacua/material-icons",
"state": {
"branch": null,
"revision": "c3db645060fd27df5f7e0a9873c2af22c280725e",
"version": "0.1.0"
}
},
{
"package": "MessagePack",
"repositoryURL": "https://github.com/a2/MessagePack.swift",

View File

@ -12,7 +12,6 @@
1929B0E0C3BC59F52713D5A2 /* FoundationCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */; };
1929B0F599D1F62C7BE53D2C /* HttpServerMiddleware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B1DC584C89C477E83FA2 /* HttpServerMiddleware.swift */; };
1929B1837C750CADB3A5BCB9 /* OpenQuicklyFileViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B1558455B3A74D93EF2A /* OpenQuicklyFileViewRow.swift */; };
1929B20CE35B43BB1CE023BA /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BC2F05E9A5C0DB039739 /* Theme.swift */; };
1929B223C6E97C090474B2C2 /* Resources.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BC40B7B7708D8BE3A272 /* Resources.swift */; };
1929B250DB3FB395A700FE8C /* RpcEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BBF0944940845485A512 /* RpcEvents.swift */; };
1929B29B95AD176D57942E08 /* UiRootReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B457B9D0FA4D21F3751E /* UiRootReducer.swift */; };
@ -44,10 +43,8 @@
1929B6D8F5FC723B7109031F /* OpenQuicklyReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B12CE56A9B36980288A4 /* OpenQuicklyReducer.swift */; };
1929B71381946860626E5224 /* FileBrowserReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BDC8F5D48578A90236E9 /* FileBrowserReducer.swift */; };
1929B8DDACEB28E6672AEC42 /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B6E01216D49BB9F3B6A3 /* MainWindow.swift */; };
1929B8E90A1378E494D481E7 /* PrefUtilsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B7BB3E4B3DC96284B686 /* PrefUtilsTest.swift */; };
1929B8F498D1E7C53F572CE2 /* KeysPref.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B14A5949FB64C4B2646F /* KeysPref.swift */; };
1929B8FB248D71BF88A35761 /* MarkdownTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B6C6C7792B05164B0216 /* MarkdownTool.swift */; };
1929B9318D32146D58BB38EC /* AppKitCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A70931D60E04200E12030 /* AppKitCommons.swift */; };
1929B990A143763A56CFCED0 /* PrefMiddleware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B364460D86F17E80943C /* PrefMiddleware.swift */; };
1929BA269EBD68251410A08E /* ShortcutsTableSubviews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B07F0085B7AE10413346 /* ShortcutsTableSubviews.swift */; };
1929BA715337FE26155B2071 /* BufferList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BA43449BA41666CD55ED /* BufferList.swift */; };
@ -68,7 +65,6 @@
1929BE0DAEE9664C5BCFA211 /* States.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BB6608B4F0E037CA0F4C /* States.swift */; };
1929BE0F64A6CE5BCE2A5092 /* MainWindow+Delegates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B714EB137AE448CE8ABD /* MainWindow+Delegates.swift */; };
1929BE2F3E0182CC51F2763A /* ThemedTableSubviews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BD2CA8DD198A6BCDBCB7 /* ThemedTableSubviews.swift */; };
1929BE601267D52FA2E0D6D2 /* Defs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B7F7A4B3FD52263D211D /* Defs.swift */; };
1929BEAE0592096BC1191B67 /* PrefPane.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B07A4A9209C88380E015 /* PrefPane.swift */; };
1929BEDE1BE950EDA9497363 /* GeneralPref.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BB55946DAEBF55D24048 /* GeneralPref.swift */; };
1929BF03FD6465F289AA80B2 /* ToolsPref.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BB2AD21A10A0ECA66A5E /* ToolsPref.swift */; };
@ -80,12 +76,9 @@
4B19BEFD1E110183007E823C /* preview in Resources */ = {isa = PBXBuildFile; fileRef = 4B19BEFB1E110183007E823C /* preview */; };
4B238BE11D3BF24200CBDD98 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B238BE01D3BF24200CBDD98 /* Application.swift */; };
4B37ADB91D6E471B00970D55 /* vimr in Resources */ = {isa = PBXBuildFile; fileRef = 4B37ADB81D6E471B00970D55 /* vimr */; };
4B3965361DEB21300082D3C1 /* InnterToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3965351DEB21300082D3C1 /* InnterToolBar.swift */; };
4B3AC8941DB031C600AC5823 /* sparkle_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = 4B3AC8931DB031C600AC5823 /* sparkle_pub.pem */; };
4B4147A31D97361400DD4A2C /* WorkspaceToolButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB489411D952CF6005BB0E8 /* WorkspaceToolButton.swift */; };
4B6423961D8EFD7100FC78C8 /* Workspace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6423951D8EFD7100FC78C8 /* Workspace.swift */; };
4B6423981D8EFDE000FC78C8 /* WorkspaceBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6423971D8EFDE000FC78C8 /* WorkspaceBar.swift */; };
4B64239A1D8EFE3000FC78C8 /* WorkspaceTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6423991D8EFE3000FC78C8 /* WorkspaceTool.swift */; };
4B69B31B24EDBAF000B1E5EB /* MaterialIcons in Frameworks */ = {isa = PBXBuildFile; productRef = 4B69B31A24EDBAF000B1E5EB /* MaterialIcons */; };
4B69B31D24EDC9F100B1E5EB /* Workspace in Frameworks */ = {isa = PBXBuildFile; productRef = 4B69B31C24EDC9F100B1E5EB /* Workspace */; };
4B6A70941D60E04200E12030 /* AppKitCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A70931D60E04200E12030 /* AppKitCommons.swift */; };
4B9433DC20B95EC6005807BA /* MacVim-bsh.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4B9433A120B95EC1005807BA /* MacVim-bsh.icns */; };
4B9433DD20B95EC6005807BA /* MacVim-generic.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4B9433A220B95EC1005807BA /* MacVim-generic.icns */; };
@ -146,8 +139,6 @@
4B94341420B95EC7005807BA /* MacVim-sch.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4B9433D920B95EC6005807BA /* MacVim-sch.icns */; };
4B94341520B95EC7005807BA /* MacVim-ps.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4B9433DA20B95EC6005807BA /* MacVim-ps.icns */; };
4B94341620B95EC7005807BA /* MacVim-css.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4B9433DB20B95EC6005807BA /* MacVim-css.icns */; };
4B96FB3F1EBBC56F00E4E164 /* PrefUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B8241CDE58F7AAF89AE4 /* PrefUtils.swift */; };
4B96FB401EBBC56F00E4E164 /* FoundationCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */; };
4B97E2CC1D33F53D00FC0660 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B97E2CE1D33F53D00FC0660 /* MainWindow.xib */; };
4B9BC41E24EB2E22000209B5 /* MessagePack in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9BC41D24EB2E22000209B5 /* MessagePack */; };
4B9BC42124EB2E45000209B5 /* RxCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9BC42024EB2E45000209B5 /* RxCocoa */; };
@ -156,7 +147,6 @@
4B9BC42724EB2E51000209B5 /* NvimView in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9BC42624EB2E51000209B5 /* NvimView */; };
4B9BC42A24EB2E6D000209B5 /* ShortcutRecorder in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9BC42924EB2E6D000209B5 /* ShortcutRecorder */; };
4BB409E51DD68CCC005F39A2 /* FileBrowserMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BB409E71DD68CCC005F39A2 /* FileBrowserMenu.xib */; };
4BB409EE1DDA77E9005F39A2 /* ProxyWorkspaceBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB409ED1DDA77E9005F39A2 /* ProxyWorkspaceBar.swift */; };
4BC97BC72273B27500B68997 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BF18C371FD2E2AB00DF95D1 /* Sparkle.framework */; };
4BC97BC82273B27600B68997 /* Sparkle.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4BF18C371FD2E2AB00DF95D1 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4BD5657324E842E900D52809 /* Swifter in Frameworks */ = {isa = PBXBuildFile; productRef = 4BD5655224E8014100D52809 /* Swifter */; };
@ -166,15 +156,13 @@
4BD5657B24E8448300D52809 /* EonilFSEvents in Frameworks */ = {isa = PBXBuildFile; productRef = 4BD5657A24E8448300D52809 /* EonilFSEvents */; };
4BD67C7824EC488200147C51 /* RxPack in Frameworks */ = {isa = PBXBuildFile; productRef = 4BD67C7724EC488200147C51 /* RxPack */; };
4BD67C7B24EC765900147C51 /* Commons in Frameworks */ = {isa = PBXBuildFile; productRef = 4BD67C7A24EC765900147C51 /* Commons */; };
4BD67CDC24EE45E900147C51 /* Nimble in Frameworks */ = {isa = PBXBuildFile; productRef = 4BD67CDB24EE45E900147C51 /* Nimble */; };
4BD67CE024EE465B00147C51 /* RxTest in Frameworks */ = {isa = PBXBuildFile; productRef = 4BD67CDF24EE465B00147C51 /* RxTest */; };
4BDF50171D77540900D8FBC3 /* OpenQuicklyWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BDF50191D77540900D8FBC3 /* OpenQuicklyWindow.xib */; };
4BEBA5091CFF374B00673FDF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBA5081CFF374B00673FDF /* AppDelegate.swift */; };
4BEBA50B1CFF374B00673FDF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4BEBA50A1CFF374B00673FDF /* Assets.xcassets */; };
4BEBA50E1CFF374B00673FDF /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BEBA50C1CFF374B00673FDF /* MainMenu.xib */; };
4BF07EE41D51326A009BECEB /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 4BF07EE61D51326A009BECEB /* Credits.rtf */; };
4BF18C3C1FD2E2AB00DF95D1 /* CocoaFontAwesome.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BF18C341FD2E2AA00DF95D1 /* CocoaFontAwesome.framework */; };
4BF18C411FD2E2C900DF95D1 /* CocoaFontAwesome.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4BF18C341FD2E2AA00DF95D1 /* CocoaFontAwesome.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4BF18C4A1FD2E2DE00DF95D1 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BF18C491FD2E2DE00DF95D1 /* Nimble.framework */; };
4BF18C531FD2E52300DF95D1 /* Nimble.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4BF18C491FD2E2DE00DF95D1 /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4BF70EC423D1B3F9009E51E9 /* FuzzyMatcher.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70EBF23D1B3F9009E51E9 /* FuzzyMatcher.mm */; };
4BF70EC823D1B3F9009E51E9 /* FuzzyMatcherPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70EC323D1B3F9009E51E9 /* FuzzyMatcherPool.swift */; };
4BF70ED223D1B4AF009E51E9 /* FoundationCommons.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70ED123D1B4AF009E51E9 /* FoundationCommons.m */; };
@ -202,7 +190,6 @@
dstSubfolderSpec = 10;
files = (
4BC97BC82273B27600B68997 /* Sparkle.framework in Embed Frameworks */,
4BF18C411FD2E2C900DF95D1 /* CocoaFontAwesome.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@ -213,7 +200,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
4BF18C531FD2E52300DF95D1 /* Nimble.framework in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -264,7 +250,6 @@
1929B71B4BB6550F5BC6D4CF /* MainWindow+CustomTitle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MainWindow+CustomTitle.swift"; sourceTree = "<group>"; };
1929B77CD37F201AEDD6E703 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.h; path = "../../third-party/libag/include/config.h"; sourceTree = "<group>"; };
1929B7A68B7109CEFAF105E8 /* AppDelegateReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegateReducer.swift; sourceTree = "<group>"; };
1929B7BB3E4B3DC96284B686 /* PrefUtilsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrefUtilsTest.swift; sourceTree = "<group>"; };
1929B7F7A4B3FD52263D211D /* Defs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Defs.swift; sourceTree = "<group>"; };
1929B8241CDE58F7AAF89AE4 /* PrefUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrefUtils.swift; sourceTree = "<group>"; };
1929B84E4B53B05F5434E464 /* lang.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lang.h; path = "../../third-party/libag/include/lang.h"; sourceTree = "<group>"; };
@ -308,11 +293,7 @@
4B238BE01D3BF24200CBDD98 /* Application.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
4B2A2C0D1D0353750074CE9A /* Bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Bridge.h; sourceTree = "<group>"; };
4B37ADB81D6E471B00970D55 /* vimr */ = {isa = PBXFileReference; fileEncoding = 1; lastKnownFileType = text.script.python; path = vimr; sourceTree = "<group>"; };
4B3965351DEB21300082D3C1 /* InnterToolBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InnterToolBar.swift; path = Workspace/InnterToolBar.swift; sourceTree = "<group>"; };
4B3AC8931DB031C600AC5823 /* sparkle_pub.pem */ = {isa = PBXFileReference; fileEncoding = 1; lastKnownFileType = text; path = sparkle_pub.pem; sourceTree = "<group>"; };
4B6423951D8EFD7100FC78C8 /* Workspace.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Workspace.swift; path = Workspace/Workspace.swift; sourceTree = "<group>"; };
4B6423971D8EFDE000FC78C8 /* WorkspaceBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WorkspaceBar.swift; path = Workspace/WorkspaceBar.swift; sourceTree = "<group>"; };
4B6423991D8EFE3000FC78C8 /* WorkspaceTool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WorkspaceTool.swift; path = Workspace/WorkspaceTool.swift; sourceTree = "<group>"; };
4B6A70931D60E04200E12030 /* AppKitCommons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppKitCommons.swift; sourceTree = "<group>"; };
4B8C64CD23F02259008733D8 /* Dev.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Dev.xcconfig; sourceTree = "<group>"; };
4B8C64CE23F022C2008733D8 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
@ -377,8 +358,6 @@
4B9433DB20B95EC6005807BA /* MacVim-css.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = "MacVim-css.icns"; path = "macvim-file-icons/MacVim-css.icns"; sourceTree = "<group>"; };
4B97E2CD1D33F53D00FC0660 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainWindow.xib; sourceTree = "<group>"; };
4BB409E61DD68CCC005F39A2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/FileBrowserMenu.xib; sourceTree = "<group>"; };
4BB409ED1DDA77E9005F39A2 /* ProxyWorkspaceBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ProxyWorkspaceBar.swift; path = Workspace/ProxyWorkspaceBar.swift; sourceTree = "<group>"; };
4BB489411D952CF6005BB0E8 /* WorkspaceToolButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WorkspaceToolButton.swift; path = Workspace/WorkspaceToolButton.swift; sourceTree = "<group>"; };
4BDF50181D77540900D8FBC3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/OpenQuicklyWindow.xib; sourceTree = "<group>"; };
4BEBA5051CFF374B00673FDF /* VimR.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VimR.app; sourceTree = BUILT_PRODUCTS_DIR; };
4BEBA5081CFF374B00673FDF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -388,9 +367,7 @@
4BEBA5141CFF374B00673FDF /* VimRTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VimRTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4BEBA51A1CFF374B00673FDF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4BF07EE51D51326A009BECEB /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = Base; path = Base.lproj/Credits.rtf; sourceTree = "<group>"; };
4BF18C341FD2E2AA00DF95D1 /* CocoaFontAwesome.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CocoaFontAwesome.framework; path = ../Carthage/Build/Mac/CocoaFontAwesome.framework; sourceTree = "<group>"; };
4BF18C371FD2E2AB00DF95D1 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = ../Carthage/Build/Mac/Sparkle.framework; sourceTree = "<group>"; };
4BF18C491FD2E2DE00DF95D1 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = ../Carthage/Build/Mac/Nimble.framework; sourceTree = "<group>"; };
4BF70EBF23D1B3F9009E51E9 /* FuzzyMatcher.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = FuzzyMatcher.mm; path = FuzzyMatcher/FuzzyMatcher.mm; sourceTree = "<group>"; };
4BF70EC123D1B3F9009E51E9 /* FuzzyMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FuzzyMatcher.h; path = FuzzyMatcher/FuzzyMatcher.h; sourceTree = "<group>"; };
4BF70EC323D1B3F9009E51E9 /* FuzzyMatcherPool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FuzzyMatcherPool.swift; path = FuzzyMatcher/FuzzyMatcherPool.swift; sourceTree = "<group>"; };
@ -417,9 +394,10 @@
4BD5657524E842E900D52809 /* Down in Frameworks */,
4B9BC42324EB2E45000209B5 /* RxSwift in Frameworks */,
4B9BC41E24EB2E22000209B5 /* MessagePack in Frameworks */,
4B69B31D24EDC9F100B1E5EB /* Workspace in Frameworks */,
4B69B31B24EDBAF000B1E5EB /* MaterialIcons in Frameworks */,
4BD5657324E842E900D52809 /* Swifter in Frameworks */,
4BC97BC72273B27500B68997 /* Sparkle.framework in Frameworks */,
4BF18C3C1FD2E2AB00DF95D1 /* CocoaFontAwesome.framework in Frameworks */,
4BD5657424E842E900D52809 /* PureLayout in Frameworks */,
4BD5657B24E8448300D52809 /* EonilFSEvents in Frameworks */,
4BD5657824E8443300D52809 /* DictionaryCoding in Frameworks */,
@ -431,7 +409,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4BF18C4A1FD2E2DE00DF95D1 /* Nimble.framework in Frameworks */,
4BD67CDC24EE45E900147C51 /* Nimble in Frameworks */,
4BD67CE024EE465B00147C51 /* RxTest in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -466,14 +445,6 @@
name = the_silver_searcher;
sourceTree = "<group>";
};
1929B275B9921DA7503A1932 /* Utils */ = {
isa = PBXGroup;
children = (
1929B7BB3E4B3DC96284B686 /* PrefUtilsTest.swift */,
);
name = Utils;
sourceTree = "<group>";
};
1929B2C6D0242153758A138A /* Shortcuts */ = {
isa = PBXGroup;
children = (
@ -633,26 +604,11 @@
4B5012001EBA791000F76C46 /* Frameworks */ = {
isa = PBXGroup;
children = (
4BF18C491FD2E2DE00DF95D1 /* Nimble.framework */,
4BF18C341FD2E2AA00DF95D1 /* CocoaFontAwesome.framework */,
4BF18C371FD2E2AB00DF95D1 /* Sparkle.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
4B6423941D8EFD6100FC78C8 /* Workspace */ = {
isa = PBXGroup;
children = (
4B6423951D8EFD7100FC78C8 /* Workspace.swift */,
4B6423971D8EFDE000FC78C8 /* WorkspaceBar.swift */,
4B6423991D8EFE3000FC78C8 /* WorkspaceTool.swift */,
4BB489411D952CF6005BB0E8 /* WorkspaceToolButton.swift */,
4BB409ED1DDA77E9005F39A2 /* ProxyWorkspaceBar.swift */,
4B3965351DEB21300082D3C1 /* InnterToolBar.swift */,
);
name = Workspace;
sourceTree = "<group>";
};
4B8C64D023F024D9008733D8 /* Build configurations */ = {
isa = PBXGroup;
children = (
@ -791,7 +747,6 @@
4BEBA5081CFF374B00673FDF /* AppDelegate.swift */,
4BF8EED91D858C4400CAC08A /* Utils */,
4BDF50101D760AB700D8FBC3 /* Commons */,
4B6423941D8EFD6100FC78C8 /* Workspace */,
4B97E2CF1D33F92200FC0660 /* resources */,
1929BA652D3B88FC071531EC /* UI */,
1929B66A5E2D00EA143AFD86 /* RxRedux.swift */,
@ -806,7 +761,6 @@
children = (
4BEBA51A1CFF374B00673FDF /* Info.plist */,
1929B79B3F03D2E050438074 /* Commons */,
1929B275B9921DA7503A1932 /* Utils */,
);
path = VimRTests;
sourceTree = "<group>";
@ -876,6 +830,8 @@
4B9BC42924EB2E6D000209B5 /* ShortcutRecorder */,
4BD67C7724EC488200147C51 /* RxPack */,
4BD67C7A24EC765900147C51 /* Commons */,
4B69B31A24EDBAF000B1E5EB /* MaterialIcons */,
4B69B31C24EDC9F100B1E5EB /* Workspace */,
);
productName = VimR;
productReference = 4BEBA5051CFF374B00673FDF /* VimR.app */;
@ -896,6 +852,10 @@
4BEBA5161CFF374B00673FDF /* PBXTargetDependency */,
);
name = VimRTests;
packageProductDependencies = (
4BD67CDB24EE45E900147C51 /* Nimble */,
4BD67CDF24EE465B00147C51 /* RxTest */,
);
productName = VimRTests;
productReference = 4BEBA5141CFF374B00673FDF /* VimRTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
@ -940,6 +900,8 @@
4B9BC41C24EB2E22000209B5 /* XCRemoteSwiftPackageReference "MessagePack" */,
4B9BC41F24EB2E45000209B5 /* XCRemoteSwiftPackageReference "RxSwift" */,
4B9BC42824EB2E6D000209B5 /* XCRemoteSwiftPackageReference "ShortcutRecorder" */,
4B69B31924EDBAF000B1E5EB /* XCRemoteSwiftPackageReference "material-icons" */,
4BD67CD824EE45CA00147C51 /* XCRemoteSwiftPackageReference "Nimble" */,
);
productRefGroup = 4BEBA5061CFF374B00673FDF /* Products */;
projectDirPath = "";
@ -1060,15 +1022,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4B4147A31D97361400DD4A2C /* WorkspaceToolButton.swift in Sources */,
4B238BE11D3BF24200CBDD98 /* Application.swift in Sources */,
4B6423961D8EFD7100FC78C8 /* Workspace.swift in Sources */,
4B6A70941D60E04200E12030 /* AppKitCommons.swift in Sources */,
4B3965361DEB21300082D3C1 /* InnterToolBar.swift in Sources */,
4B6423981D8EFDE000FC78C8 /* WorkspaceBar.swift in Sources */,
4BEBA5091CFF374B00673FDF /* AppDelegate.swift in Sources */,
4B64239A1D8EFE3000FC78C8 /* WorkspaceTool.swift in Sources */,
4BB409EE1DDA77E9005F39A2 /* ProxyWorkspaceBar.swift in Sources */,
1929B0E0C3BC59F52713D5A2 /* FoundationCommons.swift in Sources */,
1929BD2F41D93ADFF43C1C98 /* NetUtils.m in Sources */,
1929BE0DAEE9664C5BCFA211 /* States.swift in Sources */,
@ -1145,13 +1101,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4B96FB3F1EBBC56F00E4E164 /* PrefUtils.swift in Sources */,
4B96FB401EBBC56F00E4E164 /* FoundationCommons.swift in Sources */,
1929BDFDBDA7180D02ACB37E /* RxSwiftCommonsTest.swift in Sources */,
1929B8E90A1378E494D481E7 /* PrefUtilsTest.swift in Sources */,
1929B20CE35B43BB1CE023BA /* Theme.swift in Sources */,
1929B9318D32146D58BB38EC /* AppKitCommons.swift in Sources */,
1929BE601267D52FA2E0D6D2 /* Defs.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1354,9 +1304,9 @@
"@executable_path/../Frameworks",
);
OTHER_LDFLAGS = (
"$(PROJECT_DIR)/../third-party/libxz/lib/liblzma.a",
"$(PROJECT_DIR)/../third-party/libpcre/lib/libpcre.a",
"$(PROJECT_DIR)/../third-party/libag/lib/libag.a",
"$(PROJECT_DIR)/../third-party/lib/liblzma.a",
"$(PROJECT_DIR)/../third-party/lib/libpcre.a",
"$(PROJECT_DIR)/../third-party/lib/libag.a",
"-pthread",
);
PRODUCT_BUNDLE_IDENTIFIER = "$(VIMR_BUNDLE_IDENTIFIER)";
@ -1386,9 +1336,9 @@
"@executable_path/../Frameworks",
);
OTHER_LDFLAGS = (
"$(PROJECT_DIR)/../third-party/libxz/lib/liblzma.a",
"$(PROJECT_DIR)/../third-party/libpcre/lib/libpcre.a",
"$(PROJECT_DIR)/../third-party/libag/lib/libag.a",
"$(PROJECT_DIR)/../third-party/lib/liblzma.a",
"$(PROJECT_DIR)/../third-party/lib/libpcre.a",
"$(PROJECT_DIR)/../third-party/lib/libag.a",
"-pthread",
);
PRODUCT_BUNDLE_IDENTIFIER = "$(VIMR_BUNDLE_IDENTIFIER)";
@ -1413,6 +1363,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.qvacua.VimRTests;
PRODUCT_NAME = VimRTests;
SWIFT_OBJC_BRIDGING_HEADER = VimR/Bridge.h;
};
name = Debug;
};
@ -1432,6 +1383,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.qvacua.VimRTests;
PRODUCT_NAME = VimRTests;
SWIFT_OBJC_BRIDGING_HEADER = VimR/Bridge.h;
};
name = Release;
};
@ -1468,6 +1420,14 @@
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
4B69B31924EDBAF000B1E5EB /* XCRemoteSwiftPackageReference "material-icons" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/qvacua/material-icons";
requirement = {
kind = exactVersion;
version = 0.1.0;
};
};
4B9BC41C24EB2E22000209B5 /* XCRemoteSwiftPackageReference "MessagePack" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/a2/MessagePack.swift";
@ -1532,9 +1492,26 @@
version = 0.1.7;
};
};
4BD67CD824EE45CA00147C51 /* XCRemoteSwiftPackageReference "Nimble" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/Quick/Nimble";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 8.1.1;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
4B69B31A24EDBAF000B1E5EB /* MaterialIcons */ = {
isa = XCSwiftPackageProductDependency;
package = 4B69B31924EDBAF000B1E5EB /* XCRemoteSwiftPackageReference "material-icons" */;
productName = MaterialIcons;
};
4B69B31C24EDC9F100B1E5EB /* Workspace */ = {
isa = XCSwiftPackageProductDependency;
productName = Workspace;
};
4B9BC41D24EB2E22000209B5 /* MessagePack */ = {
isa = XCSwiftPackageProductDependency;
package = 4B9BC41C24EB2E22000209B5 /* XCRemoteSwiftPackageReference "MessagePack" */;
@ -1597,6 +1574,16 @@
isa = XCSwiftPackageProductDependency;
productName = Commons;
};
4BD67CDB24EE45E900147C51 /* Nimble */ = {
isa = XCSwiftPackageProductDependency;
package = 4BD67CD824EE45CA00147C51 /* XCRemoteSwiftPackageReference "Nimble" */;
productName = Nimble;
};
4BD67CDF24EE465B00147C51 /* RxTest */ = {
isa = XCSwiftPackageProductDependency;
package = 4B9BC41F24EB2E45000209B5 /* XCRemoteSwiftPackageReference "RxSwift" */;
productName = RxTest;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 4BEBA4FD1CFF374B00673FDF /* Project object */;

View File

@ -7,7 +7,6 @@ import Cocoa
import RxSwift
import PureLayout
import Sparkle
import CocoaFontAwesome
import DictionaryCoding
import os
import Commons

View File

@ -15,27 +15,6 @@ extension NSView {
extension NSAttributedString {
func draw(at point: CGPoint, angle: CGFloat) {
var translation = AffineTransform.identity
var rotation = AffineTransform.identity
translation.translate(x: point.x, y: point.y)
rotation.rotate(byRadians: angle)
(translation as NSAffineTransform).concat()
(rotation as NSAffineTransform).concat()
self.draw(at: CGPoint.zero)
rotation.invert()
translation.invert()
(rotation as NSAffineTransform).concat()
(translation as NSAffineTransform).concat()
}
var wholeRange: NSRange { NSRange(location: 0, length: self.length) }
static func infoLabel(markdown: String) -> NSAttributedString {
let size = NSFont.smallSystemFontSize
let down = Down(markdownString: markdown)

View File

@ -6,8 +6,9 @@
import Cocoa
import RxSwift
import PureLayout
import CocoaFontAwesome
import MaterialIcons
import Commons
import Workspace
class FileBrowser: NSView,
UiComponent {
@ -105,25 +106,22 @@ extension FileBrowser {
}
override func repaint(with theme: Workspace.Theme) {
self.goToParentButton.image = NSImage.fontAwesomeIcon(
name: .levelUpAlt,
style: .solid,
textColor: theme.toolbarForeground,
dimension: InnerToolBar.iconDimension
self.goToParentButton.image = Icon.arrowUpward.asImage(
dimension: InnerToolBar.iconDimension,
style: .filled,
color: theme.toolbarForeground
)
self.scrollToSourceButton.image = NSImage.fontAwesomeIcon(
name: .bullseye,
style: .solid,
textColor: theme.toolbarForeground,
dimension: InnerToolBar.iconDimension
self.scrollToSourceButton.image = Icon.adjust.asImage(
dimension: InnerToolBar.iconDimension,
style: .filled,
color: theme.toolbarForeground
)
self.refreshButton.image = NSImage.fontAwesomeIcon(
name: .sync,
style: .solid,
textColor: theme.toolbarForeground,
dimension: InnerToolBar.iconDimension
self.refreshButton.image = Icon.refresh.asImage(
dimension: InnerToolBar.iconDimension,
style: .filled,
color: theme.toolbarForeground
)
}
@ -139,8 +137,8 @@ extension FileBrowser {
let goToParent = self.goToParentButton
InnerToolBar.configureToStandardIconButton(
button: goToParent,
iconName: .levelUpAlt,
style: .solid
iconName: .arrowUpward,
style: .filled
)
goToParent.toolTip = "Set parent as working directory"
goToParent.action = #selector(FileBrowser.goToParentAction)
@ -148,14 +146,14 @@ extension FileBrowser {
let scrollToSource = self.scrollToSourceButton
InnerToolBar.configureToStandardIconButton(
button: scrollToSource,
iconName: .bullseye,
style: .solid
iconName: .adjust,
style: .filled
)
scrollToSource.toolTip = "Navigate to the current buffer"
scrollToSource.action = #selector(FileBrowser.scrollToSourceAction)
let refresh = self.refreshButton
InnerToolBar.configureToStandardIconButton(button: refresh, iconName: .sync, style: .solid)
InnerToolBar.configureToStandardIconButton(button: refresh, iconName: .sync, style: .filled)
refresh.toolTip = "Refresh"
refresh.action = #selector(FileBrowser.refreshAction)

View File

@ -7,7 +7,7 @@ import Cocoa
import NvimView
import PureLayout
import RxSwift
import CocoaFontAwesome
import MaterialIcons
import os
import Commons
@ -30,17 +30,15 @@ class FileOutlineView: NSOutlineView,
self.usesTheme = state.appearance.usesTheme
self.showsFileIcon = state.appearance.showsFileIcon
self.isShowHidden = state.fileBrowserShowHidden
self.triangleClosed = NSImage.fontAwesomeIcon(
name: .caretRight,
style: .solid,
textColor: self.theme.directoryForeground,
dimension: triangleImageSize
self.triangleClosed = Icon.chevronRight.asImage(
dimension: triangleImageSize,
style: .filled,
color: self.theme.directoryForeground
)
self.triangleOpen = NSImage.fontAwesomeIcon(
name: .caretDown,
style: .solid,
textColor: self.theme.directoryForeground,
dimension: triangleImageSize
self.triangleOpen = Icon.expandMore.asImage(
dimension: triangleImageSize,
style: .filled,
color: self.theme.directoryForeground
)
super.init(frame: .zero)
@ -317,17 +315,15 @@ class FileOutlineView: NSOutlineView,
self.theme = theme.payload
self.enclosingScrollView?.backgroundColor = self.theme.background
self.backgroundColor = self.theme.background
self.triangleClosed = NSImage.fontAwesomeIcon(
name: .caretRight,
style: .solid,
textColor: self.theme.directoryForeground,
dimension: triangleImageSize
self.triangleClosed = Icon.chevronRight.asImage(
dimension: triangleImageSize,
style: .filled,
color: self.theme.directoryForeground
)
self.triangleOpen = NSImage.fontAwesomeIcon(
name: .caretDown,
style: .solid,
textColor: self.theme.directoryForeground,
dimension: triangleImageSize
self.triangleOpen = Icon.expandMore.asImage(
dimension: triangleImageSize,
style: .filled,
color: self.theme.directoryForeground
)
self.lastThemeMark = theme.mark

View File

@ -8,7 +8,9 @@ import RxSwift
import PureLayout
import WebKit
import EonilFSEvents
import MaterialIcons
import os
import Workspace
private let fileSystemEventsLatency = 1.0
private let monitorDispatchQueue = DispatchQueue.global(qos: .userInitiated)
@ -157,11 +159,10 @@ extension HtmlPreviewTool {
}
override func repaint(with theme: Workspace.Theme) {
self.selectHtmlFile.image = NSImage.fontAwesomeIcon(
name: .fileCode,
style: .solid,
textColor: theme.toolbarForeground,
dimension: InnerToolBar.iconDimension
self.selectHtmlFile.image = Icon.description.asImage(
dimension: InnerToolBar.iconDimension,
style: .outlined,
color: theme.toolbarForeground
)
}
@ -169,8 +170,8 @@ extension HtmlPreviewTool {
let selectHtmlFile = self.selectHtmlFile
InnerToolBar.configureToStandardIconButton(
button: selectHtmlFile,
iconName: .fileCode,
style: .solid
iconName: Icon.description,
style: .outlined
)
selectHtmlFile.toolTip = "Select the HTML file"
selectHtmlFile.action = #selector(HtmlPreviewTool.selectHtmlFile)

View File

@ -7,6 +7,7 @@ import Cocoa
import RxSwift
import MessagePack
import Commons
import Workspace
// MARK: - RpcEvent Actions
extension MainWindow {

View File

@ -23,10 +23,10 @@ extension MainWindow {
self.set(repUrl: self.window.representedURL, themed: true)
self.window.contentView?.addSubview(self.workspace)
self.workspace.autoPinEdge(toSuperviewEdge: .top, withInset: 22)
self.workspace.autoPinEdge(toSuperviewEdge: .right)
self.workspace.autoPinEdge(toSuperviewEdge: .bottom)
self.workspace.autoPinEdge(toSuperviewEdge: .left)
self.workspace.autoPinEdge(toSuperviewEdge: ALEdge.top, withInset: 22)
self.workspace.autoPinEdge(toSuperviewEdge: ALEdge.right)
self.workspace.autoPinEdge(toSuperviewEdge: ALEdge.bottom)
self.workspace.autoPinEdge(toSuperviewEdge: ALEdge.left)
self.titlebarThemed = true

View File

@ -7,6 +7,7 @@ import Cocoa
import RxSwift
import NvimView
import RxPack
import Workspace
// MARK: - NvimViewDelegate
extension MainWindow {

View File

@ -5,6 +5,7 @@
import Cocoa
import NvimView
import Workspace
extension MainWindow {

View File

@ -8,6 +8,7 @@ import RxSwift
import NvimView
import PureLayout
import os
import Workspace
class MainWindow: NSObject,
UiComponent,

View File

@ -7,6 +7,7 @@ import Cocoa
import NvimView
import RxSwift
import Commons
import Workspace
struct AppState: Codable {

View File

@ -1,33 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import XCTest
import Nimble
class PrefUtilsTest: XCTestCase {
func testIgnorePatternsFromString() {
expect(PrefUtils.ignorePatterns(fromString: "a, b,c,,d")).to(equal(
Set(["a", "b", "c", "d"].map(FileItemIgnorePattern.init))
))
}
func testIgnorePatternsFromEmptyString() {
expect(PrefUtils.ignorePatterns(fromString: "")).to(equal(Set()))
}
func testIgnorePatternsFromEffectivelyEmptyString() {
expect(PrefUtils.ignorePatterns(fromString: ", , , ")).to(equal(Set()))
}
func testIgnorePatternStringFromSet() {
let set = Set(["c", "a", "d", "b"].map(FileItemIgnorePattern.init))
expect(PrefUtils.ignorePatternString(fromSet: set)).to(equal("a, b, c, d"))
}
func testIgnorePatternStringFromEmptySet() {
expect(PrefUtils.ignorePatternString(fromSet: Set())).to(equal(""))
}
}

5
Workspace/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/

26
Workspace/Package.swift Normal file
View File

@ -0,0 +1,26 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "Workspace",
platforms: [.macOS(.v10_13)],
products: [
.library(name: "Workspace", targets: ["Workspace"]),
],
dependencies: [
.package(name: "PureLayout", url: "https://github.com/PureLayout/PureLayout", .upToNextMinor(from: "3.1.6")),
.package(name: "MaterialIcons", url: "https://github.com/qvacua/material-icons", .upToNextMinor(from: "0.1.0")),
.package(path: "../Commons"),
],
targets: [
.target(
name: "Workspace",
dependencies: ["PureLayout", "MaterialIcons", "Commons"]
),
.testTarget(
name: "WorkspaceTests",
dependencies: ["Workspace"]
),
]
)

3
Workspace/README.md Normal file
View File

@ -0,0 +1,3 @@
# Workspace
A description of this package.

View File

@ -5,11 +5,11 @@
import Cocoa
import PureLayout
import CocoaFontAwesome
import MaterialIcons
class CustomToolBar: NSView {
open class CustomToolBar: NSView {
func repaint(with: Workspace.Theme) {
open func repaint(with: Workspace.Theme) {
// please implement
}
}
@ -19,24 +19,22 @@ class CustomToolBar: NSView {
- Close button
- Cog button: not shown when there's no menu
*/
class InnerToolBar: NSView, NSUserInterfaceValidations {
public class InnerToolBar: NSView, NSUserInterfaceValidations {
// MARK: - API
static let toolbarHeight = InnerToolBar.iconDimension
static let iconDimension = 18.cgf
static let itemPadding = 4.cgf
// MARK: - Public
public static let iconDimension = 16.cgf
public static let itemPadding = 4.cgf
static func configureToStandardIconButton(
public static func configureToStandardIconButton(
button: NSButton,
iconName: FontAwesome,
style: FontAwesomeStyle,
iconName: Icon,
style: Style,
color: NSColor = Workspace.Theme.default.toolbarForeground
) {
let icon = NSImage.fontAwesomeIcon(
name: iconName,
style: .solid,
textColor: color,
dimension: InnerToolBar.iconDimension
let icon = iconName.asImage(
dimension: InnerToolBar.iconDimension,
style: style,
color: color
)
button.imagePosition = .imageOnly
@ -48,42 +46,7 @@ class InnerToolBar: NSView, NSUserInterfaceValidations {
cell?.highlightsBy = .contentsCellMask
}
var customMenuItems: [NSMenuItem]? {
didSet {
self.removeCustomUiElements()
self.addViews()
}
}
var customToolbar: CustomToolBar? {
didSet {
self.removeCustomUiElements()
self.addViews()
}
}
var theme: Workspace.Theme {
return self.tool?.theme ?? Workspace.Theme.default
}
weak var tool: WorkspaceTool? {
didSet {
self.titleField.stringValue = self.tool?.title ?? ""
let toolTitle = self.tool?.title ?? "Tool"
self.closeButton.toolTip = "Close \(toolTitle)"
self.cogButton.toolTip = "\(toolTitle) Settings"
}
}
override var intrinsicContentSize: CGSize {
if #available(macOS 10.11, *) {
return CGSize(width: NSView.noIntrinsicMetric, height: InnerToolBar.height)
} else {
return CGSize(width: -1, height: InnerToolBar.height)
}
}
init(customToolbar: CustomToolBar? = nil, customMenuItems: [NSMenuItem] = []) {
public init(customToolbar: CustomToolBar? = nil, customMenuItems: [NSMenuItem] = []) {
self.customMenuItems = customMenuItems
self.customToolbar = customToolbar
@ -98,44 +61,55 @@ class InnerToolBar: NSView, NSUserInterfaceValidations {
self.addViews()
}
func repaint() {
self.layer!.backgroundColor = self.theme.toolbarBackground.cgColor
self.titleField.textColor = self.theme.toolbarForeground
self.cogButton.image = NSImage.fontAwesomeIcon(
name: .cog,
style: .solid,
textColor: self.theme.toolbarForeground,
dimension: InnerToolBar.iconDimension
)
self.closeButton.image = NSImage.fontAwesomeIcon(
name: .timesCircle,
style: .solid,
textColor: self.theme.toolbarForeground,
dimension: InnerToolBar.iconDimension
)
self.customToolbar?.repaint(with: self.theme)
self.needsDisplay = true
override public var intrinsicContentSize: CGSize {
return CGSize(width: NSView.noIntrinsicMetric, height: InnerToolBar.height)
}
override func draw(_ dirtyRect: NSRect) {
override public func draw(_ dirtyRect: NSRect) {
self.theme.separator.set()
let bottomSeparatorRect = self.bottomSeparatorRect()
if dirtyRect.intersects(bottomSeparatorRect) {
bottomSeparatorRect.fill()
}
if dirtyRect.intersects(bottomSeparatorRect) { bottomSeparatorRect.fill() }
self.theme.toolbarForeground.set()
let innerSeparatorRect = self.innerSeparatorRect()
if dirtyRect.intersects(innerSeparatorRect) {
innerSeparatorRect.fill()
if dirtyRect.intersects(innerSeparatorRect) { innerSeparatorRect.fill() }
}
// MARK: - NSUserInterfaceValidations
public func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
guard let loc = self.tool?.location else { return true }
if item.action == self.locToSelector[loc] { return false }
return true
}
// MARK: - Internal and private
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
var customMenuItems: [NSMenuItem]? {
didSet {
self.removeCustomUiElements()
self.addViews()
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
var customToolbar: CustomToolBar? {
didSet {
self.removeCustomUiElements()
self.addViews()
}
}
var theme: Workspace.Theme { self.tool?.theme ?? Workspace.Theme.default }
weak var tool: WorkspaceTool? {
didSet {
self.titleField.stringValue = self.tool?.title ?? ""
let toolTitle = self.tool?.title ?? "Tool"
self.closeButton.toolTip = "Close \(toolTitle)"
self.cogButton.toolTip = "\(toolTitle) Settings"
}
}
private static let separatorThickness = 1.cgf
@ -152,6 +126,29 @@ class InnerToolBar: NSView, NSUserInterfaceValidations {
.bottom: #selector(InnerToolBar.moveToBottomAction(_:)),
.left: #selector(InnerToolBar.moveToLeftAction(_:)),
]
}
extension InnerToolBar {
func repaint() {
self.layer!.backgroundColor = self.theme.toolbarBackground.cgColor
self.titleField.textColor = self.theme.toolbarForeground
self.cogButton.image = Icon.settings.asImage(
dimension: InnerToolBar.iconDimension,
style: .filled,
color: self.theme.toolbarForeground
)
self.closeButton.image = Icon.highlightOff.asImage(
dimension: InnerToolBar.iconDimension,
style: .outlined,
color: self.theme.toolbarForeground
)
self.customToolbar?.repaint(with: self.theme)
self.needsDisplay = true
}
private func removeCustomUiElements() {
self.customToolbar?.removeFromSuperview()
@ -172,8 +169,8 @@ class InnerToolBar: NSView, NSUserInterfaceValidations {
InnerToolBar.configureToStandardIconButton(
button: close,
iconName: .timesCircle,
style: .solid,
iconName: .highlightOff,
style: .outlined,
color: self.theme.toolbarForeground
)
close.target = self
@ -181,8 +178,8 @@ class InnerToolBar: NSView, NSUserInterfaceValidations {
InnerToolBar.configureToStandardIconButton(
button: cog,
iconName: .cog,
style: .solid,
iconName: .settings,
style: .filled,
color: self.theme.toolbarForeground
)
cog.action = #selector(InnerToolBar.cogAction)
@ -320,19 +317,3 @@ extension InnerToolBar {
tool.workspace?.move(tool: tool, to: location)
}
}
// MARK: - NSUserInterfaceValidations
extension InnerToolBar {
func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
guard let loc = self.tool?.location else {
return true
}
if item.action == self.locToSelector[loc] {
return false
}
return true
}
}

View File

@ -6,17 +6,15 @@
import Cocoa
import PureLayout
enum WorkspaceBarLocation: String, Codable {
public enum WorkspaceBarLocation: String, Codable, CaseIterable {
case top = "top"
case right = "right"
case bottom = "bottom"
case left = "left"
static let all = [ top, right, bottom, left ]
}
protocol WorkspaceDelegate: class {
public protocol WorkspaceDelegate: class {
func resizeWillStart(workspace: Workspace, tool: WorkspaceTool?)
func resizeDidEnd(workspace: Workspace, tool: WorkspaceTool?)
@ -25,70 +23,58 @@ protocol WorkspaceDelegate: class {
func moved(tool: WorkspaceTool)
}
class Workspace: NSView, WorkspaceBarDelegate {
public class Workspace: NSView, WorkspaceBarDelegate {
struct Config {
// MARK: - Public
public struct Config {
let mainViewMinimumSize: CGSize
public let mainViewMinimumSize: CGSize
public init(mainViewMinimumSize: CGSize) { self.mainViewMinimumSize = mainViewMinimumSize }
}
struct Theme {
public struct Theme {
static let `default` = Workspace.Theme()
public static let `default` = Workspace.Theme()
var foreground = NSColor.black
var background = NSColor.white
public var foreground = NSColor.black
public var background = NSColor.white
var separator = NSColor.controlShadowColor
public var separator = NSColor.controlShadowColor
var barBackground = NSColor.windowBackgroundColor
var barFocusRing = NSColor.selectedControlColor
public var barBackground = NSColor.windowBackgroundColor
public var barFocusRing = NSColor.selectedControlColor
var barButtonBackground = NSColor.clear
var barButtonHighlight = NSColor.controlShadowColor
public var barButtonBackground = NSColor.clear
public var barButtonHighlight = NSColor.controlShadowColor
var toolbarForeground = NSColor.darkGray
var toolbarBackground = NSColor(red: 0.899, green: 0.934, blue: 0.997, alpha: 1)
public var toolbarForeground = NSColor.darkGray
public var toolbarBackground = NSColor(red: 0.899, green: 0.934, blue: 0.997, alpha: 1)
public init() {}
}
private(set) var isAllToolsVisible = true {
didSet {
self.relayout()
}
public private(set) var isAllToolsVisible = true {
didSet { self.relayout() }
}
private(set) var isToolButtonsVisible = true {
didSet {
self.bars.values.forEach { $0.isButtonVisible = !$0.isButtonVisible }
}
public private(set) var isToolButtonsVisible = true {
didSet { self.bars.values.forEach { $0.isButtonVisible = !$0.isButtonVisible } }
}
private var tools = [WorkspaceTool]()
var orderedTools: [WorkspaceTool] {
public var orderedTools: [WorkspaceTool] {
return self.bars.values.reduce([]) { [$0, $1.tools].flatMap { $0 } }
}
private var isDragOngoing = false
private var draggedOnBarLocation: WorkspaceBarLocation?
private let proxyBar = ProxyWorkspaceBar(forAutoLayout: ())
public let mainView: NSView
public let config: Config
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
public var theme = Workspace.Theme.default {
didSet { self.repaint() }
}
// MARK: - API
let mainView: NSView
let bars: [WorkspaceBarLocation: WorkspaceBar]
let config: Config
public weak var delegate: WorkspaceDelegate?
var theme = Workspace.Theme.default {
didSet {
self.repaint()
}
}
weak var delegate: WorkspaceDelegate?
init(mainView: NSView, config: Config = Config(mainViewMinimumSize: CGSize(width: 100, height: 100))) {
public init(mainView: NSView, config: Config = Config(mainViewMinimumSize: CGSize(width: 100, height: 100))) {
self.config = config
self.mainView = mainView
@ -111,7 +97,7 @@ class Workspace: NSView, WorkspaceBarDelegate {
self.relayout()
}
func append(tool: WorkspaceTool, location: WorkspaceBarLocation) {
public func append(tool: WorkspaceTool, location: WorkspaceBarLocation) {
if self.tools.contains(tool) {
return
}
@ -120,48 +106,58 @@ class Workspace: NSView, WorkspaceBarDelegate {
self.bars[location]?.append(tool: tool)
}
func move(tool: WorkspaceTool, to location: WorkspaceBarLocation) {
public func move(tool: WorkspaceTool, to location: WorkspaceBarLocation) {
tool.bar?.remove(tool: tool)
self.bars[location]?.append(tool: tool)
self.delegate?.moved(tool: tool)
}
func hideAllTools() {
public func hideAllTools() {
if self.isAllToolsVisible {
self.isAllToolsVisible = false
}
}
func showAllTools() {
public func showAllTools() {
if !self.isAllToolsVisible {
self.isAllToolsVisible = true
}
}
func toggleAllTools() {
public func toggleAllTools() {
self.isAllToolsVisible = !self.isAllToolsVisible
}
func hideToolButtons() {
public func hideToolButtons() {
if self.isToolButtonsVisible {
self.isToolButtonsVisible = false
}
}
func showToolButtons() {
public func showToolButtons() {
if !self.isToolButtonsVisible {
self.isToolButtonsVisible = true
}
}
func toggleToolButtons() {
public func toggleToolButtons() {
self.isToolButtonsVisible = !self.isToolButtonsVisible
}
// MARK: - Internal and private
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
let bars: [WorkspaceBarLocation: WorkspaceBar]
private var tools = [WorkspaceTool]()
private var isDragOngoing = false
private var draggedOnBarLocation: WorkspaceBarLocation?
private let proxyBar = ProxyWorkspaceBar(forAutoLayout: ())
}
// MARK: - NSDraggingDestination
extension Workspace {
public extension Workspace {
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
self.isDragOngoing = true
@ -215,7 +211,7 @@ extension Workspace {
}
private func barLocation(inPoint loc: CGPoint) -> WorkspaceBarLocation? {
for barLoc in WorkspaceBarLocation.all {
for barLoc in WorkspaceBarLocation.allCases {
if rect(forBar: barLoc).contains(loc) {
return barLoc
}
@ -263,7 +259,7 @@ extension Workspace {
}
// MARK: - Layout
extension Workspace {
private extension Workspace {
private func repaint() {
self.bars.values.forEach { $0.repaint() }

View File

@ -44,9 +44,6 @@ private class ProxyBar: NSView {
self.wantsLayer = true
}
private let log = OSLog(subsystem: Defs.loggerSubsystem,
category: Defs.LoggerCategory.middleware)
}
class WorkspaceBar: NSView, WorkspaceToolDelegate {
@ -345,7 +342,6 @@ extension ProxyBar {
}
// 1.
self.log.debug("same spot: \(self.container!.barFrame().contains(locInBar))")
return false
}

View File

@ -11,36 +11,27 @@ protocol WorkspaceToolDelegate: class {
func toggle(_ tool: WorkspaceTool)
}
class WorkspaceTool: NSView {
public class WorkspaceTool: NSView {
private var innerToolbar: InnerToolBar?
public var dimension: CGFloat
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Public
override public var hash: Int { self.uuid.hashValue }
static func ==(left: WorkspaceTool, right: WorkspaceTool) -> Bool {
return left.uuid == right.uuid
}
// MARK: - API
override var hash: Int {
return self.uuid.hashValue
}
/**
This UUID is only memory-persistent. It's generated when the tool is instantiated.
*/
let uuid = UUID().uuidString
let title: String
let view: NSView
let button: WorkspaceToolButton
var location = WorkspaceBarLocation.left {
public let uuid = UUID().uuidString
public let title: String
public let view: NSView
public let button: WorkspaceToolButton
public var location = WorkspaceBarLocation.left {
didSet {
self.button.location = self.location
}
}
var isSelected = false {
public var isSelected = false {
didSet {
if self.isSelected {
self.button.highlight()
@ -50,6 +41,68 @@ class WorkspaceTool: NSView {
}
}
public struct Config {
let title: String
let view: NSView
let minimumDimension: CGFloat
let isWithInnerToolbar: Bool
let customToolbar: CustomToolBar?
let customMenuItems: [NSMenuItem]
public init(title: String,
view: NSView,
minimumDimension: CGFloat = 50,
withInnerToolbar: Bool = true,
customToolbar: CustomToolBar? = nil,
customMenuItems: [NSMenuItem] = []) {
self.title = title
self.view = view
self.minimumDimension = minimumDimension
self.isWithInnerToolbar = withInnerToolbar
self.customToolbar = customToolbar
self.customMenuItems = customMenuItems
}
}
public init(_ config: Config) {
self.title = config.title
self.view = config.view
self.minimumDimension = config.minimumDimension
self.dimension = minimumDimension
self.button = WorkspaceToolButton(title: title)
super.init(frame: .zero)
self.configureForAutoLayout()
self.button.tool = self
if config.isWithInnerToolbar {
self.innerToolbar = InnerToolBar(customToolbar: config.customToolbar, customMenuItems: config.customMenuItems)
self.innerToolbar?.tool = self
}
self.addViews()
}
public func toggle() {
self.isSelected = !self.isSelected
self.delegate?.toggle(self)
}
// MARK: - Internal and private
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private var innerToolbar: InnerToolBar?
static func ==(left: WorkspaceTool, right: WorkspaceTool) -> Bool {
return left.uuid == right.uuid
}
var theme: Workspace.Theme {
return self.bar?.theme ?? Workspace.Theme.default
}
@ -62,7 +115,6 @@ class WorkspaceTool: NSView {
}
let minimumDimension: CGFloat
var dimension: CGFloat
var customInnerToolbar: CustomToolBar? {
get {
@ -85,59 +137,6 @@ class WorkspaceTool: NSView {
}
}
struct Config {
let title: String
let view: NSView
let minimumDimension: CGFloat
let isWithInnerToolbar: Bool
let customToolbar: CustomToolBar?
let customMenuItems: [NSMenuItem]
init(title: String,
view: NSView,
minimumDimension: CGFloat = 50,
withInnerToolbar: Bool = true,
customToolbar: CustomToolBar? = nil,
customMenuItems: [NSMenuItem] = []) {
self.title = title
self.view = view
self.minimumDimension = minimumDimension
self.isWithInnerToolbar = withInnerToolbar
self.customToolbar = customToolbar
self.customMenuItems = customMenuItems
}
}
init(_ config: Config) {
self.title = config.title
self.view = config.view
self.minimumDimension = config.minimumDimension
self.dimension = minimumDimension
self.button = WorkspaceToolButton(title: title)
super.init(frame: .zero)
self.configureForAutoLayout()
self.button.tool = self
if config.isWithInnerToolbar {
self.innerToolbar = InnerToolBar(customToolbar: config.customToolbar, customMenuItems: config.customMenuItems)
self.innerToolbar?.tool = self
}
self.addViews()
}
func toggle() {
self.isSelected = !self.isSelected
self.delegate?.toggle(self)
}
func repaint() {
self.button.repaint()
self.innerToolbar?.repaint()

View File

@ -4,8 +4,9 @@
*/
import Cocoa
import Commons
class WorkspaceToolButton: NSView, NSDraggingSource {
public class WorkspaceToolButton: NSView, NSDraggingSource {
static private let titlePadding = CGSize(width: 8, height: 2)
static private let dummyButton = WorkspaceToolButton(title: "Dummy")
@ -15,11 +16,8 @@ class WorkspaceToolButton: NSView, NSDraggingSource {
private let title: NSMutableAttributedString
private var trackingArea = NSTrackingArea()
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
// MARK: - API
static let toolUti = "com.qvacua.vimr.tool"
static func ==(left: WorkspaceToolButton, right: WorkspaceToolButton) -> Bool {
@ -96,7 +94,7 @@ class WorkspaceToolButton: NSView, NSDraggingSource {
}
// MARK: - NSView
extension WorkspaceToolButton {
public extension WorkspaceToolButton {
override var intrinsicContentSize: NSSize {
let titleSize = self.title.size()
@ -201,7 +199,7 @@ extension WorkspaceToolButton {
}
// MARK: - NSDraggingSource
extension WorkspaceToolButton {
public extension WorkspaceToolButton {
@objc(draggingSession: sourceOperationMaskForDraggingContext:)
func draggingSession(_ session: NSDraggingSession, sourceOperationMaskFor ctc: NSDraggingContext) -> NSDragOperation {

View File

@ -0,0 +1,7 @@
import XCTest
import WorkspaceTests
var tests = [XCTestCaseEntry]()
tests += WorkspaceTests.allTests()
XCTMain(tests)

View File

@ -0,0 +1,15 @@
import XCTest
@testable import Workspace
final class WorkspaceTests: XCTestCase {
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
XCTAssertEqual(Workspace().text, "Hello, World!")
}
static var allTests = [
("testExample", testExample),
]
}

View File

@ -0,0 +1,9 @@
import XCTest
#if !canImport(ObjectiveC)
public func allTests() -> [XCTestCaseEntry] {
return [
testCase(WorkspaceTests.allTests),
]
}
#endif

View File

@ -1,128 +1,24 @@
#!/bin/bash
set -Eeuo pipefail
echo "### Building deps"
pushd "$(dirname "${BASH_SOURCE[0]}")/.." > /dev/null
readonly deployment_target_file="./resources/macos_deployment_target.txt"
readonly deployment_target=$(cat ${deployment_target_file})
readonly pcre_version="8.43"
readonly xz_version="5.2.4"
readonly ag_version="2.2.0"
readonly build_ag=${build_ag:-false}
readonly build_pcre=${build_pcre:-false}
readonly build_xz=${build_xz:-false}
build_ag () {
echo "### Building ag..."
pushd .deps > /dev/null
curl -L -o ag.tar.gz https://github.com/ggreer/the_silver_searcher/archive/${ag_version}.tar.gz
tar xf ag.tar.gz
mv the_silver_searcher-${ag_version} ag
pushd ag > /dev/null
./autogen.sh
xz_include=$(pwd)/../../third-party/libxz/include
pcre_include=$(pwd)/../../third-party/libpcre/include
./configure CFLAGS="-mmacosx-version-min=${deployment_target} -I${xz_include} -I${pcre_include}" \
LDFLAGS="-L$(pwd)/../../third-party/libxz/lib -L$(pwd)/../../third-party/libpcre/lib" \
MACOSX_DEPLOYMENT_TARGET=${deployment_target}
pushd src > /dev/null
cc -c ignore.c log.c options.c print.c scandir.c search.c lang.c util.c decompress.c zfile.c
ar -crs libag.a ignore.o log.o options.o print.o scandir.o search.o lang.o util.o decompress.o zfile.o
mkdir -p $(pwd)/../../../third-party/libag/lib
mv libag.a $(pwd)/../../../third-party/libag/lib
mkdir -p $(pwd)/../../../third-party/libag/include
cp *.h $(pwd)/../../../third-party/libag/include
popd > /dev/null
popd > /dev/null
popd > /dev/null
echo "### Built ag."
}
build_xz () {
echo "### Building xz (and ag)..."
pushd .deps > /dev/null
curl -L -o xz.tar.gz https://tukaani.org/xz/xz-${xz_version}.tar.gz
tar xf xz.tar.gz
mv xz-${xz_version} xz
pushd xz > /dev/null
# configure from https://github.com/Homebrew/homebrew-core/blob/c9882801013d6bc5202b91ef56ff5838d18bbab2/Formula/xz.rb
./configure CFLAGS="-mmacosx-version-min=${deployment_target}" MACOSX_DEPLOYMENT_TARGET=${deployment_target} \
--disable-debug \
--disable-dependency-tracking \
--disable-silent-rules \
--prefix=$(pwd)/../../third-party/libxz
make
make install
rm -rf $(pwd)/../../third-party/libxz/bin
rm -rf $(pwd)/../../third-party/libxz/share
popd > /dev/null
popd > /dev/null
echo "### Built xz (and ag)..."
}
build_pcre () {
echo "### Building pcre (and ag)..."
pushd .deps > /dev/null
curl -L -o pcre.tar.bz2 https://ftp.pcre.org/pub/pcre/pcre-${pcre_version}.tar.bz2
tar xf pcre.tar.bz2
mv pcre-${pcre_version} pcre
pushd pcre > /dev/null
# configure from https://github.com/Homebrew/homebrew-core/blob/c9882801013d6bc5202b91ef56ff5838d18bbab2/Formula/pcre.rb
./configure CFLAGS="-mmacosx-version-min=${deployment_target}" MACOSX_DEPLOYMENT_TARGET=${deployment_target} \
--disable-dependency-tracking \
--prefix=$(pwd)/../../third-party/libpcre \
--enable-utf8 \
--enable-pcre8 \
--enable-pcre16 \
--enable-pcre32 \
--enable-unicode-properties \
--enable-pcregrep-libz \
--enable-pcregrep-libbz2 \
--enable-jit
make
make install
rm -rf $(pwd)/../../third-party/libpcre/bin
rm -rf $(pwd)/../../third-party/libpcre/share
popd > /dev/null
popd > /dev/null
echo "### Built pcre (and ag)..."
}
build_vimr_deps () {
rm -rf .deps
mkdir .deps
if [[ ${build_pcre} == true ]] ; then
rm -rf third-party/libpcre
build_pcre
rm -rf third-party/libag
build_ag
fi
if [[ ${build_xz} == true ]] ; then
rm -rf third-party/libxz
build_xz
rm -rf third-party/libag
build_ag
fi
if [[ ${build_ag} == true ]] ; then
rm -rf third-party/libag
build_ag
fi
}
main () {
build_vimr_deps
pushd "$(dirname "${BASH_SOURCE[0]}")/.." > /dev/null
local -r x86_64_deployment_target=$(cat ./resources/x86_64_deployment_target.txt)
local -r arm64_deployment_target=$(cat ./resources/arm64_deployment_target.txt)
local -r pcre_version="8.43"
local -r xz_version="5.2.4"
local -r ag_version="2.2.0"
pushd ./third-party >/dev/null
python build.py \
--arm64-deployment-target="${arm64_deployment_target}" \
--x86_64-deployment-target="${x86_64_deployment_target}" \
--xz-version "${xz_version}" \
--pcre-version "${pcre_version}" \
--ag-version "${ag_version}"
popd >/dev/null
popd >/dev/null
}
main

View File

@ -1,27 +0,0 @@
#!/bin/bash
set -e
echo "### Building libnvim"
pushd NvimView/neovim
ln -f -s ../../local.mk .
rm -rf build
make distclean
../../bin/build_libnvim.sh
popd
echo "### Updating carthage"
carthage update --platform osx --cache-builds
# to avoid Xcode time out, cf https://stackoverflow.com/questions/37922146/xctests-failing-on-physical-device-canceling-tests-due-to-timeout/40790171#40790171
echo "### Building"
xcodebuild build -scheme NvimView -workspace VimR.xcworkspace
xcodebuild build -scheme VimR -workspace VimR.xcworkspace
echo "### Executing tests"
xcodebuild test -scheme VimR -workspace VimR.xcworkspace

View File

@ -4,7 +4,7 @@ set -Eeuo pipefail
echo "### Building VimR target"
pushd "$( dirname "${BASH_SOURCE[0]}" )/.." > /dev/null
readonly deployment_target_file="./resources/macos_deployment_target.txt"
readonly deployment_target_file="./resources/x86_deployment_target.txt"
readonly deployment_target=$(cat ${deployment_target_file})
readonly code_sign=${code_sign:?"true or false"}
readonly use_carthage_cache=${use_carthage_cache:?"true or false"}

View File

@ -0,0 +1 @@
11.00

View File

@ -1 +0,0 @@
10.13

View File

@ -0,0 +1 @@
10.13

1
third-party/.python-version vendored Normal file
View File

@ -0,0 +1 @@
com.qvacua.VimR.third-party

47
third-party/README.md vendored Normal file
View File

@ -0,0 +1,47 @@
## How to use
* `cd` into `/third-party`, this directory.
* Install pyenv and pyenv-virtuelenv.
* Install Python 3.8.x using pyenv.
* Create a virtualenv with the name `com.qvacua.VimR.third-party`.
* Ensure that you're running the Python in the virtualenv by
```
$ pyenv which python
/${HOME}/.pyenv/versions/com.qvacua.VimR.third-party/bin/python
```
* Do the following
```
$ python setup.py develop
```
* Run `build.py` with, for example, the following arguments
```
$ python build.py --arm64-deployment-target=11.00 --x86_64-deployment-target=10.13 \
--xz-version 5.2.4 --pcre-version 8.43 --ag-version 2.2.0
```
## Built artifacts
The resulting artifacts are structured as follows
```
third-party
lib
liba.a
libb.a
...
liba
include
a.h
...
libb
include
b.h
...
```
## IntelliJ settings
* Open /third-party, this directory.
* Add the virtualenv `com.qvacua.VimR.third-party` as Python SDK.
* Set the project SDK to the virtualenv.
* Set the content root to Sources
* Optional: Set all install paths, i.e. `lib*/` to Excluded.

0
third-party/__init__.py vendored Normal file
View File

122
third-party/build.py vendored Normal file
View File

@ -0,0 +1,122 @@
import argparse
import pathlib
import shutil
from builder import Builder
from config import Config
from deps import ag, pcre, xz
from deps.ag import AgBuilder
DEPS_FILE_NAME = ".deps"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument(
"--xz-version",
action="store",
dest="xz_version",
type=str,
required=True,
)
parser.add_argument(
"--pcre-version",
action="store",
dest="pcre_version",
type=str,
required=True,
)
parser.add_argument(
"--ag-version",
action="store",
dest="ag_version",
type=str,
required=True,
)
parser.add_argument(
"--arm64-deployment-target",
action="store",
dest="arm64_deployment_target",
type=str,
required=True,
)
parser.add_argument(
"--x86_64-deployment-target",
action="store",
dest="x86_64_deployment_target",
type=str,
required=False,
)
return parser.parse_args()
if __name__ == "__main__":
args = parse_args()
arm64_deployment_target = args.arm64_deployment_target
x86_64_deployment_target = args.x86_64_deployment_target
cwd = pathlib.Path(__file__).parent.resolve()
install_path = cwd
install_path_lib = install_path.joinpath("lib")
xz_config = Config(
version=args.xz_version,
arm64_deployment_target=arm64_deployment_target,
x86_64_deployment_target=x86_64_deployment_target,
default_cflags="-g -O2",
target_install_path_parent=cwd.joinpath("libxz"),
install_path_lib=install_path_lib,
install_path_include=install_path.joinpath("libxz/include"),
working_directory=cwd.joinpath(DEPS_FILE_NAME),
)
pcre_config = Config(
version=args.pcre_version,
arm64_deployment_target=arm64_deployment_target,
x86_64_deployment_target=x86_64_deployment_target,
default_cflags="-D_THREAD_SAFE -pthread -g -O2",
target_install_path_parent=cwd.joinpath("libpcre"),
install_path_lib=install_path_lib,
install_path_include=install_path.joinpath("libpcre/include"),
working_directory=cwd.joinpath(DEPS_FILE_NAME),
)
builders = {
"xz": Builder(
xz_config,
download_command=xz.download_command,
make_command=xz.make_command,
copy_command=xz.copy_command,
),
"pcre": Builder(
pcre_config,
download_command=pcre.download_command,
make_command=pcre.make_command,
copy_command=pcre.copy_command,
),
"ag": AgBuilder(
Config(
version=args.ag_version,
arm64_deployment_target=arm64_deployment_target,
x86_64_deployment_target=x86_64_deployment_target,
default_cflags="-g -O2 -D_THREAD_SAFE -pthread",
target_install_path_parent=cwd.joinpath("libag"),
install_path_lib=install_path_lib,
install_path_include=install_path.joinpath("libag/include"),
working_directory=cwd.joinpath(DEPS_FILE_NAME),
),
download_command=ag.download_command,
make_command=ag.make_command,
copy_command=ag.copy_command,
deps=[xz_config, pcre_config],
),
}
shutil.rmtree(install_path_lib, ignore_errors=True)
shutil.rmtree(install_path.joinpath("include"), ignore_errors=True)
builders["xz"].build()
builders["pcre"].build()
builders["ag"].build()

48
third-party/builder.py vendored Normal file
View File

@ -0,0 +1,48 @@
from dataclasses import dataclass
from string import Template
from config import Config
from utils.shell import shell
@dataclass(frozen=True)
class Builder:
config: Config
download_command: Template
make_command: Template
copy_command: Template
def download(self):
cmd = self.download_command.substitute(dict(version=self.config.version))
print(cmd)
shell(cmd, cwd=self.config.working_directory)
def make(self):
cmd = self.make_command.substitute(
dict(
cflags=self.config.x86_64_full_cflags,
deployment_target=self.config.x86_64_deployment_target,
install_path=self.config.x86_64_install_path,
)
)
print(cmd)
shell(cmd, cwd=self.config.working_directory)
def copy_to_install_path(self):
cmd = self.copy_command.substitute(
dict(
x86_64_install_path=self.config.x86_64_install_path,
install_include_path=self.config.install_path_include,
install_lib_path=self.config.install_path_lib,
)
)
print(cmd)
shell(cmd, cwd=self.config.working_directory)
def build(self):
self.config.clean_install_paths()
self.config.ensure_paths_exist()
self.download()
self.make()
self.copy_to_install_path()

51
third-party/config.py vendored Normal file
View File

@ -0,0 +1,51 @@
import shutil
from dataclasses import dataclass
from pathlib import Path
@dataclass(frozen=True)
class Config:
"""The working_directory should be set for the particular library, e.g. ./.deps/xz"""
version: str
arm64_deployment_target: str
x86_64_deployment_target: str
default_cflags: str
target_install_path_parent: Path
install_path_include: Path
install_path_lib: Path
working_directory: Path
@property
def arm64_full_cflags(self) -> str:
return f"{self.default_cflags} --target=arm64-apple-macos{self.arm64_deployment_target}"
@property
def x86_64_full_cflags(self) -> str:
return f"{self.default_cflags} --target=x86_64-apple-macos{self.x86_64_deployment_target}"
@property
def arm64_install_path(self) -> Path:
return self.target_install_path_parent.joinpath("arm64")
@property
def x86_64_install_path(self) -> Path:
return self.target_install_path_parent.joinpath("x86_64")
def clean_install_paths(self):
shutil.rmtree(self.arm64_install_path, ignore_errors=True)
shutil.rmtree(self.x86_64_install_path, ignore_errors=True)
shutil.rmtree(self.target_install_path_parent, ignore_errors=True)
def ensure_paths_exist(self):
self.target_install_path_parent.mkdir(parents=True, exist_ok=True)
self.install_path_lib.mkdir(parents=True, exist_ok=True)
self.install_path_include.mkdir(parents=True, exist_ok=True)
self.arm64_install_path.mkdir(parents=True, exist_ok=True)
self.x86_64_install_path.mkdir(parents=True, exist_ok=True)
self.working_directory.mkdir(parents=True, exist_ok=True)

0
third-party/deps/__init__.py vendored Normal file
View File

70
third-party/deps/ag.py vendored Normal file
View File

@ -0,0 +1,70 @@
from dataclasses import dataclass
from string import Template
from builder import Builder
from config import Config
from utils.shell import shell
# language=bash
download_command = Template(
"""
curl -L -s -o ag.tar.gz https://github.com/ggreer/the_silver_searcher/archive/${version}.tar.gz
rm -rf ag
tar xf ag.tar.gz
mv the_silver_searcher-${version} ag
"""
)
# language=bash
make_command = Template(
"""
pushd ag >/dev/null
./autogen.sh
./configure
CFLAGS="${cflags} ${include_flags}" \
LDFLAGS="${ldflags}" \
MACOSX_DEPLOYMENT_TARGET="${deployment_target}"
pushd src > /dev/null
cc ${cflags} ${include_flags} -c ignore.c log.c options.c print.c scandir.c search.c lang.c util.c decompress.c zfile.c
ar -crs libag.a ignore.o log.o options.o print.o scandir.o search.o lang.o util.o decompress.o zfile.o
mkdir -p "${install_path}/lib"
mv libag.a "${install_path}/lib"
mkdir -p "${install_path}/include"
cp *.h "${install_path}/include"
popd >/dev/null
popd >/dev/null
"""
)
# language=bash
copy_command = Template(
"""
cp -r "${x86_64_install_path}/include"/* "${install_include_path}"
cp -r "${x86_64_install_path}/lib"/* "${install_lib_path}"
"""
)
@dataclass(frozen=True)
class AgBuilder(Builder):
deps: [Config]
def make(self):
include_flags = " ".join(
[f'-I{c.x86_64_install_path.joinpath("include")}' for c in self.deps]
)
ldflags = " ".join([f'-L{c.x86_64_install_path.joinpath("lib")}' for c in self.deps])
cmd = self.make_command.substitute(
dict(
cflags=self.config.x86_64_full_cflags,
ldflags=ldflags,
include_flags=include_flags,
deployment_target=self.config.x86_64_deployment_target,
install_path=self.config.x86_64_install_path,
)
)
print(cmd)
shell(cmd, cwd=self.config.working_directory)

43
third-party/deps/pcre.py vendored Normal file
View File

@ -0,0 +1,43 @@
from string import Template
# language=bash
download_command = Template(
"""
curl -L -s -o pcre.tar.bz2 "https://ftp.pcre.org/pub/pcre/pcre-${version}.tar.bz2"
rm -rf pcre
tar xf pcre.tar.bz2
mv "pcre-${version}" pcre
"""
)
# language=bash
make_command = Template(
"""
pushd pcre >/dev/null
./configure \
CFLAGS="${cflags}" \
MACOSX_DEPLOYMENT_TARGET="${deployment_target}" \
--disable-dependency-tracking \
--enable-utf8 \
--enable-pcre8 \
--enable-pcre16 \
--enable-pcre32 \
--enable-unicode-properties \
--enable-pcregrep-libz \
--enable-pcregrep-libbz2 \
--enable-jit \
--disable-shared \
--prefix="${install_path}"
make MACOSX_DEPLOYMENT_TARGET="${deployment_target}" install
popd >/dev/null
"""
)
# language=bash
copy_command = Template(
"""
cp -r "${x86_64_install_path}/include"/* "${install_include_path}"
cp -r "${x86_64_install_path}/lib"/* "${install_lib_path}"
"""
)

43
third-party/deps/xz.py vendored Normal file
View File

@ -0,0 +1,43 @@
from string import Template
# language=bash
download_command = Template(
"""
curl -L -s -o xz.tar.gz "https://tukaani.org/xz/xz-${version}.tar.gz"
rm -rf xz
tar xf xz.tar.gz
mv "xz-${version}" xz
"""
)
# language=bash
make_command = Template(
"""
pushd ./xz >/dev/null
./configure \
CFLAGS="${cflags}" \
MACOSX_DEPLOYMENT_TARGET="${deployment_target}" \
--disable-debug \
--disable-dependency-tracking \
--disable-silent-rules \
--disable-shared \
--disable-xz \
--disable-xzdec \
--disable-lzmadec \
--disable-lzmainfo \
--disable-lzma-links \
--disable-scripts \
--disable-doc \
--prefix="${install_path}"
make MACOSX_DEPLOYMENT_TARGET="${deployment_target}" install
popd >/dev/null
"""
)
# language=bash
copy_command = Template(
"""
cp -r "${x86_64_install_path}/include"/* "${install_include_path}"
cp -r "${x86_64_install_path}/lib"/* "${install_lib_path}"
"""
)

3
third-party/lib/libag.a vendored Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9a0d2807adb3f3e8fd26c8ebda5d6f31b30ff21634e0a50a3b659d9864063b72
size 277680

3
third-party/lib/liblzma.a vendored Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9939baf3ac2c7f7f86f3f4dcca89c794513c0717ddaaf2110ac50524cdd8204a
size 1033720

View File

@ -5,10 +5,10 @@
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname='liblzma.5.dylib'
dlname=''
# Names of this library.
library_names='liblzma.5.dylib liblzma.dylib'
library_names=''
# The name of the static archive.
old_library='liblzma.a'
@ -38,4 +38,4 @@ dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/vimr/.deps/xz/../../third-party/libxz/lib'
libdir='/Users/hat/Projects/vimr/third-party/libxz/x86_64/lib'

3
third-party/lib/libpcre.a vendored Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cd74396cc07b9771b925ff1040ea34ce62e5d06bd661f081fbb3b3a0eadeee8a
size 4353080

41
third-party/lib/libpcre.la vendored Executable file
View File

@ -0,0 +1,41 @@
# libpcre.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6.42-b88ce
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libpcre.a'
# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=''
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libpcre.
current=3
age=2
revision=11
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib'

3
third-party/lib/libpcre16.a vendored Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e89a132443f734b45a72574598a3eed4f6636116980c4a12b8dcee6f4d3c33ed
size 4142840

41
third-party/lib/libpcre16.la vendored Executable file
View File

@ -0,0 +1,41 @@
# libpcre16.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6.42-b88ce
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libpcre16.a'
# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=''
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libpcre16.
current=2
age=2
revision=11
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib'

3
third-party/lib/libpcre32.a vendored Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:987cead18fc466262163a1c90672fd36ded65792e23b22e55466d87f15e6fb1a
size 4090184

41
third-party/lib/libpcre32.la vendored Executable file
View File

@ -0,0 +1,41 @@
# libpcre32.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6.42-b88ce
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libpcre32.a'
# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=''
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libpcre32.
current=0
age=0
revision=11
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib'

3
third-party/lib/libpcrecpp.a vendored Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4a63e497339807e804c8a9d7a20b60aa8260b3cdf0e5bfd47351b223bc3bdde7
size 47368

41
third-party/lib/libpcrecpp.la vendored Executable file
View File

@ -0,0 +1,41 @@
# libpcrecpp.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6.42-b88ce
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libpcrecpp.a'
# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=' /Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib/libpcre.la'
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libpcrecpp.
current=0
age=0
revision=1
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib'

3
third-party/lib/libpcreposix.a vendored Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f5e9c37225c8156db83b62e135cfb7fcd393d5d883c86da5f243f39f551b360a
size 12936

41
third-party/lib/libpcreposix.la vendored Executable file
View File

@ -0,0 +1,41 @@
# libpcreposix.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6.42-b88ce
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libpcreposix.a'
# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=' /Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib/libpcre.la'
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libpcreposix.
current=0
age=0
revision=6
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib'

View File

@ -5,10 +5,10 @@
# You can do whatever you want with this file.
#
prefix=/Users/hat/vimr/.deps/xz/../../third-party/libxz
exec_prefix=/Users/hat/vimr/.deps/xz/../../third-party/libxz
libdir=/Users/hat/vimr/.deps/xz/../../third-party/libxz/lib
includedir=/Users/hat/vimr/.deps/xz/../../third-party/libxz/include
prefix=/Users/hat/Projects/vimr/third-party/libxz/x86_64
exec_prefix=/Users/hat/Projects/vimr/third-party/libxz/x86_64
libdir=/Users/hat/Projects/vimr/third-party/libxz/x86_64/lib
includedir=/Users/hat/Projects/vimr/third-party/libxz/x86_64/include
Name: liblzma
Description: General purpose data compression library

13
third-party/lib/pkgconfig/libpcre.pc vendored Normal file
View File

@ -0,0 +1,13 @@
# Package Information for pkg-config
prefix=/Users/hat/Projects/vimr/third-party/libpcre/x86_64
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libpcre
Description: PCRE - Perl compatible regular expressions C library with 8 bit character support
Version: 8.43
Libs: -L${libdir} -lpcre
Libs.private: -D_THREAD_SAFE -pthread
Cflags: -I${includedir} -DPCRE_STATIC

13
third-party/lib/pkgconfig/libpcre16.pc vendored Normal file
View File

@ -0,0 +1,13 @@
# Package Information for pkg-config
prefix=/Users/hat/Projects/vimr/third-party/libpcre/x86_64
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libpcre16
Description: PCRE - Perl compatible regular expressions C library with 16 bit character support
Version: 8.43
Libs: -L${libdir} -lpcre16
Libs.private: -D_THREAD_SAFE -pthread
Cflags: -I${includedir} -DPCRE_STATIC

13
third-party/lib/pkgconfig/libpcre32.pc vendored Normal file
View File

@ -0,0 +1,13 @@
# Package Information for pkg-config
prefix=/Users/hat/Projects/vimr/third-party/libpcre/x86_64
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libpcre32
Description: PCRE - Perl compatible regular expressions C library with 32 bit character support
Version: 8.43
Libs: -L${libdir} -lpcre32
Libs.private: -D_THREAD_SAFE -pthread
Cflags: -I${includedir} -DPCRE_STATIC

12
third-party/lib/pkgconfig/libpcrecpp.pc vendored Normal file
View File

@ -0,0 +1,12 @@
# Package Information for pkg-config
prefix=/Users/hat/Projects/vimr/third-party/libpcre/x86_64
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libpcrecpp
Description: PCRECPP - C++ wrapper for PCRE
Version: 8.43
Libs: -L${libdir} -lpcre -lpcrecpp
Cflags: -I${includedir} -DPCRE_STATIC

View File

@ -0,0 +1,13 @@
# Package Information for pkg-config
prefix=/Users/hat/Projects/vimr/third-party/libpcre/x86_64
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libpcreposix
Description: PCREPosix - Posix compatible interface to libpcre
Version: 8.43
Libs: -L${libdir} -lpcreposix
Cflags: -I${includedir} -DPCRE_STATIC
Requires.private: libpcre

View File

@ -0,0 +1,120 @@
/* src/config.h. Generated from config.h.in by configure. */
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Have dirent struct member d_namlen */
#define HAVE_DIRENT_DNAMLEN /**/
/* Have dirent struct member d_type */
#define HAVE_DIRENT_DTYPE /**/
/* Define to 1 if you have the <err.h> header file. */
#define HAVE_ERR_H 1
/* Define to 1 if you have the `fgetln' function. */
#define HAVE_FGETLN 1
/* Define to 1 if you have the `fopencookie' function. */
/* #undef HAVE_FOPENCOOKIE */
/* Define to 1 if you have the `getline' function. */
#define HAVE_GETLINE 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `shlwapi' library (-lshlwapi). */
/* #undef HAVE_LIBSHLWAPI */
/* Define to 1 if you have the <lzma.h> header file. */
#define HAVE_LZMA_H 1
/* Define to 1 if you have the `madvise' function. */
#define HAVE_MADVISE 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `pledge' function. */
/* #undef HAVE_PLEDGE */
/* Define to 1 if you have the `posix_fadvise' function. */
/* #undef HAVE_POSIX_FADVISE */
/* Define to 1 if you have the <pthread.h> header file. */
#define HAVE_PTHREAD_H 1
/* Have PTHREAD_PRIO_INHERIT. */
#define HAVE_PTHREAD_PRIO_INHERIT 1
/* Define to 1 if you have the `pthread_setaffinity_np' function. */
/* #undef HAVE_PTHREAD_SETAFFINITY_NP */
/* Define to 1 if you have the `realpath' function. */
#define HAVE_REALPATH 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strlcpy' function. */
#define HAVE_STRLCPY 1
/* Define to 1 if you have the `strndup' function. */
#define HAVE_STRNDUP 1
/* Define to 1 if you have the <sys/cpuset.h> header file. */
/* #undef HAVE_SYS_CPUSET_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `vasprintf' function. */
#define HAVE_VASPRINTF 1
/* Define to 1 if you have the <zlib.h> header file. */
#define HAVE_ZLIB_H 1
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "https://github.com/ggreer/the_silver_searcher/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "the_silver_searcher"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "the_silver_searcher 2.2.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "the_silver_searcher"
/* Define to the home page for this package. */
#define PACKAGE_URL "https://github.com/ggreer/the_silver_searcher"
/* Define to the version of this package. */
#define PACKAGE_VERSION "2.2.0"
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef PTHREAD_CREATE_JOINABLE */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Use CPU_SET macros */
/* #undef USE_CPU_SET */
/* Use PCRE JIT */
#define USE_PCRE_JIT /**/

View File

@ -0,0 +1,26 @@
#ifndef DECOMPRESS_H
#define DECOMPRESS_H
#include <stdio.h>
#include "config.h"
#include "log.h"
#include "options.h"
typedef enum {
AG_NO_COMPRESSION,
AG_GZIP,
AG_COMPRESS,
AG_ZIP,
AG_XZ,
} ag_compression_type;
ag_compression_type is_zipped(const void *buf, const int buf_len);
void *decompress(const ag_compression_type zip_type, const void *buf, const int buf_len, const char *dir_full_path, int *new_buf_len);
#if HAVE_FOPENCOOKIE
FILE *decompress_open(int fd, const char *mode, ag_compression_type ctype);
#endif
#endif

View File

@ -0,0 +1,48 @@
#ifndef IGNORE_H
#define IGNORE_H
#include <dirent.h>
#include <sys/types.h>
struct ignores {
char **extensions; /* File extensions to ignore */
size_t extensions_len;
char **names; /* Non-regex ignore lines. Sorted so we can binary search them. */
size_t names_len;
char **slash_names; /* Same but starts with a slash */
size_t slash_names_len;
char **regexes; /* For patterns that need fnmatch */
size_t regexes_len;
char **invert_regexes; /* For "!" patterns */
size_t invert_regexes_len;
char **slash_regexes;
size_t slash_regexes_len;
const char *dirname;
size_t dirname_len;
char *abs_path;
size_t abs_path_len;
struct ignores *parent;
};
typedef struct ignores ignores;
ignores *root_ignores;
extern const char *evil_hardcoded_ignore_files[];
extern const char *ignore_pattern_files[];
ignores *init_ignore(ignores *parent, const char *dirname, const size_t dirname_len);
void cleanup_ignore(ignores *ig);
void add_ignore_pattern(ignores *ig, const char *pattern);
void load_ignore_patterns(ignores *ig, const char *path);
int filename_filter(const char *path, const struct dirent *dir, void *baton);
int is_empty(ignores *ig);
#endif

36
third-party/libag/x86_64/include/lang.h vendored Normal file
View File

@ -0,0 +1,36 @@
#ifndef LANG_H
#define LANG_H
#define MAX_EXTENSIONS 12
#define SINGLE_EXT_LEN 20
typedef struct {
const char *name;
const char *extensions[MAX_EXTENSIONS];
} lang_spec_t;
extern lang_spec_t langs[];
/**
Return the language count.
*/
size_t get_lang_count(void);
/**
Convert a NULL-terminated array of language extensions
into a regular expression of the form \.(extension1|extension2...)$
Caller is responsible for freeing the returned string.
*/
char *make_lang_regex(char *ext_array, size_t num_exts);
/**
Combine multiple file type extensions into one array.
The combined result is returned through *exts*;
*exts* is one-dimension array, which can contain up to 100 extensions;
The number of extensions that *exts* actually contain is returned.
*/
size_t combine_file_extensions(size_t *extension_index, size_t len, char **exts);
#endif

32
third-party/libag/x86_64/include/log.h vendored Normal file
View File

@ -0,0 +1,32 @@
#ifndef LOG_H
#define LOG_H
#include <stdarg.h>
#include "config.h"
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
pthread_mutex_t print_mtx;
enum log_level {
LOG_LEVEL_DEBUG = 10,
LOG_LEVEL_MSG = 20,
LOG_LEVEL_WARN = 30,
LOG_LEVEL_ERR = 40,
LOG_LEVEL_NONE = 100
};
void set_log_level(enum log_level threshold);
void log_debug(const char *fmt, ...);
void log_msg(const char *fmt, ...);
void log_warn(const char *fmt, ...);
void log_err(const char *fmt, ...);
void vplog(const unsigned int level, const char *fmt, va_list args);
void plog(const unsigned int level, const char *fmt, ...);
#endif

View File

@ -0,0 +1,105 @@
#ifndef OPTIONS_H
#define OPTIONS_H
#include <getopt.h>
#include <sys/stat.h>
#include <pcre.h>
#define DEFAULT_AFTER_LEN 2
#define DEFAULT_BEFORE_LEN 2
#define DEFAULT_CONTEXT_LEN 2
#define DEFAULT_MAX_SEARCH_DEPTH 25
enum case_behavior {
CASE_DEFAULT, /* Changes to CASE_SMART at the end of option parsing */
CASE_SENSITIVE,
CASE_INSENSITIVE,
CASE_SMART,
CASE_SENSITIVE_RETRY_INSENSITIVE /* for future use */
};
enum path_print_behavior {
PATH_PRINT_DEFAULT, /* PRINT_TOP if > 1 file being searched, else PRINT_NOTHING */
PATH_PRINT_DEFAULT_EACH_LINE, /* PRINT_EACH_LINE if > 1 file being searched, else PRINT_NOTHING */
PATH_PRINT_TOP,
PATH_PRINT_EACH_LINE,
PATH_PRINT_NOTHING
};
typedef struct {
int ackmate;
pcre *ackmate_dir_filter;
pcre_extra *ackmate_dir_filter_extra;
size_t after;
size_t before;
enum case_behavior casing;
const char *file_search_string;
int match_files;
pcre *file_search_regex;
pcre_extra *file_search_regex_extra;
int color;
char *color_line_number;
char *color_match;
char *color_path;
int color_win_ansi;
int column;
int context;
int follow_symlinks;
int invert_match;
int literal;
int literal_starts_wordchar;
int literal_ends_wordchar;
size_t max_matches_per_file;
int max_search_depth;
int mmap;
int multiline;
int one_dev;
int only_matching;
char path_sep;
int path_to_ignore;
int print_break;
int print_count;
int print_filename_only;
int print_path;
int print_all_paths;
int print_line_numbers;
int print_long_lines; /* TODO: support this in print.c */
int passthrough;
pcre *re;
pcre_extra *re_extra;
int recurse_dirs;
int search_all_files;
int skip_vcs_ignores;
int search_binary_files;
int search_zip_files;
int search_hidden_files;
int search_stream; /* true if tail -F blah | ag */
int stats;
size_t stream_line_num; /* This should totally not be in here */
int match_found; /* This should totally not be in here */
ino_t stdout_inode;
char *query;
int query_len;
char *pager;
int paths_len;
int parallel;
int use_thread_affinity;
int vimgrep;
size_t width;
int word_regexp;
int workers;
} cli_options;
/* global options. parse_options gives it sane values, everything else reads from it */
cli_options opts;
typedef struct option option_t;
void usage(void);
void print_version(void);
void init_options(void);
void parse_options(int argc, char **argv, char **base_paths[], char **paths[]);
void cleanup_options(void);
#endif

View File

@ -0,0 +1,26 @@
#ifndef PRINT_H
#define PRINT_H
#include "util.h"
void print_init_context(void);
void print_cleanup_context(void);
void print_context_append(const char *line, size_t len);
void print_trailing_context(const char *path, const char *buf, size_t n);
void print_path(const char *path, const char sep);
void print_path_count(const char *path, const char sep, const size_t count);
void print_line(const char *buf, size_t buf_pos, size_t prev_line_offset);
void print_binary_file_matches(const char *path);
void print_file_matches(const char *path, const char *buf, const size_t buf_len, const match_t matches[], const size_t matches_len);
void print_line_number(size_t line, const char sep);
void print_column_number(const match_t matches[], size_t last_printed_match,
size_t prev_line_offset, const char sep);
void print_file_separator(void);
const char *normalize_path(const char *path);
#ifdef _WIN32
void windows_use_ansi(int use_ansi);
int fprintf_w32(FILE *fp, const char *format, ...);
#endif
#endif

View File

@ -0,0 +1,20 @@
#ifndef SCANDIR_H
#define SCANDIR_H
#include "ignore.h"
typedef struct {
const ignores *ig;
const char *base_path;
size_t base_path_len;
const char *path_start;
} scandir_baton_t;
typedef int (*filter_fp)(const char *path, const struct dirent *, void *);
int ag_scandir(const char *dirname,
struct dirent ***namelist,
filter_fp filter,
void *baton);
#endif

View File

@ -0,0 +1,78 @@
#ifndef SEARCH_H
#define SEARCH_H
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <pcre.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#endif
#include <sys/stat.h>
#include <unistd.h>
#include "config.h"
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#include "decompress.h"
#include "ignore.h"
#include "log.h"
#include "options.h"
#include "print.h"
#include "uthash.h"
#include "util.h"
size_t alpha_skip_lookup[256];
size_t *find_skip_lookup;
uint8_t h_table[H_SIZE] __attribute__((aligned(64)));
struct work_queue_t {
char *path;
struct work_queue_t *next;
};
typedef struct work_queue_t work_queue_t;
work_queue_t *work_queue;
work_queue_t *work_queue_tail;
int done_adding_files;
pthread_cond_t files_ready;
pthread_mutex_t stats_mtx;
pthread_mutex_t work_queue_mtx;
/* For symlink loop detection */
#define SYMLOOP_ERROR (-1)
#define SYMLOOP_OK (0)
#define SYMLOOP_LOOP (1)
typedef struct {
dev_t dev;
ino_t ino;
} dirkey_t;
typedef struct {
dirkey_t key;
UT_hash_handle hh;
} symdir_t;
symdir_t *symhash;
void search_buf(const char *buf, const size_t buf_len,
const char *dir_full_path);
void search_stream(FILE *stream, const char *path);
void search_file(const char *file_full_path);
void *search_file_worker(void *i);
void search_dir(ignores *ig, const char *base_path, const char *path, const int depth, dev_t original_dev);
#endif

View File

@ -0,0 +1,971 @@
/*
Copyright (c) 2003-2014, Troy D. Hanson http://troydhanson.github.com/uthash/
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.
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 UTHASH_H
#define UTHASH_H
#include <stddef.h> /* ptrdiff_t */
#include <stdlib.h> /* exit() */
#include <string.h> /* memcmp,strlen */
/* These macros use decltype or the earlier __typeof GNU extension.
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
when compiling c++ source) this code uses whatever method is needed
or, for VS2008 where neither is available, uses casting workarounds. */
#if defined(_MSC_VER) /* MS compiler */
#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */
#define DECLTYPE(x) (decltype(x))
#else /* VS2008 or older (or VS2010 in C mode) */
#define NO_DECLTYPE
#define DECLTYPE(x)
#endif
#elif defined(__BORLANDC__) || defined(__LCC__) || defined(__WATCOMC__)
#define NO_DECLTYPE
#define DECLTYPE(x)
#else /* GNU, Sun and other compilers */
#define DECLTYPE(x) (__typeof(x))
#endif
#ifdef NO_DECLTYPE
#define DECLTYPE_ASSIGN(dst, src) \
do { \
char **_da_dst = (char **)(&(dst)); \
*_da_dst = (char *)(src); \
} while (0)
#else
#define DECLTYPE_ASSIGN(dst, src) \
do { \
(dst) = DECLTYPE(dst)(src); \
} while (0)
#endif
/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */
#if defined(_WIN32)
#if defined(_MSC_VER) && _MSC_VER >= 1600
#include <stdint.h>
#elif defined(__WATCOMC__)
#include <stdint.h>
#else
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
#endif
#else
#include <stdint.h>
#endif
#define UTHASH_VERSION 1.9.9
#ifndef uthash_fatal
#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
#endif
#ifndef uthash_malloc
#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
#endif
#ifndef uthash_free
#define uthash_free(ptr, sz) free(ptr) /* free fcn */
#endif
#ifndef uthash_noexpand_fyi
#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
#endif
#ifndef uthash_expand_fyi
#define uthash_expand_fyi(tbl) /* can be defined to log expands */
#endif
/* initial number of buckets */
#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */
#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */
#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */
/* calculate the element whose hash handle address is hhe */
#define ELMT_FROM_HH(tbl, hhp) ((void *)(((char *)(hhp)) - ((tbl)->hho)))
#define HASH_FIND(hh, head, keyptr, keylen, out) \
do { \
unsigned _hf_bkt, _hf_hashv; \
out = NULL; \
if (head) { \
HASH_FCN(keyptr, keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \
HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[_hf_bkt], keyptr, keylen, out); \
} \
} \
} while (0)
#ifdef HASH_BLOOM
#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN / 8) + ((HASH_BLOOM_BITLEN % 8) ? 1 : 0)
#define HASH_BLOOM_MAKE(tbl) \
do { \
(tbl)->bloom_nbits = HASH_BLOOM; \
(tbl)->bloom_bv = (uint8_t *)uthash_malloc(HASH_BLOOM_BYTELEN); \
if (!((tbl)->bloom_bv)) { \
uthash_fatal("out of memory"); \
} \
memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \
(tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \
} while (0)
#define HASH_BLOOM_FREE(tbl) \
do { \
uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \
} while (0)
#define HASH_BLOOM_BITSET(bv, idx) (bv[(idx) / 8] |= (1U << ((idx) % 8)))
#define HASH_BLOOM_BITTEST(bv, idx) (bv[(idx) / 8] & (1U << ((idx) % 8)))
#define HASH_BLOOM_ADD(tbl, hashv) \
HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
#define HASH_BLOOM_TEST(tbl, hashv) \
HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
#else
#define HASH_BLOOM_MAKE(tbl)
#define HASH_BLOOM_FREE(tbl)
#define HASH_BLOOM_ADD(tbl, hashv)
#define HASH_BLOOM_TEST(tbl, hashv) (1)
#define HASH_BLOOM_BYTELEN 0
#endif
#define HASH_MAKE_TABLE(hh, head) \
do { \
(head)->hh.tbl = (UT_hash_table *)uthash_malloc(sizeof(UT_hash_table)); \
if (!((head)->hh.tbl)) { \
uthash_fatal("out of memory"); \
} \
memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \
(head)->hh.tbl->tail = &((head)->hh); \
(head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \
(head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \
(head)->hh.tbl->hho = (char *)(&(head)->hh) - (char *)(head); \
(head)->hh.tbl->buckets = (UT_hash_bucket *)uthash_malloc(HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \
if (!(head)->hh.tbl->buckets) { \
uthash_fatal("out of memory"); \
} \
memset((head)->hh.tbl->buckets, 0, HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \
HASH_BLOOM_MAKE((head)->hh.tbl); \
(head)->hh.tbl->signature = HASH_SIGNATURE; \
} while (0)
#define HASH_ADD(hh, head, fieldname, keylen_in, add) \
HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add)
#define HASH_REPLACE(hh, head, fieldname, keylen_in, add, replaced) \
do { \
replaced = NULL; \
HASH_FIND(hh, head, &((add)->fieldname), keylen_in, replaced); \
if (replaced != NULL) { \
HASH_DELETE(hh, head, replaced); \
}; \
HASH_ADD(hh, head, fieldname, keylen_in, add); \
} while (0)
#define HASH_ADD_KEYPTR(hh, head, keyptr, keylen_in, add) \
do { \
unsigned _ha_bkt; \
(add)->hh.next = NULL; \
(add)->hh.key = (char *)(keyptr); \
(add)->hh.keylen = (unsigned)(keylen_in); \
if (!(head)) { \
head = (add); \
(head)->hh.prev = NULL; \
HASH_MAKE_TABLE(hh, head); \
} else { \
(head)->hh.tbl->tail->next = (add); \
(add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
(head)->hh.tbl->tail = &((add)->hh); \
} \
(head)->hh.tbl->num_items++; \
(add)->hh.tbl = (head)->hh.tbl; \
HASH_FCN(keyptr, keylen_in, (head)->hh.tbl->num_buckets, (add)->hh.hashv, _ha_bkt); \
HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \
HASH_BLOOM_ADD((head)->hh.tbl, (add)->hh.hashv); \
HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \
HASH_FSCK(hh, head); \
} while (0)
#define HASH_TO_BKT(hashv, num_bkts, bkt) \
do { \
bkt = ((hashv) & (num_bkts - 1)); \
} while (0)
/* delete "delptr" from the hash table.
* "the usual" patch-up process for the app-order doubly-linked-list.
* The use of _hd_hh_del below deserves special explanation.
* These used to be expressed using (delptr) but that led to a bug
* if someone used the same symbol for the head and deletee, like
* HASH_DELETE(hh,users,users);
* We want that to work, but by changing the head (users) below
* we were forfeiting our ability to further refer to the deletee (users)
* in the patch-up process. Solution: use scratch space to
* copy the deletee pointer, then the latter references are via that
* scratch pointer rather than through the repointed (users) symbol.
*/
#define HASH_DELETE(hh, head, delptr) \
do { \
unsigned _hd_bkt; \
struct UT_hash_handle *_hd_hh_del; \
if (((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL)) { \
uthash_free((head)->hh.tbl->buckets, (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
HASH_BLOOM_FREE((head)->hh.tbl); \
uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
head = NULL; \
} else { \
_hd_hh_del = &((delptr)->hh); \
if ((delptr) == ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail)) { \
(head)->hh.tbl->tail = (UT_hash_handle *)((ptrdiff_t)((delptr)->hh.prev) + (head)->hh.tbl->hho); \
} \
if ((delptr)->hh.prev) { \
((UT_hash_handle *)((ptrdiff_t)((delptr)->hh.prev) + (head)->hh.tbl->hho))->next = (delptr)->hh.next; \
} else { \
DECLTYPE_ASSIGN(head, (delptr)->hh.next); \
} \
if (_hd_hh_del->next) { \
((UT_hash_handle *)((ptrdiff_t)_hd_hh_del->next + (head)->hh.tbl->hho))->prev = _hd_hh_del->prev; \
} \
HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
HASH_DEL_IN_BKT(hh, (head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
(head)->hh.tbl->num_items--; \
} \
HASH_FSCK(hh, head); \
} while (0)
/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
#define HASH_FIND_STR(head, findstr, out) \
HASH_FIND(hh, head, findstr, strlen(findstr), out)
#define HASH_ADD_STR(head, strfield, add) \
HASH_ADD(hh, head, strfield[0], strlen(add->strfield), add)
#define HASH_REPLACE_STR(head, strfield, add, replaced) \
HASH_REPLACE(hh, head, strfield[0], strlen(add->strfield), add, replaced)
#define HASH_FIND_INT(head, findint, out) \
HASH_FIND(hh, head, findint, sizeof(int), out)
#define HASH_ADD_INT(head, intfield, add) \
HASH_ADD(hh, head, intfield, sizeof(int), add)
#define HASH_REPLACE_INT(head, intfield, add, replaced) \
HASH_REPLACE(hh, head, intfield, sizeof(int), add, replaced)
#define HASH_FIND_PTR(head, findptr, out) \
HASH_FIND(hh, head, findptr, sizeof(void *), out)
#define HASH_ADD_PTR(head, ptrfield, add) \
HASH_ADD(hh, head, ptrfield, sizeof(void *), add)
#define HASH_REPLACE_PTR(head, ptrfield, add, replaced) \
HASH_REPLACE(hh, head, ptrfield, sizeof(void *), add, replaced)
#define HASH_DEL(head, delptr) \
HASH_DELETE(hh, head, delptr)
/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
* This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
*/
#ifdef HASH_DEBUG
#define HASH_OOPS(...) \
do { \
fprintf(stderr, __VA_ARGS__); \
exit(-1); \
} while (0)
#define HASH_FSCK(hh, head) \
do { \
unsigned _bkt_i; \
unsigned _count, _bkt_count; \
char *_prev; \
struct UT_hash_handle *_thh; \
if (head) { \
_count = 0; \
for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \
_bkt_count = 0; \
_thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \
_prev = NULL; \
while (_thh) { \
if (_prev != (char *)(_thh->hh_prev)) { \
HASH_OOPS("invalid hh_prev %p, actual %p\n", _thh->hh_prev, _prev); \
} \
_bkt_count++; \
_prev = (char *)(_thh); \
_thh = _thh->hh_next; \
} \
_count += _bkt_count; \
if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \
HASH_OOPS("invalid bucket count %d, actual %d\n", (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \
} \
} \
if (_count != (head)->hh.tbl->num_items) { \
HASH_OOPS("invalid hh item count %d, actual %d\n", (head)->hh.tbl->num_items, _count); \
} \
/* traverse hh in app order; check next/prev integrity, count */ \
_count = 0; \
_prev = NULL; \
_thh = &(head)->hh; \
while (_thh) { \
_count++; \
if (_prev != (char *)(_thh->prev)) { \
HASH_OOPS("invalid prev %p, actual %p\n", _thh->prev, _prev); \
} \
_prev = (char *)ELMT_FROM_HH((head)->hh.tbl, _thh); \
_thh = (_thh->next ? (UT_hash_handle *)((char *)(_thh->next) + (head)->hh.tbl->hho) : NULL); \
} \
if (_count != (head)->hh.tbl->num_items) { \
HASH_OOPS("invalid app item count %d, actual %d\n", (head)->hh.tbl->num_items, _count); \
} \
} \
} while (0)
#else
#define HASH_FSCK(hh, head)
#endif
/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
* the descriptor to which this macro is defined for tuning the hash function.
* The app can #include <unistd.h> to get the prototype for write(2). */
#ifdef HASH_EMIT_KEYS
#define HASH_EMIT_KEY(hh, head, keyptr, fieldlen) \
do { \
unsigned _klen = fieldlen; \
write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
write(HASH_EMIT_KEYS, keyptr, fieldlen); \
} while (0)
#else
#define HASH_EMIT_KEY(hh, head, keyptr, fieldlen)
#endif
/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
#ifdef HASH_FUNCTION
#define HASH_FCN HASH_FUNCTION
#else
#define HASH_FCN HASH_JEN
#endif
/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */
#define HASH_BER(key, keylen, num_bkts, hashv, bkt) \
do { \
unsigned _hb_keylen = keylen; \
char *_hb_key = (char *)(key); \
(hashv) = 0; \
while (_hb_keylen--) { \
(hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \
} \
bkt = (hashv) & (num_bkts - 1); \
} while (0)
/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
#define HASH_SAX(key, keylen, num_bkts, hashv, bkt) \
do { \
unsigned _sx_i; \
char *_hs_key = (char *)(key); \
hashv = 0; \
for (_sx_i = 0; _sx_i < keylen; _sx_i++) \
hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
bkt = hashv & (num_bkts - 1); \
} while (0)
/* FNV-1a variation */
#define HASH_FNV(key, keylen, num_bkts, hashv, bkt) \
do { \
unsigned _fn_i; \
char *_hf_key = (char *)(key); \
hashv = 2166136261UL; \
for (_fn_i = 0; _fn_i < keylen; _fn_i++) \
hashv = hashv ^ _hf_key[_fn_i]; \
hashv = hashv * 16777619; \
bkt = hashv & (num_bkts - 1); \
} while (0)
#define HASH_OAT(key, keylen, num_bkts, hashv, bkt) \
do { \
unsigned _ho_i; \
char *_ho_key = (char *)(key); \
hashv = 0; \
for (_ho_i = 0; _ho_i < keylen; _ho_i++) { \
hashv += _ho_key[_ho_i]; \
hashv += (hashv << 10); \
hashv ^= (hashv >> 6); \
} \
hashv += (hashv << 3); \
hashv ^= (hashv >> 11); \
hashv += (hashv << 15); \
bkt = hashv & (num_bkts - 1); \
} while (0)
#define HASH_JEN_MIX(a, b, c) \
do { \
a -= b; \
a -= c; \
a ^= (c >> 13); \
b -= c; \
b -= a; \
b ^= (a << 8); \
c -= a; \
c -= b; \
c ^= (b >> 13); \
a -= b; \
a -= c; \
a ^= (c >> 12); \
b -= c; \
b -= a; \
b ^= (a << 16); \
c -= a; \
c -= b; \
c ^= (b >> 5); \
a -= b; \
a -= c; \
a ^= (c >> 3); \
b -= c; \
b -= a; \
b ^= (a << 10); \
c -= a; \
c -= b; \
c ^= (b >> 15); \
} while (0)
#define HASH_JEN(key, keylen, num_bkts, hashv, bkt) \
do { \
unsigned _hj_i, _hj_j, _hj_k; \
unsigned char *_hj_key = (unsigned char *)(key); \
hashv = 0xfeedbeef; \
_hj_i = _hj_j = 0x9e3779b9; \
_hj_k = (unsigned)(keylen); \
while (_hj_k >= 12) { \
_hj_i += (_hj_key[0] + ((unsigned)_hj_key[1] << 8) + ((unsigned)_hj_key[2] << 16) + ((unsigned)_hj_key[3] << 24)); \
_hj_j += (_hj_key[4] + ((unsigned)_hj_key[5] << 8) + ((unsigned)_hj_key[6] << 16) + ((unsigned)_hj_key[7] << 24)); \
hashv += (_hj_key[8] + ((unsigned)_hj_key[9] << 8) + ((unsigned)_hj_key[10] << 16) + ((unsigned)_hj_key[11] << 24)); \
\
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
\
_hj_key += 12; \
_hj_k -= 12; \
} \
hashv += keylen; \
switch (_hj_k) { \
case 11: \
hashv += ((unsigned)_hj_key[10] << 24); \
/* fall through */ \
case 10: \
hashv += ((unsigned)_hj_key[9] << 16); \
/* fall through */ \
case 9: \
hashv += ((unsigned)_hj_key[8] << 8); \
/* fall through */ \
case 8: \
_hj_j += ((unsigned)_hj_key[7] << 24); \
/* fall through */ \
case 7: \
_hj_j += ((unsigned)_hj_key[6] << 16); \
/* fall through */ \
case 6: \
_hj_j += ((unsigned)_hj_key[5] << 8); \
/* fall through */ \
case 5: \
_hj_j += _hj_key[4]; \
/* fall through */ \
case 4: \
_hj_i += ((unsigned)_hj_key[3] << 24); \
/* fall through */ \
case 3: \
_hj_i += ((unsigned)_hj_key[2] << 16); \
/* fall through */ \
case 2: \
_hj_i += ((unsigned)_hj_key[1] << 8); \
/* fall through */ \
case 1: \
_hj_i += _hj_key[0]; \
} \
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
bkt = hashv & (num_bkts - 1); \
} while (0)
/* The Paul Hsieh hash function */
#undef get16bits
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) || defined(_MSC_VER) || defined(__BORLANDC__) || defined(__TURBOC__)
#define get16bits(d) (*((const uint16_t *)(d)))
#endif
#if !defined(get16bits)
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) + (uint32_t)(((const uint8_t *)(d))[0]))
#endif
#define HASH_SFH(key, keylen, num_bkts, hashv, bkt) \
do { \
unsigned char *_sfh_key = (unsigned char *)(key); \
uint32_t _sfh_tmp, _sfh_len = keylen; \
\
int _sfh_rem = _sfh_len & 3; \
_sfh_len >>= 2; \
hashv = 0xcafebabe; \
\
/* Main loop */ \
for (; _sfh_len > 0; _sfh_len--) { \
hashv += get16bits(_sfh_key); \
_sfh_tmp = (uint32_t)(get16bits(_sfh_key + 2)) << 11 ^ hashv; \
hashv = (hashv << 16) ^ _sfh_tmp; \
_sfh_key += 2 * sizeof(uint16_t); \
hashv += hashv >> 11; \
} \
\
/* Handle end cases */ \
switch (_sfh_rem) { \
case 3: \
hashv += get16bits(_sfh_key); \
hashv ^= hashv << 16; \
hashv ^= (uint32_t)(_sfh_key[sizeof(uint16_t)] << 18); \
hashv += hashv >> 11; \
break; \
case 2: \
hashv += get16bits(_sfh_key); \
hashv ^= hashv << 11; \
hashv += hashv >> 17; \
break; \
case 1: \
hashv += *_sfh_key; \
hashv ^= hashv << 10; \
hashv += hashv >> 1; \
} \
\
/* Force "avalanching" of final 127 bits */ \
hashv ^= hashv << 3; \
hashv += hashv >> 5; \
hashv ^= hashv << 4; \
hashv += hashv >> 17; \
hashv ^= hashv << 25; \
hashv += hashv >> 6; \
bkt = hashv & (num_bkts - 1); \
} while (0)
#ifdef HASH_USING_NO_STRICT_ALIASING
/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
* For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
* MurmurHash uses the faster approach only on CPU's where we know it's safe.
*
* Note the preprocessor built-in defines can be emitted using:
*
* gcc -m64 -dM -E - < /dev/null (on gcc)
* cc -## a.c (where a.c is a simple test file) (Sun Studio)
*/
#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86))
#define MUR_GETBLOCK(p, i) p[i]
#else /* non intel */
#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0)
#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1)
#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2)
#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3)
#define WP(p) ((uint32_t *)((unsigned long)(p) & ~3UL))
#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
#define MUR_THREE_ONE(p) ((((*WP(p)) & 0x00ffffff) << 8) | (((*(WP(p) + 1)) & 0xff000000) >> 24))
#define MUR_TWO_TWO(p) ((((*WP(p)) & 0x0000ffff) << 16) | (((*(WP(p) + 1)) & 0xffff0000) >> 16))
#define MUR_ONE_THREE(p) ((((*WP(p)) & 0x000000ff) << 24) | (((*(WP(p) + 1)) & 0xffffff00) >> 8))
#else /* assume little endian non-intel */
#define MUR_THREE_ONE(p) ((((*WP(p)) & 0xffffff00) >> 8) | (((*(WP(p) + 1)) & 0x000000ff) << 24))
#define MUR_TWO_TWO(p) ((((*WP(p)) & 0xffff0000) >> 16) | (((*(WP(p) + 1)) & 0x0000ffff) << 16))
#define MUR_ONE_THREE(p) ((((*WP(p)) & 0xff000000) >> 24) | (((*(WP(p) + 1)) & 0x00ffffff) << 8))
#endif
#define MUR_GETBLOCK(p, i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : MUR_ONE_THREE(p))))
#endif
#define MUR_ROTL32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
#define MUR_FMIX(_h) \
do { \
_h ^= _h >> 16; \
_h *= 0x85ebca6b; \
_h ^= _h >> 13; \
_h *= 0xc2b2ae35l; \
_h ^= _h >> 16; \
} while (0)
#define HASH_MUR(key, keylen, num_bkts, hashv, bkt) \
do { \
const uint8_t *_mur_data = (const uint8_t *)(key); \
const int _mur_nblocks = (keylen) / 4; \
uint32_t _mur_h1 = 0xf88D5353; \
uint32_t _mur_c1 = 0xcc9e2d51; \
uint32_t _mur_c2 = 0x1b873593; \
uint32_t _mur_k1 = 0; \
const uint8_t *_mur_tail; \
const uint32_t *_mur_blocks = (const uint32_t *)(_mur_data + _mur_nblocks * 4); \
int _mur_i; \
for (_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \
_mur_k1 = MUR_GETBLOCK(_mur_blocks, _mur_i); \
_mur_k1 *= _mur_c1; \
_mur_k1 = MUR_ROTL32(_mur_k1, 15); \
_mur_k1 *= _mur_c2; \
\
_mur_h1 ^= _mur_k1; \
_mur_h1 = MUR_ROTL32(_mur_h1, 13); \
_mur_h1 = _mur_h1 * 5 + 0xe6546b64; \
} \
_mur_tail = (const uint8_t *)(_mur_data + _mur_nblocks * 4); \
_mur_k1 = 0; \
switch (keylen & 3) { \
case 3: \
_mur_k1 ^= _mur_tail[2] << 16; \
case 2: \
_mur_k1 ^= _mur_tail[1] << 8; \
case 1: \
_mur_k1 ^= _mur_tail[0]; \
_mur_k1 *= _mur_c1; \
_mur_k1 = MUR_ROTL32(_mur_k1, 15); \
_mur_k1 *= _mur_c2; \
_mur_h1 ^= _mur_k1; \
} \
_mur_h1 ^= (keylen); \
MUR_FMIX(_mur_h1); \
hashv = _mur_h1; \
bkt = hashv & (num_bkts - 1); \
} while (0)
#endif /* HASH_USING_NO_STRICT_ALIASING */
/* key comparison function; return 0 if keys equal */
#define HASH_KEYCMP(a, b, len) memcmp(a, b, len)
/* iterate over items in a known bucket to find desired item */
#define HASH_FIND_IN_BKT(tbl, hh, head, keyptr, keylen_in, out) \
do { \
if (head.hh_head) \
DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, head.hh_head)); \
else \
out = NULL; \
while (out) { \
if ((out)->hh.keylen == keylen_in) { \
if ((HASH_KEYCMP((out)->hh.key, keyptr, keylen_in)) == 0) \
break; \
} \
if ((out)->hh.hh_next) \
DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \
else \
out = NULL; \
} \
} while (0)
/* add an item to a bucket */
#define HASH_ADD_TO_BKT(head, addhh) \
do { \
head.count++; \
(addhh)->hh_next = head.hh_head; \
(addhh)->hh_prev = NULL; \
if (head.hh_head) { \
(head).hh_head->hh_prev = (addhh); \
} \
(head).hh_head = addhh; \
if (head.count >= ((head.expand_mult + 1) * HASH_BKT_CAPACITY_THRESH) && (addhh)->tbl->noexpand != 1) { \
HASH_EXPAND_BUCKETS((addhh)->tbl); \
} \
} while (0)
/* remove an item from a given bucket */
#define HASH_DEL_IN_BKT(hh, head, hh_del) \
(head).count--; \
if ((head).hh_head == hh_del) { \
(head).hh_head = hh_del->hh_next; \
} \
if (hh_del->hh_prev) { \
hh_del->hh_prev->hh_next = hh_del->hh_next; \
} \
if (hh_del->hh_next) { \
hh_del->hh_next->hh_prev = hh_del->hh_prev; \
}
/* Bucket expansion has the effect of doubling the number of buckets
* and redistributing the items into the new buckets. Ideally the
* items will distribute more or less evenly into the new buckets
* (the extent to which this is true is a measure of the quality of
* the hash function as it applies to the key domain).
*
* With the items distributed into more buckets, the chain length
* (item count) in each bucket is reduced. Thus by expanding buckets
* the hash keeps a bound on the chain length. This bounded chain
* length is the essence of how a hash provides constant time lookup.
*
* The calculation of tbl->ideal_chain_maxlen below deserves some
* explanation. First, keep in mind that we're calculating the ideal
* maximum chain length based on the *new* (doubled) bucket count.
* In fractions this is just n/b (n=number of items,b=new num buckets).
* Since the ideal chain length is an integer, we want to calculate
* ceil(n/b). We don't depend on floating point arithmetic in this
* hash, so to calculate ceil(n/b) with integers we could write
*
* ceil(n/b) = (n/b) + ((n%b)?1:0)
*
* and in fact a previous version of this hash did just that.
* But now we have improved things a bit by recognizing that b is
* always a power of two. We keep its base 2 log handy (call it lb),
* so now we can write this with a bit shift and logical AND:
*
* ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
*
*/
#define HASH_EXPAND_BUCKETS(tbl) \
do { \
unsigned _he_bkt; \
unsigned _he_bkt_i; \
struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
_he_new_buckets = (UT_hash_bucket *)uthash_malloc(2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
if (!_he_new_buckets) { \
uthash_fatal("out of memory"); \
} \
memset(_he_new_buckets, 0, 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
tbl->ideal_chain_maxlen = (tbl->num_items >> (tbl->log2_num_buckets + 1)) + ((tbl->num_items & ((tbl->num_buckets * 2) - 1)) ? 1 : 0); \
tbl->nonideal_items = 0; \
for (_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) { \
_he_thh = tbl->buckets[_he_bkt_i].hh_head; \
while (_he_thh) { \
_he_hh_nxt = _he_thh->hh_next; \
HASH_TO_BKT(_he_thh->hashv, tbl->num_buckets * 2, _he_bkt); \
_he_newbkt = &(_he_new_buckets[_he_bkt]); \
if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \
tbl->nonideal_items++; \
_he_newbkt->expand_mult = _he_newbkt->count / tbl->ideal_chain_maxlen; \
} \
_he_thh->hh_prev = NULL; \
_he_thh->hh_next = _he_newbkt->hh_head; \
if (_he_newbkt->hh_head) \
_he_newbkt->hh_head->hh_prev = _he_thh; \
_he_newbkt->hh_head = _he_thh; \
_he_thh = _he_hh_nxt; \
} \
} \
uthash_free(tbl->buckets, tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
tbl->num_buckets *= 2; \
tbl->log2_num_buckets++; \
tbl->buckets = _he_new_buckets; \
tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? (tbl->ineff_expands + 1) : 0; \
if (tbl->ineff_expands > 1) { \
tbl->noexpand = 1; \
uthash_noexpand_fyi(tbl); \
} \
uthash_expand_fyi(tbl); \
} while (0)
/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
/* Note that HASH_SORT assumes the hash handle name to be hh.
* HASH_SRT was added to allow the hash handle name to be passed in. */
#define HASH_SORT(head, cmpfcn) HASH_SRT(hh, head, cmpfcn)
#define HASH_SRT(hh, head, cmpfcn) \
do { \
unsigned _hs_i; \
unsigned _hs_looping, _hs_nmerges, _hs_insize, _hs_psize, _hs_qsize; \
struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
if (head) { \
_hs_insize = 1; \
_hs_looping = 1; \
_hs_list = &((head)->hh); \
while (_hs_looping) { \
_hs_p = _hs_list; \
_hs_list = NULL; \
_hs_tail = NULL; \
_hs_nmerges = 0; \
while (_hs_p) { \
_hs_nmerges++; \
_hs_q = _hs_p; \
_hs_psize = 0; \
for (_hs_i = 0; _hs_i < _hs_insize; _hs_i++) { \
_hs_psize++; \
_hs_q = (UT_hash_handle *)((_hs_q->next) ? ((void *)((char *)(_hs_q->next) + (head)->hh.tbl->hho)) : NULL); \
if (!(_hs_q)) \
break; \
} \
_hs_qsize = _hs_insize; \
while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q)) { \
if (_hs_psize == 0) { \
_hs_e = _hs_q; \
_hs_q = (UT_hash_handle *)((_hs_q->next) ? ((void *)((char *)(_hs_q->next) + (head)->hh.tbl->hho)) : NULL); \
_hs_qsize--; \
} else if ((_hs_qsize == 0) || !(_hs_q)) { \
_hs_e = _hs_p; \
if (_hs_p) { \
_hs_p = (UT_hash_handle *)((_hs_p->next) ? ((void *)((char *)(_hs_p->next) + (head)->hh.tbl->hho)) : NULL); \
} \
_hs_psize--; \
} else if ((cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)))) <= 0) { \
_hs_e = _hs_p; \
if (_hs_p) { \
_hs_p = (UT_hash_handle *)((_hs_p->next) ? ((void *)((char *)(_hs_p->next) + (head)->hh.tbl->hho)) : NULL); \
} \
_hs_psize--; \
} else { \
_hs_e = _hs_q; \
_hs_q = (UT_hash_handle *)((_hs_q->next) ? ((void *)((char *)(_hs_q->next) + (head)->hh.tbl->hho)) : NULL); \
_hs_qsize--; \
} \
if (_hs_tail) { \
_hs_tail->next = ((_hs_e) ? ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \
} else { \
_hs_list = _hs_e; \
} \
if (_hs_e) { \
_hs_e->prev = ((_hs_tail) ? ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \
} \
_hs_tail = _hs_e; \
} \
_hs_p = _hs_q; \
} \
if (_hs_tail) { \
_hs_tail->next = NULL; \
} \
if (_hs_nmerges <= 1) { \
_hs_looping = 0; \
(head)->hh.tbl->tail = _hs_tail; \
DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \
} \
_hs_insize *= 2; \
} \
HASH_FSCK(hh, head); \
} \
} while (0)
/* This function selects items from one hash into another hash.
* The end result is that the selected items have dual presence
* in both hashes. There is no copy of the items made; rather
* they are added into the new hash through a secondary hash
* hash handle that must be present in the structure. */
#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
do { \
unsigned _src_bkt, _dst_bkt; \
void *_last_elt = NULL, *_elt; \
UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh = NULL; \
ptrdiff_t _dst_hho = ((char *)(&(dst)->hh_dst) - (char *)(dst)); \
if (src) { \
for (_src_bkt = 0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \
for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; _src_hh; _src_hh = _src_hh->hh_next) { \
_elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
if (cond(_elt)) { \
_dst_hh = (UT_hash_handle *)(((char *)_elt) + _dst_hho); \
_dst_hh->key = _src_hh->key; \
_dst_hh->keylen = _src_hh->keylen; \
_dst_hh->hashv = _src_hh->hashv; \
_dst_hh->prev = _last_elt; \
_dst_hh->next = NULL; \
if (_last_elt_hh) { \
_last_elt_hh->next = _elt; \
} \
if (!dst) { \
DECLTYPE_ASSIGN(dst, _elt); \
HASH_MAKE_TABLE(hh_dst, dst); \
} else { \
_dst_hh->tbl = (dst)->hh_dst.tbl; \
} \
HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], _dst_hh); \
(dst)->hh_dst.tbl->num_items++; \
_last_elt = _elt; \
_last_elt_hh = _dst_hh; \
} \
} \
} \
} \
HASH_FSCK(hh_dst, dst); \
} while (0)
#define HASH_CLEAR(hh, head) \
do { \
if (head) { \
uthash_free((head)->hh.tbl->buckets, (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
HASH_BLOOM_FREE((head)->hh.tbl); \
uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
(head) = NULL; \
} \
} while (0)
#define HASH_OVERHEAD(hh, head) \
(size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \
((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \
(sizeof(UT_hash_table)) + \
(HASH_BLOOM_BYTELEN)))
#ifdef NO_DECLTYPE
#define HASH_ITER(hh, head, el, tmp) for ((el) = (head), (*(char **)(&(tmp))) = (char *)((head) ? (head)->hh.next : NULL); \
el; (el) = (tmp), (*(char **)(&(tmp))) = (char *)((tmp) ? (tmp)->hh.next : NULL))
#else
#define HASH_ITER(hh, head, el, tmp) for ((el) = (head), (tmp) = DECLTYPE(el)((head) ? (head)->hh.next : NULL); \
el; (el) = (tmp), (tmp) = DECLTYPE(el)((tmp) ? (tmp)->hh.next : NULL))
#endif
/* obtain a count of items in the hash */
#define HASH_COUNT(head) HASH_CNT(hh, head)
#define HASH_CNT(hh, head) ((head) ? ((head)->hh.tbl->num_items) : 0)
typedef struct UT_hash_bucket {
struct UT_hash_handle *hh_head;
unsigned count;
/* expand_mult is normally set to 0. In this situation, the max chain length
* threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
* the bucket's chain exceeds this length, bucket expansion is triggered).
* However, setting expand_mult to a non-zero value delays bucket expansion
* (that would be triggered by additions to this particular bucket)
* until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
* (The multiplier is simply expand_mult+1). The whole idea of this
* multiplier is to reduce bucket expansions, since they are expensive, in
* situations where we know that a particular bucket tends to be overused.
* It is better to let its chain length grow to a longer yet-still-bounded
* value, than to do an O(n) bucket expansion too often.
*/
unsigned expand_mult;
} UT_hash_bucket;
/* random signature used only to find hash tables in external analysis */
#define HASH_SIGNATURE 0xa0111fe1
#define HASH_BLOOM_SIGNATURE 0xb12220f2
typedef struct UT_hash_table {
UT_hash_bucket *buckets;
unsigned num_buckets, log2_num_buckets;
unsigned num_items;
struct UT_hash_handle *tail; /* tail hh in app order, for fast append */
ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
/* in an ideal situation (all buckets used equally), no bucket would have
* more than ceil(#items/#buckets) items. that's the ideal chain length. */
unsigned ideal_chain_maxlen;
/* nonideal_items is the number of items in the hash whose chain position
* exceeds the ideal chain maxlen. these items pay the penalty for an uneven
* hash distribution; reaching them in a chain traversal takes >ideal steps */
unsigned nonideal_items;
/* ineffective expands occur when a bucket doubling was performed, but
* afterward, more than half the items in the hash had nonideal chain
* positions. If this happens on two consecutive expansions we inhibit any
* further expansion, as it's not helping; this happens when the hash
* function isn't a good fit for the key domain. When expansion is inhibited
* the hash will still work, albeit no longer in constant time. */
unsigned ineff_expands, noexpand;
uint32_t signature; /* used only to find hash tables in external analysis */
#ifdef HASH_BLOOM
uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
uint8_t *bloom_bv;
char bloom_nbits;
#endif
} UT_hash_table;
typedef struct UT_hash_handle {
struct UT_hash_table *tbl;
void *prev; /* prev element in app order */
void *next; /* next element in app order */
struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
struct UT_hash_handle *hh_next; /* next hh in bucket order */
void *key; /* ptr to enclosing struct's key */
unsigned keylen; /* enclosing struct's key len */
unsigned hashv; /* result of hash-fcn(key) */
} UT_hash_handle;
#endif /* UTHASH_H */

119
third-party/libag/x86_64/include/util.h vendored Normal file
View File

@ -0,0 +1,119 @@
#ifndef UTIL_H
#define UTIL_H
#include <dirent.h>
#include <pcre.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "config.h"
#include "log.h"
#include "options.h"
FILE *out_fd;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define H_SIZE (64 * 1024)
#ifdef __clang__
#define NO_SANITIZE_ALIGNMENT __attribute__((no_sanitize("alignment")))
#else
#define NO_SANITIZE_ALIGNMENT
#endif
void *ag_malloc(size_t size);
void *ag_realloc(void *ptr, size_t size);
void *ag_calloc(size_t nelem, size_t elsize);
char *ag_strdup(const char *s);
char *ag_strndup(const char *s, size_t size);
typedef struct {
size_t start; /* Byte at which the match starts */
size_t end; /* and where it ends */
} match_t;
typedef struct {
size_t total_bytes;
size_t total_files;
size_t total_matches;
size_t total_file_matches;
struct timeval time_start;
struct timeval time_end;
} ag_stats;
ag_stats stats;
/* Union to translate between chars and words without violating strict aliasing */
typedef union {
char as_chars[sizeof(uint16_t)];
uint16_t as_word;
} word_t;
void free_strings(char **strs, const size_t strs_len);
void generate_alpha_skip(const char *find, size_t f_len, size_t skip_lookup[], const int case_sensitive);
int is_prefix(const char *s, const size_t s_len, const size_t pos, const int case_sensitive);
size_t suffix_len(const char *s, const size_t s_len, const size_t pos, const int case_sensitive);
void generate_find_skip(const char *find, const size_t f_len, size_t **skip_lookup, const int case_sensitive);
void generate_hash(const char *find, const size_t f_len, uint8_t *H, const int case_sensitive);
/* max is already defined on spec-violating compilers such as MinGW */
size_t ag_max(size_t a, size_t b);
size_t ag_min(size_t a, size_t b);
const char *boyer_moore_strnstr(const char *s, const char *find, const size_t s_len, const size_t f_len,
const size_t alpha_skip_lookup[], const size_t *find_skip_lookup, const int case_insensitive);
const char *hash_strnstr(const char *s, const char *find, const size_t s_len, const size_t f_len, uint8_t *h_table, const int case_sensitive);
size_t invert_matches(const char *buf, const size_t buf_len, match_t matches[], size_t matches_len);
void realloc_matches(match_t **matches, size_t *matches_size, size_t matches_len);
void compile_study(pcre **re, pcre_extra **re_extra, char *q, const int pcre_opts, const int study_opts);
int is_binary(const void *buf, const size_t buf_len);
int is_regex(const char *query);
int is_fnmatch(const char *filename);
int binary_search(const char *needle, char **haystack, int start, int end);
void init_wordchar_table(void);
int is_wordchar(char ch);
int is_lowercase(const char *s);
int is_directory(const char *path, const struct dirent *d);
int is_symlink(const char *path, const struct dirent *d);
int is_named_pipe(const char *path, const struct dirent *d);
void die(const char *fmt, ...);
void ag_asprintf(char **ret, const char *fmt, ...);
ssize_t buf_getline(const char **line, const char *buf, const size_t buf_len, const size_t buf_offset);
#ifndef HAVE_FGETLN
char *fgetln(FILE *fp, size_t *lenp);
#endif
#ifndef HAVE_GETLINE
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
#endif
#ifndef HAVE_REALPATH
char *realpath(const char *path, char *resolved_path);
#endif
#ifndef HAVE_STRLCPY
size_t strlcpy(char *dest, const char *src, size_t size);
#endif
#ifndef HAVE_VASPRINTF
int vasprintf(char **ret, const char *fmt, va_list args);
#endif
#endif

3
third-party/libag/x86_64/lib/libag.a vendored Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9a0d2807adb3f3e8fd26c8ebda5d6f31b30ff21634e0a50a3b659d9864063b72
size 277680

133
third-party/libpcre/x86_64/bin/pcre-config vendored Executable file
View File

@ -0,0 +1,133 @@
#!/bin/sh
prefix=/Users/hat/Projects/vimr/third-party/libpcre/x86_64
exec_prefix=${prefix}
exec_prefix_set=no
cflags="[--cflags]"
if test yes = yes ; then
libs="[--libs-cpp]"
else
libs=
fi
if test yes = yes ; then
libs="[--libs16] $libs"
fi
if test yes = yes ; then
libs="[--libs32] $libs"
fi
if test yes = yes ; then
libs="[--libs] [--libs-posix] $libs"
cflags="$cflags [--cflags-posix]"
fi
usage="Usage: pcre-config [--prefix] [--exec-prefix] [--version] $libs $cflags"
if test $# -eq 0; then
echo "${usage}" 1>&2
exit 1
fi
libR=
case `uname -s` in
*SunOS*)
libR=" -R${exec_prefix}/lib"
;;
*BSD*)
libR=" -Wl,-R${exec_prefix}/lib"
;;
esac
libS=
if test ${exec_prefix}/lib != /usr/lib ; then
libS=-L${exec_prefix}/lib
fi
while test $# -gt 0; do
case "$1" in
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) optarg= ;;
esac
case $1 in
--prefix=*)
prefix=$optarg
if test $exec_prefix_set = no ; then
exec_prefix=$optarg
fi
;;
--prefix)
echo $prefix
;;
--exec-prefix=*)
exec_prefix=$optarg
exec_prefix_set=yes
;;
--exec-prefix)
echo $exec_prefix
;;
--version)
echo 8.43
;;
--cflags)
if test ${prefix}/include != /usr/include ; then
includes=-I${prefix}/include
fi
echo $includes -DPCRE_STATIC
;;
--cflags-posix)
if test yes = yes ; then
if test ${prefix}/include != /usr/include ; then
includes=-I${prefix}/include
fi
echo $includes -DPCRE_STATIC
else
echo "${usage}" 1>&2
fi
;;
--libs-posix)
if test yes = yes ; then
echo $libS$libR -lpcreposix -lpcre
else
echo "${usage}" 1>&2
fi
;;
--libs)
if test yes = yes ; then
echo $libS$libR -lpcre
else
echo "${usage}" 1>&2
fi
;;
--libs16)
if test yes = yes ; then
echo $libS$libR -lpcre16
else
echo "${usage}" 1>&2
fi
;;
--libs32)
if test yes = yes ; then
echo $libS$libR -lpcre32
else
echo "${usage}" 1>&2
fi
;;
--libs-cpp)
if test yes = yes ; then
echo $libS$libR -lpcrecpp -lpcre
else
echo "${usage}" 1>&2
fi
;;
*)
echo "${usage}" 1>&2
exit 1
;;
esac
shift
done

BIN
third-party/libpcre/x86_64/bin/pcregrep vendored Executable file

Binary file not shown.

BIN
third-party/libpcre/x86_64/bin/pcretest vendored Executable file

Binary file not shown.

View File

@ -0,0 +1,677 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/* This is the public header file for the PCRE library, to be #included by
applications that call the PCRE functions.
Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
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.
* Neither the name of the University of Cambridge nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
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 _PCRE_H
#define _PCRE_H
/* The current PCRE version information. */
#define PCRE_MAJOR 8
#define PCRE_MINOR 43
#define PCRE_PRERELEASE
#define PCRE_DATE 2019-02-23
/* When an application links to a PCRE DLL in Windows, the symbols that are
imported have to be identified as such. When building PCRE, the appropriate
export setting is defined in pcre_internal.h, which includes this file. So we
don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */
#if defined(_WIN32) && !defined(PCRE_STATIC)
# ifndef PCRE_EXP_DECL
# define PCRE_EXP_DECL extern __declspec(dllimport)
# endif
# ifdef __cplusplus
# ifndef PCRECPP_EXP_DECL
# define PCRECPP_EXP_DECL extern __declspec(dllimport)
# endif
# ifndef PCRECPP_EXP_DEFN
# define PCRECPP_EXP_DEFN __declspec(dllimport)
# endif
# endif
#endif
/* By default, we use the standard "extern" declarations. */
#ifndef PCRE_EXP_DECL
# ifdef __cplusplus
# define PCRE_EXP_DECL extern "C"
# else
# define PCRE_EXP_DECL extern
# endif
#endif
#ifdef __cplusplus
# ifndef PCRECPP_EXP_DECL
# define PCRECPP_EXP_DECL extern
# endif
# ifndef PCRECPP_EXP_DEFN
# define PCRECPP_EXP_DEFN
# endif
#endif
/* Have to include stdlib.h in order to ensure that size_t is defined;
it is needed here for malloc. */
#include <stdlib.h>
/* Allow for C++ users */
#ifdef __cplusplus
extern "C" {
#endif
/* Public options. Some are compile-time only, some are run-time only, and some
are both. Most of the compile-time options are saved with the compiled regex so
that they can be inspected during studying (and therefore JIT compiling). Note
that pcre_study() has its own set of options. Originally, all the options
defined here used distinct bits. However, almost all the bits in a 32-bit word
are now used, so in order to conserve them, option bits that were previously
only recognized at matching time (i.e. by pcre_exec() or pcre_dfa_exec()) may
also be used for compile-time options that affect only compiling and are not
relevant for studying or JIT compiling.
Some options for pcre_compile() change its behaviour but do not affect the
behaviour of the execution functions. Other options are passed through to the
execution functions and affect their behaviour, with or without affecting the
behaviour of pcre_compile().
Options that can be passed to pcre_compile() are tagged Cx below, with these
variants:
C1 Affects compile only
C2 Does not affect compile; affects exec, dfa_exec
C3 Affects compile, exec, dfa_exec
C4 Affects compile, exec, dfa_exec, study
C5 Affects compile, exec, study
Options that can be set for pcre_exec() and/or pcre_dfa_exec() are flagged with
E and D, respectively. They take precedence over C3, C4, and C5 settings passed
from pcre_compile(). Those that are compatible with JIT execution are flagged
with J. */
#define PCRE_CASELESS 0x00000001 /* C1 */
#define PCRE_MULTILINE 0x00000002 /* C1 */
#define PCRE_DOTALL 0x00000004 /* C1 */
#define PCRE_EXTENDED 0x00000008 /* C1 */
#define PCRE_ANCHORED 0x00000010 /* C4 E D */
#define PCRE_DOLLAR_ENDONLY 0x00000020 /* C2 */
#define PCRE_EXTRA 0x00000040 /* C1 */
#define PCRE_NOTBOL 0x00000080 /* E D J */
#define PCRE_NOTEOL 0x00000100 /* E D J */
#define PCRE_UNGREEDY 0x00000200 /* C1 */
#define PCRE_NOTEMPTY 0x00000400 /* E D J */
#define PCRE_UTF8 0x00000800 /* C4 ) */
#define PCRE_UTF16 0x00000800 /* C4 ) Synonyms */
#define PCRE_UTF32 0x00000800 /* C4 ) */
#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* C1 */
#define PCRE_NO_UTF8_CHECK 0x00002000 /* C1 E D J ) */
#define PCRE_NO_UTF16_CHECK 0x00002000 /* C1 E D J ) Synonyms */
#define PCRE_NO_UTF32_CHECK 0x00002000 /* C1 E D J ) */
#define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */
#define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */
#define PCRE_PARTIAL 0x00008000 /* E D J ) */
/* This pair use the same bit. */
#define PCRE_NEVER_UTF 0x00010000 /* C1 ) Overlaid */
#define PCRE_DFA_SHORTEST 0x00010000 /* D ) Overlaid */
/* This pair use the same bit. */
#define PCRE_NO_AUTO_POSSESS 0x00020000 /* C1 ) Overlaid */
#define PCRE_DFA_RESTART 0x00020000 /* D ) Overlaid */
#define PCRE_FIRSTLINE 0x00040000 /* C3 */
#define PCRE_DUPNAMES 0x00080000 /* C1 */
#define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */
#define PCRE_NEWLINE_LF 0x00200000 /* C3 E D */
#define PCRE_NEWLINE_CRLF 0x00300000 /* C3 E D */
#define PCRE_NEWLINE_ANY 0x00400000 /* C3 E D */
#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* C3 E D */
#define PCRE_BSR_ANYCRLF 0x00800000 /* C3 E D */
#define PCRE_BSR_UNICODE 0x01000000 /* C3 E D */
#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* C5 */
#define PCRE_NO_START_OPTIMIZE 0x04000000 /* C2 E D ) Synonyms */
#define PCRE_NO_START_OPTIMISE 0x04000000 /* C2 E D ) */
#define PCRE_PARTIAL_HARD 0x08000000 /* E D J */
#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* E D J */
#define PCRE_UCP 0x20000000 /* C3 */
/* Exec-time and get/set-time error codes */
#define PCRE_ERROR_NOMATCH (-1)
#define PCRE_ERROR_NULL (-2)
#define PCRE_ERROR_BADOPTION (-3)
#define PCRE_ERROR_BADMAGIC (-4)
#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
#define PCRE_ERROR_NOMEMORY (-6)
#define PCRE_ERROR_NOSUBSTRING (-7)
#define PCRE_ERROR_MATCHLIMIT (-8)
#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16/32 */
#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16/32 */
#define PCRE_ERROR_BADUTF32 (-10) /* Same for 8/16/32 */
#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */
#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */
#define PCRE_ERROR_PARTIAL (-12)
#define PCRE_ERROR_BADPARTIAL (-13)
#define PCRE_ERROR_INTERNAL (-14)
#define PCRE_ERROR_BADCOUNT (-15)
#define PCRE_ERROR_DFA_UITEM (-16)
#define PCRE_ERROR_DFA_UCOND (-17)
#define PCRE_ERROR_DFA_UMLIMIT (-18)
#define PCRE_ERROR_DFA_WSSIZE (-19)
#define PCRE_ERROR_DFA_RECURSE (-20)
#define PCRE_ERROR_RECURSIONLIMIT (-21)
#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
#define PCRE_ERROR_BADNEWLINE (-23)
#define PCRE_ERROR_BADOFFSET (-24)
#define PCRE_ERROR_SHORTUTF8 (-25)
#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */
#define PCRE_ERROR_RECURSELOOP (-26)
#define PCRE_ERROR_JIT_STACKLIMIT (-27)
#define PCRE_ERROR_BADMODE (-28)
#define PCRE_ERROR_BADENDIANNESS (-29)
#define PCRE_ERROR_DFA_BADRESTART (-30)
#define PCRE_ERROR_JIT_BADOPTION (-31)
#define PCRE_ERROR_BADLENGTH (-32)
#define PCRE_ERROR_UNSET (-33)
/* Specific error codes for UTF-8 validity checks */
#define PCRE_UTF8_ERR0 0
#define PCRE_UTF8_ERR1 1
#define PCRE_UTF8_ERR2 2
#define PCRE_UTF8_ERR3 3
#define PCRE_UTF8_ERR4 4
#define PCRE_UTF8_ERR5 5
#define PCRE_UTF8_ERR6 6
#define PCRE_UTF8_ERR7 7
#define PCRE_UTF8_ERR8 8
#define PCRE_UTF8_ERR9 9
#define PCRE_UTF8_ERR10 10
#define PCRE_UTF8_ERR11 11
#define PCRE_UTF8_ERR12 12
#define PCRE_UTF8_ERR13 13
#define PCRE_UTF8_ERR14 14
#define PCRE_UTF8_ERR15 15
#define PCRE_UTF8_ERR16 16
#define PCRE_UTF8_ERR17 17
#define PCRE_UTF8_ERR18 18
#define PCRE_UTF8_ERR19 19
#define PCRE_UTF8_ERR20 20
#define PCRE_UTF8_ERR21 21
#define PCRE_UTF8_ERR22 22 /* Unused (was non-character) */
/* Specific error codes for UTF-16 validity checks */
#define PCRE_UTF16_ERR0 0
#define PCRE_UTF16_ERR1 1
#define PCRE_UTF16_ERR2 2
#define PCRE_UTF16_ERR3 3
#define PCRE_UTF16_ERR4 4 /* Unused (was non-character) */
/* Specific error codes for UTF-32 validity checks */
#define PCRE_UTF32_ERR0 0
#define PCRE_UTF32_ERR1 1
#define PCRE_UTF32_ERR2 2 /* Unused (was non-character) */
#define PCRE_UTF32_ERR3 3
/* Request types for pcre_fullinfo() */
#define PCRE_INFO_OPTIONS 0
#define PCRE_INFO_SIZE 1
#define PCRE_INFO_CAPTURECOUNT 2
#define PCRE_INFO_BACKREFMAX 3
#define PCRE_INFO_FIRSTBYTE 4
#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
#define PCRE_INFO_FIRSTTABLE 5
#define PCRE_INFO_LASTLITERAL 6
#define PCRE_INFO_NAMEENTRYSIZE 7
#define PCRE_INFO_NAMECOUNT 8
#define PCRE_INFO_NAMETABLE 9
#define PCRE_INFO_STUDYSIZE 10
#define PCRE_INFO_DEFAULT_TABLES 11
#define PCRE_INFO_OKPARTIAL 12
#define PCRE_INFO_JCHANGED 13
#define PCRE_INFO_HASCRORLF 14
#define PCRE_INFO_MINLENGTH 15
#define PCRE_INFO_JIT 16
#define PCRE_INFO_JITSIZE 17
#define PCRE_INFO_MAXLOOKBEHIND 18
#define PCRE_INFO_FIRSTCHARACTER 19
#define PCRE_INFO_FIRSTCHARACTERFLAGS 20
#define PCRE_INFO_REQUIREDCHAR 21
#define PCRE_INFO_REQUIREDCHARFLAGS 22
#define PCRE_INFO_MATCHLIMIT 23
#define PCRE_INFO_RECURSIONLIMIT 24
#define PCRE_INFO_MATCH_EMPTY 25
/* Request types for pcre_config(). Do not re-arrange, in order to remain
compatible. */
#define PCRE_CONFIG_UTF8 0
#define PCRE_CONFIG_NEWLINE 1
#define PCRE_CONFIG_LINK_SIZE 2
#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
#define PCRE_CONFIG_MATCH_LIMIT 4
#define PCRE_CONFIG_STACKRECURSE 5
#define PCRE_CONFIG_UNICODE_PROPERTIES 6
#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
#define PCRE_CONFIG_BSR 8
#define PCRE_CONFIG_JIT 9
#define PCRE_CONFIG_UTF16 10
#define PCRE_CONFIG_JITTARGET 11
#define PCRE_CONFIG_UTF32 12
#define PCRE_CONFIG_PARENS_LIMIT 13
/* Request types for pcre_study(). Do not re-arrange, in order to remain
compatible. */
#define PCRE_STUDY_JIT_COMPILE 0x0001
#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002
#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004
#define PCRE_STUDY_EXTRA_NEEDED 0x0008
/* Bit flags for the pcre[16|32]_extra structure. Do not re-arrange or redefine
these bits, just add new ones on the end, in order to remain compatible. */
#define PCRE_EXTRA_STUDY_DATA 0x0001
#define PCRE_EXTRA_MATCH_LIMIT 0x0002
#define PCRE_EXTRA_CALLOUT_DATA 0x0004
#define PCRE_EXTRA_TABLES 0x0008
#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
#define PCRE_EXTRA_MARK 0x0020
#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040
/* Types */
struct real_pcre8_or_16; /* declaration; the definition is private */
typedef struct real_pcre8_or_16 pcre;
struct real_pcre8_or_16; /* declaration; the definition is private */
typedef struct real_pcre8_or_16 pcre16;
struct real_pcre32; /* declaration; the definition is private */
typedef struct real_pcre32 pcre32;
struct real_pcre_jit_stack; /* declaration; the definition is private */
typedef struct real_pcre_jit_stack pcre_jit_stack;
struct real_pcre16_jit_stack; /* declaration; the definition is private */
typedef struct real_pcre16_jit_stack pcre16_jit_stack;
struct real_pcre32_jit_stack; /* declaration; the definition is private */
typedef struct real_pcre32_jit_stack pcre32_jit_stack;
/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain
a 16 bit wide signed data type. Otherwise it can be a dummy data type since
pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */
#ifndef PCRE_UCHAR16
#define PCRE_UCHAR16 unsigned short
#endif
#ifndef PCRE_SPTR16
#define PCRE_SPTR16 const PCRE_UCHAR16 *
#endif
/* If PCRE is compiled with 32 bit character support, PCRE_UCHAR32 must contain
a 32 bit wide signed data type. Otherwise it can be a dummy data type since
pcre32 functions are not implemented. There is a check for this in pcre_internal.h. */
#ifndef PCRE_UCHAR32
#define PCRE_UCHAR32 unsigned int
#endif
#ifndef PCRE_SPTR32
#define PCRE_SPTR32 const PCRE_UCHAR32 *
#endif
/* When PCRE is compiled as a C++ library, the subject pointer type can be
replaced with a custom type. For conventional use, the public interface is a
const char *. */
#ifndef PCRE_SPTR
#define PCRE_SPTR const char *
#endif
/* The structure for passing additional data to pcre_exec(). This is defined in
such as way as to be extensible. Always add new fields at the end, in order to
remain compatible. */
typedef struct pcre_extra {
unsigned long int flags; /* Bits for which fields are set */
void *study_data; /* Opaque data from pcre_study() */
unsigned long int match_limit; /* Maximum number of calls to match() */
void *callout_data; /* Data passed back in callouts */
const unsigned char *tables; /* Pointer to character tables */
unsigned long int match_limit_recursion; /* Max recursive calls to match() */
unsigned char **mark; /* For passing back a mark pointer */
void *executable_jit; /* Contains a pointer to a compiled jit code */
} pcre_extra;
/* Same structure as above, but with 16 bit char pointers. */
typedef struct pcre16_extra {
unsigned long int flags; /* Bits for which fields are set */
void *study_data; /* Opaque data from pcre_study() */
unsigned long int match_limit; /* Maximum number of calls to match() */
void *callout_data; /* Data passed back in callouts */
const unsigned char *tables; /* Pointer to character tables */
unsigned long int match_limit_recursion; /* Max recursive calls to match() */
PCRE_UCHAR16 **mark; /* For passing back a mark pointer */
void *executable_jit; /* Contains a pointer to a compiled jit code */
} pcre16_extra;
/* Same structure as above, but with 32 bit char pointers. */
typedef struct pcre32_extra {
unsigned long int flags; /* Bits for which fields are set */
void *study_data; /* Opaque data from pcre_study() */
unsigned long int match_limit; /* Maximum number of calls to match() */
void *callout_data; /* Data passed back in callouts */
const unsigned char *tables; /* Pointer to character tables */
unsigned long int match_limit_recursion; /* Max recursive calls to match() */
PCRE_UCHAR32 **mark; /* For passing back a mark pointer */
void *executable_jit; /* Contains a pointer to a compiled jit code */
} pcre32_extra;
/* The structure for passing out data via the pcre_callout_function. We use a
structure so that new fields can be added on the end in future versions,
without changing the API of the function, thereby allowing old clients to work
without modification. */
typedef struct pcre_callout_block {
int version; /* Identifies version of block */
/* ------------------------ Version 0 ------------------------------- */
int callout_number; /* Number compiled into pattern */
int *offset_vector; /* The offset vector */
PCRE_SPTR subject; /* The subject being matched */
int subject_length; /* The length of the subject */
int start_match; /* Offset to start of this match attempt */
int current_position; /* Where we currently are in the subject */
int capture_top; /* Max current capture */
int capture_last; /* Most recently closed capture */
void *callout_data; /* Data passed in with the call */
/* ------------------- Added for Version 1 -------------------------- */
int pattern_position; /* Offset to next item in the pattern */
int next_item_length; /* Length of next item in the pattern */
/* ------------------- Added for Version 2 -------------------------- */
const unsigned char *mark; /* Pointer to current mark or NULL */
/* ------------------------------------------------------------------ */
} pcre_callout_block;
/* Same structure as above, but with 16 bit char pointers. */
typedef struct pcre16_callout_block {
int version; /* Identifies version of block */
/* ------------------------ Version 0 ------------------------------- */
int callout_number; /* Number compiled into pattern */
int *offset_vector; /* The offset vector */
PCRE_SPTR16 subject; /* The subject being matched */
int subject_length; /* The length of the subject */
int start_match; /* Offset to start of this match attempt */
int current_position; /* Where we currently are in the subject */
int capture_top; /* Max current capture */
int capture_last; /* Most recently closed capture */
void *callout_data; /* Data passed in with the call */
/* ------------------- Added for Version 1 -------------------------- */
int pattern_position; /* Offset to next item in the pattern */
int next_item_length; /* Length of next item in the pattern */
/* ------------------- Added for Version 2 -------------------------- */
const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */
/* ------------------------------------------------------------------ */
} pcre16_callout_block;
/* Same structure as above, but with 32 bit char pointers. */
typedef struct pcre32_callout_block {
int version; /* Identifies version of block */
/* ------------------------ Version 0 ------------------------------- */
int callout_number; /* Number compiled into pattern */
int *offset_vector; /* The offset vector */
PCRE_SPTR32 subject; /* The subject being matched */
int subject_length; /* The length of the subject */
int start_match; /* Offset to start of this match attempt */
int current_position; /* Where we currently are in the subject */
int capture_top; /* Max current capture */
int capture_last; /* Most recently closed capture */
void *callout_data; /* Data passed in with the call */
/* ------------------- Added for Version 1 -------------------------- */
int pattern_position; /* Offset to next item in the pattern */
int next_item_length; /* Length of next item in the pattern */
/* ------------------- Added for Version 2 -------------------------- */
const PCRE_UCHAR32 *mark; /* Pointer to current mark or NULL */
/* ------------------------------------------------------------------ */
} pcre32_callout_block;
/* Indirection for store get and free functions. These can be set to
alternative malloc/free functions if required. Special ones are used in the
non-recursive case for "frames". There is also an optional callout function
that is triggered by the (?) regex item. For Virtual Pascal, these definitions
have to take another form. */
#ifndef VPCOMPAT
PCRE_EXP_DECL void *(*pcre_malloc)(size_t);
PCRE_EXP_DECL void (*pcre_free)(void *);
PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
PCRE_EXP_DECL void (*pcre_stack_free)(void *);
PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
PCRE_EXP_DECL int (*pcre_stack_guard)(void);
PCRE_EXP_DECL void *(*pcre16_malloc)(size_t);
PCRE_EXP_DECL void (*pcre16_free)(void *);
PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
PCRE_EXP_DECL void (*pcre16_stack_free)(void *);
PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *);
PCRE_EXP_DECL int (*pcre16_stack_guard)(void);
PCRE_EXP_DECL void *(*pcre32_malloc)(size_t);
PCRE_EXP_DECL void (*pcre32_free)(void *);
PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t);
PCRE_EXP_DECL void (*pcre32_stack_free)(void *);
PCRE_EXP_DECL int (*pcre32_callout)(pcre32_callout_block *);
PCRE_EXP_DECL int (*pcre32_stack_guard)(void);
#else /* VPCOMPAT */
PCRE_EXP_DECL void *pcre_malloc(size_t);
PCRE_EXP_DECL void pcre_free(void *);
PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
PCRE_EXP_DECL void pcre_stack_free(void *);
PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
PCRE_EXP_DECL int pcre_stack_guard(void);
PCRE_EXP_DECL void *pcre16_malloc(size_t);
PCRE_EXP_DECL void pcre16_free(void *);
PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
PCRE_EXP_DECL void pcre16_stack_free(void *);
PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *);
PCRE_EXP_DECL int pcre16_stack_guard(void);
PCRE_EXP_DECL void *pcre32_malloc(size_t);
PCRE_EXP_DECL void pcre32_free(void *);
PCRE_EXP_DECL void *pcre32_stack_malloc(size_t);
PCRE_EXP_DECL void pcre32_stack_free(void *);
PCRE_EXP_DECL int pcre32_callout(pcre32_callout_block *);
PCRE_EXP_DECL int pcre32_stack_guard(void);
#endif /* VPCOMPAT */
/* User defined callback which provides a stack just before the match starts. */
typedef pcre_jit_stack *(*pcre_jit_callback)(void *);
typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *);
typedef pcre32_jit_stack *(*pcre32_jit_callback)(void *);
/* Exported PCRE functions */
PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
const unsigned char *);
PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *,
const unsigned char *);
PCRE_EXP_DECL pcre32 *pcre32_compile(PCRE_SPTR32, int, const char **, int *,
const unsigned char *);
PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
int *, const unsigned char *);
PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **,
int *, const unsigned char *);
PCRE_EXP_DECL pcre32 *pcre32_compile2(PCRE_SPTR32, int, int *, const char **,
int *, const unsigned char *);
PCRE_EXP_DECL int pcre_config(int, void *);
PCRE_EXP_DECL int pcre16_config(int, void *);
PCRE_EXP_DECL int pcre32_config(int, void *);
PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
int *, int, const char *, char *, int);
PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16,
int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int);
PCRE_EXP_DECL int pcre32_copy_named_substring(const pcre32 *, PCRE_SPTR32,
int *, int, PCRE_SPTR32, PCRE_UCHAR32 *, int);
PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int,
char *, int);
PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int,
PCRE_UCHAR16 *, int);
PCRE_EXP_DECL int pcre32_copy_substring(PCRE_SPTR32, int *, int, int,
PCRE_UCHAR32 *, int);
PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
const char *, int, int, int, int *, int , int *, int);
PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *,
PCRE_SPTR16, int, int, int, int *, int , int *, int);
PCRE_EXP_DECL int pcre32_dfa_exec(const pcre32 *, const pcre32_extra *,
PCRE_SPTR32, int, int, int, int *, int , int *, int);
PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
int, int, int, int *, int);
PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *,
PCRE_SPTR16, int, int, int, int *, int);
PCRE_EXP_DECL int pcre32_exec(const pcre32 *, const pcre32_extra *,
PCRE_SPTR32, int, int, int, int *, int);
PCRE_EXP_DECL int pcre_jit_exec(const pcre *, const pcre_extra *,
PCRE_SPTR, int, int, int, int *, int,
pcre_jit_stack *);
PCRE_EXP_DECL int pcre16_jit_exec(const pcre16 *, const pcre16_extra *,
PCRE_SPTR16, int, int, int, int *, int,
pcre16_jit_stack *);
PCRE_EXP_DECL int pcre32_jit_exec(const pcre32 *, const pcre32_extra *,
PCRE_SPTR32, int, int, int, int *, int,
pcre32_jit_stack *);
PCRE_EXP_DECL void pcre_free_substring(const char *);
PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16);
PCRE_EXP_DECL void pcre32_free_substring(PCRE_SPTR32);
PCRE_EXP_DECL void pcre_free_substring_list(const char **);
PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *);
PCRE_EXP_DECL void pcre32_free_substring_list(PCRE_SPTR32 *);
PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
void *);
PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int,
void *);
PCRE_EXP_DECL int pcre32_fullinfo(const pcre32 *, const pcre32_extra *, int,
void *);
PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
int *, int, const char *, const char **);
PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16,
int *, int, PCRE_SPTR16, PCRE_SPTR16 *);
PCRE_EXP_DECL int pcre32_get_named_substring(const pcre32 *, PCRE_SPTR32,
int *, int, PCRE_SPTR32, PCRE_SPTR32 *);
PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16);
PCRE_EXP_DECL int pcre32_get_stringnumber(const pcre32 *, PCRE_SPTR32);
PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
char **, char **);
PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16,
PCRE_UCHAR16 **, PCRE_UCHAR16 **);
PCRE_EXP_DECL int pcre32_get_stringtable_entries(const pcre32 *, PCRE_SPTR32,
PCRE_UCHAR32 **, PCRE_UCHAR32 **);
PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
const char **);
PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int,
PCRE_SPTR16 *);
PCRE_EXP_DECL int pcre32_get_substring(PCRE_SPTR32, int *, int, int,
PCRE_SPTR32 *);
PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
const char ***);
PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int,
PCRE_SPTR16 **);
PCRE_EXP_DECL int pcre32_get_substring_list(PCRE_SPTR32, int *, int,
PCRE_SPTR32 **);
PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
PCRE_EXP_DECL const unsigned char *pcre16_maketables(void);
PCRE_EXP_DECL const unsigned char *pcre32_maketables(void);
PCRE_EXP_DECL int pcre_refcount(pcre *, int);
PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int);
PCRE_EXP_DECL int pcre32_refcount(pcre32 *, int);
PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **);
PCRE_EXP_DECL pcre32_extra *pcre32_study(const pcre32 *, int, const char **);
PCRE_EXP_DECL void pcre_free_study(pcre_extra *);
PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *);
PCRE_EXP_DECL void pcre32_free_study(pcre32_extra *);
PCRE_EXP_DECL const char *pcre_version(void);
PCRE_EXP_DECL const char *pcre16_version(void);
PCRE_EXP_DECL const char *pcre32_version(void);
/* Utility functions for byte order swaps. */
PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *,
const unsigned char *);
PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
const unsigned char *);
PCRE_EXP_DECL int pcre32_pattern_to_host_byte_order(pcre32 *, pcre32_extra *,
const unsigned char *);
PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
PCRE_SPTR16, int, int *, int);
PCRE_EXP_DECL int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *,
PCRE_SPTR32, int, int *, int);
/* JIT compiler related functions. */
PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int);
PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int);
PCRE_EXP_DECL pcre32_jit_stack *pcre32_jit_stack_alloc(int, int);
PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *);
PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *);
PCRE_EXP_DECL void pcre32_jit_stack_free(pcre32_jit_stack *);
PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *,
pcre_jit_callback, void *);
PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
pcre16_jit_callback, void *);
PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *,
pcre32_jit_callback, void *);
PCRE_EXP_DECL void pcre_jit_free_unused_memory(void);
PCRE_EXP_DECL void pcre16_jit_free_unused_memory(void);
PCRE_EXP_DECL void pcre32_jit_free_unused_memory(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* End of pcre.h */

View File

@ -0,0 +1,172 @@
// Copyright (c) 2005, Google Inc.
// 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.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// 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.
//
// Author: Sanjay Ghemawat
//
// Regular-expression based scanner for parsing an input stream.
//
// Example 1: parse a sequence of "var = number" entries from input:
//
// Scanner scanner(input);
// string var;
// int number;
// scanner.SetSkipExpression("\\s+"); // Skip any white space we encounter
// while (scanner.Consume("(\\w+) = (\\d+)", &var, &number)) {
// ...;
// }
#ifndef _PCRE_SCANNER_H
#define _PCRE_SCANNER_H
#include <assert.h>
#include <string>
#include <vector>
#include <pcrecpp.h>
#include <pcre_stringpiece.h>
namespace pcrecpp {
class PCRECPP_EXP_DEFN Scanner {
public:
Scanner();
explicit Scanner(const std::string& input);
~Scanner();
// Return current line number. The returned line-number is
// one-based. I.e. it returns 1 + the number of consumed newlines.
//
// Note: this method may be slow. It may take time proportional to
// the size of the input.
int LineNumber() const;
// Return the byte-offset that the scanner is looking in the
// input data;
int Offset() const;
// Return true iff the start of the remaining input matches "re"
bool LookingAt(const RE& re) const;
// Return true iff all of the following are true
// a. the start of the remaining input matches "re",
// b. if any arguments are supplied, matched sub-patterns can be
// parsed and stored into the arguments.
// If it returns true, it skips over the matched input and any
// following input that matches the "skip" regular expression.
bool Consume(const RE& re,
const Arg& arg0 = RE::no_arg,
const Arg& arg1 = RE::no_arg,
const Arg& arg2 = RE::no_arg
// TODO: Allow more arguments?
);
// Set the "skip" regular expression. If after consuming some data,
// a prefix of the input matches this RE, it is automatically
// skipped. For example, a programming language scanner would use
// a skip RE that matches white space and comments.
//
// scanner.SetSkipExpression("\\s+|//.*|/[*](.|\n)*?[*]/");
//
// Skipping repeats as long as it succeeds. We used to let people do
// this by writing "(...)*" in the regular expression, but that added
// up to lots of recursive calls within the pcre library, so now we
// control repetition explicitly via the function call API.
//
// You can pass NULL for "re" if you do not want any data to be skipped.
void Skip(const char* re); // DEPRECATED; does *not* repeat
void SetSkipExpression(const char* re);
// Temporarily pause "skip"ing. This
// Skip("Foo"); code ; DisableSkip(); code; EnableSkip()
// is similar to
// Skip("Foo"); code ; Skip(NULL); code ; Skip("Foo");
// but avoids creating/deleting new RE objects.
void DisableSkip();
// Reenable previously paused skipping. Any prefix of the input
// that matches the skip pattern is immediately dropped.
void EnableSkip();
/***** Special wrappers around SetSkip() for some common idioms *****/
// Arranges to skip whitespace, C comments, C++ comments.
// The overall RE is a disjunction of the following REs:
// \\s whitespace
// //.*\n C++ comment
// /[*](.|\n)*?[*]/ C comment (x*? means minimal repetitions of x)
// We get repetition via the semantics of SetSkipExpression, not by using *
void SkipCXXComments() {
SetSkipExpression("\\s|//.*\n|/[*](?:\n|.)*?[*]/");
}
void set_save_comments(bool comments) {
save_comments_ = comments;
}
bool save_comments() {
return save_comments_;
}
// Append to vector ranges the comments found in the
// byte range [start,end] (inclusive) of the input data.
// Only comments that were extracted entirely within that
// range are returned: no range splitting of atomically-extracted
// comments is performed.
void GetComments(int start, int end, std::vector<StringPiece> *ranges);
// Append to vector ranges the comments added
// since the last time this was called. This
// functionality is provided for efficiency when
// interleaving scanning with parsing.
void GetNextComments(std::vector<StringPiece> *ranges);
private:
std::string data_; // All the input data
StringPiece input_; // Unprocessed input
RE* skip_; // If non-NULL, RE for skipping input
bool should_skip_; // If true, use skip_
bool skip_repeat_; // If true, repeat skip_ as long as it works
bool save_comments_; // If true, aggregate the skip expression
// the skipped comments
// TODO: later consider requiring that the StringPieces be added
// in order by their start position
std::vector<StringPiece> *comments_;
// the offset into comments_ that has been returned by GetNextComments
int comments_offset_;
// helper function to consume *skip_ and honour
// save_comments_
void ConsumeSkip();
};
} // namespace pcrecpp
#endif /* _PCRE_SCANNER_H */

View File

@ -0,0 +1,180 @@
// Copyright (c) 2005, Google Inc.
// 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.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// 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.
//
// Author: Sanjay Ghemawat
//
// A string like object that points into another piece of memory.
// Useful for providing an interface that allows clients to easily
// pass in either a "const char*" or a "string".
//
// Arghh! I wish C++ literals were automatically of type "string".
#ifndef _PCRE_STRINGPIECE_H
#define _PCRE_STRINGPIECE_H
#include <cstring>
#include <string>
#include <iosfwd> // for ostream forward-declaration
#if 0
#define HAVE_TYPE_TRAITS
#include <type_traits.h>
#elif 0
#define HAVE_TYPE_TRAITS
#include <bits/type_traits.h>
#endif
#include <pcre.h>
namespace pcrecpp {
using std::memcmp;
using std::strlen;
using std::string;
class PCRECPP_EXP_DEFN StringPiece {
private:
const char* ptr_;
int length_;
public:
// We provide non-explicit singleton constructors so users can pass
// in a "const char*" or a "string" wherever a "StringPiece" is
// expected.
StringPiece()
: ptr_(NULL), length_(0) { }
StringPiece(const char* str)
: ptr_(str), length_(static_cast<int>(strlen(ptr_))) { }
StringPiece(const unsigned char* str)
: ptr_(reinterpret_cast<const char*>(str)),
length_(static_cast<int>(strlen(ptr_))) { }
StringPiece(const string& str)
: ptr_(str.data()), length_(static_cast<int>(str.size())) { }
StringPiece(const char* offset, int len)
: ptr_(offset), length_(len) { }
// data() may return a pointer to a buffer with embedded NULs, and the
// returned buffer may or may not be null terminated. Therefore it is
// typically a mistake to pass data() to a routine that expects a NUL
// terminated string. Use "as_string().c_str()" if you really need to do
// this. Or better yet, change your routine so it does not rely on NUL
// termination.
const char* data() const { return ptr_; }
int size() const { return length_; }
bool empty() const { return length_ == 0; }
void clear() { ptr_ = NULL; length_ = 0; }
void set(const char* buffer, int len) { ptr_ = buffer; length_ = len; }
void set(const char* str) {
ptr_ = str;
length_ = static_cast<int>(strlen(str));
}
void set(const void* buffer, int len) {
ptr_ = reinterpret_cast<const char*>(buffer);
length_ = len;
}
char operator[](int i) const { return ptr_[i]; }
void remove_prefix(int n) {
ptr_ += n;
length_ -= n;
}
void remove_suffix(int n) {
length_ -= n;
}
bool operator==(const StringPiece& x) const {
return ((length_ == x.length_) &&
(memcmp(ptr_, x.ptr_, length_) == 0));
}
bool operator!=(const StringPiece& x) const {
return !(*this == x);
}
#define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp) \
bool operator cmp (const StringPiece& x) const { \
int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \
return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_))); \
}
STRINGPIECE_BINARY_PREDICATE(<, <);
STRINGPIECE_BINARY_PREDICATE(<=, <);
STRINGPIECE_BINARY_PREDICATE(>=, >);
STRINGPIECE_BINARY_PREDICATE(>, >);
#undef STRINGPIECE_BINARY_PREDICATE
int compare(const StringPiece& x) const {
int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_);
if (r == 0) {
if (length_ < x.length_) r = -1;
else if (length_ > x.length_) r = +1;
}
return r;
}
string as_string() const {
return string(data(), size());
}
void CopyToString(string* target) const {
target->assign(ptr_, length_);
}
// Does "this" start with "x"
bool starts_with(const StringPiece& x) const {
return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0));
}
};
} // namespace pcrecpp
// ------------------------------------------------------------------
// Functions used to create STL containers that use StringPiece
// Remember that a StringPiece's lifetime had better be less than
// that of the underlying string or char*. If it is not, then you
// cannot safely store a StringPiece into an STL container
// ------------------------------------------------------------------
#ifdef HAVE_TYPE_TRAITS
// This makes vector<StringPiece> really fast for some STL implementations
template<> struct __type_traits<pcrecpp::StringPiece> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
#endif
// allow StringPiece to be logged
PCRECPP_EXP_DECL std::ostream& operator<<(std::ostream& o,
const pcrecpp::StringPiece& piece);
#endif /* _PCRE_STRINGPIECE_H */

View File

@ -0,0 +1,710 @@
// Copyright (c) 2005, Google Inc.
// 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.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// 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.
//
// Author: Sanjay Ghemawat
// Support for PCRE_XXX modifiers added by Giuseppe Maxia, July 2005
#ifndef _PCRECPP_H
#define _PCRECPP_H
// C++ interface to the pcre regular-expression library. RE supports
// Perl-style regular expressions (with extensions like \d, \w, \s,
// ...).
//
// -----------------------------------------------------------------------
// REGEXP SYNTAX:
//
// This module is part of the pcre library and hence supports its syntax
// for regular expressions.
//
// The syntax is pretty similar to Perl's. For those not familiar
// with Perl's regular expressions, here are some examples of the most
// commonly used extensions:
//
// "hello (\\w+) world" -- \w matches a "word" character
// "version (\\d+)" -- \d matches a digit
// "hello\\s+world" -- \s matches any whitespace character
// "\\b(\\w+)\\b" -- \b matches empty string at a word boundary
// "(?i)hello" -- (?i) turns on case-insensitive matching
// "/\\*(.*?)\\*/" -- .*? matches . minimum no. of times possible
//
// -----------------------------------------------------------------------
// MATCHING INTERFACE:
//
// The "FullMatch" operation checks that supplied text matches a
// supplied pattern exactly.
//
// Example: successful match
// pcrecpp::RE re("h.*o");
// re.FullMatch("hello");
//
// Example: unsuccessful match (requires full match):
// pcrecpp::RE re("e");
// !re.FullMatch("hello");
//
// Example: creating a temporary RE object:
// pcrecpp::RE("h.*o").FullMatch("hello");
//
// You can pass in a "const char*" or a "string" for "text". The
// examples below tend to use a const char*.
//
// You can, as in the different examples above, store the RE object
// explicitly in a variable or use a temporary RE object. The
// examples below use one mode or the other arbitrarily. Either
// could correctly be used for any of these examples.
//
// -----------------------------------------------------------------------
// MATCHING WITH SUB-STRING EXTRACTION:
//
// You can supply extra pointer arguments to extract matched subpieces.
//
// Example: extracts "ruby" into "s" and 1234 into "i"
// int i;
// string s;
// pcrecpp::RE re("(\\w+):(\\d+)");
// re.FullMatch("ruby:1234", &s, &i);
//
// Example: does not try to extract any extra sub-patterns
// re.FullMatch("ruby:1234", &s);
//
// Example: does not try to extract into NULL
// re.FullMatch("ruby:1234", NULL, &i);
//
// Example: integer overflow causes failure
// !re.FullMatch("ruby:1234567891234", NULL, &i);
//
// Example: fails because there aren't enough sub-patterns:
// !pcrecpp::RE("\\w+:\\d+").FullMatch("ruby:1234", &s);
//
// Example: fails because string cannot be stored in integer
// !pcrecpp::RE("(.*)").FullMatch("ruby", &i);
//
// The provided pointer arguments can be pointers to any scalar numeric
// type, or one of
// string (matched piece is copied to string)
// StringPiece (StringPiece is mutated to point to matched piece)
// T (where "bool T::ParseFrom(const char*, int)" exists)
// NULL (the corresponding matched sub-pattern is not copied)
//
// CAVEAT: An optional sub-pattern that does not exist in the matched
// string is assigned the empty string. Therefore, the following will
// return false (because the empty string is not a valid number):
// int number;
// pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number);
//
// -----------------------------------------------------------------------
// DO_MATCH
//
// The matching interface supports at most 16 arguments per call.
// If you need more, consider using the more general interface
// pcrecpp::RE::DoMatch(). See pcrecpp.h for the signature for DoMatch.
//
// -----------------------------------------------------------------------
// PARTIAL MATCHES
//
// You can use the "PartialMatch" operation when you want the pattern
// to match any substring of the text.
//
// Example: simple search for a string:
// pcrecpp::RE("ell").PartialMatch("hello");
//
// Example: find first number in a string:
// int number;
// pcrecpp::RE re("(\\d+)");
// re.PartialMatch("x*100 + 20", &number);
// assert(number == 100);
//
// -----------------------------------------------------------------------
// UTF-8 AND THE MATCHING INTERFACE:
//
// By default, pattern and text are plain text, one byte per character.
// The UTF8 flag, passed to the constructor, causes both pattern
// and string to be treated as UTF-8 text, still a byte stream but
// potentially multiple bytes per character. In practice, the text
// is likelier to be UTF-8 than the pattern, but the match returned
// may depend on the UTF8 flag, so always use it when matching
// UTF8 text. E.g., "." will match one byte normally but with UTF8
// set may match up to three bytes of a multi-byte character.
//
// Example:
// pcrecpp::RE_Options options;
// options.set_utf8();
// pcrecpp::RE re(utf8_pattern, options);
// re.FullMatch(utf8_string);
//
// Example: using the convenience function UTF8():
// pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8());
// re.FullMatch(utf8_string);
//
// NOTE: The UTF8 option is ignored if pcre was not configured with the
// --enable-utf8 flag.
//
// -----------------------------------------------------------------------
// PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE
//
// PCRE defines some modifiers to change the behavior of the regular
// expression engine.
// The C++ wrapper defines an auxiliary class, RE_Options, as a vehicle
// to pass such modifiers to a RE class.
//
// Currently, the following modifiers are supported
//
// modifier description Perl corresponding
//
// PCRE_CASELESS case insensitive match /i
// PCRE_MULTILINE multiple lines match /m
// PCRE_DOTALL dot matches newlines /s
// PCRE_DOLLAR_ENDONLY $ matches only at end N/A
// PCRE_EXTRA strict escape parsing N/A
// PCRE_EXTENDED ignore whitespaces /x
// PCRE_UTF8 handles UTF8 chars built-in
// PCRE_UNGREEDY reverses * and *? N/A
// PCRE_NO_AUTO_CAPTURE disables matching parens N/A (*)
//
// (For a full account on how each modifier works, please check the
// PCRE API reference manual).
//
// (*) Both Perl and PCRE allow non matching parentheses by means of the
// "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not
// capture, while (ab|cd) does.
//
// For each modifier, there are two member functions whose name is made
// out of the modifier in lowercase, without the "PCRE_" prefix. For
// instance, PCRE_CASELESS is handled by
// bool caseless(),
// which returns true if the modifier is set, and
// RE_Options & set_caseless(bool),
// which sets or unsets the modifier.
//
// Moreover, PCRE_EXTRA_MATCH_LIMIT can be accessed through the
// set_match_limit() and match_limit() member functions.
// Setting match_limit to a non-zero value will limit the executation of
// pcre to keep it from doing bad things like blowing the stack or taking
// an eternity to return a result. A value of 5000 is good enough to stop
// stack blowup in a 2MB thread stack. Setting match_limit to zero will
// disable match limiting. Alternately, you can set match_limit_recursion()
// which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to limit how much pcre
// recurses. match_limit() caps the number of matches pcre does;
// match_limit_recrusion() caps the depth of recursion.
//
// Normally, to pass one or more modifiers to a RE class, you declare
// a RE_Options object, set the appropriate options, and pass this
// object to a RE constructor. Example:
//
// RE_options opt;
// opt.set_caseless(true);
//
// if (RE("HELLO", opt).PartialMatch("hello world")) ...
//
// RE_options has two constructors. The default constructor takes no
// arguments and creates a set of flags that are off by default.
//
// The optional parameter 'option_flags' is to facilitate transfer
// of legacy code from C programs. This lets you do
// RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str);
//
// But new code is better off doing
// RE(pattern,
// RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str);
// (See below)
//
// If you are going to pass one of the most used modifiers, there are some
// convenience functions that return a RE_Options class with the
// appropriate modifier already set:
// CASELESS(), UTF8(), MULTILINE(), DOTALL(), EXTENDED()
//
// If you need to set several options at once, and you don't want to go
// through the pains of declaring a RE_Options object and setting several
// options, there is a parallel method that give you such ability on the
// fly. You can concatenate several set_xxxxx member functions, since each
// of them returns a reference to its class object. e.g.: to pass
// PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one
// statement, you may write
//
// RE(" ^ xyz \\s+ .* blah$", RE_Options()
// .set_caseless(true)
// .set_extended(true)
// .set_multiline(true)).PartialMatch(sometext);
//
// -----------------------------------------------------------------------
// SCANNING TEXT INCREMENTALLY
//
// The "Consume" operation may be useful if you want to repeatedly
// match regular expressions at the front of a string and skip over
// them as they match. This requires use of the "StringPiece" type,
// which represents a sub-range of a real string. Like RE, StringPiece
// is defined in the pcrecpp namespace.
//
// Example: read lines of the form "var = value" from a string.
// string contents = ...; // Fill string somehow
// pcrecpp::StringPiece input(contents); // Wrap in a StringPiece
//
// string var;
// int value;
// pcrecpp::RE re("(\\w+) = (\\d+)\n");
// while (re.Consume(&input, &var, &value)) {
// ...;
// }
//
// Each successful call to "Consume" will set "var/value", and also
// advance "input" so it points past the matched text.
//
// The "FindAndConsume" operation is similar to "Consume" but does not
// anchor your match at the beginning of the string. For example, you
// could extract all words from a string by repeatedly calling
// pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word)
//
// -----------------------------------------------------------------------
// PARSING HEX/OCTAL/C-RADIX NUMBERS
//
// By default, if you pass a pointer to a numeric value, the
// corresponding text is interpreted as a base-10 number. You can
// instead wrap the pointer with a call to one of the operators Hex(),
// Octal(), or CRadix() to interpret the text in another base. The
// CRadix operator interprets C-style "0" (base-8) and "0x" (base-16)
// prefixes, but defaults to base-10.
//
// Example:
// int a, b, c, d;
// pcrecpp::RE re("(.*) (.*) (.*) (.*)");
// re.FullMatch("100 40 0100 0x40",
// pcrecpp::Octal(&a), pcrecpp::Hex(&b),
// pcrecpp::CRadix(&c), pcrecpp::CRadix(&d));
// will leave 64 in a, b, c, and d.
//
// -----------------------------------------------------------------------
// REPLACING PARTS OF STRINGS
//
// You can replace the first match of "pattern" in "str" with
// "rewrite". Within "rewrite", backslash-escaped digits (\1 to \9)
// can be used to insert text matching corresponding parenthesized
// group from the pattern. \0 in "rewrite" refers to the entire
// matching text. E.g.,
//
// string s = "yabba dabba doo";
// pcrecpp::RE("b+").Replace("d", &s);
//
// will leave "s" containing "yada dabba doo". The result is true if
// the pattern matches and a replacement occurs, or false otherwise.
//
// GlobalReplace() is like Replace(), except that it replaces all
// occurrences of the pattern in the string with the rewrite.
// Replacements are not subject to re-matching. E.g.,
//
// string s = "yabba dabba doo";
// pcrecpp::RE("b+").GlobalReplace("d", &s);
//
// will leave "s" containing "yada dada doo". It returns the number
// of replacements made.
//
// Extract() is like Replace(), except that if the pattern matches,
// "rewrite" is copied into "out" (an additional argument) with
// substitutions. The non-matching portions of "text" are ignored.
// Returns true iff a match occurred and the extraction happened
// successfully. If no match occurs, the string is left unaffected.
#include <string>
#include <pcre.h>
#include <pcrecpparg.h> // defines the Arg class
// This isn't technically needed here, but we include it
// anyway so folks who include pcrecpp.h don't have to.
#include <pcre_stringpiece.h>
namespace pcrecpp {
#define PCRE_SET_OR_CLEAR(b, o) \
if (b) all_options_ |= (o); else all_options_ &= ~(o); \
return *this
#define PCRE_IS_SET(o) \
(all_options_ & o) == o
/***** Compiling regular expressions: the RE class *****/
// RE_Options allow you to set options to be passed along to pcre,
// along with other options we put on top of pcre.
// Only 9 modifiers, plus match_limit and match_limit_recursion,
// are supported now.
class PCRECPP_EXP_DEFN RE_Options {
public:
// constructor
RE_Options() : match_limit_(0), match_limit_recursion_(0), all_options_(0) {}
// alternative constructor.
// To facilitate transfer of legacy code from C programs
//
// This lets you do
// RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str);
// But new code is better off doing
// RE(pattern,
// RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str);
RE_Options(int option_flags) : match_limit_(0), match_limit_recursion_(0),
all_options_(option_flags) {}
// we're fine with the default destructor, copy constructor, etc.
// accessors and mutators
int match_limit() const { return match_limit_; };
RE_Options &set_match_limit(int limit) {
match_limit_ = limit;
return *this;
}
int match_limit_recursion() const { return match_limit_recursion_; };
RE_Options &set_match_limit_recursion(int limit) {
match_limit_recursion_ = limit;
return *this;
}
bool caseless() const {
return PCRE_IS_SET(PCRE_CASELESS);
}
RE_Options &set_caseless(bool x) {
PCRE_SET_OR_CLEAR(x, PCRE_CASELESS);
}
bool multiline() const {
return PCRE_IS_SET(PCRE_MULTILINE);
}
RE_Options &set_multiline(bool x) {
PCRE_SET_OR_CLEAR(x, PCRE_MULTILINE);
}
bool dotall() const {
return PCRE_IS_SET(PCRE_DOTALL);
}
RE_Options &set_dotall(bool x) {
PCRE_SET_OR_CLEAR(x, PCRE_DOTALL);
}
bool extended() const {
return PCRE_IS_SET(PCRE_EXTENDED);
}
RE_Options &set_extended(bool x) {
PCRE_SET_OR_CLEAR(x, PCRE_EXTENDED);
}
bool dollar_endonly() const {
return PCRE_IS_SET(PCRE_DOLLAR_ENDONLY);
}
RE_Options &set_dollar_endonly(bool x) {
PCRE_SET_OR_CLEAR(x, PCRE_DOLLAR_ENDONLY);
}
bool extra() const {
return PCRE_IS_SET(PCRE_EXTRA);
}
RE_Options &set_extra(bool x) {
PCRE_SET_OR_CLEAR(x, PCRE_EXTRA);
}
bool ungreedy() const {
return PCRE_IS_SET(PCRE_UNGREEDY);
}
RE_Options &set_ungreedy(bool x) {
PCRE_SET_OR_CLEAR(x, PCRE_UNGREEDY);
}
bool utf8() const {
return PCRE_IS_SET(PCRE_UTF8);
}
RE_Options &set_utf8(bool x) {
PCRE_SET_OR_CLEAR(x, PCRE_UTF8);
}
bool no_auto_capture() const {
return PCRE_IS_SET(PCRE_NO_AUTO_CAPTURE);
}
RE_Options &set_no_auto_capture(bool x) {
PCRE_SET_OR_CLEAR(x, PCRE_NO_AUTO_CAPTURE);
}
RE_Options &set_all_options(int opt) {
all_options_ = opt;
return *this;
}
int all_options() const {
return all_options_ ;
}
// TODO: add other pcre flags
private:
int match_limit_;
int match_limit_recursion_;
int all_options_;
};
// These functions return some common RE_Options
static inline RE_Options UTF8() {
return RE_Options().set_utf8(true);
}
static inline RE_Options CASELESS() {
return RE_Options().set_caseless(true);
}
static inline RE_Options MULTILINE() {
return RE_Options().set_multiline(true);
}
static inline RE_Options DOTALL() {
return RE_Options().set_dotall(true);
}
static inline RE_Options EXTENDED() {
return RE_Options().set_extended(true);
}
// Interface for regular expression matching. Also corresponds to a
// pre-compiled regular expression. An "RE" object is safe for
// concurrent use by multiple threads.
class PCRECPP_EXP_DEFN RE {
public:
// We provide implicit conversions from strings so that users can
// pass in a string or a "const char*" wherever an "RE" is expected.
RE(const string& pat) { Init(pat, NULL); }
RE(const string& pat, const RE_Options& option) { Init(pat, &option); }
RE(const char* pat) { Init(pat, NULL); }
RE(const char* pat, const RE_Options& option) { Init(pat, &option); }
RE(const unsigned char* pat) {
Init(reinterpret_cast<const char*>(pat), NULL);
}
RE(const unsigned char* pat, const RE_Options& option) {
Init(reinterpret_cast<const char*>(pat), &option);
}
// Copy constructor & assignment - note that these are expensive
// because they recompile the expression.
RE(const RE& re) { Init(re.pattern_, &re.options_); }
const RE& operator=(const RE& re) {
if (this != &re) {
Cleanup();
// This is the code that originally came from Google
// Init(re.pattern_.c_str(), &re.options_);
// This is the replacement from Ari Pollak
Init(re.pattern_, &re.options_);
}
return *this;
}
~RE();
// The string specification for this RE. E.g.
// RE re("ab*c?d+");
// re.pattern(); // "ab*c?d+"
const string& pattern() const { return pattern_; }
// If RE could not be created properly, returns an error string.
// Else returns the empty string.
const string& error() const { return *error_; }
/***** The useful part: the matching interface *****/
// This is provided so one can do pattern.ReplaceAll() just as
// easily as ReplaceAll(pattern-text, ....)
bool FullMatch(const StringPiece& text,
const Arg& ptr1 = no_arg,
const Arg& ptr2 = no_arg,
const Arg& ptr3 = no_arg,
const Arg& ptr4 = no_arg,
const Arg& ptr5 = no_arg,
const Arg& ptr6 = no_arg,
const Arg& ptr7 = no_arg,
const Arg& ptr8 = no_arg,
const Arg& ptr9 = no_arg,
const Arg& ptr10 = no_arg,
const Arg& ptr11 = no_arg,
const Arg& ptr12 = no_arg,
const Arg& ptr13 = no_arg,
const Arg& ptr14 = no_arg,
const Arg& ptr15 = no_arg,
const Arg& ptr16 = no_arg) const;
bool PartialMatch(const StringPiece& text,
const Arg& ptr1 = no_arg,
const Arg& ptr2 = no_arg,
const Arg& ptr3 = no_arg,
const Arg& ptr4 = no_arg,
const Arg& ptr5 = no_arg,
const Arg& ptr6 = no_arg,
const Arg& ptr7 = no_arg,
const Arg& ptr8 = no_arg,
const Arg& ptr9 = no_arg,
const Arg& ptr10 = no_arg,
const Arg& ptr11 = no_arg,
const Arg& ptr12 = no_arg,
const Arg& ptr13 = no_arg,
const Arg& ptr14 = no_arg,
const Arg& ptr15 = no_arg,
const Arg& ptr16 = no_arg) const;
bool Consume(StringPiece* input,
const Arg& ptr1 = no_arg,
const Arg& ptr2 = no_arg,
const Arg& ptr3 = no_arg,
const Arg& ptr4 = no_arg,
const Arg& ptr5 = no_arg,
const Arg& ptr6 = no_arg,
const Arg& ptr7 = no_arg,
const Arg& ptr8 = no_arg,
const Arg& ptr9 = no_arg,
const Arg& ptr10 = no_arg,
const Arg& ptr11 = no_arg,
const Arg& ptr12 = no_arg,
const Arg& ptr13 = no_arg,
const Arg& ptr14 = no_arg,
const Arg& ptr15 = no_arg,
const Arg& ptr16 = no_arg) const;
bool FindAndConsume(StringPiece* input,
const Arg& ptr1 = no_arg,
const Arg& ptr2 = no_arg,
const Arg& ptr3 = no_arg,
const Arg& ptr4 = no_arg,
const Arg& ptr5 = no_arg,
const Arg& ptr6 = no_arg,
const Arg& ptr7 = no_arg,
const Arg& ptr8 = no_arg,
const Arg& ptr9 = no_arg,
const Arg& ptr10 = no_arg,
const Arg& ptr11 = no_arg,
const Arg& ptr12 = no_arg,
const Arg& ptr13 = no_arg,
const Arg& ptr14 = no_arg,
const Arg& ptr15 = no_arg,
const Arg& ptr16 = no_arg) const;
bool Replace(const StringPiece& rewrite,
string *str) const;
int GlobalReplace(const StringPiece& rewrite,
string *str) const;
bool Extract(const StringPiece &rewrite,
const StringPiece &text,
string *out) const;
// Escapes all potentially meaningful regexp characters in
// 'unquoted'. The returned string, used as a regular expression,
// will exactly match the original string. For example,
// 1.5-2.0?
// may become:
// 1\.5\-2\.0\?
// Note QuoteMeta behaves the same as perl's QuoteMeta function,
// *except* that it escapes the NUL character (\0) as backslash + 0,
// rather than backslash + NUL.
static string QuoteMeta(const StringPiece& unquoted);
/***** Generic matching interface *****/
// Type of match (TODO: Should be restructured as part of RE_Options)
enum Anchor {
UNANCHORED, // No anchoring
ANCHOR_START, // Anchor at start only
ANCHOR_BOTH // Anchor at start and end
};
// General matching routine. Stores the length of the match in
// "*consumed" if successful.
bool DoMatch(const StringPiece& text,
Anchor anchor,
int* consumed,
const Arg* const* args, int n) const;
// Return the number of capturing subpatterns, or -1 if the
// regexp wasn't valid on construction.
int NumberOfCapturingGroups() const;
// The default value for an argument, to indicate the end of the argument
// list. This must be used only in optional argument defaults. It should NOT
// be passed explicitly. Some people have tried to use it like this:
//
// FullMatch(x, y, &z, no_arg, &w);
//
// This is a mistake, and will not work.
static Arg no_arg;
private:
void Init(const string& pattern, const RE_Options* options);
void Cleanup();
// Match against "text", filling in "vec" (up to "vecsize" * 2/3) with
// pairs of integers for the beginning and end positions of matched
// text. The first pair corresponds to the entire matched text;
// subsequent pairs correspond, in order, to parentheses-captured
// matches. Returns the number of pairs (one more than the number of
// the last subpattern with a match) if matching was successful
// and zero if the match failed.
// I.e. for RE("(foo)|(bar)|(baz)") it will return 2, 3, and 4 when matching
// against "foo", "bar", and "baz" respectively.
// When matching RE("(foo)|hello") against "hello", it will return 1.
// But the values for all subpattern are filled in into "vec".
int TryMatch(const StringPiece& text,
int startpos,
Anchor anchor,
bool empty_ok,
int *vec,
int vecsize) const;
// Append the "rewrite" string, with backslash subsitutions from "text"
// and "vec", to string "out".
bool Rewrite(string *out,
const StringPiece& rewrite,
const StringPiece& text,
int *vec,
int veclen) const;
// internal implementation for DoMatch
bool DoMatchImpl(const StringPiece& text,
Anchor anchor,
int* consumed,
const Arg* const args[],
int n,
int* vec,
int vecsize) const;
// Compile the regexp for the specified anchoring mode
pcre* Compile(Anchor anchor);
string pattern_;
RE_Options options_;
pcre* re_full_; // For full matches
pcre* re_partial_; // For partial matches
const string* error_; // Error indicator (or points to empty string)
};
} // namespace pcrecpp
#endif /* _PCRECPP_H */

View File

@ -0,0 +1,174 @@
// Copyright (c) 2005, Google Inc.
// 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.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// 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.
//
// Author: Sanjay Ghemawat
#ifndef _PCRECPPARG_H
#define _PCRECPPARG_H
#include <stdlib.h> // for NULL
#include <string>
#include <pcre.h>
namespace pcrecpp {
class StringPiece;
// Hex/Octal/Binary?
// Special class for parsing into objects that define a ParseFrom() method
template <class T>
class _RE_MatchObject {
public:
static inline bool Parse(const char* str, int n, void* dest) {
if (dest == NULL) return true;
T* object = reinterpret_cast<T*>(dest);
return object->ParseFrom(str, n);
}
};
class PCRECPP_EXP_DEFN Arg {
public:
// Empty constructor so we can declare arrays of Arg
Arg();
// Constructor specially designed for NULL arguments
Arg(void*);
typedef bool (*Parser)(const char* str, int n, void* dest);
// Type-specific parsers
#define PCRE_MAKE_PARSER(type,name) \
Arg(type* p) : arg_(p), parser_(name) { } \
Arg(type* p, Parser parser) : arg_(p), parser_(parser) { }
PCRE_MAKE_PARSER(char, parse_char);
PCRE_MAKE_PARSER(unsigned char, parse_uchar);
PCRE_MAKE_PARSER(short, parse_short);
PCRE_MAKE_PARSER(unsigned short, parse_ushort);
PCRE_MAKE_PARSER(int, parse_int);
PCRE_MAKE_PARSER(unsigned int, parse_uint);
PCRE_MAKE_PARSER(long, parse_long);
PCRE_MAKE_PARSER(unsigned long, parse_ulong);
#if 1
PCRE_MAKE_PARSER(long long, parse_longlong);
#endif
#if 1
PCRE_MAKE_PARSER(unsigned long long, parse_ulonglong);
#endif
PCRE_MAKE_PARSER(float, parse_float);
PCRE_MAKE_PARSER(double, parse_double);
PCRE_MAKE_PARSER(std::string, parse_string);
PCRE_MAKE_PARSER(StringPiece, parse_stringpiece);
#undef PCRE_MAKE_PARSER
// Generic constructor
template <class T> Arg(T*, Parser parser);
// Generic constructor template
template <class T> Arg(T* p)
: arg_(p), parser_(_RE_MatchObject<T>::Parse) {
}
// Parse the data
bool Parse(const char* str, int n) const;
private:
void* arg_;
Parser parser_;
static bool parse_null (const char* str, int n, void* dest);
static bool parse_char (const char* str, int n, void* dest);
static bool parse_uchar (const char* str, int n, void* dest);
static bool parse_float (const char* str, int n, void* dest);
static bool parse_double (const char* str, int n, void* dest);
static bool parse_string (const char* str, int n, void* dest);
static bool parse_stringpiece (const char* str, int n, void* dest);
#define PCRE_DECLARE_INTEGER_PARSER(name) \
private: \
static bool parse_ ## name(const char* str, int n, void* dest); \
static bool parse_ ## name ## _radix( \
const char* str, int n, void* dest, int radix); \
public: \
static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \
static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \
static bool parse_ ## name ## _cradix(const char* str, int n, void* dest)
PCRE_DECLARE_INTEGER_PARSER(short);
PCRE_DECLARE_INTEGER_PARSER(ushort);
PCRE_DECLARE_INTEGER_PARSER(int);
PCRE_DECLARE_INTEGER_PARSER(uint);
PCRE_DECLARE_INTEGER_PARSER(long);
PCRE_DECLARE_INTEGER_PARSER(ulong);
PCRE_DECLARE_INTEGER_PARSER(longlong);
PCRE_DECLARE_INTEGER_PARSER(ulonglong);
#undef PCRE_DECLARE_INTEGER_PARSER
};
inline Arg::Arg() : arg_(NULL), parser_(parse_null) { }
inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { }
inline bool Arg::Parse(const char* str, int n) const {
return (*parser_)(str, n, arg_);
}
// This part of the parser, appropriate only for ints, deals with bases
#define MAKE_INTEGER_PARSER(type, name) \
inline Arg Hex(type* ptr) { \
return Arg(ptr, Arg::parse_ ## name ## _hex); } \
inline Arg Octal(type* ptr) { \
return Arg(ptr, Arg::parse_ ## name ## _octal); } \
inline Arg CRadix(type* ptr) { \
return Arg(ptr, Arg::parse_ ## name ## _cradix); }
MAKE_INTEGER_PARSER(short, short) /* */
MAKE_INTEGER_PARSER(unsigned short, ushort) /* */
MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */
MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */
MAKE_INTEGER_PARSER(long, long) /* because they can cause */
MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */
#if 1 /* the checking level is */
MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */
#endif /* */
#if 1 /* */
MAKE_INTEGER_PARSER(unsigned long long, ulonglong) /* */
#endif
#undef PCRE_IS_SET
#undef PCRE_SET_OR_CLEAR
#undef MAKE_INTEGER_PARSER
} // namespace pcrecpp
#endif /* _PCRECPPARG_H */

View File

@ -0,0 +1,146 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
#ifndef _PCREPOSIX_H
#define _PCREPOSIX_H
/* This is the header for the POSIX wrapper interface to the PCRE Perl-
Compatible Regular Expression library. It defines the things POSIX says should
be there. I hope.
Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
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.
* Neither the name of the University of Cambridge nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
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.
-----------------------------------------------------------------------------
*/
/* Have to include stdlib.h in order to ensure that size_t is defined. */
#include <stdlib.h>
/* Allow for C++ users */
#ifdef __cplusplus
extern "C" {
#endif
/* Options, mostly defined by POSIX, but with some extras. */
#define REG_ICASE 0x0001 /* Maps to PCRE_CASELESS */
#define REG_NEWLINE 0x0002 /* Maps to PCRE_MULTILINE */
#define REG_NOTBOL 0x0004 /* Maps to PCRE_NOTBOL */
#define REG_NOTEOL 0x0008 /* Maps to PCRE_NOTEOL */
#define REG_DOTALL 0x0010 /* NOT defined by POSIX; maps to PCRE_DOTALL */
#define REG_NOSUB 0x0020 /* Maps to PCRE_NO_AUTO_CAPTURE */
#define REG_UTF8 0x0040 /* NOT defined by POSIX; maps to PCRE_UTF8 */
#define REG_STARTEND 0x0080 /* BSD feature: pass subject string by so,eo */
#define REG_NOTEMPTY 0x0100 /* NOT defined by POSIX; maps to PCRE_NOTEMPTY */
#define REG_UNGREEDY 0x0200 /* NOT defined by POSIX; maps to PCRE_UNGREEDY */
#define REG_UCP 0x0400 /* NOT defined by POSIX; maps to PCRE_UCP */
/* This is not used by PCRE, but by defining it we make it easier
to slot PCRE into existing programs that make POSIX calls. */
#define REG_EXTENDED 0
/* Error values. Not all these are relevant or used by the wrapper. */
enum {
REG_ASSERT = 1, /* internal error ? */
REG_BADBR, /* invalid repeat counts in {} */
REG_BADPAT, /* pattern error */
REG_BADRPT, /* ? * + invalid */
REG_EBRACE, /* unbalanced {} */
REG_EBRACK, /* unbalanced [] */
REG_ECOLLATE, /* collation error - not relevant */
REG_ECTYPE, /* bad class */
REG_EESCAPE, /* bad escape sequence */
REG_EMPTY, /* empty expression */
REG_EPAREN, /* unbalanced () */
REG_ERANGE, /* bad range inside [] */
REG_ESIZE, /* expression too big */
REG_ESPACE, /* failed to get memory */
REG_ESUBREG, /* bad back reference */
REG_INVARG, /* bad argument */
REG_NOMATCH /* match failed */
};
/* The structure representing a compiled regular expression. */
typedef struct {
void *re_pcre;
size_t re_nsub;
size_t re_erroffset;
} regex_t;
/* The structure in which a captured offset is returned. */
typedef int regoff_t;
typedef struct {
regoff_t rm_so;
regoff_t rm_eo;
} regmatch_t;
/* When an application links to a PCRE DLL in Windows, the symbols that are
imported have to be identified as such. When building PCRE, the appropriate
export settings are needed, and are set in pcreposix.c before including this
file. */
#if defined(_WIN32) && !defined(PCRE_STATIC) && !defined(PCREPOSIX_EXP_DECL)
# define PCREPOSIX_EXP_DECL extern __declspec(dllimport)
# define PCREPOSIX_EXP_DEFN __declspec(dllimport)
#endif
/* By default, we use the standard "extern" declarations. */
#ifndef PCREPOSIX_EXP_DECL
# ifdef __cplusplus
# define PCREPOSIX_EXP_DECL extern "C"
# define PCREPOSIX_EXP_DEFN extern "C"
# else
# define PCREPOSIX_EXP_DECL extern
# define PCREPOSIX_EXP_DEFN extern
# endif
#endif
/* The functions */
PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int);
PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t,
regmatch_t *, int);
PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t);
PCREPOSIX_EXP_DECL void regfree(regex_t *);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* End of pcreposix.h */

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cd74396cc07b9771b925ff1040ea34ce62e5d06bd661f081fbb3b3a0eadeee8a
size 4353080

41
third-party/libpcre/x86_64/lib/libpcre.la vendored Executable file
View File

@ -0,0 +1,41 @@
# libpcre.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6.42-b88ce
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libpcre.a'
# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=''
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libpcre.
current=3
age=2
revision=11
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib'

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e89a132443f734b45a72574598a3eed4f6636116980c4a12b8dcee6f4d3c33ed
size 4142840

41
third-party/libpcre/x86_64/lib/libpcre16.la vendored Executable file
View File

@ -0,0 +1,41 @@
# libpcre16.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6.42-b88ce
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libpcre16.a'
# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=''
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libpcre16.
current=2
age=2
revision=11
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib'

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:987cead18fc466262163a1c90672fd36ded65792e23b22e55466d87f15e6fb1a
size 4090184

41
third-party/libpcre/x86_64/lib/libpcre32.la vendored Executable file
View File

@ -0,0 +1,41 @@
# libpcre32.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6.42-b88ce
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libpcre32.a'
# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=''
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libpcre32.
current=0
age=0
revision=11
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib'

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4a63e497339807e804c8a9d7a20b60aa8260b3cdf0e5bfd47351b223bc3bdde7
size 47368

41
third-party/libpcre/x86_64/lib/libpcrecpp.la vendored Executable file
View File

@ -0,0 +1,41 @@
# libpcrecpp.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6.42-b88ce
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libpcrecpp.a'
# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=' /Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib/libpcre.la'
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libpcrecpp.
current=0
age=0
revision=1
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib'

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f5e9c37225c8156db83b62e135cfb7fcd393d5d883c86da5f243f39f551b360a
size 12936

View File

@ -0,0 +1,41 @@
# libpcreposix.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6.42-b88ce
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libpcreposix.a'
# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=' /Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib/libpcre.la'
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libpcreposix.
current=0
age=0
revision=6
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/Users/hat/Projects/vimr/third-party/libpcre/x86_64/lib'

View File

@ -0,0 +1,13 @@
# Package Information for pkg-config
prefix=/Users/hat/Projects/vimr/third-party/libpcre/x86_64
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libpcre
Description: PCRE - Perl compatible regular expressions C library with 8 bit character support
Version: 8.43
Libs: -L${libdir} -lpcre
Libs.private: -D_THREAD_SAFE -pthread
Cflags: -I${includedir} -DPCRE_STATIC

View File

@ -0,0 +1,13 @@
# Package Information for pkg-config
prefix=/Users/hat/Projects/vimr/third-party/libpcre/x86_64
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libpcre16
Description: PCRE - Perl compatible regular expressions C library with 16 bit character support
Version: 8.43
Libs: -L${libdir} -lpcre16
Libs.private: -D_THREAD_SAFE -pthread
Cflags: -I${includedir} -DPCRE_STATIC

View File

@ -0,0 +1,13 @@
# Package Information for pkg-config
prefix=/Users/hat/Projects/vimr/third-party/libpcre/x86_64
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libpcre32
Description: PCRE - Perl compatible regular expressions C library with 32 bit character support
Version: 8.43
Libs: -L${libdir} -lpcre32
Libs.private: -D_THREAD_SAFE -pthread
Cflags: -I${includedir} -DPCRE_STATIC

Some files were not shown because too many files have changed in this diff Show More