├── .github
└── workflows
│ └── stale.yml
├── .gitignore
├── CHANGES.md
├── Code_of_Conduct.md
├── LATESTVERSION
├── Makefile
├── Mjolnir.xcodeproj
└── project.pbxproj
├── Mjolnir
├── AutoUpdaterWindow.xib
├── ConsoleWindow.xib
├── Credits.rtf
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── icon_128x128.png
│ │ ├── icon_128x128@2x.png
│ │ ├── icon_16x16.png
│ │ ├── icon_16x16@2x.png
│ │ ├── icon_256x256.png
│ │ ├── icon_256x256@2x.png
│ │ ├── icon_32x32.png
│ │ ├── icon_32x32@2x.png
│ │ ├── icon_512x512.png
│ │ └── icon_512x512@2x.png
├── MJAccessibilityUtils.h
├── MJAccessibilityUtils.m
├── MJAppDelegate.m
├── MJAutoLaunch.h
├── MJAutoLaunch.m
├── MJAutoUpdaterWindowController.h
├── MJAutoUpdaterWindowController.m
├── MJConfigUtils.h
├── MJConfigUtils.m
├── MJConsoleWindowController.h
├── MJConsoleWindowController.m
├── MJDockIcon.h
├── MJDockIcon.m
├── MJFileUtils.h
├── MJFileUtils.m
├── MJLua.h
├── MJLua.m
├── MJMenuIcon.h
├── MJMenuIcon.m
├── MJPreferencesWindowController.h
├── MJPreferencesWindowController.m
├── MJSecurityUtils.h
├── MJSecurityUtils.m
├── MJUpdate.h
├── MJUpdate.m
├── MJUpdateChecker.h
├── MJUpdateChecker.m
├── MJUserNotificationManager.h
├── MJUserNotificationManager.m
├── MJVersionUtils.h
├── MJVersionUtils.m
├── MainMenu.xib
├── Mjolnir-Info.plist
├── Mjolnir-Prefix.pch
├── MjolnirRestarter
│ └── main.m
├── PreferencesWindow.xib
├── lua
│ ├── lapi.c
│ ├── lapi.h
│ ├── lauxlib.c
│ ├── lauxlib.h
│ ├── lbaselib.c
│ ├── lbitlib.c
│ ├── lcode.c
│ ├── lcode.h
│ ├── lcorolib.c
│ ├── lctype.c
│ ├── lctype.h
│ ├── ldblib.c
│ ├── ldebug.c
│ ├── ldebug.h
│ ├── ldo.c
│ ├── ldo.h
│ ├── ldump.c
│ ├── lfunc.c
│ ├── lfunc.h
│ ├── lgc.c
│ ├── lgc.h
│ ├── linit.c
│ ├── liolib.c
│ ├── llex.c
│ ├── llex.h
│ ├── llimits.h
│ ├── lmathlib.c
│ ├── lmem.c
│ ├── lmem.h
│ ├── loadlib.c
│ ├── lobject.c
│ ├── lobject.h
│ ├── lopcodes.c
│ ├── lopcodes.h
│ ├── loslib.c
│ ├── lparser.c
│ ├── lparser.h
│ ├── lprefix.h
│ ├── lstate.c
│ ├── lstate.h
│ ├── lstring.c
│ ├── lstring.h
│ ├── lstrlib.c
│ ├── ltable.c
│ ├── ltable.h
│ ├── ltablib.c
│ ├── ltm.c
│ ├── ltm.h
│ ├── lua.c
│ ├── lua.h
│ ├── lua.hpp
│ ├── luac.c
│ ├── luaconf.h
│ ├── lualib.h
│ ├── lundump.c
│ ├── lundump.h
│ ├── lutf8lib.c
│ ├── lvm.c
│ ├── lvm.h
│ ├── lzio.c
│ └── lzio.h
├── setup.lua
├── statusicon.png
├── statusicon@2x.png
└── variables.h
├── README.md
├── docs
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── Makefile
├── README.md
├── bin
│ ├── download
│ ├── gencomments
│ ├── genhtml
│ ├── genjson
│ └── gensql
└── templates
│ ├── Mjolnir.docset
│ ├── Contents
│ │ ├── Info.plist
│ │ └── Resources
│ │ │ └── Documents
│ │ │ └── .gitkeep
│ ├── icon.png
│ └── icon@2x.png
│ ├── ext.html.erb
│ ├── index.html.erb
│ └── index.md
├── mods
├── LICENSE.md
├── README.md
├── alert
│ ├── .gitignore
│ ├── Alert.xcodeproj
│ │ └── project.pbxproj
│ ├── alert.m
│ └── mjolnir.alert-0.2-1.rockspec
├── application
│ ├── .gitignore
│ ├── Application.xcodeproj
│ │ └── project.pbxproj
│ ├── application.h
│ ├── application.lua
│ ├── application.m
│ ├── mjolnir.application-0.3-1.rockspec
│ ├── window.h
│ ├── window.lua
│ └── window.m
├── fnutils
│ ├── .gitignore
│ ├── fnutils.lua
│ └── mjolnir.fnutils-0.1-1.rockspec
├── geometry
│ ├── .gitignore
│ ├── Geometry.xcodeproj
│ │ └── project.pbxproj
│ ├── geometry.lua
│ ├── geometry.m
│ └── mjolnir.geometry-0.2-1.rockspec
├── hotkey
│ ├── .gitignore
│ ├── Hotkey.xcodeproj
│ │ └── project.pbxproj
│ ├── hotkey.lua
│ ├── hotkey.m
│ └── mjolnir.hotkey-0.3-1.rockspec
├── keycodes
│ ├── .gitignore
│ ├── Keycodes.xcodeproj
│ │ └── project.pbxproj
│ ├── keycodes.lua
│ ├── keycodes.m
│ └── mjolnir.keycodes-0.2-1.rockspec
└── screen
│ ├── .gitignore
│ ├── Screen.xcodeproj
│ └── project.pbxproj
│ ├── mjolnir.screen-0.2-1.rockspec
│ ├── screen.lua
│ └── screen.m
├── sample-plugin
├── .gitignore
├── README.md
├── foobar.lua
├── foobar.m
└── mjolnir.yourid.foobar-0.1-1.rockspec
└── screenshots
├── dict.gif
└── grid.gif
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: Mark stale issues and pull requests
2 |
3 | on:
4 | schedule:
5 | - cron: "0 0 * * *"
6 |
7 | jobs:
8 | stale:
9 |
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/stale@v1
14 | with:
15 | repo-token: ${{ secrets.GITHUB_TOKEN }}
16 | stale-issue-message: 'Stale issue message'
17 | stale-pr-message: 'Stale pull request message'
18 | stale-issue-label: 'no-issue-activity'
19 | stale-pr-label: 'no-pr-activity'
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | *.xcworkspace
13 | !default.xcworkspace
14 | xcuserdata
15 | profile
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 |
20 | /Mjolnir.app
21 | /Mjolnir*.zip
22 | /Mjolnir*.tgz
23 |
--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------
1 | ### 0.3.1
2 |
3 | - Renamed global `mj` to `mjolnir`
4 |
5 | ### 0.3
6 |
7 | - The UI has changed drastically. Expect nothing to be in the same
8 | place or look the same. Pretend it's a brand new app.
9 | - Extensions are now handled by LuaRocks instead of by the app itself.
10 | - The "core" namespace has been renamed to "mj".
11 | - The 'mj.window' module now ships with the 'mj.application' LuaRocks
12 | package since they depend on each other.
13 | - `mj.screen:frame_without_dock_or_menu()` is now called `mj.screen:frame()`
14 | - `mj.screen:frame_including_dock_and_menu()` is now called `mj.screen:fullframe()`
15 |
--------------------------------------------------------------------------------
/Code_of_Conduct.md:
--------------------------------------------------------------------------------
1 | # Contributor Code of Conduct
2 |
3 | 1. Don't make me have to add more things to this.
4 |
--------------------------------------------------------------------------------
/LATESTVERSION:
--------------------------------------------------------------------------------
1 | 0.4.3
2 | https://github.com/sdegutis/mjolnir/releases/download/0.4.3/Mjolnir-0.4.3.tgz
3 | MCwCFG1Wl/1LRJC9MYi/pON1hHGG7iWNAhRqAwvqHNuTZw0tcqf98ZrFx/Wo/Q==
4 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | VERSION = $(shell defaults read `pwd`/Mjolnir/Mjolnir-Info CFBundleVersion)
2 | APPFILE = Mjolnir.app
3 | TGZFILE = Mjolnir-$(VERSION).tgz
4 | ZIPFILE = Mjolnir-$(VERSION).zip
5 | VERSIONFILE = LATESTVERSION
6 |
7 | release: $(TGZFILE) $(ZIPFILE) $(VERSIONFILE)
8 |
9 | $(APPFILE): $(shell find Mjolnir -type f)
10 | rm -rf $@
11 | xcodebuild clean build > /dev/null
12 | cp -R build/Release/Mjolnir.app $@
13 |
14 | $(TGZFILE): $(APPFILE)
15 | tar -czf $@ $<
16 |
17 | $(ZIPFILE): $(APPFILE)
18 | zip -qr $@ $<
19 |
20 | $(VERSIONFILE): $(TGZFILE)
21 | test -n "$(KEYFILE)"
22 | echo $(VERSION) > $@
23 | echo https://github.com/sdegutis/mjolnir/releases/download/$(VERSION)/Mjolnir-$(VERSION).tgz >> $@
24 | openssl dgst -sha1 -binary < $(TGZFILE) | openssl dgst -dss1 -sign $(KEYFILE) | openssl enc -base64 >> $@
25 |
26 | clean:
27 | rm -rf $(APPFILE) $(TGZFILE) $(ZIPFILE)
28 |
29 | .PHONY: release clean
30 |
--------------------------------------------------------------------------------
/Mjolnir/ConsoleWindow.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/Mjolnir/Credits.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf210
2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;}
3 | {\colortbl;\red255\green255\blue255;}
4 | \margl1440\margr1440\vieww22840\viewh13760\viewkind0
5 | \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\qc
6 |
7 | \f0\fs22 \cf0 \
8 | {\field{\*\fldinst{HYPERLINK "http://mjolnir.io"}}{\fldrslt mjolnir.io}}\
9 | \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
10 | \cf0 \
11 |
12 | \b App Icon
13 | \b0 \
14 | \
15 | Created by {\field{\*\fldinst{HYPERLINK "https://github.com/jasonm23/"}}{\fldrslt jasonm23}}\
16 | \
17 |
18 | \b Lua 5.1
19 | \b0 \
20 | \
21 | Copyright (c) 1994-2014 {\field{\*\fldinst{HYPERLINK "http://Lua.org"}}{\fldrslt Lua.org}}, PUC-Rio.\
22 | \
23 | Permission is hereby granted, free of charge, to any person obtaining\
24 | a copy of this software and associated documentation files (the\
25 | "Software"), to deal in the Software without restriction, including\
26 | without limitation the rights to use, copy, modify, merge, publish,\
27 | distribute, sublicense, and/or sell copies of the Software, and to\
28 | permit persons to whom the Software is furnished to do so, subject to\
29 | the following conditions:\
30 | \
31 | The above copyright notice and this permission notice shall be\
32 | included in all copies or substantial portions of the Software.\
33 | \
34 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\
35 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\
36 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\
37 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\
38 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\
39 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\
40 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.}
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "icon_16x16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "icon_16x16@2x.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "icon_32x32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "icon_32x32@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "icon_128x128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "icon_128x128@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "icon_256x256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "icon_256x256@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "icon_512x512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "icon_512x512@2x.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_128x128.png
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_16x16.png
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_256x256.png
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_32x32.png
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_512x512.png
--------------------------------------------------------------------------------
/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png
--------------------------------------------------------------------------------
/Mjolnir/MJAccessibilityUtils.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | BOOL MJAccessibilityIsEnabled(void);
4 | void MJAccessibilityOpenPanel(void);
5 |
--------------------------------------------------------------------------------
/Mjolnir/MJAccessibilityUtils.m:
--------------------------------------------------------------------------------
1 | #import "MJAccessibilityUtils.h"
2 |
3 | extern Boolean AXIsProcessTrustedWithOptions(CFDictionaryRef options) __attribute__((weak_import));
4 | extern CFStringRef kAXTrustedCheckOptionPrompt __attribute__((weak_import));
5 |
6 |
7 | BOOL MJAccessibilityIsEnabled(void) {
8 | if (AXIsProcessTrustedWithOptions != NULL)
9 | return AXIsProcessTrustedWithOptions(NULL);
10 | else
11 | return AXAPIEnabled();
12 | }
13 |
14 | void MJAccessibilityOpenPanel(void) {
15 | if (AXIsProcessTrustedWithOptions != NULL) {
16 | AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)@{(__bridge id)kAXTrustedCheckOptionPrompt: @YES});
17 | }
18 | else {
19 | static NSString* script = @"tell application \"System Preferences\"\nactivate\nset current pane to pane \"com.apple.preference.universalaccess\"\nend tell";
20 | [[[NSAppleScript alloc] initWithSource:script] executeAndReturnError:nil];
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Mjolnir/MJAppDelegate.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import "MJConsoleWindowController.h"
3 | #import "MJPreferencesWindowController.h"
4 | #import "MJUpdateChecker.h"
5 | #import "MJDockIcon.h"
6 | #import "MJMenuIcon.h"
7 | #import "MJLua.h"
8 | #import "MJVersionUtils.h"
9 | #import "MJConfigUtils.h"
10 | #import "MJFileUtils.h"
11 | #import "variables.h"
12 |
13 | @interface MJAppDelegate : NSObject
14 | @property IBOutlet NSMenu* menuBarMenu;
15 | @end
16 |
17 | @implementation MJAppDelegate
18 |
19 | static BOOL MJFirstRunForCurrentVersion(void) {
20 | NSString* key = [NSString stringWithFormat:@"%@_%d", MJHasRunAlreadyKey, MJVersionFromThisApp()];
21 |
22 | BOOL firstRun = ![[NSUserDefaults standardUserDefaults] boolForKey:key];
23 |
24 | if (firstRun)
25 | [[NSUserDefaults standardUserDefaults] setBool:YES forKey:key];
26 |
27 | return firstRun;
28 | }
29 |
30 | - (BOOL) applicationShouldHandleReopen:(NSApplication*)theApplication hasVisibleWindows:(BOOL)hasVisibleWindows {
31 | [[MJConsoleWindowController singleton] showWindow: nil];
32 | return NO;
33 | }
34 |
35 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
36 | MJEnsureDirectoryExists(MJConfigDir());
37 | [[NSFileManager defaultManager] changeCurrentDirectoryPath:MJConfigDir()];
38 |
39 | [self registerDefaultDefaults];
40 | MJMenuIconSetup(self.menuBarMenu);
41 | MJDockIconSetup();
42 | MJUpdateCheckerSetup();
43 | [[MJConsoleWindowController singleton] setup];
44 | MJLuaSetup();
45 |
46 | if (MJFirstRunForCurrentVersion())
47 | [[MJPreferencesWindowController singleton] showWindow: nil];
48 | }
49 |
50 | - (void) registerDefaultDefaults {
51 | [[NSUserDefaults standardUserDefaults]
52 | registerDefaults: @{MJCheckForUpdatesKey: @YES,
53 | MJShowDockIconKey: @YES,
54 | MJShowMenuIconKey: @NO,
55 | MJCheckForUpdatesIntervalKey: @(60.0 * 60.0 * 24.0)}];
56 | }
57 |
58 | - (IBAction) reloadConfig:(id)sender {
59 | MJLuaSetup();
60 | }
61 |
62 | - (IBAction) showConsoleWindow:(id)sender {
63 | [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
64 | [[MJConsoleWindowController singleton] showWindow: nil];
65 | }
66 |
67 | - (IBAction) showPreferencesWindow:(id)sender {
68 | [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
69 | [[MJPreferencesWindowController singleton] showWindow: nil];
70 | }
71 |
72 | - (IBAction) showAboutPanel:(id)sender {
73 | [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
74 | [[NSApplication sharedApplication] orderFrontStandardAboutPanel: nil];
75 | }
76 |
77 | - (IBAction) checkForUpdates:(id)sender {
78 | [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
79 | MJUpdateCheckerCheckVerbosely();
80 | }
81 |
82 | - (IBAction) openConfig:(id)sender {
83 | NSString* path = MJConfigFileFullPath();
84 |
85 | if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
86 | [[NSFileManager defaultManager] createFileAtPath:path
87 | contents:[NSData data]
88 | attributes:nil];
89 | }
90 |
91 | [[NSWorkspace sharedWorkspace] openFile: path];
92 | }
93 |
94 | @end
95 |
96 | int main(int argc, const char * argv[]) {
97 | return NSApplicationMain(argc, argv);
98 | }
99 |
--------------------------------------------------------------------------------
/Mjolnir/MJAutoLaunch.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | BOOL MJAutoLaunchGet(void);
4 | void MJAutoLaunchSet(BOOL opensAtLogin);
5 |
--------------------------------------------------------------------------------
/Mjolnir/MJAutoLaunch.m:
--------------------------------------------------------------------------------
1 | #import "MJAutoLaunch.h"
2 |
3 | static LSSharedFileListRef shared_file_list() {
4 | static LSSharedFileListRef list;
5 | static dispatch_once_t onceToken;
6 | dispatch_once(&onceToken, ^{
7 | list = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
8 | });
9 | return list;
10 | }
11 |
12 | BOOL MJAutoLaunchGet(void) {
13 | NSURL *appURL = [[[NSBundle mainBundle] bundleURL] fileReferenceURL];
14 |
15 | UInt32 seed;
16 | NSArray *sharedFileListArray = (__bridge_transfer NSArray*)LSSharedFileListCopySnapshot(shared_file_list(), &seed);
17 | for (id item in sharedFileListArray) {
18 | LSSharedFileListItemRef sharedFileItem = (__bridge LSSharedFileListItemRef)item;
19 | CFURLRef url = NULL;
20 |
21 | OSStatus result = LSSharedFileListItemResolve(sharedFileItem, 0, &url, NULL);
22 | if (result == noErr && url != NULL) {
23 | BOOL foundIt = [appURL isEqual: [(__bridge NSURL*)url fileReferenceURL]];
24 |
25 | CFRelease(url);
26 |
27 | if (foundIt) {
28 | return YES;
29 | }
30 | }
31 | }
32 |
33 | return NO;
34 | }
35 |
36 | void MJAutoLaunchSet(BOOL opensAtLogin) {
37 | NSURL *appURL = [[[NSBundle mainBundle] bundleURL] fileReferenceURL];
38 |
39 | if (opensAtLogin) {
40 | LSSharedFileListItemRef result = LSSharedFileListInsertItemURL(shared_file_list(),
41 | kLSSharedFileListItemLast,
42 | NULL,
43 | NULL,
44 | (__bridge CFURLRef)appURL,
45 | NULL,
46 | NULL);
47 | CFRelease(result);
48 | }
49 | else {
50 | UInt32 seed;
51 | NSArray *sharedFileListArray = (__bridge_transfer NSArray*)LSSharedFileListCopySnapshot(shared_file_list(), &seed);
52 | for (id item in sharedFileListArray) {
53 | LSSharedFileListItemRef sharedFileItem = (__bridge LSSharedFileListItemRef)item;
54 | CFURLRef url = NULL;
55 |
56 | OSStatus result = LSSharedFileListItemResolve(sharedFileItem, 0, &url, NULL);
57 | if (result == noErr && url != nil) {
58 | if ([appURL isEqual: [(__bridge NSURL*)url fileReferenceURL]])
59 | LSSharedFileListItemRemove(shared_file_list(), sharedFileItem);
60 |
61 | CFRelease(url);
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Mjolnir/MJAutoUpdaterWindowController.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "MJUpdate.h"
3 |
4 | @interface MJAutoUpdaterWindowController : NSWindowController
5 |
6 | @property MJUpdate* update;
7 | @property NSString* error;
8 |
9 | - (void) showCheckingPage;
10 | - (void) showUpToDatePage;
11 | - (void) showFoundPage;
12 | - (void) showErrorPage;
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/Mjolnir/MJAutoUpdaterWindowController.m:
--------------------------------------------------------------------------------
1 | #import "MJAutoUpdaterWindowController.h"
2 | #import "variables.h"
3 |
4 | @interface MJAutoUpdaterWindowController ()
5 |
6 | @property (weak) IBOutlet NSTabView* tabView;
7 | @property (weak) IBOutlet NSProgressIndicator* checkingProgressBar;
8 | @property (weak) IBOutlet NSProgressIndicator* installationProgressBar;
9 | @property (weak) IBOutlet NSButton* showChangeLogButton;
10 |
11 | @end
12 |
13 | @implementation MJAutoUpdaterWindowController
14 |
15 | - (NSString*) windowNibName {
16 | return @"AutoUpdaterWindow";
17 | }
18 |
19 | - (IBAction) showReleaseNotes:(id)sender {
20 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:MJReleaseNotesURL]];
21 | }
22 |
23 | - (void) windowDidLoad {
24 | [super windowDidLoad];
25 | [self.checkingProgressBar startAnimation:self];
26 | [self.installationProgressBar startAnimation:self];
27 | [self makeFakeLink];
28 | }
29 |
30 | - (void) makeFakeLink {
31 | NSRange r = NSMakeRange(0, [[self.showChangeLogButton title] length]);
32 | NSMutableAttributedString* title = [[self.showChangeLogButton attributedTitle] mutableCopy];
33 | [title addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range: r];
34 | [title addAttribute:NSUnderlineStyleAttributeName value:@1 range: r];
35 | [self.showChangeLogButton setAttributedTitle:title];
36 | }
37 |
38 | - (IBAction) dismiss:(id)sender {
39 | [self close];
40 | }
41 |
42 | - (IBAction) cancel:(id)sender {
43 | [self close];
44 | }
45 |
46 | - (IBAction) install:(id)sender {
47 | [self showInstallingPage];
48 | [self.update install:^(NSString *error, NSString *reason) {
49 | self.error = [NSString stringWithFormat:@"%@ (%@)", error, reason];
50 | [self showErrorPage];
51 | }];
52 | }
53 |
54 | - (IBAction) visitDownloadPage:(id)sender {
55 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:MJDownloadPage]];
56 | [self close];
57 | }
58 |
59 | - (void) showTab:(int)n {
60 | NSDisableScreenUpdates();
61 | if (![[self window] isVisible])
62 | [[self window] center];
63 | [[self window] makeKeyAndOrderFront: self];
64 | [self.tabView selectTabViewItemAtIndex:n];
65 | NSEnableScreenUpdates();
66 | }
67 |
68 | - (void) showCheckingPage {
69 | self.error = nil;
70 | [self showTab: 0];
71 | }
72 |
73 | - (void) showUpToDatePage {
74 | self.error = nil;
75 | [self showTab: 1];
76 | }
77 |
78 | - (void) showFoundPage {
79 | self.error = nil;
80 | [self showTab: 2];
81 | }
82 |
83 | - (void) showErrorPage {
84 | [self showTab: 3];
85 | }
86 |
87 | - (void) showInstallingPage {
88 | self.error = nil;
89 | [self showTab: 4];
90 | }
91 |
92 | @end
93 |
94 | @interface MJLinkButton : NSButton
95 | @end
96 |
97 | @implementation MJLinkButton
98 |
99 | - (void)resetCursorRects {
100 | [self addCursorRect:[self bounds]
101 | cursor:[NSCursor pointingHandCursor]];
102 | }
103 |
104 | @end
105 |
--------------------------------------------------------------------------------
/Mjolnir/MJConfigUtils.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | NSString* MJConfigDir(void);
4 | NSString* MJConfigFileFullPath(void);
5 |
--------------------------------------------------------------------------------
/Mjolnir/MJConfigUtils.m:
--------------------------------------------------------------------------------
1 | #import "MJConfigUtils.h"
2 | #import "variables.h"
3 |
4 | NSString* MJConfigDir(void) {
5 | return [MJConfigFileFullPath() stringByDeletingLastPathComponent];
6 | }
7 |
8 | NSString* MJConfigFileFullPath(void) {
9 | return [MJConfigFile stringByStandardizingPath];
10 | }
11 |
--------------------------------------------------------------------------------
/Mjolnir/MJConsoleWindowController.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface MJConsoleWindowController : NSWindowController
4 |
5 | + (instancetype) singleton;
6 | - (void) setup;
7 |
8 | @end
9 |
10 | BOOL MJConsoleWindowAlwaysOnTop(void);
11 | void MJConsoleWindowSetAlwaysOnTop(BOOL alwaysOnTop);
12 |
--------------------------------------------------------------------------------
/Mjolnir/MJConsoleWindowController.m:
--------------------------------------------------------------------------------
1 | #import "MJConsoleWindowController.h"
2 | #import "MJLua.h"
3 | #import "variables.h"
4 |
5 | #define MJColorForStdout [NSColor colorWithCalibratedHue:0.88 saturation:1.0 brightness:0.6 alpha:1.0]
6 | #define MJColorForCommand [NSColor blackColor]
7 | #define MJColorForResult [NSColor colorWithCalibratedHue:0.54 saturation:1.0 brightness:0.7 alpha:1.0]
8 |
9 | @interface MJConsoleWindowController ()
10 |
11 | @property NSMutableArray* history;
12 | @property NSInteger historyIndex;
13 | @property IBOutlet NSTextView* outputView;
14 | @property (weak) IBOutlet NSTextField* inputField;
15 | @property NSMutableArray* preshownStdouts;
16 |
17 | @end
18 |
19 | typedef NS_ENUM(NSUInteger, MJReplLineType) {
20 | MJReplLineTypeCommand,
21 | MJReplLineTypeResult,
22 | MJReplLineTypeStdout,
23 | };
24 |
25 | @implementation MJConsoleWindowController
26 |
27 | - (NSString*) windowNibName {
28 | return @"ConsoleWindow";
29 | }
30 |
31 | + (instancetype) singleton {
32 | static MJConsoleWindowController* s;
33 | static dispatch_once_t onceToken;
34 | dispatch_once(&onceToken, ^{
35 | s = [[MJConsoleWindowController alloc] init];
36 | });
37 | return s;
38 | }
39 |
40 | - (void) setup {
41 | self.preshownStdouts = [NSMutableArray array];
42 | MJLuaSetupLogHandler(^(NSString* str){
43 | if (self.outputView) {
44 | [self appendString:str type:MJReplLineTypeStdout];
45 | [self.outputView scrollToEndOfDocument:self];
46 | }
47 | else {
48 | [self.preshownStdouts addObject:str];
49 | }
50 | });
51 | [self reflectDefaults];
52 | }
53 |
54 | - (void) reflectDefaults {
55 | [[self window] setLevel: MJConsoleWindowAlwaysOnTop() ? NSFloatingWindowLevel : NSNormalWindowLevel];
56 | }
57 |
58 | - (void) windowDidLoad {
59 | [[self window] center];
60 |
61 | self.history = [NSMutableArray array];
62 | [self.outputView setEditable:NO];
63 | [self.outputView setSelectable:YES];
64 |
65 | [self appendString:@""
66 | "Welcome to the Mjolnir Console!\n"
67 | "You can run any Lua code in here.\n\n"
68 | type:MJReplLineTypeStdout];
69 |
70 | for (NSString* str in self.preshownStdouts)
71 | [self appendString:str type:MJReplLineTypeStdout];
72 |
73 | [self.outputView scrollToEndOfDocument:self];
74 | self.preshownStdouts = nil;
75 | }
76 |
77 | - (void) appendString:(NSString*)str type:(MJReplLineType)type {
78 | NSColor* color = nil;
79 | switch (type) {
80 | case MJReplLineTypeStdout: color = MJColorForStdout; break;
81 | case MJReplLineTypeCommand: color = MJColorForCommand; break;
82 | case MJReplLineTypeResult: color = MJColorForResult; break;
83 | }
84 |
85 | NSDictionary* attrs = @{NSFontAttributeName: [NSFont fontWithName:@"Menlo" size:12.0], NSForegroundColorAttributeName: color};
86 | NSAttributedString* attrstr = [[NSAttributedString alloc] initWithString:str attributes:attrs];
87 | [[self.outputView textStorage] appendAttributedString:attrstr];
88 | }
89 |
90 | - (NSString*) run:(NSString*)command {
91 | return MJLuaRunString(command);
92 | }
93 |
94 | - (IBAction) tryMessage:(NSTextField*)sender {
95 | NSString* command = [sender stringValue];
96 | [self appendString:[NSString stringWithFormat:@"\n> %@\n", command] type:MJReplLineTypeCommand];
97 |
98 | NSString* result = [self run:command];
99 | [self appendString:[NSString stringWithFormat:@"%@\n", result] type:MJReplLineTypeResult];
100 |
101 | [sender setStringValue:@""];
102 | [self saveToHistory:command];
103 | [self.outputView scrollToEndOfDocument:self];
104 | }
105 |
106 | - (void) saveToHistory:(NSString*)cmd {
107 | [self.history addObject:cmd];
108 | self.historyIndex = [self.history count];
109 | [self useCurrentHistoryIndex];
110 | }
111 |
112 | - (void) goPrevHistory {
113 | self.historyIndex = MAX(self.historyIndex - 1, 0);
114 | [self useCurrentHistoryIndex];
115 | }
116 |
117 | - (void) goNextHistory {
118 | self.historyIndex = MIN(self.historyIndex + 1, [self.history count]);
119 | [self useCurrentHistoryIndex];
120 | }
121 |
122 | - (void) useCurrentHistoryIndex {
123 | if (self.historyIndex == [self.history count])
124 | [self.inputField setStringValue: @""];
125 | else
126 | [self.inputField setStringValue: [self.history objectAtIndex:self.historyIndex]];
127 |
128 | NSText* editor = [[self.inputField window] fieldEditor:YES forObject:self.inputField];
129 | [editor moveToEndOfDocument:self];
130 | }
131 |
132 | - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command {
133 | if (command == @selector(moveUp:)) {
134 | [self goPrevHistory];
135 | return YES;
136 | }
137 | else if (command == @selector(moveDown:)) {
138 | [self goNextHistory];
139 | return YES;
140 | }
141 | return NO;
142 | }
143 |
144 | BOOL MJConsoleWindowAlwaysOnTop(void) {
145 | return [[NSUserDefaults standardUserDefaults] boolForKey: MJKeepConsoleOnTopKey];
146 | }
147 |
148 | void MJConsoleWindowSetAlwaysOnTop(BOOL alwaysOnTop) {
149 | [[NSUserDefaults standardUserDefaults] setBool:alwaysOnTop
150 | forKey:MJKeepConsoleOnTopKey];
151 | [[MJConsoleWindowController singleton] reflectDefaults];
152 | }
153 |
154 | @end
155 |
--------------------------------------------------------------------------------
/Mjolnir/MJDockIcon.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | void MJDockIconSetup(void);
4 | BOOL MJDockIconVisible(void);
5 | void MJDockIconSetVisible(BOOL visible);
6 |
--------------------------------------------------------------------------------
/Mjolnir/MJDockIcon.m:
--------------------------------------------------------------------------------
1 | #import "MJDockIcon.h"
2 | #import "variables.h"
3 |
4 | static void reflect_defaults(void);
5 |
6 | void MJDockIconSetup(void) {
7 | reflect_defaults();
8 | }
9 |
10 | BOOL MJDockIconVisible(void) {
11 | return [[NSUserDefaults standardUserDefaults] boolForKey:MJShowDockIconKey];
12 | }
13 |
14 | void MJDockIconSetVisible(BOOL visible) {
15 | [[NSUserDefaults standardUserDefaults] setBool:visible
16 | forKey:MJShowDockIconKey];
17 | reflect_defaults();
18 | }
19 |
20 | static void reflect_defaults(void) {
21 | NSApplication* app = [NSApplication sharedApplication]; // NSApp is typed to 'id'; lame
22 | NSDisableScreenUpdates();
23 | [app setActivationPolicy: MJDockIconVisible() ? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory];
24 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
25 | [app unhide: nil];
26 | [app activateIgnoringOtherApps:YES];
27 | NSEnableScreenUpdates();
28 | });
29 | }
30 |
--------------------------------------------------------------------------------
/Mjolnir/MJFileUtils.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | void MJDownloadFile(NSString* url, void(^handler)(NSError* err, NSData* data));
4 | NSString* MJCreateEmptyTempDirectory(NSString* prefix, NSError* __autoreleasing* error);
5 | BOOL MJUntar(NSData* tardata, NSString* intoDirectory, NSError*__autoreleasing* error);
6 | BOOL MJEnsureDirectoryExists(NSString* dir);
7 |
--------------------------------------------------------------------------------
/Mjolnir/MJFileUtils.m:
--------------------------------------------------------------------------------
1 | #import "MJFileUtils.h"
2 |
3 | void MJDownloadFile(NSString* url, void(^handler)(NSError* err, NSData* data)) {
4 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
5 | [NSURLConnection sendAsynchronousRequest:req
6 | queue:[NSOperationQueue mainQueue]
7 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
8 | handler(connectionError, data);
9 | }];
10 | }
11 |
12 | NSString* MJCreateEmptyTempDirectory(NSString* prefix, NSError* __autoreleasing* error) {
13 | NSString* relativeTemplate = [NSString stringWithFormat:@"%@XXXXXX", prefix];
14 | const char* tempFileTemplate = [[NSTemporaryDirectory() stringByAppendingPathComponent:relativeTemplate] fileSystemRepresentation];
15 | char* tempFileName = malloc(strlen(tempFileTemplate) + 1);
16 | strcpy(tempFileName, tempFileTemplate);
17 |
18 | NSString* path = nil;
19 |
20 | if (mkdtemp(tempFileName))
21 | path = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:tempFileName length:strlen(tempFileName)];
22 | else
23 | *error = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil];
24 |
25 | free(tempFileName);
26 | return path;
27 | }
28 |
29 | BOOL MJUntar(NSData* tardata, NSString* intoDirectory, NSError*__autoreleasing* error) {
30 | BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:intoDirectory withIntermediateDirectories:YES attributes:nil error:error];
31 | if (!success) return NO;
32 |
33 | NSPipe* pipe = [NSPipe pipe];
34 | NSTask* untar = [[NSTask alloc] init];
35 | [untar setLaunchPath:@"/usr/bin/tar"];
36 | [untar setArguments:@[@"-xzf-", @"-C", intoDirectory]];
37 | [untar setStandardInput:pipe];
38 | [untar launch];
39 | [[pipe fileHandleForWriting] writeData:tardata];
40 | [[pipe fileHandleForWriting] closeFile];
41 | [untar waitUntilExit];
42 | if ([untar terminationStatus]) {
43 | *error = [NSError errorWithDomain:@"tar" code:[untar terminationStatus] userInfo:@{NSLocalizedDescriptionKey: @"could not extract the tgz archive"}];
44 | return NO;
45 | }
46 |
47 | return YES;
48 | }
49 |
50 | BOOL MJEnsureDirectoryExists(NSString* dir) {
51 | return [[NSFileManager defaultManager] createDirectoryAtPath:dir
52 | withIntermediateDirectories:YES
53 | attributes:nil
54 | error:NULL];
55 | }
56 |
--------------------------------------------------------------------------------
/Mjolnir/MJLua.h:
--------------------------------------------------------------------------------
1 | #import "lauxlib.h"
2 | #import "lualib.h"
3 |
4 | void MJLuaSetup(void);
5 | void MJLuaSetupLogHandler(void(^blk)(NSString* str));
6 | NSString* MJLuaRunString(NSString* command);
7 | NSString* MJFindInitFile(void);
8 |
--------------------------------------------------------------------------------
/Mjolnir/MJLua.m:
--------------------------------------------------------------------------------
1 | #import "MJLua.h"
2 | #import "MJConsoleWindowController.h"
3 | #import "MJUserNotificationManager.h"
4 | #import "MJConfigUtils.h"
5 | #import "variables.h"
6 |
7 | static lua_State* MJLuaState;
8 | static int evalfn;
9 |
10 | /// === mjolnir ===
11 | ///
12 | /// Core Mjolnir functionality.
13 |
14 | static void(^loghandler)(NSString* str);
15 | void MJLuaSetupLogHandler(void(^blk)(NSString* str)) {
16 | loghandler = blk;
17 | }
18 |
19 | /// mjolnir.openconsole()
20 | /// Function
21 | /// Opens the Mjolnir Console window and focuses it.
22 | static int core_openconsole(lua_State* L) {
23 | [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
24 | [[MJConsoleWindowController singleton] showWindow: nil];
25 | return 0;
26 | }
27 |
28 | /// mjolnir.reload()
29 | /// Function
30 | /// Reloads your init-file in a fresh Lua environment.
31 | static int core_reload(lua_State* L) {
32 | dispatch_async(dispatch_get_main_queue(), ^{
33 | MJLuaSetup();
34 | });
35 | return 0;
36 | }
37 |
38 | /// mjolnir.focus()
39 | /// Function
40 | /// Makes Mjolnir the foreground app.
41 | static int core_focus(lua_State* L) {
42 | [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
43 | return 0;
44 | }
45 |
46 | static int core_exit(lua_State* L) {
47 | if (lua_toboolean(L, 2))
48 | lua_close(L);
49 |
50 | [[NSApplication sharedApplication] terminate: nil];
51 | return 0; // lol
52 | }
53 |
54 | static int core_logmessage(lua_State* L) {
55 | size_t len;
56 | const char* s = lua_tolstring(L, 1, &len);
57 | NSString* str = [[NSString alloc] initWithData:[NSData dataWithBytes:s length:len] encoding:NSUTF8StringEncoding];
58 | loghandler(str);
59 | return 0;
60 | }
61 |
62 | static int core_notify(lua_State* L) {
63 | size_t len;
64 | const char* s = lua_tolstring(L, 1, &len);
65 | NSString* str = [[NSString alloc] initWithData:[NSData dataWithBytes:s length:len] encoding:NSUTF8StringEncoding];
66 | [[MJUserNotificationManager sharedManager] sendNotification:str handler:^{
67 | [[MJConsoleWindowController singleton] showWindow: nil];
68 | }];
69 | return 0;
70 | }
71 |
72 | static luaL_Reg corelib[] = {
73 | {"openconsole", core_openconsole},
74 | {"reload", core_reload},
75 | {"focus", core_focus},
76 | {"_exit", core_exit},
77 | {"_logmessage", core_logmessage},
78 | {"_notify", core_notify},
79 | {}
80 | };
81 |
82 | void MJLuaSetup(void) {
83 | if (MJLuaState)
84 | lua_close(MJLuaState);
85 |
86 | lua_State* L = MJLuaState = luaL_newstate();
87 | luaL_openlibs(L);
88 |
89 | luaL_newlib(L, corelib);
90 | lua_setglobal(L, "mjolnir");
91 |
92 | luaL_loadfile(L, [[[NSBundle mainBundle] pathForResource:@"setup" ofType:@"lua"] fileSystemRepresentation]);
93 |
94 | lua_pushstring(L, [MJConfigFile UTF8String]);
95 | lua_pushstring(L, [MJConfigFileFullPath() UTF8String]);
96 | lua_pushstring(L, [MJConfigDir() UTF8String]);
97 | lua_pushboolean(L, [[NSFileManager defaultManager] fileExistsAtPath: MJConfigFileFullPath()]);
98 |
99 | lua_pcall(L, 4, 1, 0);
100 |
101 | evalfn = luaL_ref(L, LUA_REGISTRYINDEX);
102 | }
103 |
104 | NSString* MJLuaRunString(NSString* command) {
105 | lua_State* L = MJLuaState;
106 |
107 | lua_rawgeti(L, LUA_REGISTRYINDEX, evalfn);
108 | lua_pushstring(L, [command UTF8String]);
109 | lua_call(L, 1, 1);
110 |
111 | size_t len;
112 | const char* s = lua_tolstring(L, -1, &len);
113 | NSString* str = [[NSString alloc] initWithData:[NSData dataWithBytes:s length:len] encoding:NSUTF8StringEncoding];
114 | lua_pop(L, 1);
115 |
116 | return str;
117 | }
118 |
--------------------------------------------------------------------------------
/Mjolnir/MJMenuIcon.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | void MJMenuIconSetup(NSMenu* menu);
4 | BOOL MJMenuIconVisible(void);
5 | void MJMenuIconSetVisible(BOOL visible);
6 |
--------------------------------------------------------------------------------
/Mjolnir/MJMenuIcon.m:
--------------------------------------------------------------------------------
1 | #import "MJMenuIcon.h"
2 | #import "variables.h"
3 |
4 | static void reflect_defaults(void);
5 |
6 | static NSStatusItem* statusItem;
7 | static NSMenu* menuItemMenu;
8 |
9 | void MJMenuIconSetup(NSMenu* menu) {
10 | menuItemMenu = menu;
11 | reflect_defaults();
12 | }
13 |
14 | BOOL MJMenuIconVisible(void) {
15 | return [[NSUserDefaults standardUserDefaults] boolForKey:MJShowMenuIconKey];
16 | }
17 |
18 | void MJMenuIconSetVisible(BOOL visible) {
19 | [[NSUserDefaults standardUserDefaults] setBool:visible
20 | forKey:MJShowMenuIconKey];
21 | reflect_defaults();
22 | }
23 |
24 | static void reflect_defaults(void) {
25 | if (MJMenuIconVisible()) {
26 | NSImage* icon = [NSImage imageNamed:@"statusicon"];
27 | [icon setTemplate:YES];
28 |
29 | statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
30 | [statusItem setImage:icon];
31 | [statusItem setHighlightMode:YES];
32 | [statusItem setMenu: menuItemMenu];
33 | }
34 | else {
35 | if (statusItem) {
36 | [[NSStatusBar systemStatusBar] removeStatusItem: statusItem];
37 | statusItem = nil;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Mjolnir/MJPreferencesWindowController.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface MJPreferencesWindowController : NSWindowController
4 |
5 | + (instancetype) singleton;
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/Mjolnir/MJPreferencesWindowController.m:
--------------------------------------------------------------------------------
1 | #import "MJPreferencesWindowController.h"
2 | #import "MJAutoLaunch.h"
3 | #import "MJLua.h"
4 | #import "MJUpdateChecker.h"
5 | #import "MJDockIcon.h"
6 | #import "MJMenuIcon.h"
7 | #import "MJAccessibilityUtils.h"
8 | #import "MJConsoleWindowController.h"
9 | #import "variables.h"
10 |
11 | #define MJSkipDockMenuIconProblemAlertKey @"MJSkipDockMenuIconProblemAlertKey"
12 |
13 | @interface MJPreferencesWindowController ()
14 |
15 | @property (weak) IBOutlet NSButton* openAtLoginCheckbox;
16 | @property (weak) IBOutlet NSButton* showDockIconCheckbox;
17 | @property (weak) IBOutlet NSButton* showMenuIconCheckbox;
18 | @property (weak) IBOutlet NSButton* checkForUpdatesCheckbox;
19 | @property (weak) IBOutlet NSButton* keepConsoleOnTopCheckbox;
20 |
21 | @property BOOL isAccessibilityEnabled;
22 |
23 | @end
24 |
25 | @implementation MJPreferencesWindowController
26 |
27 | + (instancetype) singleton {
28 | static MJPreferencesWindowController* s;
29 | static dispatch_once_t onceToken;
30 | dispatch_once(&onceToken, ^{
31 | s = [[MJPreferencesWindowController alloc] init];
32 | });
33 | return s;
34 | }
35 |
36 | - (void) showWindow:(id)sender {
37 | if (![[self window] isVisible])
38 | [[self window] center];
39 | [super showWindow: sender];
40 | }
41 |
42 | - (NSString*) windowNibName {
43 | return @"PreferencesWindow";
44 | }
45 |
46 | - (void)windowDidLoad {
47 | dispatch_async(dispatch_get_main_queue(), ^{
48 | [self cacheIsAccessibilityEnabled];
49 | });
50 |
51 | [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(accessibilityChanged:) name:@"com.apple.accessibility.api" object:nil];
52 |
53 | [self.openAtLoginCheckbox setState:MJAutoLaunchGet() ? NSOnState : NSOffState];
54 | [self.showDockIconCheckbox setState: MJDockIconVisible() ? NSOnState : NSOffState];
55 | [self.showMenuIconCheckbox setState: MJMenuIconVisible() ? NSOnState : NSOffState];
56 | [self.checkForUpdatesCheckbox setState: MJUpdateCheckerEnabled() ? NSOnState : NSOffState];
57 | [self.keepConsoleOnTopCheckbox setState: MJConsoleWindowAlwaysOnTop() ? NSOnState : NSOffState];
58 | }
59 |
60 | - (void) accessibilityChanged:(NSNotification*)note {
61 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
62 | [self cacheIsAccessibilityEnabled];
63 | });
64 | }
65 |
66 | - (void) cacheIsAccessibilityEnabled {
67 | self.isAccessibilityEnabled = MJAccessibilityIsEnabled();
68 | }
69 |
70 | - (NSString*) maybeEnableAccessibilityString {
71 | if (self.isAccessibilityEnabled)
72 | return @"Accessibility is enabled. You're all set!";
73 | else
74 | return @"Enable Accessibility for best results.";
75 | }
76 |
77 | - (NSImage*) isAccessibilityEnabledImage {
78 | if (self.isAccessibilityEnabled)
79 | return [NSImage imageNamed:NSImageNameStatusAvailable];
80 | else
81 | return [NSImage imageNamed:NSImageNameStatusPartiallyAvailable];
82 | }
83 |
84 | + (NSSet*) keyPathsForValuesAffectingMaybeEnableAccessibilityString {
85 | return [NSSet setWithArray:@[@"isAccessibilityEnabled"]];
86 | }
87 |
88 | + (NSSet*) keyPathsForValuesAffectingIsAccessibilityEnabledImage {
89 | return [NSSet setWithArray:@[@"isAccessibilityEnabled"]];
90 | }
91 |
92 | - (IBAction) openAccessibility:(id)sender {
93 | MJAccessibilityOpenPanel();
94 | }
95 |
96 | - (IBAction) toggleOpensAtLogin:(NSButton*)sender {
97 | BOOL enabled = [sender state] == NSOnState;
98 | MJAutoLaunchSet(enabled);
99 | }
100 |
101 | - (IBAction) toggleShowDockIcon:(NSButton*)sender {
102 | [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(actuallyToggleShowDockIcon) object:nil];
103 | [self performSelector:@selector(actuallyToggleShowDockIcon) withObject:nil afterDelay:0.3];
104 | }
105 |
106 | - (void) actuallyToggleShowDockIcon {
107 | BOOL enabled = [self.showDockIconCheckbox state] == NSOnState;
108 | MJDockIconSetVisible(enabled);
109 | [self maybeWarnAboutDockMenuProblem];
110 | }
111 |
112 | - (IBAction) toggleMenuDockIcon:(NSButton*)sender {
113 | BOOL enabled = [sender state] == NSOnState;
114 | MJMenuIconSetVisible(enabled);
115 | [self maybeWarnAboutDockMenuProblem];
116 | }
117 |
118 | - (IBAction) toggleCheckForUpdates:(NSButton*)sender {
119 | MJUpdateCheckerSetEnabled([sender state] == NSOnState);
120 | if (MJUpdateCheckerEnabled())
121 | MJUpdateCheckerCheckSilently();
122 | }
123 |
124 | - (IBAction) toggleKeepConsoleOnTop:(id)sender {
125 | MJConsoleWindowSetAlwaysOnTop([sender state] == NSOnState);
126 | }
127 |
128 | - (void) dockMenuProblemAlertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
129 | BOOL skipNextTime = ([[alert suppressionButton] state] == NSOnState);
130 | [[NSUserDefaults standardUserDefaults] setBool:skipNextTime forKey:MJSkipDockMenuIconProblemAlertKey];
131 | }
132 |
133 | - (void) maybeWarnAboutDockMenuProblem {
134 | if (MJMenuIconVisible() || MJDockIconVisible())
135 | return;
136 |
137 | if ([[NSUserDefaults standardUserDefaults] boolForKey:MJSkipDockMenuIconProblemAlertKey])
138 | return;
139 |
140 | NSAlert* alert = [[NSAlert alloc] init];
141 | [alert setAlertStyle:NSWarningAlertStyle];
142 | [alert setMessageText:@"How to get back to this window"];
143 | [alert setInformativeText:@"When both the dock icon and menu icon are disabled, you can get back to this Preferences window by activating Mjolnir from Spotlight or by running `open -a Mjolnir` from Terminal, and then pressing Command + Comma."];
144 | [alert setShowsSuppressionButton:YES];
145 | [alert beginSheetModalForWindow:[self window]
146 | modalDelegate:self
147 | didEndSelector:@selector(dockMenuProblemAlertDidEnd:returnCode:contextInfo:)
148 | contextInfo:NULL];
149 | }
150 |
151 | @end
152 |
--------------------------------------------------------------------------------
/Mjolnir/MJSecurityUtils.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | BOOL MJVerifySignedData(NSData* sig, NSData* data);
4 |
--------------------------------------------------------------------------------
/Mjolnir/MJSecurityUtils.m:
--------------------------------------------------------------------------------
1 | #import "MJSecurityUtils.h"
2 | #import
3 | #import "variables.h"
4 |
5 | static SecKeyRef MJCreatePublicKey(void) {
6 | CFArrayRef items = NULL;
7 | SecKeyRef security_key = NULL;
8 |
9 | NSData* pubkeyData = [MJPublicKey dataUsingEncoding:NSUTF8StringEncoding];
10 | if ([pubkeyData length] == 0) goto cleanup;
11 |
12 | SecExternalFormat format = kSecFormatOpenSSL;
13 | SecExternalItemType itemType = kSecItemTypePublicKey;
14 | SecItemImportExportKeyParameters parameters = {};
15 |
16 | OSStatus status = SecItemImport((__bridge CFDataRef)pubkeyData, NULL, &format, &itemType, 0, ¶meters, NULL, &items);
17 |
18 | if (status != noErr) { printf("invalid status: %d\n", status); goto cleanup; }
19 | if (items == NULL) { printf("items were unexpectedly null\n"); goto cleanup; }
20 | if (format != kSecFormatOpenSSL) { printf("format isn't kSecFormatOpenSSL: %d\n", format); goto cleanup; }
21 | if (itemType != kSecItemTypePublicKey) { printf("item type isn't kSecItemTypePublicKey: %d\n", itemType); goto cleanup; }
22 | if (CFArrayGetCount(items) != 1) { printf("items count isn't 1, it's: %ld\n", CFArrayGetCount(items)); goto cleanup; }
23 |
24 | security_key = (SecKeyRef)CFRetain(CFArrayGetValueAtIndex(items, 0));
25 |
26 | cleanup:
27 | if (items) CFRelease(items);
28 | return security_key;
29 | }
30 |
31 | static NSData* MJDataFromBase64String(NSData* indata, CFErrorRef* error) {
32 | CFDataRef result = NULL;
33 |
34 | SecTransformRef decoder = SecDecodeTransformCreate(kSecBase64Encoding, error);
35 | if (!decoder) goto cleanup;
36 |
37 | SecTransformSetAttribute(decoder, kSecTransformInputAttributeName, (__bridge CFTypeRef)indata, error);
38 | if (*error) goto cleanup;
39 |
40 | result = SecTransformExecute(decoder, error);
41 |
42 | cleanup:
43 |
44 | if (decoder) CFRelease(decoder);
45 | return (__bridge_transfer NSData*)result;
46 | }
47 |
48 | BOOL MJVerifySignedData(NSData* sig, NSData* data) {
49 | BOOL verified = NO;
50 |
51 | SecKeyRef security_key = NULL;
52 |
53 | NSData *signature = nil;
54 | NSInputStream *input_stream = nil;
55 |
56 | SecGroupTransformRef group = SecTransformCreateGroupTransform();
57 | SecTransformRef read_transform = NULL;
58 | SecTransformRef digest_transform = NULL;
59 | SecTransformRef verify_transform = NULL;
60 | CFErrorRef error = NULL;
61 | CFBooleanRef success = NULL;
62 |
63 | security_key = MJCreatePublicKey();
64 | if (security_key == NULL) { printf("security key was null\n"); goto cleanup; }
65 |
66 | signature = MJDataFromBase64String(sig, &error);
67 | if (signature == nil) { printf("signature was null\n"); goto cleanup; }
68 |
69 | input_stream = [NSInputStream inputStreamWithData:data];
70 | if (input_stream == nil) { printf("input stream was null\n"); goto cleanup; }
71 |
72 | read_transform = SecTransformCreateReadTransformWithReadStream((__bridge CFReadStreamRef)input_stream);
73 | if (read_transform == NULL) { printf("read transform was null\n"); goto cleanup; }
74 |
75 | digest_transform = SecDigestTransformCreate(kSecDigestSHA1, CC_SHA1_DIGEST_LENGTH, NULL);
76 | if (digest_transform == NULL) { printf("digest transform was null\n"); goto cleanup; }
77 |
78 | verify_transform = SecVerifyTransformCreate(security_key, (__bridge CFDataRef)signature, NULL);
79 | if (verify_transform == NULL) { printf("verify transform was null\n"); goto cleanup; }
80 |
81 | SecTransformConnectTransforms(read_transform, kSecTransformOutputAttributeName, digest_transform, kSecTransformInputAttributeName, group, &error);
82 | if (error) { printf("read transform failed to connect to digest transform:\n"); CFShow(error); goto cleanup; }
83 |
84 | SecTransformConnectTransforms(digest_transform, kSecTransformOutputAttributeName, verify_transform, kSecTransformInputAttributeName, group, &error);
85 | if (error) { printf("digest transform failed to connect to verify transform:\n"); CFShow(error); goto cleanup; }
86 |
87 | success = SecTransformExecute(group, &error);
88 | if (error) { printf("executing transform failed: %ld\n", CFErrorGetCode(error)); CFShow(error); goto cleanup; }
89 |
90 | verified = CFBooleanGetValue(success);
91 |
92 | cleanup:
93 |
94 | if (group) CFRelease(group);
95 | if (security_key) CFRelease(security_key);
96 | if (read_transform) CFRelease(read_transform);
97 | if (digest_transform) CFRelease(digest_transform);
98 | if (verify_transform) CFRelease(verify_transform);
99 | if (success) CFRelease(success);
100 | if (error) CFRelease(error);
101 |
102 | return verified;
103 | }
104 |
--------------------------------------------------------------------------------
/Mjolnir/MJUpdate.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface MJUpdate : NSObject
4 |
5 | @property NSString* newerVersion;
6 | @property NSString* yourVersion;
7 | @property BOOL canAutoInstall;
8 |
9 | + (void) checkForUpdate:(void(^)(MJUpdate* updater, NSError* connError))handler;
10 | - (void) install:(void(^)(NSString* error, NSString* reason))handler;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Mjolnir/MJUpdate.m:
--------------------------------------------------------------------------------
1 | #import "MJUpdate.h"
2 | #import "MJFileUtils.h"
3 | #import "MJSecurityUtils.h"
4 | #import "MJVersionUtils.h"
5 | #import "variables.h"
6 |
7 | @interface MJUpdate ()
8 | @property NSString* downloadURL;
9 | @property NSString* signature;
10 | @end
11 |
12 | @implementation MJUpdate
13 |
14 | + (void) checkForUpdate:(void(^)(MJUpdate* updater, NSError* connError))handler {
15 | MJDownloadFile(MJUpdatesURL, ^(NSError *connectionError, NSData *data) {
16 | if (!data) {
17 | handler(nil, connectionError);
18 | return;
19 | }
20 |
21 | NSString* wholeString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
22 | NSArray* lines = [wholeString componentsSeparatedByString:@"\n"];
23 | NSString* versionString = [lines objectAtIndex:0];
24 | NSString* tgzURL = [lines objectAtIndex:1];
25 | NSString* signature = [lines objectAtIndex:2];
26 |
27 | if (MJVersionFromString(versionString) <= MJVersionFromThisApp()) {
28 | handler(nil, nil);
29 | return;
30 | }
31 |
32 | MJUpdate* updater = [[MJUpdate alloc] init];
33 | updater.signature = signature;
34 | updater.downloadURL = tgzURL;
35 | updater.newerVersion = versionString;
36 | updater.yourVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
37 | updater.canAutoInstall = [[NSFileManager defaultManager] isDeletableFileAtPath:[[NSBundle mainBundle] bundlePath]];
38 | handler(updater, nil);
39 | });
40 | }
41 |
42 | - (void) install:(void(^)(NSString* error, NSString* reason))handler {
43 | MJDownloadFile(self.downloadURL, ^(NSError *connectionError, NSData *tgzdata) {
44 | if (!tgzdata) {
45 | handler(@"Error downloading Mjolnir.tgz", [connectionError localizedDescription]);
46 | return;
47 | }
48 |
49 | if (!MJVerifySignedData([self.signature dataUsingEncoding:NSUTF8StringEncoding], tgzdata)) {
50 | handler(@"Mjolnir.tgz failed security verification!", @"DSA signature could not be verified.");
51 | return;
52 | }
53 |
54 | NSError *__autoreleasing mkTempDirError;
55 | NSString* tempDirectory = MJCreateEmptyTempDirectory(@"mjolnir-", &mkTempDirError);
56 | if (!tempDirectory) {
57 | handler(@"Error creating temporary directory for Mjolnir.tgz", [mkTempDirError localizedDescription]);
58 | return;
59 | }
60 |
61 | NSError* __autoreleasing untarError;
62 | BOOL untarSuccess = MJUntar(tgzdata, tempDirectory, &untarError);
63 | if (!untarSuccess) {
64 | handler(@"Error extracting Mjolnir.tgz", [untarError localizedDescription]);
65 | return;
66 | }
67 |
68 | NSString* thispath = [[NSBundle mainBundle] bundlePath];
69 | NSString* newpath = [tempDirectory stringByAppendingPathComponent:@"Mjolnir.app"];
70 | NSString* pidstring = [NSString stringWithFormat:@"%d", getpid()];
71 |
72 | NSTask* task = [[NSTask alloc] init];
73 | [task setLaunchPath:[[NSBundle mainBundle] pathForResource:@"MjolnirRestarter" ofType:@""]];
74 | [task setArguments:@[pidstring, thispath, newpath]];
75 | [task launch];
76 | exit(0);
77 | });
78 | }
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/Mjolnir/MJUpdateChecker.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | void MJUpdateCheckerSetup(void);
4 |
5 | void MJUpdateCheckerCheckSilently(void);
6 | void MJUpdateCheckerCheckVerbosely(void);
7 |
8 | BOOL MJUpdateCheckerEnabled(void);
9 | void MJUpdateCheckerSetEnabled(BOOL checkingEnabled);
10 |
--------------------------------------------------------------------------------
/Mjolnir/MJUpdateChecker.m:
--------------------------------------------------------------------------------
1 | #import "MJUpdateChecker.h"
2 | #import "MJAutoUpdaterWindowController.h"
3 | #import "MJUserNotificationManager.h"
4 | #import "MJUpdate.h"
5 | #import "variables.h"
6 |
7 | static CFRunLoopTimerRef autoupdateTimer;
8 | static MJAutoUpdaterWindowController* updaterWindowController;
9 | static id closedObserver;
10 |
11 | void callback(CFRunLoopTimerRef timer, void *info) {
12 | MJUpdateCheckerCheckSilently();
13 | }
14 |
15 | static void reflect_defaults(void) {
16 | if (MJUpdateCheckerEnabled())
17 | CFRunLoopAddTimer(CFRunLoopGetMain(), autoupdateTimer, kCFRunLoopCommonModes);
18 | else
19 | CFRunLoopRemoveTimer(CFRunLoopGetMain(), autoupdateTimer, kCFRunLoopCommonModes);
20 | }
21 |
22 | void MJUpdateCheckerSetup(void) {
23 | CFTimeInterval interval = [[NSUserDefaults standardUserDefaults] doubleForKey:MJCheckForUpdatesIntervalKey];
24 | autoupdateTimer = CFRunLoopTimerCreate(NULL, 0, interval, 0, 0, &callback, NULL);
25 | reflect_defaults();
26 |
27 | if (MJUpdateCheckerEnabled())
28 | CFRunLoopTimerSetNextFireDate(autoupdateTimer, CFAbsoluteTimeGetCurrent());
29 | }
30 |
31 | static MJAutoUpdaterWindowController* definitelyRealWindowController(void) {
32 | if (!updaterWindowController) {
33 | updaterWindowController = [[MJAutoUpdaterWindowController alloc] init];
34 | closedObserver = [[NSNotificationCenter defaultCenter]
35 | addObserverForName:NSWindowWillCloseNotification
36 | object:[updaterWindowController window]
37 | queue:[NSOperationQueue mainQueue]
38 | usingBlock:^(NSNotification *note) {
39 | updaterWindowController = nil;
40 |
41 | [[NSNotificationCenter defaultCenter]
42 | removeObserver:closedObserver];
43 | closedObserver = nil;
44 | }];
45 | }
46 |
47 | return updaterWindowController;
48 | }
49 |
50 | void MJUpdateCheckerCheckSilently(void) {
51 | if (!MJUpdateCheckerEnabled())
52 | return;
53 |
54 | [MJUpdate checkForUpdate:^(MJUpdate *update, NSError* connError) {
55 | if (update) {
56 | MJAutoUpdaterWindowController* wc = definitelyRealWindowController();
57 | wc.update = update;
58 |
59 | [[MJUserNotificationManager sharedManager] sendNotification:@"Mjolnir update available" handler:^{
60 | [wc showFoundPage];
61 | }];
62 | }
63 | }];
64 | }
65 |
66 | BOOL MJUpdateCheckerEnabled(void) {
67 | return [[NSUserDefaults standardUserDefaults] boolForKey:MJCheckForUpdatesKey];
68 | }
69 |
70 | void MJUpdateCheckerSetEnabled(BOOL checkingEnabled) {
71 | [[NSUserDefaults standardUserDefaults] setBool:checkingEnabled
72 | forKey:MJCheckForUpdatesKey];
73 | reflect_defaults();
74 | }
75 |
76 | void MJUpdateCheckerCheckVerbosely(void) {
77 | MJAutoUpdaterWindowController* wc = definitelyRealWindowController();
78 |
79 | [wc showCheckingPage];
80 |
81 | [MJUpdate checkForUpdate:^(MJUpdate *update, NSError* connError) {
82 | if (!updaterWindowController)
83 | return;
84 |
85 | if (update) {
86 | wc.update = update;
87 | [wc showFoundPage];
88 | }
89 | else if (connError) {
90 | wc.error = [connError localizedDescription];
91 | [wc showErrorPage];
92 | }
93 | else {
94 | [wc showUpToDatePage];
95 | }
96 | }];
97 | }
98 |
--------------------------------------------------------------------------------
/Mjolnir/MJUserNotificationManager.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface MJUserNotificationManager : NSObject
4 |
5 | + (MJUserNotificationManager*) sharedManager;
6 |
7 | - (void) sendNotification:(NSString*)title handler:(dispatch_block_t)handler;
8 |
9 | @end
10 |
--------------------------------------------------------------------------------
/Mjolnir/MJUserNotificationManager.m:
--------------------------------------------------------------------------------
1 | #import "MJUserNotificationManager.h"
2 |
3 | @interface MJUserNotificationManager ()
4 | @property NSMutableDictionary* callbacks;
5 | @end
6 |
7 | @implementation MJUserNotificationManager
8 |
9 | + (MJUserNotificationManager*) sharedManager {
10 | static MJUserNotificationManager* sharedManager;
11 | static dispatch_once_t onceToken;
12 | dispatch_once(&onceToken, ^{
13 | sharedManager = [[MJUserNotificationManager alloc] init];
14 | sharedManager.callbacks = [NSMutableDictionary dictionary];
15 | [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:sharedManager];
16 | });
17 | return sharedManager;
18 | }
19 |
20 | - (void) sendNotification:(NSString*)title handler:(dispatch_block_t)handler {
21 | NSUserNotification* note = [[NSUserNotification alloc] init];
22 | note.title = title;
23 | [self.callbacks setObject:[handler copy] forKey:note];
24 | [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification: note];
25 | }
26 |
27 | - (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification {
28 | [[NSUserNotificationCenter defaultUserNotificationCenter] removeDeliveredNotification: notification]; // is this unnecessary? can't tell, docs suck.
29 |
30 | dispatch_block_t callback = [self.callbacks objectForKey: notification];
31 | if (callback)
32 | callback();
33 |
34 | [self.callbacks removeObjectForKey: notification];
35 | }
36 |
37 | - (BOOL) userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification {
38 | return YES;
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Mjolnir/MJVersionUtils.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | int MJVersionFromThisApp(void);
4 | int MJVersionFromString(NSString* str);
5 |
--------------------------------------------------------------------------------
/Mjolnir/MJVersionUtils.m:
--------------------------------------------------------------------------------
1 | #import "MJVersionUtils.h"
2 |
3 | int MJVersionFromThisApp(void) {
4 | static int v;
5 | static dispatch_once_t onceToken;
6 | dispatch_once(&onceToken, ^{
7 | v = MJVersionFromString([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]);
8 | });
9 | return v;
10 | }
11 |
12 | int MJVersionFromString(NSString* str) {
13 | NSScanner* scanner = [NSScanner scannerWithString:str];
14 | int major;
15 | int minor;
16 | int bugfix = 0;
17 | [scanner scanInt:&major];
18 | [scanner scanString:@"." intoString:NULL];
19 | [scanner scanInt:&minor];
20 | if ([scanner scanString:@"." intoString:NULL]) {
21 | [scanner scanInt:&bugfix];
22 | }
23 | return major * 10000 + minor * 100 + bugfix;
24 | }
25 |
--------------------------------------------------------------------------------
/Mjolnir/Mjolnir-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIconFile
10 | Mjolnir
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0.2
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0.2
25 | LSApplicationCategoryType
26 | public.app-category.utilities
27 | LSMinimumSystemVersion
28 | ${MACOSX_DEPLOYMENT_TARGET}
29 | NSHumanReadableCopyright
30 | Released under MIT license.
31 | NSMainNibFile
32 | MainMenu
33 | NSPrincipalClass
34 | NSApplication
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Mjolnir/Mjolnir-Prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #endif
4 |
5 | #define LUA_USE_MACOSX 1
6 |
--------------------------------------------------------------------------------
/Mjolnir/MjolnirRestarter/main.m:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | static NSString* live_app_path;
4 | static NSString* temp_app_path;
5 | static pid_t parent_pid;
6 | static NSImage* app_icon;
7 |
8 | static void MJShowError(NSString* command, NSString* error) {
9 | NSAlert* alert = [[NSAlert alloc] init];
10 | [alert setAlertStyle: NSCriticalAlertStyle];
11 | [alert setIcon:app_icon];
12 | [alert setMessageText:@"Error installing update"];
13 | [alert setInformativeText:[NSString stringWithFormat:@"Command that failed: %@\n\nError: %@", command, error]];
14 | [alert runModal];
15 | }
16 |
17 | static void MJOpenLiveApp(void) {
18 | [[NSWorkspace sharedWorkspace] launchApplication:live_app_path];
19 | exit(0);
20 | }
21 |
22 | static void MJRelaunch(void) {
23 | NSError* __autoreleasing rmError;
24 | BOOL rmSuccess = [[NSFileManager defaultManager] removeItemAtPath:live_app_path error:&rmError];
25 | if (!rmSuccess) {
26 | MJShowError([NSString stringWithFormat:@"rm %@", live_app_path], [rmError localizedDescription]);
27 | MJOpenLiveApp();
28 | }
29 |
30 | NSError* __autoreleasing cpError;
31 | if (![[NSFileManager defaultManager] copyItemAtPath:temp_app_path toPath:live_app_path error:&cpError]) {
32 | MJShowError([NSString stringWithFormat:@"cp %@ %@", temp_app_path, live_app_path], [cpError localizedDescription]);
33 | exit(1);
34 | }
35 |
36 | MJOpenLiveApp();
37 | }
38 |
39 | static void MJBorrowAppIcon() {
40 | NSString* iconPath = [[NSBundle bundleWithPath:live_app_path] pathForResource:@"Mjolnir" ofType:@"icns"];
41 | app_icon = [[NSImage alloc] initWithContentsOfFile:iconPath];
42 | }
43 |
44 | int main(int argc, const char * argv[]) {
45 | @autoreleasepool {
46 | parent_pid = atoi(argv[1]);
47 | live_app_path = [NSString stringWithUTF8String:argv[2]];
48 | temp_app_path = [NSString stringWithUTF8String:argv[3]];
49 |
50 | [[[NSWorkspace sharedWorkspace] notificationCenter]
51 | addObserverForName:NSWorkspaceDidTerminateApplicationNotification
52 | object:nil
53 | queue:[NSOperationQueue mainQueue]
54 | usingBlock:^(NSNotification *note) {
55 | NSRunningApplication* app = [[note userInfo] valueForKey:NSWorkspaceApplicationKey];
56 | if ([app processIdentifier] == parent_pid) {
57 | MJRelaunch();
58 | }
59 | }];
60 |
61 | dispatch_async(dispatch_get_main_queue(), ^{
62 | if (getppid() == 1) {
63 | MJRelaunch();
64 | }
65 | });
66 |
67 | MJBorrowAppIcon();
68 | [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
69 | [[NSApplication sharedApplication] run];
70 | }
71 | return 0;
72 | }
73 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lapi.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Auxiliary functions from Lua API
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lapi_h
8 | #define lapi_h
9 |
10 |
11 | #include "llimits.h"
12 | #include "lstate.h"
13 |
14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
15 | "stack overflow");}
16 |
17 | #define adjustresults(L,nres) \
18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
19 |
20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
21 | "not enough elements in the stack")
22 |
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lbitlib.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Standard library for bitwise operations
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #define lbitlib_c
8 | #define LUA_LIB
9 |
10 | #include "lprefix.h"
11 |
12 |
13 | #include "lua.h"
14 |
15 | #include "lauxlib.h"
16 | #include "lualib.h"
17 |
18 |
19 | #if defined(LUA_COMPAT_BITLIB) /* { */
20 |
21 |
22 | #define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
23 | #define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i))
24 |
25 |
26 | /* number of bits to consider in a number */
27 | #if !defined(LUA_NBITS)
28 | #define LUA_NBITS 32
29 | #endif
30 |
31 |
32 | /*
33 | ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must
34 | ** be made in two parts to avoid problems when LUA_NBITS is equal to the
35 | ** number of bits in a lua_Unsigned.)
36 | */
37 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
38 |
39 |
40 | /* macro to trim extra bits */
41 | #define trim(x) ((x) & ALLONES)
42 |
43 |
44 | /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
45 | #define mask(n) (~((ALLONES << 1) << ((n) - 1)))
46 |
47 |
48 |
49 | static lua_Unsigned andaux (lua_State *L) {
50 | int i, n = lua_gettop(L);
51 | lua_Unsigned r = ~(lua_Unsigned)0;
52 | for (i = 1; i <= n; i++)
53 | r &= checkunsigned(L, i);
54 | return trim(r);
55 | }
56 |
57 |
58 | static int b_and (lua_State *L) {
59 | lua_Unsigned r = andaux(L);
60 | pushunsigned(L, r);
61 | return 1;
62 | }
63 |
64 |
65 | static int b_test (lua_State *L) {
66 | lua_Unsigned r = andaux(L);
67 | lua_pushboolean(L, r != 0);
68 | return 1;
69 | }
70 |
71 |
72 | static int b_or (lua_State *L) {
73 | int i, n = lua_gettop(L);
74 | lua_Unsigned r = 0;
75 | for (i = 1; i <= n; i++)
76 | r |= checkunsigned(L, i);
77 | pushunsigned(L, trim(r));
78 | return 1;
79 | }
80 |
81 |
82 | static int b_xor (lua_State *L) {
83 | int i, n = lua_gettop(L);
84 | lua_Unsigned r = 0;
85 | for (i = 1; i <= n; i++)
86 | r ^= checkunsigned(L, i);
87 | pushunsigned(L, trim(r));
88 | return 1;
89 | }
90 |
91 |
92 | static int b_not (lua_State *L) {
93 | lua_Unsigned r = ~checkunsigned(L, 1);
94 | pushunsigned(L, trim(r));
95 | return 1;
96 | }
97 |
98 |
99 | static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) {
100 | if (i < 0) { /* shift right? */
101 | i = -i;
102 | r = trim(r);
103 | if (i >= LUA_NBITS) r = 0;
104 | else r >>= i;
105 | }
106 | else { /* shift left */
107 | if (i >= LUA_NBITS) r = 0;
108 | else r <<= i;
109 | r = trim(r);
110 | }
111 | pushunsigned(L, r);
112 | return 1;
113 | }
114 |
115 |
116 | static int b_lshift (lua_State *L) {
117 | return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2));
118 | }
119 |
120 |
121 | static int b_rshift (lua_State *L) {
122 | return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2));
123 | }
124 |
125 |
126 | static int b_arshift (lua_State *L) {
127 | lua_Unsigned r = checkunsigned(L, 1);
128 | lua_Integer i = luaL_checkinteger(L, 2);
129 | if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1))))
130 | return b_shift(L, r, -i);
131 | else { /* arithmetic shift for 'negative' number */
132 | if (i >= LUA_NBITS) r = ALLONES;
133 | else
134 | r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */
135 | pushunsigned(L, r);
136 | return 1;
137 | }
138 | }
139 |
140 |
141 | static int b_rot (lua_State *L, lua_Integer d) {
142 | lua_Unsigned r = checkunsigned(L, 1);
143 | int i = d & (LUA_NBITS - 1); /* i = d % NBITS */
144 | r = trim(r);
145 | if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
146 | r = (r << i) | (r >> (LUA_NBITS - i));
147 | pushunsigned(L, trim(r));
148 | return 1;
149 | }
150 |
151 |
152 | static int b_lrot (lua_State *L) {
153 | return b_rot(L, luaL_checkinteger(L, 2));
154 | }
155 |
156 |
157 | static int b_rrot (lua_State *L) {
158 | return b_rot(L, -luaL_checkinteger(L, 2));
159 | }
160 |
161 |
162 | /*
163 | ** get field and width arguments for field-manipulation functions,
164 | ** checking whether they are valid.
165 | ** ('luaL_error' called without 'return' to avoid later warnings about
166 | ** 'width' being used uninitialized.)
167 | */
168 | static int fieldargs (lua_State *L, int farg, int *width) {
169 | lua_Integer f = luaL_checkinteger(L, farg);
170 | lua_Integer w = luaL_optinteger(L, farg + 1, 1);
171 | luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
172 | luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
173 | if (f + w > LUA_NBITS)
174 | luaL_error(L, "trying to access non-existent bits");
175 | *width = (int)w;
176 | return (int)f;
177 | }
178 |
179 |
180 | static int b_extract (lua_State *L) {
181 | int w;
182 | lua_Unsigned r = trim(checkunsigned(L, 1));
183 | int f = fieldargs(L, 2, &w);
184 | r = (r >> f) & mask(w);
185 | pushunsigned(L, r);
186 | return 1;
187 | }
188 |
189 |
190 | static int b_replace (lua_State *L) {
191 | int w;
192 | lua_Unsigned r = trim(checkunsigned(L, 1));
193 | lua_Unsigned v = trim(checkunsigned(L, 2));
194 | int f = fieldargs(L, 3, &w);
195 | lua_Unsigned m = mask(w);
196 | r = (r & ~(m << f)) | ((v & m) << f);
197 | pushunsigned(L, r);
198 | return 1;
199 | }
200 |
201 |
202 | static const luaL_Reg bitlib[] = {
203 | {"arshift", b_arshift},
204 | {"band", b_and},
205 | {"bnot", b_not},
206 | {"bor", b_or},
207 | {"bxor", b_xor},
208 | {"btest", b_test},
209 | {"extract", b_extract},
210 | {"lrotate", b_lrot},
211 | {"lshift", b_lshift},
212 | {"replace", b_replace},
213 | {"rrotate", b_rrot},
214 | {"rshift", b_rshift},
215 | {NULL, NULL}
216 | };
217 |
218 |
219 |
220 | LUAMOD_API int luaopen_bit32 (lua_State *L) {
221 | luaL_newlib(L, bitlib);
222 | return 1;
223 | }
224 |
225 |
226 | #else /* }{ */
227 |
228 |
229 | LUAMOD_API int luaopen_bit32 (lua_State *L) {
230 | return luaL_error(L, "library 'bit32' has been deprecated");
231 | }
232 |
233 | #endif /* } */
234 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lcode.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lcode.h,v 1.64.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Code generator for Lua
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lcode_h
8 | #define lcode_h
9 |
10 | #include "llex.h"
11 | #include "lobject.h"
12 | #include "lopcodes.h"
13 | #include "lparser.h"
14 |
15 |
16 | /*
17 | ** Marks the end of a patch list. It is an invalid value both as an absolute
18 | ** address, and as a list link (would link an element to itself).
19 | */
20 | #define NO_JUMP (-1)
21 |
22 |
23 | /*
24 | ** grep "ORDER OPR" if you change these enums (ORDER OP)
25 | */
26 | typedef enum BinOpr {
27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW,
28 | OPR_DIV,
29 | OPR_IDIV,
30 | OPR_BAND, OPR_BOR, OPR_BXOR,
31 | OPR_SHL, OPR_SHR,
32 | OPR_CONCAT,
33 | OPR_EQ, OPR_LT, OPR_LE,
34 | OPR_NE, OPR_GT, OPR_GE,
35 | OPR_AND, OPR_OR,
36 | OPR_NOBINOPR
37 | } BinOpr;
38 |
39 |
40 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
41 |
42 |
43 | /* get (pointer to) instruction of given 'expdesc' */
44 | #define getinstruction(fs,e) ((fs)->f->code[(e)->u.info])
45 |
46 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
47 |
48 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
49 |
50 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t)
51 |
52 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
53 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
54 | LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k);
55 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
56 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
57 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
58 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
59 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
60 | LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n);
61 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
62 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
63 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
64 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
65 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
66 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
67 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
68 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
69 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
70 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
71 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
72 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
73 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
74 | LUAI_FUNC int luaK_jump (FuncState *fs);
75 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
76 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
77 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
78 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level);
79 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
80 | LUAI_FUNC int luaK_getlabel (FuncState *fs);
81 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line);
82 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
83 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
84 | expdesc *v2, int line);
85 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
86 |
87 |
88 | #endif
89 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lcorolib.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lcorolib.c,v 1.10.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Coroutine Library
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #define lcorolib_c
8 | #define LUA_LIB
9 |
10 | #include "lprefix.h"
11 |
12 |
13 | #include
14 |
15 | #include "lua.h"
16 |
17 | #include "lauxlib.h"
18 | #include "lualib.h"
19 |
20 |
21 | static lua_State *getco (lua_State *L) {
22 | lua_State *co = lua_tothread(L, 1);
23 | luaL_argcheck(L, co, 1, "thread expected");
24 | return co;
25 | }
26 |
27 |
28 | static int auxresume (lua_State *L, lua_State *co, int narg) {
29 | int status;
30 | if (!lua_checkstack(co, narg)) {
31 | lua_pushliteral(L, "too many arguments to resume");
32 | return -1; /* error flag */
33 | }
34 | if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
35 | lua_pushliteral(L, "cannot resume dead coroutine");
36 | return -1; /* error flag */
37 | }
38 | lua_xmove(L, co, narg);
39 | status = lua_resume(co, L, narg);
40 | if (status == LUA_OK || status == LUA_YIELD) {
41 | int nres = lua_gettop(co);
42 | if (!lua_checkstack(L, nres + 1)) {
43 | lua_pop(co, nres); /* remove results anyway */
44 | lua_pushliteral(L, "too many results to resume");
45 | return -1; /* error flag */
46 | }
47 | lua_xmove(co, L, nres); /* move yielded values */
48 | return nres;
49 | }
50 | else {
51 | lua_xmove(co, L, 1); /* move error message */
52 | return -1; /* error flag */
53 | }
54 | }
55 |
56 |
57 | static int luaB_coresume (lua_State *L) {
58 | lua_State *co = getco(L);
59 | int r;
60 | r = auxresume(L, co, lua_gettop(L) - 1);
61 | if (r < 0) {
62 | lua_pushboolean(L, 0);
63 | lua_insert(L, -2);
64 | return 2; /* return false + error message */
65 | }
66 | else {
67 | lua_pushboolean(L, 1);
68 | lua_insert(L, -(r + 1));
69 | return r + 1; /* return true + 'resume' returns */
70 | }
71 | }
72 |
73 |
74 | static int luaB_auxwrap (lua_State *L) {
75 | lua_State *co = lua_tothread(L, lua_upvalueindex(1));
76 | int r = auxresume(L, co, lua_gettop(L));
77 | if (r < 0) {
78 | if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */
79 | luaL_where(L, 1); /* add extra info */
80 | lua_insert(L, -2);
81 | lua_concat(L, 2);
82 | }
83 | return lua_error(L); /* propagate error */
84 | }
85 | return r;
86 | }
87 |
88 |
89 | static int luaB_cocreate (lua_State *L) {
90 | lua_State *NL;
91 | luaL_checktype(L, 1, LUA_TFUNCTION);
92 | NL = lua_newthread(L);
93 | lua_pushvalue(L, 1); /* move function to top */
94 | lua_xmove(L, NL, 1); /* move function from L to NL */
95 | return 1;
96 | }
97 |
98 |
99 | static int luaB_cowrap (lua_State *L) {
100 | luaB_cocreate(L);
101 | lua_pushcclosure(L, luaB_auxwrap, 1);
102 | return 1;
103 | }
104 |
105 |
106 | static int luaB_yield (lua_State *L) {
107 | return lua_yield(L, lua_gettop(L));
108 | }
109 |
110 |
111 | static int luaB_costatus (lua_State *L) {
112 | lua_State *co = getco(L);
113 | if (L == co) lua_pushliteral(L, "running");
114 | else {
115 | switch (lua_status(co)) {
116 | case LUA_YIELD:
117 | lua_pushliteral(L, "suspended");
118 | break;
119 | case LUA_OK: {
120 | lua_Debug ar;
121 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
122 | lua_pushliteral(L, "normal"); /* it is running */
123 | else if (lua_gettop(co) == 0)
124 | lua_pushliteral(L, "dead");
125 | else
126 | lua_pushliteral(L, "suspended"); /* initial state */
127 | break;
128 | }
129 | default: /* some error occurred */
130 | lua_pushliteral(L, "dead");
131 | break;
132 | }
133 | }
134 | return 1;
135 | }
136 |
137 |
138 | static int luaB_yieldable (lua_State *L) {
139 | lua_pushboolean(L, lua_isyieldable(L));
140 | return 1;
141 | }
142 |
143 |
144 | static int luaB_corunning (lua_State *L) {
145 | int ismain = lua_pushthread(L);
146 | lua_pushboolean(L, ismain);
147 | return 2;
148 | }
149 |
150 |
151 | static const luaL_Reg co_funcs[] = {
152 | {"create", luaB_cocreate},
153 | {"resume", luaB_coresume},
154 | {"running", luaB_corunning},
155 | {"status", luaB_costatus},
156 | {"wrap", luaB_cowrap},
157 | {"yield", luaB_yield},
158 | {"isyieldable", luaB_yieldable},
159 | {NULL, NULL}
160 | };
161 |
162 |
163 |
164 | LUAMOD_API int luaopen_coroutine (lua_State *L) {
165 | luaL_newlib(L, co_funcs);
166 | return 1;
167 | }
168 |
169 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lctype.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lctype.c,v 1.12.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** 'ctype' functions for Lua
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #define lctype_c
8 | #define LUA_CORE
9 |
10 | #include "lprefix.h"
11 |
12 |
13 | #include "lctype.h"
14 |
15 | #if !LUA_USE_CTYPE /* { */
16 |
17 | #include
18 |
19 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
20 | 0x00, /* EOZ */
21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */
22 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */
24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */
26 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
27 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */
28 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
29 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */
30 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
31 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */
32 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05,
33 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */
34 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
35 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */
36 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00,
37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */
38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */
40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */
42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */
44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */
46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */
48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */
50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */
52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 | };
54 |
55 | #endif /* } */
56 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lctype.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
3 | ** 'ctype' functions for Lua
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lctype_h
8 | #define lctype_h
9 |
10 | #include "lua.h"
11 |
12 |
13 | /*
14 | ** WARNING: the functions defined here do not necessarily correspond
15 | ** to the similar functions in the standard C ctype.h. They are
16 | ** optimized for the specific needs of Lua
17 | */
18 |
19 | #if !defined(LUA_USE_CTYPE)
20 |
21 | #if 'A' == 65 && '0' == 48
22 | /* ASCII case: can use its own tables; faster and fixed */
23 | #define LUA_USE_CTYPE 0
24 | #else
25 | /* must use standard C ctype */
26 | #define LUA_USE_CTYPE 1
27 | #endif
28 |
29 | #endif
30 |
31 |
32 | #if !LUA_USE_CTYPE /* { */
33 |
34 | #include
35 |
36 | #include "llimits.h"
37 |
38 |
39 | #define ALPHABIT 0
40 | #define DIGITBIT 1
41 | #define PRINTBIT 2
42 | #define SPACEBIT 3
43 | #define XDIGITBIT 4
44 |
45 |
46 | #define MASK(B) (1 << (B))
47 |
48 |
49 | /*
50 | ** add 1 to char to allow index -1 (EOZ)
51 | */
52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p))
53 |
54 | /*
55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
56 | */
57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT))
58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT))
60 | #define lisspace(c) testprop(c, MASK(SPACEBIT))
61 | #define lisprint(c) testprop(c, MASK(PRINTBIT))
62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
63 |
64 | /*
65 | ** this 'ltolower' only works for alphabetic characters
66 | */
67 | #define ltolower(c) ((c) | ('A' ^ 'a'))
68 |
69 |
70 | /* two more entries for 0 and -1 (EOZ) */
71 | LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
72 |
73 |
74 | #else /* }{ */
75 |
76 | /*
77 | ** use standard C ctypes
78 | */
79 |
80 | #include
81 |
82 |
83 | #define lislalpha(c) (isalpha(c) || (c) == '_')
84 | #define lislalnum(c) (isalnum(c) || (c) == '_')
85 | #define lisdigit(c) (isdigit(c))
86 | #define lisspace(c) (isspace(c))
87 | #define lisprint(c) (isprint(c))
88 | #define lisxdigit(c) (isxdigit(c))
89 |
90 | #define ltolower(c) (tolower(c))
91 |
92 | #endif /* } */
93 |
94 | #endif
95 |
96 |
--------------------------------------------------------------------------------
/Mjolnir/lua/ldebug.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Auxiliary functions from Debug Interface module
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef ldebug_h
8 | #define ldebug_h
9 |
10 |
11 | #include "lstate.h"
12 |
13 |
14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
15 |
16 | #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
17 |
18 | #define resethookcount(L) (L->hookcount = L->basehookcount)
19 |
20 |
21 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
22 | const char *opname);
23 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1,
24 | const TValue *p2);
25 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1,
26 | const TValue *p2,
27 | const char *msg);
28 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1,
29 | const TValue *p2);
30 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
31 | const TValue *p2);
32 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
33 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
34 | TString *src, int line);
35 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
36 | LUAI_FUNC void luaG_traceexec (lua_State *L);
37 |
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/Mjolnir/lua/ldo.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: ldo.h,v 2.29.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Stack and Call structure of Lua
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef ldo_h
8 | #define ldo_h
9 |
10 |
11 | #include "lobject.h"
12 | #include "lstate.h"
13 | #include "lzio.h"
14 |
15 |
16 | /*
17 | ** Macro to check stack size and grow stack if needed. Parameters
18 | ** 'pre'/'pos' allow the macro to preserve a pointer into the
19 | ** stack across reallocations, doing the work only when needed.
20 | ** 'condmovestack' is used in heavy tests to force a stack reallocation
21 | ** at every check.
22 | */
23 | #define luaD_checkstackaux(L,n,pre,pos) \
24 | if (L->stack_last - L->top <= (n)) \
25 | { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); }
26 |
27 | /* In general, 'pre'/'pos' are empty (nothing to save) */
28 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0)
29 |
30 |
31 |
32 | #define savestack(L,p) ((char *)(p) - (char *)L->stack)
33 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
34 |
35 |
36 | /* type of protected functions, to be ran by 'runprotected' */
37 | typedef void (*Pfunc) (lua_State *L, void *ud);
38 |
39 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
40 | const char *mode);
41 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
42 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
43 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
44 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
45 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
46 | ptrdiff_t oldtop, ptrdiff_t ef);
47 | LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult,
48 | int nres);
49 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
50 | LUAI_FUNC void luaD_growstack (lua_State *L, int n);
51 | LUAI_FUNC void luaD_shrinkstack (lua_State *L);
52 | LUAI_FUNC void luaD_inctop (lua_State *L);
53 |
54 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
55 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
56 |
57 | #endif
58 |
59 |
--------------------------------------------------------------------------------
/Mjolnir/lua/ldump.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: ldump.c,v 2.37.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** save precompiled Lua chunks
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #define ldump_c
8 | #define LUA_CORE
9 |
10 | #include "lprefix.h"
11 |
12 |
13 | #include
14 |
15 | #include "lua.h"
16 |
17 | #include "lobject.h"
18 | #include "lstate.h"
19 | #include "lundump.h"
20 |
21 |
22 | typedef struct {
23 | lua_State *L;
24 | lua_Writer writer;
25 | void *data;
26 | int strip;
27 | int status;
28 | } DumpState;
29 |
30 |
31 | /*
32 | ** All high-level dumps go through DumpVector; you can change it to
33 | ** change the endianness of the result
34 | */
35 | #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D)
36 |
37 | #define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D)
38 |
39 |
40 | static void DumpBlock (const void *b, size_t size, DumpState *D) {
41 | if (D->status == 0 && size > 0) {
42 | lua_unlock(D->L);
43 | D->status = (*D->writer)(D->L, b, size, D->data);
44 | lua_lock(D->L);
45 | }
46 | }
47 |
48 |
49 | #define DumpVar(x,D) DumpVector(&x,1,D)
50 |
51 |
52 | static void DumpByte (int y, DumpState *D) {
53 | lu_byte x = (lu_byte)y;
54 | DumpVar(x, D);
55 | }
56 |
57 |
58 | static void DumpInt (int x, DumpState *D) {
59 | DumpVar(x, D);
60 | }
61 |
62 |
63 | static void DumpNumber (lua_Number x, DumpState *D) {
64 | DumpVar(x, D);
65 | }
66 |
67 |
68 | static void DumpInteger (lua_Integer x, DumpState *D) {
69 | DumpVar(x, D);
70 | }
71 |
72 |
73 | static void DumpString (const TString *s, DumpState *D) {
74 | if (s == NULL)
75 | DumpByte(0, D);
76 | else {
77 | size_t size = tsslen(s) + 1; /* include trailing '\0' */
78 | const char *str = getstr(s);
79 | if (size < 0xFF)
80 | DumpByte(cast_int(size), D);
81 | else {
82 | DumpByte(0xFF, D);
83 | DumpVar(size, D);
84 | }
85 | DumpVector(str, size - 1, D); /* no need to save '\0' */
86 | }
87 | }
88 |
89 |
90 | static void DumpCode (const Proto *f, DumpState *D) {
91 | DumpInt(f->sizecode, D);
92 | DumpVector(f->code, f->sizecode, D);
93 | }
94 |
95 |
96 | static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
97 |
98 | static void DumpConstants (const Proto *f, DumpState *D) {
99 | int i;
100 | int n = f->sizek;
101 | DumpInt(n, D);
102 | for (i = 0; i < n; i++) {
103 | const TValue *o = &f->k[i];
104 | DumpByte(ttype(o), D);
105 | switch (ttype(o)) {
106 | case LUA_TNIL:
107 | break;
108 | case LUA_TBOOLEAN:
109 | DumpByte(bvalue(o), D);
110 | break;
111 | case LUA_TNUMFLT:
112 | DumpNumber(fltvalue(o), D);
113 | break;
114 | case LUA_TNUMINT:
115 | DumpInteger(ivalue(o), D);
116 | break;
117 | case LUA_TSHRSTR:
118 | case LUA_TLNGSTR:
119 | DumpString(tsvalue(o), D);
120 | break;
121 | default:
122 | lua_assert(0);
123 | }
124 | }
125 | }
126 |
127 |
128 | static void DumpProtos (const Proto *f, DumpState *D) {
129 | int i;
130 | int n = f->sizep;
131 | DumpInt(n, D);
132 | for (i = 0; i < n; i++)
133 | DumpFunction(f->p[i], f->source, D);
134 | }
135 |
136 |
137 | static void DumpUpvalues (const Proto *f, DumpState *D) {
138 | int i, n = f->sizeupvalues;
139 | DumpInt(n, D);
140 | for (i = 0; i < n; i++) {
141 | DumpByte(f->upvalues[i].instack, D);
142 | DumpByte(f->upvalues[i].idx, D);
143 | }
144 | }
145 |
146 |
147 | static void DumpDebug (const Proto *f, DumpState *D) {
148 | int i, n;
149 | n = (D->strip) ? 0 : f->sizelineinfo;
150 | DumpInt(n, D);
151 | DumpVector(f->lineinfo, n, D);
152 | n = (D->strip) ? 0 : f->sizelocvars;
153 | DumpInt(n, D);
154 | for (i = 0; i < n; i++) {
155 | DumpString(f->locvars[i].varname, D);
156 | DumpInt(f->locvars[i].startpc, D);
157 | DumpInt(f->locvars[i].endpc, D);
158 | }
159 | n = (D->strip) ? 0 : f->sizeupvalues;
160 | DumpInt(n, D);
161 | for (i = 0; i < n; i++)
162 | DumpString(f->upvalues[i].name, D);
163 | }
164 |
165 |
166 | static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
167 | if (D->strip || f->source == psource)
168 | DumpString(NULL, D); /* no debug info or same source as its parent */
169 | else
170 | DumpString(f->source, D);
171 | DumpInt(f->linedefined, D);
172 | DumpInt(f->lastlinedefined, D);
173 | DumpByte(f->numparams, D);
174 | DumpByte(f->is_vararg, D);
175 | DumpByte(f->maxstacksize, D);
176 | DumpCode(f, D);
177 | DumpConstants(f, D);
178 | DumpUpvalues(f, D);
179 | DumpProtos(f, D);
180 | DumpDebug(f, D);
181 | }
182 |
183 |
184 | static void DumpHeader (DumpState *D) {
185 | DumpLiteral(LUA_SIGNATURE, D);
186 | DumpByte(LUAC_VERSION, D);
187 | DumpByte(LUAC_FORMAT, D);
188 | DumpLiteral(LUAC_DATA, D);
189 | DumpByte(sizeof(int), D);
190 | DumpByte(sizeof(size_t), D);
191 | DumpByte(sizeof(Instruction), D);
192 | DumpByte(sizeof(lua_Integer), D);
193 | DumpByte(sizeof(lua_Number), D);
194 | DumpInteger(LUAC_INT, D);
195 | DumpNumber(LUAC_NUM, D);
196 | }
197 |
198 |
199 | /*
200 | ** dump Lua function as precompiled chunk
201 | */
202 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
203 | int strip) {
204 | DumpState D;
205 | D.L = L;
206 | D.writer = w;
207 | D.data = data;
208 | D.strip = strip;
209 | D.status = 0;
210 | DumpHeader(&D);
211 | DumpByte(f->sizeupvalues, &D);
212 | DumpFunction(f, NULL, &D);
213 | return D.status;
214 | }
215 |
216 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lfunc.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lfunc.c,v 2.45.1.1 2017/04/19 17:39:34 roberto Exp $
3 | ** Auxiliary functions to manipulate prototypes and closures
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #define lfunc_c
8 | #define LUA_CORE
9 |
10 | #include "lprefix.h"
11 |
12 |
13 | #include
14 |
15 | #include "lua.h"
16 |
17 | #include "lfunc.h"
18 | #include "lgc.h"
19 | #include "lmem.h"
20 | #include "lobject.h"
21 | #include "lstate.h"
22 |
23 |
24 |
25 | CClosure *luaF_newCclosure (lua_State *L, int n) {
26 | GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n));
27 | CClosure *c = gco2ccl(o);
28 | c->nupvalues = cast_byte(n);
29 | return c;
30 | }
31 |
32 |
33 | LClosure *luaF_newLclosure (lua_State *L, int n) {
34 | GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n));
35 | LClosure *c = gco2lcl(o);
36 | c->p = NULL;
37 | c->nupvalues = cast_byte(n);
38 | while (n--) c->upvals[n] = NULL;
39 | return c;
40 | }
41 |
42 | /*
43 | ** fill a closure with new closed upvalues
44 | */
45 | void luaF_initupvals (lua_State *L, LClosure *cl) {
46 | int i;
47 | for (i = 0; i < cl->nupvalues; i++) {
48 | UpVal *uv = luaM_new(L, UpVal);
49 | uv->refcount = 1;
50 | uv->v = &uv->u.value; /* make it closed */
51 | setnilvalue(uv->v);
52 | cl->upvals[i] = uv;
53 | }
54 | }
55 |
56 |
57 | UpVal *luaF_findupval (lua_State *L, StkId level) {
58 | UpVal **pp = &L->openupval;
59 | UpVal *p;
60 | UpVal *uv;
61 | lua_assert(isintwups(L) || L->openupval == NULL);
62 | while (*pp != NULL && (p = *pp)->v >= level) {
63 | lua_assert(upisopen(p));
64 | if (p->v == level) /* found a corresponding upvalue? */
65 | return p; /* return it */
66 | pp = &p->u.open.next;
67 | }
68 | /* not found: create a new upvalue */
69 | uv = luaM_new(L, UpVal);
70 | uv->refcount = 0;
71 | uv->u.open.next = *pp; /* link it to list of open upvalues */
72 | uv->u.open.touched = 1;
73 | *pp = uv;
74 | uv->v = level; /* current value lives in the stack */
75 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */
76 | L->twups = G(L)->twups; /* link it to the list */
77 | G(L)->twups = L;
78 | }
79 | return uv;
80 | }
81 |
82 |
83 | void luaF_close (lua_State *L, StkId level) {
84 | UpVal *uv;
85 | while (L->openupval != NULL && (uv = L->openupval)->v >= level) {
86 | lua_assert(upisopen(uv));
87 | L->openupval = uv->u.open.next; /* remove from 'open' list */
88 | if (uv->refcount == 0) /* no references? */
89 | luaM_free(L, uv); /* free upvalue */
90 | else {
91 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */
92 | uv->v = &uv->u.value; /* now current value lives here */
93 | luaC_upvalbarrier(L, uv);
94 | }
95 | }
96 | }
97 |
98 |
99 | Proto *luaF_newproto (lua_State *L) {
100 | GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
101 | Proto *f = gco2p(o);
102 | f->k = NULL;
103 | f->sizek = 0;
104 | f->p = NULL;
105 | f->sizep = 0;
106 | f->code = NULL;
107 | f->cache = NULL;
108 | f->sizecode = 0;
109 | f->lineinfo = NULL;
110 | f->sizelineinfo = 0;
111 | f->upvalues = NULL;
112 | f->sizeupvalues = 0;
113 | f->numparams = 0;
114 | f->is_vararg = 0;
115 | f->maxstacksize = 0;
116 | f->locvars = NULL;
117 | f->sizelocvars = 0;
118 | f->linedefined = 0;
119 | f->lastlinedefined = 0;
120 | f->source = NULL;
121 | return f;
122 | }
123 |
124 |
125 | void luaF_freeproto (lua_State *L, Proto *f) {
126 | luaM_freearray(L, f->code, f->sizecode);
127 | luaM_freearray(L, f->p, f->sizep);
128 | luaM_freearray(L, f->k, f->sizek);
129 | luaM_freearray(L, f->lineinfo, f->sizelineinfo);
130 | luaM_freearray(L, f->locvars, f->sizelocvars);
131 | luaM_freearray(L, f->upvalues, f->sizeupvalues);
132 | luaM_free(L, f);
133 | }
134 |
135 |
136 | /*
137 | ** Look for n-th local variable at line 'line' in function 'func'.
138 | ** Returns NULL if not found.
139 | */
140 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
141 | int i;
142 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) {
143 | if (pc < f->locvars[i].endpc) { /* is variable active? */
144 | local_number--;
145 | if (local_number == 0)
146 | return getstr(f->locvars[i].varname);
147 | }
148 | }
149 | return NULL; /* not found */
150 | }
151 |
152 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lfunc.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lfunc.h,v 2.15.1.1 2017/04/19 17:39:34 roberto Exp $
3 | ** Auxiliary functions to manipulate prototypes and closures
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lfunc_h
8 | #define lfunc_h
9 |
10 |
11 | #include "lobject.h"
12 |
13 |
14 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
15 | cast(int, sizeof(TValue)*((n)-1)))
16 |
17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
18 | cast(int, sizeof(TValue *)*((n)-1)))
19 |
20 |
21 | /* test whether thread is in 'twups' list */
22 | #define isintwups(L) (L->twups != L)
23 |
24 |
25 | /*
26 | ** maximum number of upvalues in a closure (both C and Lua). (Value
27 | ** must fit in a VM register.)
28 | */
29 | #define MAXUPVAL 255
30 |
31 |
32 | /*
33 | ** Upvalues for Lua closures
34 | */
35 | struct UpVal {
36 | TValue *v; /* points to stack or to its own value */
37 | lu_mem refcount; /* reference counter */
38 | union {
39 | struct { /* (when open) */
40 | UpVal *next; /* linked list */
41 | int touched; /* mark to avoid cycles with dead threads */
42 | } open;
43 | TValue value; /* the value (when closed) */
44 | } u;
45 | };
46 |
47 | #define upisopen(up) ((up)->v != &(up)->u.value)
48 |
49 |
50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L);
51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
55 | LUAI_FUNC void luaF_close (lua_State *L, StkId level);
56 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
57 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
58 | int pc);
59 |
60 |
61 | #endif
62 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lgc.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lgc.h,v 2.91.1.1 2017/04/19 17:39:34 roberto Exp $
3 | ** Garbage Collector
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lgc_h
8 | #define lgc_h
9 |
10 |
11 | #include "lobject.h"
12 | #include "lstate.h"
13 |
14 | /*
15 | ** Collectable objects may have one of three colors: white, which
16 | ** means the object is not marked; gray, which means the
17 | ** object is marked, but its references may be not marked; and
18 | ** black, which means that the object and all its references are marked.
19 | ** The main invariant of the garbage collector, while marking objects,
20 | ** is that a black object can never point to a white one. Moreover,
21 | ** any gray object must be in a "gray list" (gray, grayagain, weak,
22 | ** allweak, ephemeron) so that it can be visited again before finishing
23 | ** the collection cycle. These lists have no meaning when the invariant
24 | ** is not being enforced (e.g., sweep phase).
25 | */
26 |
27 |
28 |
29 | /* how much to allocate before next GC step */
30 | #if !defined(GCSTEPSIZE)
31 | /* ~100 small strings */
32 | #define GCSTEPSIZE (cast_int(100 * sizeof(TString)))
33 | #endif
34 |
35 |
36 | /*
37 | ** Possible states of the Garbage Collector
38 | */
39 | #define GCSpropagate 0
40 | #define GCSatomic 1
41 | #define GCSswpallgc 2
42 | #define GCSswpfinobj 3
43 | #define GCSswptobefnz 4
44 | #define GCSswpend 5
45 | #define GCScallfin 6
46 | #define GCSpause 7
47 |
48 |
49 | #define issweepphase(g) \
50 | (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
51 |
52 |
53 | /*
54 | ** macro to tell when main invariant (white objects cannot point to black
55 | ** ones) must be kept. During a collection, the sweep
56 | ** phase may break the invariant, as objects turned white may point to
57 | ** still-black objects. The invariant is restored when sweep ends and
58 | ** all objects are white again.
59 | */
60 |
61 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic)
62 |
63 |
64 | /*
65 | ** some useful bit tricks
66 | */
67 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
68 | #define setbits(x,m) ((x) |= (m))
69 | #define testbits(x,m) ((x) & (m))
70 | #define bitmask(b) (1<<(b))
71 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
72 | #define l_setbit(x,b) setbits(x, bitmask(b))
73 | #define resetbit(x,b) resetbits(x, bitmask(b))
74 | #define testbit(x,b) testbits(x, bitmask(b))
75 |
76 |
77 | /* Layout for bit use in 'marked' field: */
78 | #define WHITE0BIT 0 /* object is white (type 0) */
79 | #define WHITE1BIT 1 /* object is white (type 1) */
80 | #define BLACKBIT 2 /* object is black */
81 | #define FINALIZEDBIT 3 /* object has been marked for finalization */
82 | /* bit 7 is currently used by tests (luaL_checkmemory) */
83 |
84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
85 |
86 |
87 | #define iswhite(x) testbits((x)->marked, WHITEBITS)
88 | #define isblack(x) testbit((x)->marked, BLACKBIT)
89 | #define isgray(x) /* neither white nor black */ \
90 | (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
91 |
92 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
93 |
94 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
95 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
96 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
97 |
98 | #define changewhite(x) ((x)->marked ^= WHITEBITS)
99 | #define gray2black(x) l_setbit((x)->marked, BLACKBIT)
100 |
101 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
102 |
103 |
104 | /*
105 | ** Does one step of collection when debt becomes positive. 'pre'/'pos'
106 | ** allows some adjustments to be done only when needed. macro
107 | ** 'condchangemem' is used only for heavy tests (forcing a full
108 | ** GC cycle on every opportunity)
109 | */
110 | #define luaC_condGC(L,pre,pos) \
111 | { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \
112 | condchangemem(L,pre,pos); }
113 |
114 | /* more often than not, 'pre'/'pos' are empty */
115 | #define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
116 |
117 |
118 | #define luaC_barrier(L,p,v) ( \
119 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
120 | luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0))
121 |
122 | #define luaC_barrierback(L,p,v) ( \
123 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
124 | luaC_barrierback_(L,p) : cast_void(0))
125 |
126 | #define luaC_objbarrier(L,p,o) ( \
127 | (isblack(p) && iswhite(o)) ? \
128 | luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
129 |
130 | #define luaC_upvalbarrier(L,uv) ( \
131 | (iscollectable((uv)->v) && !upisopen(uv)) ? \
132 | luaC_upvalbarrier_(L,uv) : cast_void(0))
133 |
134 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
135 | LUAI_FUNC void luaC_freeallobjects (lua_State *L);
136 | LUAI_FUNC void luaC_step (lua_State *L);
137 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
138 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
139 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
140 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
141 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o);
142 | LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv);
143 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
144 | LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv);
145 |
146 |
147 | #endif
148 |
--------------------------------------------------------------------------------
/Mjolnir/lua/linit.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: linit.c,v 1.39.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Initialization of libraries for lua.c and other clients
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 |
8 | #define linit_c
9 | #define LUA_LIB
10 |
11 | /*
12 | ** If you embed Lua in your program and need to open the standard
13 | ** libraries, call luaL_openlibs in your program. If you need a
14 | ** different set of libraries, copy this file to your project and edit
15 | ** it to suit your needs.
16 | **
17 | ** You can also *preload* libraries, so that a later 'require' can
18 | ** open the library, which is already linked to the application.
19 | ** For that, do the following code:
20 | **
21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
22 | ** lua_pushcfunction(L, luaopen_modname);
23 | ** lua_setfield(L, -2, modname);
24 | ** lua_pop(L, 1); // remove PRELOAD table
25 | */
26 |
27 | #include "lprefix.h"
28 |
29 |
30 | #include
31 |
32 | #include "lua.h"
33 |
34 | #include "lualib.h"
35 | #include "lauxlib.h"
36 |
37 |
38 | /*
39 | ** these libs are loaded by lua.c and are readily available to any Lua
40 | ** program
41 | */
42 | static const luaL_Reg loadedlibs[] = {
43 | {"_G", luaopen_base},
44 | {LUA_LOADLIBNAME, luaopen_package},
45 | {LUA_COLIBNAME, luaopen_coroutine},
46 | {LUA_TABLIBNAME, luaopen_table},
47 | {LUA_IOLIBNAME, luaopen_io},
48 | {LUA_OSLIBNAME, luaopen_os},
49 | {LUA_STRLIBNAME, luaopen_string},
50 | {LUA_MATHLIBNAME, luaopen_math},
51 | {LUA_UTF8LIBNAME, luaopen_utf8},
52 | {LUA_DBLIBNAME, luaopen_debug},
53 | #if defined(LUA_COMPAT_BITLIB)
54 | {LUA_BITLIBNAME, luaopen_bit32},
55 | #endif
56 | {NULL, NULL}
57 | };
58 |
59 |
60 | LUALIB_API void luaL_openlibs (lua_State *L) {
61 | const luaL_Reg *lib;
62 | /* "require" functions from 'loadedlibs' and set results to global table */
63 | for (lib = loadedlibs; lib->func; lib++) {
64 | luaL_requiref(L, lib->name, lib->func, 1);
65 | lua_pop(L, 1); /* remove lib */
66 | }
67 | }
68 |
69 |
--------------------------------------------------------------------------------
/Mjolnir/lua/llex.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: llex.h,v 1.79.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Lexical Analyzer
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef llex_h
8 | #define llex_h
9 |
10 | #include "lobject.h"
11 | #include "lzio.h"
12 |
13 |
14 | #define FIRST_RESERVED 257
15 |
16 |
17 | #if !defined(LUA_ENV)
18 | #define LUA_ENV "_ENV"
19 | #endif
20 |
21 |
22 | /*
23 | * WARNING: if you change the order of this enumeration,
24 | * grep "ORDER RESERVED"
25 | */
26 | enum RESERVED {
27 | /* terminal symbols denoted by reserved words */
28 | TK_AND = FIRST_RESERVED, TK_BREAK,
29 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
30 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
31 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
32 | /* other terminal symbols */
33 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
34 | TK_SHL, TK_SHR,
35 | TK_DBCOLON, TK_EOS,
36 | TK_FLT, TK_INT, TK_NAME, TK_STRING
37 | };
38 |
39 | /* number of reserved words */
40 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
41 |
42 |
43 | typedef union {
44 | lua_Number r;
45 | lua_Integer i;
46 | TString *ts;
47 | } SemInfo; /* semantics information */
48 |
49 |
50 | typedef struct Token {
51 | int token;
52 | SemInfo seminfo;
53 | } Token;
54 |
55 |
56 | /* state of the lexer plus state of the parser when shared by all
57 | functions */
58 | typedef struct LexState {
59 | int current; /* current character (charint) */
60 | int linenumber; /* input line counter */
61 | int lastline; /* line of last token 'consumed' */
62 | Token t; /* current token */
63 | Token lookahead; /* look ahead token */
64 | struct FuncState *fs; /* current function (parser) */
65 | struct lua_State *L;
66 | ZIO *z; /* input stream */
67 | Mbuffer *buff; /* buffer for tokens */
68 | Table *h; /* to avoid collection/reuse strings */
69 | struct Dyndata *dyd; /* dynamic structures used by the parser */
70 | TString *source; /* current source name */
71 | TString *envn; /* environment variable name */
72 | } LexState;
73 |
74 |
75 | LUAI_FUNC void luaX_init (lua_State *L);
76 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
77 | TString *source, int firstchar);
78 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
79 | LUAI_FUNC void luaX_next (LexState *ls);
80 | LUAI_FUNC int luaX_lookahead (LexState *ls);
81 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s);
82 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
83 |
84 |
85 | #endif
86 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lmem.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lmem.c,v 1.91.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Interface to Memory Manager
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #define lmem_c
8 | #define LUA_CORE
9 |
10 | #include "lprefix.h"
11 |
12 |
13 | #include
14 |
15 | #include "lua.h"
16 |
17 | #include "ldebug.h"
18 | #include "ldo.h"
19 | #include "lgc.h"
20 | #include "lmem.h"
21 | #include "lobject.h"
22 | #include "lstate.h"
23 |
24 |
25 |
26 | /*
27 | ** About the realloc function:
28 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
29 | ** ('osize' is the old size, 'nsize' is the new size)
30 | **
31 | ** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no
32 | ** matter 'x').
33 | **
34 | ** * frealloc(ud, p, x, 0) frees the block 'p'
35 | ** (in this specific case, frealloc must return NULL);
36 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing
37 | ** (which is equivalent to free(NULL) in ISO C)
38 | **
39 | ** frealloc returns NULL if it cannot create or reallocate the area
40 | ** (any reallocation to an equal or smaller size cannot fail!)
41 | */
42 |
43 |
44 |
45 | #define MINSIZEARRAY 4
46 |
47 |
48 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
49 | int limit, const char *what) {
50 | void *newblock;
51 | int newsize;
52 | if (*size >= limit/2) { /* cannot double it? */
53 | if (*size >= limit) /* cannot grow even a little? */
54 | luaG_runerror(L, "too many %s (limit is %d)", what, limit);
55 | newsize = limit; /* still have at least one free place */
56 | }
57 | else {
58 | newsize = (*size)*2;
59 | if (newsize < MINSIZEARRAY)
60 | newsize = MINSIZEARRAY; /* minimum size */
61 | }
62 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
63 | *size = newsize; /* update only when everything else is OK */
64 | return newblock;
65 | }
66 |
67 |
68 | l_noret luaM_toobig (lua_State *L) {
69 | luaG_runerror(L, "memory allocation error: block too big");
70 | }
71 |
72 |
73 |
74 | /*
75 | ** generic allocation routine.
76 | */
77 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
78 | void *newblock;
79 | global_State *g = G(L);
80 | size_t realosize = (block) ? osize : 0;
81 | lua_assert((realosize == 0) == (block == NULL));
82 | #if defined(HARDMEMTESTS)
83 | if (nsize > realosize && g->gcrunning)
84 | luaC_fullgc(L, 1); /* force a GC whenever possible */
85 | #endif
86 | newblock = (*g->frealloc)(g->ud, block, osize, nsize);
87 | if (newblock == NULL && nsize > 0) {
88 | lua_assert(nsize > realosize); /* cannot fail when shrinking a block */
89 | if (g->version) { /* is state fully built? */
90 | luaC_fullgc(L, 1); /* try to free some memory... */
91 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
92 | }
93 | if (newblock == NULL)
94 | luaD_throw(L, LUA_ERRMEM);
95 | }
96 | lua_assert((nsize == 0) == (newblock == NULL));
97 | g->GCdebt = (g->GCdebt + nsize) - realosize;
98 | return newblock;
99 | }
100 |
101 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lmem.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lmem.h,v 1.43.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Interface to Memory Manager
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lmem_h
8 | #define lmem_h
9 |
10 |
11 | #include
12 |
13 | #include "llimits.h"
14 | #include "lua.h"
15 |
16 |
17 | /*
18 | ** This macro reallocs a vector 'b' from 'on' to 'n' elements, where
19 | ** each element has size 'e'. In case of arithmetic overflow of the
20 | ** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because
21 | ** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e).
22 | **
23 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof'
24 | ** comparison avoids a runtime comparison when overflow cannot occur.
25 | ** The compiler should be able to optimize the real test by itself, but
26 | ** when it does it, it may give a warning about "comparison is always
27 | ** false due to limited range of data type"; the +1 tricks the compiler,
28 | ** avoiding this warning but also this optimization.)
29 | */
30 | #define luaM_reallocv(L,b,on,n,e) \
31 | (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \
32 | ? luaM_toobig(L) : cast_void(0)) , \
33 | luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
34 |
35 | /*
36 | ** Arrays of chars do not need any test
37 | */
38 | #define luaM_reallocvchar(L,b,on,n) \
39 | cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char)))
40 |
41 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
42 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
43 | #define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0)
44 |
45 | #define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s))
46 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
47 | #define luaM_newvector(L,n,t) \
48 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
49 |
50 | #define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s))
51 |
52 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \
53 | if ((nelems)+1 > (size)) \
54 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
55 |
56 | #define luaM_reallocvector(L, v,oldn,n,t) \
57 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
58 |
59 | LUAI_FUNC l_noret luaM_toobig (lua_State *L);
60 |
61 | /* not to be called directly */
62 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
63 | size_t size);
64 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
65 | size_t size_elem, int limit,
66 | const char *what);
67 |
68 | #endif
69 |
70 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lopcodes.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lopcodes.c,v 1.55.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Opcodes for Lua virtual machine
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #define lopcodes_c
8 | #define LUA_CORE
9 |
10 | #include "lprefix.h"
11 |
12 |
13 | #include
14 |
15 | #include "lopcodes.h"
16 |
17 |
18 | /* ORDER OP */
19 |
20 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
21 | "MOVE",
22 | "LOADK",
23 | "LOADKX",
24 | "LOADBOOL",
25 | "LOADNIL",
26 | "GETUPVAL",
27 | "GETTABUP",
28 | "GETTABLE",
29 | "SETTABUP",
30 | "SETUPVAL",
31 | "SETTABLE",
32 | "NEWTABLE",
33 | "SELF",
34 | "ADD",
35 | "SUB",
36 | "MUL",
37 | "MOD",
38 | "POW",
39 | "DIV",
40 | "IDIV",
41 | "BAND",
42 | "BOR",
43 | "BXOR",
44 | "SHL",
45 | "SHR",
46 | "UNM",
47 | "BNOT",
48 | "NOT",
49 | "LEN",
50 | "CONCAT",
51 | "JMP",
52 | "EQ",
53 | "LT",
54 | "LE",
55 | "TEST",
56 | "TESTSET",
57 | "CALL",
58 | "TAILCALL",
59 | "RETURN",
60 | "FORLOOP",
61 | "FORPREP",
62 | "TFORCALL",
63 | "TFORLOOP",
64 | "SETLIST",
65 | "CLOSURE",
66 | "VARARG",
67 | "EXTRAARG",
68 | NULL
69 | };
70 |
71 |
72 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
73 |
74 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
75 | /* T A B C mode opcode */
76 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
77 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
78 | ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */
79 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
80 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */
81 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
82 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */
83 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
84 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */
85 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
86 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
87 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
88 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
89 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
90 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
91 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
92 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
93 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
94 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
95 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */
96 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */
97 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */
98 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */
99 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */
100 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */
101 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
102 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */
103 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
104 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
105 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
106 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
107 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
108 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
109 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
110 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */
111 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
112 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
113 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
114 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
115 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
116 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
117 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */
118 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */
119 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
120 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
121 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
122 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */
123 | };
124 |
125 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lparser.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lparser.h,v 1.76.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Lua Parser
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lparser_h
8 | #define lparser_h
9 |
10 | #include "llimits.h"
11 | #include "lobject.h"
12 | #include "lzio.h"
13 |
14 |
15 | /*
16 | ** Expression and variable descriptor.
17 | ** Code generation for variables and expressions can be delayed to allow
18 | ** optimizations; An 'expdesc' structure describes a potentially-delayed
19 | ** variable/expression. It has a description of its "main" value plus a
20 | ** list of conditional jumps that can also produce its value (generated
21 | ** by short-circuit operators 'and'/'or').
22 | */
23 |
24 | /* kinds of variables/expressions */
25 | typedef enum {
26 | VVOID, /* when 'expdesc' describes the last expression a list,
27 | this kind means an empty list (so, no expression) */
28 | VNIL, /* constant nil */
29 | VTRUE, /* constant true */
30 | VFALSE, /* constant false */
31 | VK, /* constant in 'k'; info = index of constant in 'k' */
32 | VKFLT, /* floating constant; nval = numerical float value */
33 | VKINT, /* integer constant; nval = numerical integer value */
34 | VNONRELOC, /* expression has its value in a fixed register;
35 | info = result register */
36 | VLOCAL, /* local variable; info = local register */
37 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
38 | VINDEXED, /* indexed variable;
39 | ind.vt = whether 't' is register or upvalue;
40 | ind.t = table register or upvalue;
41 | ind.idx = key's R/K index */
42 | VJMP, /* expression is a test/comparison;
43 | info = pc of corresponding jump instruction */
44 | VRELOCABLE, /* expression can put result in any register;
45 | info = instruction pc */
46 | VCALL, /* expression is a function call; info = instruction pc */
47 | VVARARG /* vararg expression; info = instruction pc */
48 | } expkind;
49 |
50 |
51 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED)
52 | #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL)
53 |
54 | typedef struct expdesc {
55 | expkind k;
56 | union {
57 | lua_Integer ival; /* for VKINT */
58 | lua_Number nval; /* for VKFLT */
59 | int info; /* for generic use */
60 | struct { /* for indexed variables (VINDEXED) */
61 | short idx; /* index (R/K) */
62 | lu_byte t; /* table (register or upvalue) */
63 | lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
64 | } ind;
65 | } u;
66 | int t; /* patch list of 'exit when true' */
67 | int f; /* patch list of 'exit when false' */
68 | } expdesc;
69 |
70 |
71 | /* description of active local variable */
72 | typedef struct Vardesc {
73 | short idx; /* variable index in stack */
74 | } Vardesc;
75 |
76 |
77 | /* description of pending goto statements and label statements */
78 | typedef struct Labeldesc {
79 | TString *name; /* label identifier */
80 | int pc; /* position in code */
81 | int line; /* line where it appeared */
82 | lu_byte nactvar; /* local level where it appears in current block */
83 | } Labeldesc;
84 |
85 |
86 | /* list of labels or gotos */
87 | typedef struct Labellist {
88 | Labeldesc *arr; /* array */
89 | int n; /* number of entries in use */
90 | int size; /* array size */
91 | } Labellist;
92 |
93 |
94 | /* dynamic structures used by the parser */
95 | typedef struct Dyndata {
96 | struct { /* list of active local variables */
97 | Vardesc *arr;
98 | int n;
99 | int size;
100 | } actvar;
101 | Labellist gt; /* list of pending gotos */
102 | Labellist label; /* list of active labels */
103 | } Dyndata;
104 |
105 |
106 | /* control of blocks */
107 | struct BlockCnt; /* defined in lparser.c */
108 |
109 |
110 | /* state needed to generate code for a given function */
111 | typedef struct FuncState {
112 | Proto *f; /* current function header */
113 | struct FuncState *prev; /* enclosing function */
114 | struct LexState *ls; /* lexical state */
115 | struct BlockCnt *bl; /* chain of current blocks */
116 | int pc; /* next position to code (equivalent to 'ncode') */
117 | int lasttarget; /* 'label' of last 'jump label' */
118 | int jpc; /* list of pending jumps to 'pc' */
119 | int nk; /* number of elements in 'k' */
120 | int np; /* number of elements in 'p' */
121 | int firstlocal; /* index of first local var (in Dyndata array) */
122 | short nlocvars; /* number of elements in 'f->locvars' */
123 | lu_byte nactvar; /* number of active local variables */
124 | lu_byte nups; /* number of upvalues */
125 | lu_byte freereg; /* first free register */
126 | } FuncState;
127 |
128 |
129 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
130 | Dyndata *dyd, const char *name, int firstchar);
131 |
132 |
133 | #endif
134 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lprefix.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lprefix.h,v 1.2.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Definitions for Lua code that must come before any other header file
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lprefix_h
8 | #define lprefix_h
9 |
10 |
11 | /*
12 | ** Allows POSIX/XSI stuff
13 | */
14 | #if !defined(LUA_USE_C89) /* { */
15 |
16 | #if !defined(_XOPEN_SOURCE)
17 | #define _XOPEN_SOURCE 600
18 | #elif _XOPEN_SOURCE == 0
19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */
20 | #endif
21 |
22 | /*
23 | ** Allows manipulation of large files in gcc and some other compilers
24 | */
25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS)
26 | #define _LARGEFILE_SOURCE 1
27 | #define _FILE_OFFSET_BITS 64
28 | #endif
29 |
30 | #endif /* } */
31 |
32 |
33 | /*
34 | ** Windows stuff
35 | */
36 | #if defined(_WIN32) /* { */
37 |
38 | #if !defined(_CRT_SECURE_NO_WARNINGS)
39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */
40 | #endif
41 |
42 | #endif /* } */
43 |
44 | #endif
45 |
46 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lstring.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** String table (keep all strings handled by Lua)
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lstring_h
8 | #define lstring_h
9 |
10 | #include "lgc.h"
11 | #include "lobject.h"
12 | #include "lstate.h"
13 |
14 |
15 | #define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
16 |
17 | #define sizeludata(l) (sizeof(union UUdata) + (l))
18 | #define sizeudata(u) sizeludata((u)->len)
19 |
20 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
21 | (sizeof(s)/sizeof(char))-1))
22 |
23 |
24 | /*
25 | ** test whether a string is a reserved word
26 | */
27 | #define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0)
28 |
29 |
30 | /*
31 | ** equality for short strings, which are always internalized
32 | */
33 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b))
34 |
35 |
36 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
37 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts);
38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
39 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
40 | LUAI_FUNC void luaS_clearcache (global_State *g);
41 | LUAI_FUNC void luaS_init (lua_State *L);
42 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
43 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
44 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
45 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
46 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l);
47 |
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/Mjolnir/lua/ltable.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: ltable.h,v 2.23.1.2 2018/05/24 19:39:05 roberto Exp $
3 | ** Lua tables (hash)
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef ltable_h
8 | #define ltable_h
9 |
10 | #include "lobject.h"
11 |
12 |
13 | #define gnode(t,i) (&(t)->node[i])
14 | #define gval(n) (&(n)->i_val)
15 | #define gnext(n) ((n)->i_key.nk.next)
16 |
17 |
18 | /* 'const' to avoid wrong writings that can mess up field 'next' */
19 | #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk))
20 |
21 | /*
22 | ** writable version of 'gkey'; allows updates to individual fields,
23 | ** but not to the whole (which has incompatible type)
24 | */
25 | #define wgkey(n) (&(n)->i_key.nk)
26 |
27 | #define invalidateTMcache(t) ((t)->flags = 0)
28 |
29 |
30 | /* true when 't' is using 'dummynode' as its hash part */
31 | #define isdummy(t) ((t)->lastfree == NULL)
32 |
33 |
34 | /* allocated size for hash nodes */
35 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
36 |
37 |
38 | /* returns the key, given the value of a table entry */
39 | #define keyfromval(v) \
40 | (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
41 |
42 |
43 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
44 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
45 | TValue *value);
46 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
47 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
48 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
49 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
50 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
51 | LUAI_FUNC Table *luaH_new (lua_State *L);
52 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
53 | unsigned int nhsize);
54 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize);
55 | LUAI_FUNC void luaH_free (lua_State *L, Table *t);
56 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
57 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t);
58 |
59 |
60 | #if defined(LUA_DEBUG)
61 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
62 | LUAI_FUNC int luaH_isdummy (const Table *t);
63 | #endif
64 |
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/Mjolnir/lua/ltm.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $
3 | ** Tag methods
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #define ltm_c
8 | #define LUA_CORE
9 |
10 | #include "lprefix.h"
11 |
12 |
13 | #include
14 |
15 | #include "lua.h"
16 |
17 | #include "ldebug.h"
18 | #include "ldo.h"
19 | #include "lobject.h"
20 | #include "lstate.h"
21 | #include "lstring.h"
22 | #include "ltable.h"
23 | #include "ltm.h"
24 | #include "lvm.h"
25 |
26 |
27 | static const char udatatypename[] = "userdata";
28 |
29 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
30 | "no value",
31 | "nil", "boolean", udatatypename, "number",
32 | "string", "table", "function", udatatypename, "thread",
33 | "proto" /* this last case is used for tests only */
34 | };
35 |
36 |
37 | void luaT_init (lua_State *L) {
38 | static const char *const luaT_eventname[] = { /* ORDER TM */
39 | "__index", "__newindex",
40 | "__gc", "__mode", "__len", "__eq",
41 | "__add", "__sub", "__mul", "__mod", "__pow",
42 | "__div", "__idiv",
43 | "__band", "__bor", "__bxor", "__shl", "__shr",
44 | "__unm", "__bnot", "__lt", "__le",
45 | "__concat", "__call"
46 | };
47 | int i;
48 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]);
50 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */
51 | }
52 | }
53 |
54 |
55 | /*
56 | ** function to be used with macro "fasttm": optimized for absence of
57 | ** tag methods
58 | */
59 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
60 | const TValue *tm = luaH_getshortstr(events, ename);
61 | lua_assert(event <= TM_EQ);
62 | if (ttisnil(tm)) { /* no tag method? */
63 | events->flags |= cast_byte(1u<metatable;
75 | break;
76 | case LUA_TUSERDATA:
77 | mt = uvalue(o)->metatable;
78 | break;
79 | default:
80 | mt = G(L)->mt[ttnov(o)];
81 | }
82 | return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject);
83 | }
84 |
85 |
86 | /*
87 | ** Return the name of the type of an object. For tables and userdata
88 | ** with metatable, use their '__name' metafield, if present.
89 | */
90 | const char *luaT_objtypename (lua_State *L, const TValue *o) {
91 | Table *mt;
92 | if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
93 | (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
94 | const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
95 | if (ttisstring(name)) /* is '__name' a string? */
96 | return getstr(tsvalue(name)); /* use it as type name */
97 | }
98 | return ttypename(ttnov(o)); /* else use standard type name */
99 | }
100 |
101 |
102 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
103 | const TValue *p2, TValue *p3, int hasres) {
104 | ptrdiff_t result = savestack(L, p3);
105 | StkId func = L->top;
106 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
107 | setobj2s(L, func + 1, p1); /* 1st argument */
108 | setobj2s(L, func + 2, p2); /* 2nd argument */
109 | L->top += 3;
110 | if (!hasres) /* no result? 'p3' is third argument */
111 | setobj2s(L, L->top++, p3); /* 3rd argument */
112 | /* metamethod may yield only when called from Lua code */
113 | if (isLua(L->ci))
114 | luaD_call(L, func, hasres);
115 | else
116 | luaD_callnoyield(L, func, hasres);
117 | if (hasres) { /* if has result, move it to its place */
118 | p3 = restorestack(L, result);
119 | setobjs2s(L, p3, --L->top);
120 | }
121 | }
122 |
123 |
124 | int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
125 | StkId res, TMS event) {
126 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
127 | if (ttisnil(tm))
128 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
129 | if (ttisnil(tm)) return 0;
130 | luaT_callTM(L, tm, p1, p2, res, 1);
131 | return 1;
132 | }
133 |
134 |
135 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
136 | StkId res, TMS event) {
137 | if (!luaT_callbinTM(L, p1, p2, res, event)) {
138 | switch (event) {
139 | case TM_CONCAT:
140 | luaG_concaterror(L, p1, p2);
141 | /* call never returns, but to avoid warnings: *//* FALLTHROUGH */
142 | case TM_BAND: case TM_BOR: case TM_BXOR:
143 | case TM_SHL: case TM_SHR: case TM_BNOT: {
144 | lua_Number dummy;
145 | if (tonumber(p1, &dummy) && tonumber(p2, &dummy))
146 | luaG_tointerror(L, p1, p2);
147 | else
148 | luaG_opinterror(L, p1, p2, "perform bitwise operation on");
149 | }
150 | /* calls never return, but to avoid warnings: *//* FALLTHROUGH */
151 | default:
152 | luaG_opinterror(L, p1, p2, "perform arithmetic on");
153 | }
154 | }
155 | }
156 |
157 |
158 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
159 | TMS event) {
160 | if (!luaT_callbinTM(L, p1, p2, L->top, event))
161 | return -1; /* no metamethod */
162 | else
163 | return !l_isfalse(L->top);
164 | }
165 |
166 |
--------------------------------------------------------------------------------
/Mjolnir/lua/ltm.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Tag methods
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef ltm_h
8 | #define ltm_h
9 |
10 |
11 | #include "lobject.h"
12 |
13 |
14 | /*
15 | * WARNING: if you change the order of this enumeration,
16 | * grep "ORDER TM" and "ORDER OP"
17 | */
18 | typedef enum {
19 | TM_INDEX,
20 | TM_NEWINDEX,
21 | TM_GC,
22 | TM_MODE,
23 | TM_LEN,
24 | TM_EQ, /* last tag method with fast access */
25 | TM_ADD,
26 | TM_SUB,
27 | TM_MUL,
28 | TM_MOD,
29 | TM_POW,
30 | TM_DIV,
31 | TM_IDIV,
32 | TM_BAND,
33 | TM_BOR,
34 | TM_BXOR,
35 | TM_SHL,
36 | TM_SHR,
37 | TM_UNM,
38 | TM_BNOT,
39 | TM_LT,
40 | TM_LE,
41 | TM_CONCAT,
42 | TM_CALL,
43 | TM_N /* number of elements in the enum */
44 | } TMS;
45 |
46 |
47 |
48 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \
49 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
50 |
51 | #define fasttm(l,et,e) gfasttm(G(l), et, e)
52 |
53 | #define ttypename(x) luaT_typenames_[(x) + 1]
54 |
55 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
56 |
57 |
58 | LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o);
59 |
60 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
61 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
62 | TMS event);
63 | LUAI_FUNC void luaT_init (lua_State *L);
64 |
65 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
66 | const TValue *p2, TValue *p3, int hasres);
67 | LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
68 | StkId res, TMS event);
69 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
70 | StkId res, TMS event);
71 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
72 | const TValue *p2, TMS event);
73 |
74 |
75 |
76 | #endif
77 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lua.hpp:
--------------------------------------------------------------------------------
1 | // lua.hpp
2 | // Lua header files for C++
3 | // <> not supplied automatically because Lua also compiles as C++
4 |
5 | extern "C" {
6 | #include "lua.h"
7 | #include "lualib.h"
8 | #include "lauxlib.h"
9 | }
10 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lualib.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lualib.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Lua standard libraries
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 |
8 | #ifndef lualib_h
9 | #define lualib_h
10 |
11 | #include "lua.h"
12 |
13 |
14 | /* version suffix for environment variable names */
15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
16 |
17 |
18 | LUAMOD_API int (luaopen_base) (lua_State *L);
19 |
20 | #define LUA_COLIBNAME "coroutine"
21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L);
22 |
23 | #define LUA_TABLIBNAME "table"
24 | LUAMOD_API int (luaopen_table) (lua_State *L);
25 |
26 | #define LUA_IOLIBNAME "io"
27 | LUAMOD_API int (luaopen_io) (lua_State *L);
28 |
29 | #define LUA_OSLIBNAME "os"
30 | LUAMOD_API int (luaopen_os) (lua_State *L);
31 |
32 | #define LUA_STRLIBNAME "string"
33 | LUAMOD_API int (luaopen_string) (lua_State *L);
34 |
35 | #define LUA_UTF8LIBNAME "utf8"
36 | LUAMOD_API int (luaopen_utf8) (lua_State *L);
37 |
38 | #define LUA_BITLIBNAME "bit32"
39 | LUAMOD_API int (luaopen_bit32) (lua_State *L);
40 |
41 | #define LUA_MATHLIBNAME "math"
42 | LUAMOD_API int (luaopen_math) (lua_State *L);
43 |
44 | #define LUA_DBLIBNAME "debug"
45 | LUAMOD_API int (luaopen_debug) (lua_State *L);
46 |
47 | #define LUA_LOADLIBNAME "package"
48 | LUAMOD_API int (luaopen_package) (lua_State *L);
49 |
50 |
51 | /* open all previous libraries */
52 | LUALIB_API void (luaL_openlibs) (lua_State *L);
53 |
54 |
55 |
56 | #if !defined(lua_assert)
57 | #define lua_assert(x) ((void)0)
58 | #endif
59 |
60 |
61 | #endif
62 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lundump.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lundump.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** load precompiled Lua chunks
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lundump_h
8 | #define lundump_h
9 |
10 | #include "llimits.h"
11 | #include "lobject.h"
12 | #include "lzio.h"
13 |
14 |
15 | /* data to catch conversion errors */
16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n"
17 |
18 | #define LUAC_INT 0x5678
19 | #define LUAC_NUM cast_num(370.5)
20 |
21 | #define MYINT(s) (s[0]-'0')
22 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR))
23 | #define LUAC_FORMAT 0 /* this is the official format */
24 |
25 | /* load one chunk; from lundump.c */
26 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name);
27 |
28 | /* dump one chunk; from ldump.c */
29 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w,
30 | void* data, int strip);
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lvm.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lvm.h,v 2.41.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Lua virtual machine
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lvm_h
8 | #define lvm_h
9 |
10 |
11 | #include "ldo.h"
12 | #include "lobject.h"
13 | #include "ltm.h"
14 |
15 |
16 | #if !defined(LUA_NOCVTN2S)
17 | #define cvt2str(o) ttisnumber(o)
18 | #else
19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */
20 | #endif
21 |
22 |
23 | #if !defined(LUA_NOCVTS2N)
24 | #define cvt2num(o) ttisstring(o)
25 | #else
26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */
27 | #endif
28 |
29 |
30 | /*
31 | ** You can define LUA_FLOORN2I if you want to convert floats to integers
32 | ** by flooring them (instead of raising an error if they are not
33 | ** integral values)
34 | */
35 | #if !defined(LUA_FLOORN2I)
36 | #define LUA_FLOORN2I 0
37 | #endif
38 |
39 |
40 | #define tonumber(o,n) \
41 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
42 |
43 | #define tointeger(o,i) \
44 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I))
45 |
46 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
47 |
48 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2)
49 |
50 |
51 | /*
52 | ** fast track for 'gettable': if 't' is a table and 't[k]' is not nil,
53 | ** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise,
54 | ** return 0 (meaning it will have to check metamethod) with 'slot'
55 | ** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise).
56 | ** 'f' is the raw get function to use.
57 | */
58 | #define luaV_fastget(L,t,k,slot,f) \
59 | (!ttistable(t) \
60 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
61 | : (slot = f(hvalue(t), k), /* else, do raw access */ \
62 | !ttisnil(slot))) /* result not nil? */
63 |
64 | /*
65 | ** standard implementation for 'gettable'
66 | */
67 | #define luaV_gettable(L,t,k,v) { const TValue *slot; \
68 | if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
69 | else luaV_finishget(L,t,k,v,slot); }
70 |
71 |
72 | /*
73 | ** Fast track for set table. If 't' is a table and 't[k]' is not nil,
74 | ** call GC barrier, do a raw 't[k]=v', and return true; otherwise,
75 | ** return false with 'slot' equal to NULL (if 't' is not a table) or
76 | ** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro
77 | ** returns true, there is no need to 'invalidateTMcache', because the
78 | ** call is not creating a new entry.
79 | */
80 | #define luaV_fastset(L,t,k,slot,f,v) \
81 | (!ttistable(t) \
82 | ? (slot = NULL, 0) \
83 | : (slot = f(hvalue(t), k), \
84 | ttisnil(slot) ? 0 \
85 | : (luaC_barrierback(L, hvalue(t), v), \
86 | setobj2t(L, cast(TValue *,slot), v), \
87 | 1)))
88 |
89 |
90 | #define luaV_settable(L,t,k,v) { const TValue *slot; \
91 | if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \
92 | luaV_finishset(L,t,k,v,slot); }
93 |
94 |
95 |
96 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
97 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
98 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
99 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
100 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
101 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
102 | StkId val, const TValue *slot);
103 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
104 | StkId val, const TValue *slot);
105 | LUAI_FUNC void luaV_finishOp (lua_State *L);
106 | LUAI_FUNC void luaV_execute (lua_State *L);
107 | LUAI_FUNC void luaV_concat (lua_State *L, int total);
108 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
109 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
110 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y);
111 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
112 |
113 | #endif
114 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lzio.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lzio.c,v 1.37.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Buffered streams
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #define lzio_c
8 | #define LUA_CORE
9 |
10 | #include "lprefix.h"
11 |
12 |
13 | #include
14 |
15 | #include "lua.h"
16 |
17 | #include "llimits.h"
18 | #include "lmem.h"
19 | #include "lstate.h"
20 | #include "lzio.h"
21 |
22 |
23 | int luaZ_fill (ZIO *z) {
24 | size_t size;
25 | lua_State *L = z->L;
26 | const char *buff;
27 | lua_unlock(L);
28 | buff = z->reader(L, z->data, &size);
29 | lua_lock(L);
30 | if (buff == NULL || size == 0)
31 | return EOZ;
32 | z->n = size - 1; /* discount char being returned */
33 | z->p = buff;
34 | return cast_uchar(*(z->p++));
35 | }
36 |
37 |
38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
39 | z->L = L;
40 | z->reader = reader;
41 | z->data = data;
42 | z->n = 0;
43 | z->p = NULL;
44 | }
45 |
46 |
47 | /* --------------------------------------------------------------- read --- */
48 | size_t luaZ_read (ZIO *z, void *b, size_t n) {
49 | while (n) {
50 | size_t m;
51 | if (z->n == 0) { /* no bytes in buffer? */
52 | if (luaZ_fill(z) == EOZ) /* try to read more */
53 | return n; /* no more input; return number of missing bytes */
54 | else {
55 | z->n++; /* luaZ_fill consumed first byte; put it back */
56 | z->p--;
57 | }
58 | }
59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
60 | memcpy(b, z->p, m);
61 | z->n -= m;
62 | z->p += m;
63 | b = (char *)b + m;
64 | n -= m;
65 | }
66 | return 0;
67 | }
68 |
69 |
--------------------------------------------------------------------------------
/Mjolnir/lua/lzio.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lzio.h,v 1.31.1.1 2017/04/19 17:20:42 roberto Exp $
3 | ** Buffered streams
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 |
8 | #ifndef lzio_h
9 | #define lzio_h
10 |
11 | #include "lua.h"
12 |
13 | #include "lmem.h"
14 |
15 |
16 | #define EOZ (-1) /* end of stream */
17 |
18 | typedef struct Zio ZIO;
19 |
20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z))
21 |
22 |
23 | typedef struct Mbuffer {
24 | char *buffer;
25 | size_t n;
26 | size_t buffsize;
27 | } Mbuffer;
28 |
29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
30 |
31 | #define luaZ_buffer(buff) ((buff)->buffer)
32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize)
33 | #define luaZ_bufflen(buff) ((buff)->n)
34 |
35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i))
36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0)
37 |
38 |
39 | #define luaZ_resizebuffer(L, buff, size) \
40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \
41 | (buff)->buffsize, size), \
42 | (buff)->buffsize = size)
43 |
44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
45 |
46 |
47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
48 | void *data);
49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */
50 |
51 |
52 |
53 | /* --------- Private Part ------------------ */
54 |
55 | struct Zio {
56 | size_t n; /* bytes still unread */
57 | const char *p; /* current position in buffer */
58 | lua_Reader reader; /* reader function */
59 | void *data; /* additional data */
60 | lua_State *L; /* Lua state (for reader) */
61 | };
62 |
63 |
64 | LUAI_FUNC int luaZ_fill (ZIO *z);
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/Mjolnir/setup.lua:
--------------------------------------------------------------------------------
1 | local prettypath, fullpath, configdir, hasinitfile = ...
2 |
3 | os.exit = mjolnir._exit
4 |
5 | local function runstring(s)
6 | local fn, err = load("return " .. s)
7 | if not fn then fn, err = load(s) end
8 | if not fn then return tostring(err) end
9 |
10 | local str = ""
11 | local results = table.pack(pcall(fn))
12 | for i = 2,results.n do
13 | if i > 2 then str = str .. "\t" end
14 | str = str .. tostring(results[i])
15 | end
16 | return str
17 | end
18 |
19 | --- mjolnir.configdir = "~/.mjolnir/"
20 | --- Constant
21 | --- The user's Mjolnir config directory. Modules may use it, assuming
22 | --- they've worked out a contract with the user about how to use it.
23 | mjolnir.configdir = configdir
24 |
25 | --- mjolnir.showerror(err)
26 | --- Function
27 | ---
28 | --- Presents an error to the user via Mjolnir's GUI. The default
29 | --- implementation prints the error, focuses Mjolnir, and opens
30 | --- Mjolnir's console.
31 | ---
32 | --- Users can override this with a new function that shows errors in a
33 | --- custom way.
34 | ---
35 | --- Modules can call this in the event of an error, e.g. in callbacks
36 | --- from the user:
37 | ---
38 | --- local ok, err = xpcall(callbackfn, debug.traceback)
39 | --- if not ok then mjolnir.showerror(err) end
40 | function mjolnir.showerror(err)
41 | mjolnir._notify("Mjolnir error occurred") -- undecided on this line
42 | print(err)
43 | mjolnir.focus()
44 | mjolnir.openconsole()
45 | end
46 |
47 | --- mjolnir.rawprint = print
48 | --- Function
49 | --- The original print function, before Mjolnir overrides it.
50 | local rawprint = print
51 | mjolnir.rawprint = rawprint
52 | function print(...)
53 | rawprint(...)
54 | local vals = table.pack(...)
55 |
56 | for k = 1, vals.n do
57 | vals[k] = tostring(vals[k])
58 | end
59 |
60 | local str = table.concat(vals, "\t") .. "\n"
61 | mjolnir._logmessage(str)
62 | end
63 |
64 | if not hasinitfile then
65 | print(string.format("-- Can't find %s; create it and reload your config.", prettypath))
66 | return runstring
67 | end
68 |
69 | print("-- Loading " .. prettypath)
70 | local fn, err = loadfile(fullpath)
71 | if not fn then mjolnir.showerror(err) return runstring end
72 |
73 | local ok, err = xpcall(fn, debug.traceback)
74 | if not ok then mjolnir.showerror(err) return runstring end
75 |
76 | print "-- Done."
77 |
78 | return runstring
79 |
--------------------------------------------------------------------------------
/Mjolnir/statusicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/statusicon.png
--------------------------------------------------------------------------------
/Mjolnir/statusicon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/Mjolnir/statusicon@2x.png
--------------------------------------------------------------------------------
/Mjolnir/variables.h:
--------------------------------------------------------------------------------
1 | #ifndef Mjolnir_variables_h
2 | #define Mjolnir_variables_h
3 |
4 |
5 | static NSString* MJReleaseNotesURL = @"https://github.com/sdegutis/mjolnir#changes";
6 | static NSString* MJDownloadPage = @"https://github.com/sdegutis/mjolnir/releases/latest";
7 | static NSString* MJUpdatesURL = @"https://raw.githubusercontent.com/sdegutis/mjolnir/master/LATESTVERSION";
8 |
9 | static NSString* MJPublicKey = @""
10 | "-----BEGIN PUBLIC KEY-----\n"
11 | "MIIBtzCCASsGByqGSM44BAEwggEeAoGBAKI1LKQiFEWu6woOAzKPeVrvMoUFLv43\n"
12 | "I2PYizYCAUkzdh8Rgos0qSwg6+qaStVB3SYHxXlwtyiuJwm9CZtiPJzXUFDESvha\n"
13 | "hJckBRxL93zrUIW1gCIeXrvX89ZNzn9pgj6c72z+rkfV/SFYYXWNm375t6gZwoTy\n"
14 | "rlZVNnUewetvAhUAhUtGFpd0rJmqhaMEuPRDDUQGlhkCgYBEm3G1/p058vDw8rKW\n"
15 | "u0UKHN6syEATqditlyqcH0F28pxwVTXIt44o9nrygDdSgcZne2GQC6PJU1tSDliH\n"
16 | "77nJGCvfJ6Uyj69ieAY3q7Enshk5M3rBub+Nq5Ec0YtpuDVUB6ytXnwpld/bbOQ3\n"
17 | "WlMqy6lTidH72azA1+UVcSOLXQOBhQACgYEAmV6CvXE5N1gScnbD+5E4VM4JFyF8\n"
18 | "xjA+0xzpoW2ctFKvgQxMswlmvvZvU7oTm/KHrJkK8arlWi3kV2qfNk1Ry7GKE9fW\n"
19 | "jebNdfI+fWntQjd1bCIlACFGrH5ioucI0Hdzxarx/7Ie10UPveSRf8ifO9JU1bSH\n"
20 | "cohzwU5/305uivg=\n"
21 | "-----END PUBLIC KEY-----\n";
22 |
23 | #define MJCheckForUpdatesKey @"MJCheckForUpdatesKey"
24 | #define MJShowDockIconKey @"MJShowDockIconKey"
25 | #define MJShowMenuIconKey @"MJShowMenuIconKey"
26 | #define MJKeepConsoleOnTopKey @"MJKeepConsoleOnTopKey"
27 | #define MJHasRunAlreadyKey @"MJHasRunAlreadyKey"
28 | #define MJCheckForUpdatesIntervalKey @"MJCheckForUpdatesIntervalKey"
29 |
30 | static NSString* MJConfigFile = @"~/.mjolnir/init.lua";
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/docs/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'github-markdown'
4 |
--------------------------------------------------------------------------------
/docs/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | github-markdown (0.6.6)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | github-markdown
11 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | all: build/Mjolnir.tgz
2 |
3 | build/Mjolnir.tgz: build/Mjolnir.docset
4 | tar --exclude='.DS_Store' -cvzf $@ -C build Mjolnir.docset
5 |
6 | build/Mjolnir.docset: build/docs.sql.out build/docs.html.d
7 | rm -rf $@
8 | cp -R templates/Mjolnir.docset $@
9 | cp build/docs.sql.out $@/Contents/Resources/docSet.dsidx
10 | cp build/docs.html.d/* $@/Contents/Resources/Documents/
11 |
12 | build/docs.html.d: build/docs.json
13 | mkdir -p $@
14 | rm -f $@/*
15 | bin/genhtml $@ < $<
16 |
17 | build/docs.sql.out: build/docs.sql
18 | sqlite3 $@ < $<
19 |
20 | build/docs.sql: build/docs.json
21 | bin/gensql < $< > $@
22 |
23 | build/docs.json: build/comments.json
24 | bin/genjson < $< > $@
25 |
26 | build/comments.json: build/candidates.txt
27 | bin/gencomments < $< > $@
28 |
29 | build/candidates.txt: build/candidates
30 | find $< -type f \( -name '*.lua' -o -name '*.m' \) -not -path '*/_docsignore/*' -exec cat {} + > $@
31 |
32 | build/candidates: build/repos.txt
33 | mkdir -p $@
34 | bin/download $@ < $<
35 |
36 | build/repos.txt: build/wiki
37 | cp build/wiki/Repos.md $@
38 |
39 | build/wiki:
40 | git clone https://github.com/sdegutis/mjolnir.wiki.git $@
41 |
42 | clean:
43 | rm -rf build/*
44 |
45 | .PHONY: all clean
46 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ### To write docs
2 |
3 | 1. Any comment that starts with `---` or `///` is a doc-string (i.e. 3 comment-characters in a row)
4 | 2. Doc-strings continue on until a non-docstring line
5 | 3. Doc-strings for modules contain `=== my.modulename ===`, then any number of lines describing it
6 | 4. Doc-strings for items (functions, variables, etc.) go like this:
7 | 1. The first line starts with `my.modulename.item` or `my.modulename:item` -- this is the item name
8 | 2. Any non-alphanumeric character ends the item name and is ignored, i.e. parentheses or spaces:
9 | 1. `my.modulename:foo()`
10 | 2. `my.modulename:foo(bar) -> string`
11 | 3. `my.modulename.foo(bar, fn(int) -> int)`
12 | 4. `my.modulename.foo = {}`
13 | 3. The second line is a single captitalized word, like "Variable" or "Function" or "Method"
14 | 4. The remaining lines describe the item
15 | 5. Any comment that starts with 4 comment-characters is ignored
16 | 6. Anything in a directory `_docsignore` or subdirectory of it are skipped
17 | 7. Only files ending in `.lua` or `.m` are scanned
18 |
19 | ### To generate docs
20 |
21 | ~~~bash
22 | $ bundle install
23 | $ make
24 | ~~~
25 |
26 | ### To add your module
27 |
28 | 1. Add your repo's `.tar.gz` URL to Repos page in this wiki
29 | 2. Clone this repo
30 | 3. Generate docs (see above)
31 | 4. Verify the built Mjolnir.docset looks like it should
32 | 5. Send PR to https://github.com/kapeli/Dash-User-Contributions
33 | 1. Fork his repo
34 | 2. Copy `build/Mjolnir.tgz` (from step #3) into `Dash-User-Contributions/docsets/Mjolnir/`
35 | 3. Update the version number in `Dash-User-Contributions/docsets/Mjolnir/docset.json`
36 | 4. Send PR on our behalf
37 |
--------------------------------------------------------------------------------
/docs/bin/download:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | DEST=$1
3 | while read -r url; do
4 | url=$(echo $url | tr -d '\r')
5 | echo "### Cloning [${url}] to $DEST"
6 | curl -L -s $url | tar -x -C $DEST
7 | done
8 |
--------------------------------------------------------------------------------
/docs/bin/gencomments:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | Encoding.default_external = Encoding::UTF_8
3 | Encoding.default_internal = Encoding::UTF_8
4 |
5 | require 'json'
6 |
7 | comments = []
8 |
9 | partialcomment = []
10 | incomment = false
11 |
12 | STDIN.read.split("\n").each do |line|
13 | islua = line.start_with?('-'*3) and !line.start_with?('-'*4)
14 | isobjc = line.start_with?('/'*3) and !line.start_with?('/'*4)
15 |
16 | if islua || isobjc then
17 | incomment = true
18 | partialcomment << line[3..-1].sub(/^\s/, '')
19 | elsif incomment then
20 | incomment = false
21 | comments << partialcomment
22 | partialcomment = []
23 | end
24 | end
25 |
26 | puts JSON.pretty_generate(comments)
27 |
--------------------------------------------------------------------------------
/docs/bin/genhtml:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'json'
3 | require 'github/markdown'
4 | require 'erb'
5 |
6 | outdir = ARGV.first
7 | docmods = JSON.load(STDIN.read)
8 |
9 | mod_template = ERB.new(File.read('templates/ext.html.erb'))
10 | index_template = ERB.new(File.read('templates/index.html.erb'))
11 |
12 | content = GitHub::Markdown.render_gfm(File.read('templates/index.md'))
13 | html = index_template.result(binding)
14 | File.write("#{outdir}/index.html", html)
15 |
16 | docmods.each do |mod|
17 | File.write("#{outdir}/#{mod['name']}.html", mod_template.result(binding))
18 | end
19 |
--------------------------------------------------------------------------------
/docs/bin/genjson:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'json'
3 |
4 | comments = JSON.load(STDIN.read)
5 |
6 | newmod = ->(c) {{name: c[0].gsub('=', '').strip,
7 | doc: c[1..-1].join("\n").strip,
8 | items: []}}
9 |
10 | newitem = ->(c) {{type: c[1],
11 | name: nil,
12 | def: c[0],
13 | doc: c[2..-1].join("\n").strip}}
14 |
15 | ismod = ->(c) { c[0].include?('===') }
16 | mods = comments.select(&ismod).map(&newmod)
17 | items = comments.reject(&ismod).map(&newitem)
18 | orderedmods = mods.sort_by{|m|m[:name]}.reverse
19 |
20 | items.each do |item|
21 | mod = orderedmods.find{|mod| item[:def].start_with?(mod[:name])}
22 | if mod.nil?
23 | abort "error: couldn't find module for #{item[:def]}"
24 | end
25 | item[:name] = item[:def][(mod[:name].size+1)..-1].match(/\w+/)[0]
26 | mod[:items] << item
27 | end
28 |
29 | mods.sort_by!{|m|m[:name]}
30 | puts JSON.pretty_generate(mods)
31 |
--------------------------------------------------------------------------------
/docs/bin/gensql:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'json'
3 |
4 | docmods = JSON.load(STDIN.read)
5 |
6 | puts "CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);"
7 | puts "CREATE UNIQUE INDEX anchor ON searchIndex (name, type, path);"
8 |
9 | docmods.each do |mod|
10 | mod['items'].each do |item|
11 | puts "INSERT INTO searchIndex VALUES (NULL, '#{mod['name']}.#{item['name']}', '#{item['type']}', '#{mod['name']}.html##{item['name']}');"
12 | end
13 | puts "INSERT INTO searchIndex VALUES (NULL, '#{mod['name']}', 'Module', '#{mod['name']}.html');"
14 | end
15 |
--------------------------------------------------------------------------------
/docs/templates/Mjolnir.docset/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIdentifier
6 | mjolnir
7 | CFBundleName
8 | Mjolnir
9 | DocSetPlatformFamily
10 | mjolnir
11 | isDashDocset
12 |
13 | dashIndexFilePath
14 | index.html
15 | DashDocSetFamily
16 | dashtoc
17 |
18 |
19 |
--------------------------------------------------------------------------------
/docs/templates/Mjolnir.docset/Contents/Resources/Documents/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/docs/templates/Mjolnir.docset/Contents/Resources/Documents/.gitkeep
--------------------------------------------------------------------------------
/docs/templates/Mjolnir.docset/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/docs/templates/Mjolnir.docset/icon.png
--------------------------------------------------------------------------------
/docs/templates/Mjolnir.docset/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/docs/templates/Mjolnir.docset/icon@2x.png
--------------------------------------------------------------------------------
/docs/templates/ext.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | Mjolnir docs: <%= mod['name'] %> module
4 |
10 |
11 |
12 |
13 | <%= mod['name'] %>
14 | <%= GitHub::Markdown.render_gfm(mod['doc']) %>
15 |
16 | <% mod['items'].sort_by{|m|m['def']}.each do |item| %>
17 |
18 |
19 |
20 | <%= item['def'] %>
21 | <%= GitHub::Markdown.render_gfm(item['doc']) %>
22 |
23 | <% end %>
24 |
25 |
26 |
--------------------------------------------------------------------------------
/docs/templates/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | Mjolnir docs
4 |
9 |
10 |
11 |
14 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/docs/templates/index.md:
--------------------------------------------------------------------------------
1 | ### Project links
2 |
3 | Resource | Link
4 | -------------------------|---------------------------------------------------
5 | Fancy Website | http://mjolnir.io/
6 | Github page | https://github.com/sdegutis/mjolnir/
7 | Mailing List | https://groups.google.com/forum/#!forum/mjolnir-io
8 | IRC channel | #mjolnir on freenode
9 |
--------------------------------------------------------------------------------
/mods/LICENSE.md:
--------------------------------------------------------------------------------
1 | > Released under MIT license.
2 | >
3 | > Copyright (c) 2013 Steven Degutis
4 | >
5 | > Permission is hereby granted, free of charge, to any person obtaining a copy
6 | > of this software and associated documentation files (the "Software"), to deal
7 | > in the Software without restriction, including without limitation the rights
8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | > copies of the Software, and to permit persons to whom the Software is
10 | > furnished to do so, subject to the following conditions:
11 | >
12 | > The above copyright notice and this permission notice shall be included in
13 | > all copies or substantial portions of the Software.
14 | >
15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | > THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/mods/README.md:
--------------------------------------------------------------------------------
1 | Fundamental Lua modules for [Mjolnir](https://github.com/sdegutis/mjolnir).
2 |
3 | You can find them here: https://rocks.moonscript.org/search?q=mjolnir
4 |
--------------------------------------------------------------------------------
/mods/alert/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | *.xcworkspace
13 | !default.xcworkspace
14 | xcuserdata
15 | profile
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 |
20 | # LuaRocks
21 | *.o
22 | *.so
23 | *.rock
24 |
--------------------------------------------------------------------------------
/mods/alert/mjolnir.alert-0.2-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "mjolnir.alert"
2 | version = "0.2-1"
3 | local url = "github.com/sdegutis/mjolnir-modules"
4 | local desc = "Mjolnir module to show brief messages on-screen."
5 | source = {url = "git://" .. url}
6 | description = {
7 | summary = desc,
8 | detailed = desc,
9 | homepage = "https://" .. url,
10 | license = "MIT",
11 | }
12 | supported_platforms = {"macosx"}
13 | dependencies = {
14 | "lua >= 5.2",
15 | }
16 | build = {
17 | type = "builtin",
18 | modules = {
19 | ["mjolnir.alert"] = "alert.m",
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/mods/application/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | *.xcworkspace
13 | !default.xcworkspace
14 | xcuserdata
15 | profile
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 |
20 | # LuaRocks
21 | *.o
22 | *.so
23 | *.rock
24 |
--------------------------------------------------------------------------------
/mods/application/application.h:
--------------------------------------------------------------------------------
1 | #ifndef Application_application_h
2 | #define Application_application_h
3 |
4 | static void new_application(lua_State* L, pid_t pid) {
5 | AXUIElementRef* appptr = lua_newuserdata(L, sizeof(AXUIElementRef));
6 | *appptr = AXUIElementCreateApplication(pid);
7 |
8 | luaL_getmetatable(L, "mjolnir.application");
9 | lua_setmetatable(L, -2);
10 |
11 | lua_newtable(L);
12 | lua_pushnumber(L, pid);
13 | lua_setfield(L, -2, "pid");
14 | lua_setuservalue(L, -2);
15 | }
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/mods/application/application.lua:
--------------------------------------------------------------------------------
1 | --- === mjolnir.application ===
2 | ---
3 | --- Manipulate running applications.
4 |
5 | local application = require "mjolnir.application.internal"
6 | local fnutils = require "mjolnir.fnutils"
7 | local window = require "mjolnir.window"
8 |
9 | --- mjolnir.application:visiblewindows() -> win[]
10 | --- Method
11 | --- Returns only the app's windows that are visible.
12 | function application:visiblewindows()
13 | return fnutils.filter(self:allwindows(), window.isvisible)
14 | end
15 |
16 | --- mjolnir.application:activate(allwindows = false) -> bool
17 | --- Method
18 | --- Tries to activate the app (make its key window focused) and returns whether it succeeded; if allwindows is true, all windows of the application are brought forward as well.
19 | function application:activate(allwindows)
20 | if self:isunresponsive() then return false end
21 | local win = self:_focusedwindow()
22 | if win then
23 | return win:becomemain() and self:_bringtofront(allwindows)
24 | else
25 | return self:_activate(allwindows)
26 | end
27 | end
28 |
29 | return application
30 |
--------------------------------------------------------------------------------
/mods/application/mjolnir.application-0.3-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "mjolnir.application"
2 | version = "0.3-1"
3 | local url = "github.com/sdegutis/mjolnir-modules"
4 | local desc = "Mjolnir module to inspect and manipulate running applications and their windows."
5 | source = {url = "git://" .. url}
6 | description = {
7 | summary = desc,
8 | detailed = desc,
9 | homepage = "https://" .. url,
10 | license = "MIT",
11 | }
12 | supported_platforms = {"macosx"}
13 | dependencies = {
14 | "lua >= 5.2",
15 | "mjolnir.fnutils",
16 | "mjolnir.geometry",
17 | "mjolnir.screen",
18 | }
19 | build = {
20 | type = "builtin",
21 | modules = {
22 | ["mjolnir.application"] = "application.lua",
23 | ["mjolnir.application.internal"] = "application.m",
24 | ["mjolnir.window"] = "window.lua",
25 | ["mjolnir.window.internal"] = "window.m",
26 | },
27 | }
28 |
--------------------------------------------------------------------------------
/mods/application/window.h:
--------------------------------------------------------------------------------
1 | #ifndef Window_application_h
2 | #define Window_application_h
3 |
4 | #import
5 | #import
6 |
7 | static void new_window(lua_State* L, AXUIElementRef win) {
8 | AXUIElementRef* winptr = lua_newuserdata(L, sizeof(AXUIElementRef));
9 | *winptr = win;
10 |
11 | luaL_getmetatable(L, "mjolnir.window");
12 | lua_setmetatable(L, -2);
13 |
14 | lua_newtable(L);
15 | lua_setuservalue(L, -2);
16 | }
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/mods/fnutils/.gitignore:
--------------------------------------------------------------------------------
1 | # LuaRocks
2 | *.o
3 | *.so
4 | *.rock
5 |
--------------------------------------------------------------------------------
/mods/fnutils/fnutils.lua:
--------------------------------------------------------------------------------
1 | --- === mjolnir.fnutils ===
2 | ---
3 | --- Super-helpful functional programming utilities.
4 |
5 | local fnutils = {}
6 |
7 |
8 | --- mjolnir.fnutils.map(t, fn) -> t
9 | --- Function
10 | --- Returns a table of the results of fn(el) on every el in t.
11 | function fnutils.map(t, fn)
12 | local nt = {}
13 | for k, v in pairs(t) do
14 | table.insert(nt, fn(v) or nil)
15 | end
16 | return nt
17 | end
18 |
19 | --- mjolnir.fnutils.each(t, fn) -> t
20 | --- Function
21 | --- Runs fn(el) for every el in t.
22 | function fnutils.each(t, fn)
23 | for k, v in pairs(t) do
24 | fn(v)
25 | end
26 | end
27 |
28 | --- mjolnir.fnutils.filter(t, fn) -> t
29 | --- Function
30 | --- Returns a table of the elements in t in which fn(el) is truthy.
31 | function fnutils.filter(t, fn)
32 | local nt = {}
33 | for k, v in pairs(t) do
34 | if fn(v) then table.insert(nt, v) end
35 | end
36 | return nt
37 | end
38 |
39 | --- mjolnir.fnutils.copy(t) -> t2
40 | --- Function
41 | --- Returns a new copy of t using pairs(t).
42 | function fnutils.copy(t)
43 | local nt = {}
44 | for k, v in pairs(t) do
45 | nt[k] = v
46 | end
47 | return nt
48 | end
49 |
50 | --- mjolnir.fnutils.contains(t, el) -> bool
51 | --- Function
52 | --- Returns whether the table contains the given element.
53 | function fnutils.contains(t, el)
54 | for k, v in pairs(t) do
55 | if v == el then
56 | return true
57 | end
58 | end
59 | return false
60 | end
61 |
62 | --- mjolnir.fnutils.indexof(t, el) -> int or nil
63 | --- Function
64 | --- Returns the index of a given element in a table, or nil if not found.
65 | function fnutils.indexof(t, el)
66 | for k, v in pairs(t) do
67 | if v == el then
68 | return k
69 | end
70 | end
71 | return nil
72 | end
73 |
74 | --- mjolnir.fnutils.concat(t1, t2)
75 | --- Function
76 | --- Adds all elements of t2 to the end of t1.
77 | function fnutils.concat(t1, t2)
78 | for i = 1, #t2 do
79 | t1[#t1 + 1] = t2[i]
80 | end
81 | return t1
82 | end
83 |
84 | --- mjolnir.fnutils.mapcat(t, fn) -> t2
85 | --- Function
86 | --- Runs fn(el) for every el in t, and assuming the results are tables, combines them into a new table.
87 | function fnutils.mapcat(t, fn)
88 | local nt = {}
89 | for k, v in pairs(t) do
90 | fnutils.concat(nt, fn(v))
91 | end
92 | return nt
93 | end
94 |
95 | --- mjolnir.fnutils.reduce(t, fn) -> t2
96 | --- Function
97 | --- Runs fn(el1, el2) for every el in t, then fn(result, el3), etc, until there's only one left.
98 | function fnutils.reduce(t, fn)
99 | local len = #t
100 | if len == 0 then return nil end
101 | if len == 1 then return t[1] end
102 |
103 | local result = t[1]
104 | for i = 2, #t do
105 | result = fn(result, t[i])
106 | end
107 | return result
108 | end
109 |
110 | --- mjolnir.fnutils.find(t, fn) -> el
111 | --- Function
112 | --- Returns the first element where fn(el) is truthy.
113 | function fnutils.find(t, fn)
114 | for _, v in pairs(t) do
115 | if fn(v) then return v end
116 | end
117 | return nil
118 | end
119 |
120 | --- mjolnir.fnutils.sequence(...) -> fn
121 | --- Function
122 | --- Returns a list of the results of the passed functions.
123 | function fnutils.sequence(...)
124 | local arg = table.pack(...)
125 | return function()
126 | local results = {}
127 | for _, fn in ipairs(arg) do
128 | table.insert(results, fn())
129 | end
130 | return results
131 | end
132 | end
133 |
134 | --- mjolnir.fnutils.partial(fn, ...) -> fn'
135 | --- Function
136 | --- Returns fn partially applied to arg (...).
137 | function fnutils.partial(fn, ...)
138 | local args = table.pack(...)
139 | return function(...)
140 | for idx, val in ipairs(table.pack(...)) do
141 | args[args.n + idx] = val
142 | end
143 | return fn(table.unpack(args))
144 | end
145 | end
146 |
147 | --- mjolnir.fnutils.cycle(t) -> fn() -> t[n]
148 | --- Function
149 | --- Returns a function that returns t[1], t[2], ... t[#t], t[1], ... on successive calls.
150 | --- Example:
151 | --- f = cycle({4, 5, 6})
152 | --- {f(), f(), f(), f(), f(), f(), f()} == {4, 5, 6, 4, 5, 6, 4}
153 | function fnutils.cycle(t)
154 | local i = 1
155 | return function()
156 | local x = t[i]
157 | i = i % #t + 1
158 | return x
159 | end
160 | end
161 |
162 | return fnutils
163 |
--------------------------------------------------------------------------------
/mods/fnutils/mjolnir.fnutils-0.1-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "mjolnir.fnutils"
2 | version = "0.1-1"
3 | local url = "github.com/sdegutis/mjolnir-modules"
4 | local desc = "Mjolnir module to help with functional programming."
5 | source = {url = "git://" .. url}
6 | description = {
7 | summary = desc,
8 | detailed = desc,
9 | homepage = "https://" .. url,
10 | license = "MIT",
11 | }
12 | supported_platforms = {"macosx"}
13 | dependencies = {
14 | "lua >= 5.2",
15 | }
16 | build = {
17 | type = "builtin",
18 | modules = {
19 | ["mjolnir.fnutils"] = "fnutils.lua",
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/mods/geometry/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | *.xcworkspace
13 | !default.xcworkspace
14 | xcuserdata
15 | profile
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 |
20 | # LuaRocks
21 | *.o
22 | *.so
23 | *.rock
24 |
--------------------------------------------------------------------------------
/mods/geometry/geometry.lua:
--------------------------------------------------------------------------------
1 | --- === mjolnir.geometry ===
2 | ---
3 | --- Mathy stuff.
4 |
5 | local geometry = require "mjolnir.geometry.internal"
6 |
7 | --- mjolnir.geometry.rotateccw(point, aroundpoint, ntimes = 1) -> point
8 | --- Function
9 | --- Rotates a point around another point N times.
10 | function geometry.rotateccw(point, aroundpoint, ntimes)
11 | local p = {x = point.x, y = point.y}
12 | for i = 1, ntimes or 1 do
13 | local px = p.x
14 | p.x = (aroundpoint.x - (p.y - aroundpoint.y))
15 | p.y = (aroundpoint.y + (px - aroundpoint.x))
16 | end
17 | return p
18 | end
19 |
20 | --- mjolnir.geometry.hypot(point) -> number
21 | --- Function
22 | --- Returns hypotenuse of a line defined from 0,0 to point.
23 | function geometry.hypot(p)
24 | return math.sqrt(p.x * p.x + p.y * p.y)
25 | end
26 |
27 | --- mjolnir.geometry.rect(x, y, w, h) -> rect
28 | --- Constructor
29 | --- Convenience function for creating a rect-table.
30 | function geometry.rect(x, y, w, h)
31 | return {x = x, y = y, w = w, h = h}
32 | end
33 |
34 | --- mjolnir.geometry.point(x, y) -> point
35 | --- Constructor
36 | --- Convenience function for creating a point-table.
37 | function geometry.point(x, y)
38 | return {x = x, y = y}
39 | end
40 |
41 | --- mjolnir.geometry.size(w, h) -> size
42 | --- Constructor
43 | --- Convenience function for creating a size-table.
44 | function geometry.size(w, h)
45 | return {w = w, h = h}
46 | end
47 |
48 | return geometry
49 |
--------------------------------------------------------------------------------
/mods/geometry/geometry.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | static NSRect geom_torect(lua_State* L, int idx) {
5 | luaL_checktype(L, idx, LUA_TTABLE);
6 | CGFloat x = (lua_getfield(L, idx, "x"), luaL_checknumber(L, -1));
7 | CGFloat y = (lua_getfield(L, idx, "y"), luaL_checknumber(L, -1));
8 | CGFloat w = (lua_getfield(L, idx, "w"), luaL_checknumber(L, -1));
9 | CGFloat h = (lua_getfield(L, idx, "h"), luaL_checknumber(L, -1));
10 | lua_pop(L, 4);
11 | return NSMakeRect(x, y, w, h);
12 | }
13 |
14 | void geom_pushpoint(lua_State* L, NSPoint point) {
15 | lua_newtable(L);
16 | lua_pushnumber(L, point.x); lua_setfield(L, -2, "x");
17 | lua_pushnumber(L, point.y); lua_setfield(L, -2, "y");
18 | }
19 |
20 | static void geom_pushrect(lua_State* L, NSRect rect) {
21 | lua_newtable(L);
22 | lua_pushnumber(L, rect.origin.x); lua_setfield(L, -2, "x");
23 | lua_pushnumber(L, rect.origin.y); lua_setfield(L, -2, "y");
24 | lua_pushnumber(L, rect.size.width); lua_setfield(L, -2, "w");
25 | lua_pushnumber(L, rect.size.height); lua_setfield(L, -2, "h");
26 | }
27 |
28 | /// mjolnir.geometry.intersectionrect(rect1, rect2) -> rect3
29 | /// Function
30 | /// Returns the intersection of two rects as a new rect.
31 | static int geometry_intersectionrect(lua_State* L) {
32 | NSRect r1 = geom_torect(L, 1);
33 | NSRect r2 = geom_torect(L, 2);
34 | geom_pushrect(L, NSIntersectionRect(r1, r2));
35 | return 1;
36 | }
37 |
38 | /// mjolnir.geometry.rectmidpoint(rect) -> point
39 | /// Function
40 | /// Returns the midpoint of a rect.
41 | static int geometry_rectmidpoint(lua_State* L) {
42 | NSRect r = geom_torect(L, 1);
43 | geom_pushpoint(L, NSMakePoint(NSMidX(r), NSMidY(r)));
44 | return 1;
45 | }
46 |
47 |
48 | static const luaL_Reg geometrylib[] = {
49 | {"intersectionrect", geometry_intersectionrect},
50 | {"rectmidpoint", geometry_rectmidpoint},
51 | {NULL, NULL}
52 | };
53 |
54 | int luaopen_mjolnir_geometry_internal(lua_State* L) {
55 | luaL_newlib(L, geometrylib);
56 | return 1;
57 | }
58 |
--------------------------------------------------------------------------------
/mods/geometry/mjolnir.geometry-0.2-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "mjolnir.geometry"
2 | version = "0.2-1"
3 | local url = "github.com/sdegutis/mjolnir-modules"
4 | local desc = "Mjolnir module to help with mathy stuff."
5 | source = {url = "git://" .. url}
6 | description = {
7 | summary = desc,
8 | detailed = desc,
9 | homepage = "https://" .. url,
10 | license = "MIT",
11 | }
12 | supported_platforms = {"macosx"}
13 | dependencies = {
14 | "lua >= 5.2",
15 | }
16 | build = {
17 | type = "builtin",
18 | modules = {
19 | ["mjolnir.geometry"] = "geometry.lua",
20 | ["mjolnir.geometry.internal"] = "geometry.m",
21 | },
22 | }
23 |
--------------------------------------------------------------------------------
/mods/hotkey/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | *.xcworkspace
13 | !default.xcworkspace
14 | xcuserdata
15 | profile
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 |
20 | # LuaRocks
21 | *.o
22 | *.so
23 | *.rock
24 |
--------------------------------------------------------------------------------
/mods/hotkey/hotkey.lua:
--------------------------------------------------------------------------------
1 | --- === mjolnir.hotkey ===
2 | ---
3 | --- Create and manage global hotkeys.
4 |
5 | local hotkey = require "mjolnir.hotkey.internal"
6 | local keycodes = require "mjolnir.keycodes"
7 |
8 | --- mjolnir.hotkey.new(mods, key, pressedfn, releasedfn = nil) -> hotkey
9 | --- Constructor
10 | --- Creates a new hotkey that can be enabled.
11 | ---
12 | --- The `mods` parameter is case-insensitive and may contain any of the following strings: "cmd", "ctrl", "alt", or "shift".
13 | ---
14 | --- The `key` parameter is case-insensitive and may be any string value found in mjolnir.keycodes.map
15 | ---
16 | --- The `pressedfn` parameter is the function that will be called when this hotkey is pressed.
17 | ---
18 | --- The `releasedfn` parameter is the function that will be called when this hotkey is released; this field is optional (i.e. may be nil or omitted).
19 |
20 | local function wrap(fn)
21 | return function()
22 | if fn then
23 | local ok, err = xpcall(fn, debug.traceback)
24 | if not ok then mjolnir.showerror(err) end
25 | end
26 | end
27 | end
28 |
29 | function hotkey.new(mods, key, pressedfn, releasedfn)
30 | local keycode
31 |
32 | if (key:sub(1, 1) == '#') then
33 | keycode = tonumber(key:sub(2))
34 | else
35 | keycode = keycodes.map[key:lower()]
36 | end
37 |
38 | local _pressedfn = wrap(pressedfn)
39 | local _releasedfn = wrap(releasedfn)
40 |
41 | local k = hotkey._new(mods, keycode, _pressedfn, _releasedfn)
42 | return k
43 | end
44 |
45 | --- mjolnir.hotkey.bind(mods, key, pressedfn, releasedfn) -> hotkey
46 | --- Constructor
47 | --- Shortcut for: return mjolnir.hotkey.new(mods, key, pressedfn, releasedfn):enable()
48 | function hotkey.bind(...)
49 | return hotkey.new(...):enable()
50 | end
51 |
52 | return hotkey
53 |
--------------------------------------------------------------------------------
/mods/hotkey/hotkey.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 | static NSMutableIndexSet* handlers;
6 |
7 | static int store_hotkey(lua_State* L, int idx) {
8 | lua_pushvalue(L, idx);
9 | int x = luaL_ref(L, LUA_REGISTRYINDEX);
10 | [handlers addIndex: x];
11 | return x;
12 | }
13 |
14 | static void remove_hotkey(lua_State* L, int x) {
15 | luaL_unref(L, LUA_REGISTRYINDEX, x);
16 | [handlers removeIndex: x];
17 | }
18 |
19 | static void* push_hotkey(lua_State* L, int x) {
20 | lua_rawgeti(L, LUA_REGISTRYINDEX, x);
21 | return lua_touserdata(L, -1);
22 | }
23 |
24 | typedef struct _hotkey_t {
25 | UInt32 mods;
26 | UInt32 keycode;
27 | UInt32 uid;
28 | int pressedfn;
29 | int releasedfn;
30 | BOOL enabled;
31 | EventHotKeyRef carbonHotKey;
32 | } hotkey_t;
33 |
34 |
35 | static int hotkey_new(lua_State* L) {
36 | luaL_checktype(L, 1, LUA_TTABLE);
37 | UInt32 keycode = luaL_checknumber(L, 2);
38 | luaL_checktype(L, 3, LUA_TFUNCTION);
39 | luaL_checktype(L, 4, LUA_TFUNCTION);
40 | lua_settop(L, 4);
41 |
42 | hotkey_t* hotkey = lua_newuserdata(L, sizeof(hotkey_t));
43 | memset(hotkey, 0, sizeof(hotkey_t));
44 |
45 | hotkey->keycode = keycode;
46 |
47 | // use 'mjolnir.hotkey' metatable
48 | luaL_getmetatable(L, "mjolnir.hotkey");
49 | lua_setmetatable(L, -2);
50 |
51 | // store pressedfn
52 | lua_pushvalue(L, 3);
53 | hotkey->pressedfn = luaL_ref(L, LUA_REGISTRYINDEX);
54 |
55 | // store releasedfn
56 | lua_pushvalue(L, 4);
57 | hotkey->releasedfn = luaL_ref(L, LUA_REGISTRYINDEX);
58 |
59 | // save mods
60 | lua_pushnil(L);
61 | while (lua_next(L, 1) != 0) {
62 | NSString* mod = [[NSString stringWithUTF8String:luaL_checkstring(L, -1)] lowercaseString];
63 | if ([mod isEqualToString: @"cmd"]) hotkey->mods |= cmdKey;
64 | else if ([mod isEqualToString: @"ctrl"]) hotkey->mods |= controlKey;
65 | else if ([mod isEqualToString: @"alt"]) hotkey->mods |= optionKey;
66 | else if ([mod isEqualToString: @"shift"]) hotkey->mods |= shiftKey;
67 | lua_pop(L, 1);
68 | }
69 |
70 | return 1;
71 | }
72 |
73 | /// mjolnir.hotkey:enable() -> self
74 | /// Method
75 | /// Registers the hotkey's fn as the callback when the user presses key while holding mods.
76 | static int hotkey_enable(lua_State* L) {
77 | hotkey_t* hotkey = luaL_checkudata(L, 1, "mjolnir.hotkey");
78 | lua_settop(L, 1);
79 |
80 | if (hotkey->enabled)
81 | return 1;
82 |
83 | hotkey->enabled = YES;
84 | hotkey->uid = store_hotkey(L, 1);
85 | EventHotKeyID hotKeyID = { .signature = 'MJLN', .id = hotkey->uid };
86 | hotkey->carbonHotKey = NULL;
87 | RegisterEventHotKey(hotkey->keycode, hotkey->mods, hotKeyID, GetEventDispatcherTarget(), kEventHotKeyExclusive, &hotkey->carbonHotKey);
88 |
89 | lua_pushvalue(L, 1);
90 | return 1;
91 | }
92 |
93 | static void stop(lua_State* L, hotkey_t* hotkey) {
94 | if (!hotkey->enabled)
95 | return;
96 |
97 | hotkey->enabled = NO;
98 | remove_hotkey(L, hotkey->uid);
99 | UnregisterEventHotKey(hotkey->carbonHotKey);
100 | }
101 |
102 | /// mjolnir.hotkey:disable() -> self
103 | /// Method
104 | /// Disables the given hotkey; does not remove it from mjolnir.hotkey.keys.
105 | static int hotkey_disable(lua_State* L) {
106 | hotkey_t* hotkey = luaL_checkudata(L, 1, "mjolnir.hotkey");
107 | stop(L, hotkey);
108 | lua_pushvalue(L, 1);
109 | return 1;
110 | }
111 |
112 | static int hotkey_gc(lua_State* L) {
113 | hotkey_t* hotkey = luaL_checkudata(L, 1, "mjolnir.hotkey");
114 | stop(L, hotkey);
115 | luaL_unref(L, LUA_REGISTRYINDEX, hotkey->pressedfn);
116 | luaL_unref(L, LUA_REGISTRYINDEX, hotkey->releasedfn);
117 | return 0;
118 | }
119 |
120 | static const luaL_Reg hotkeylib[] = {
121 | {"_new", hotkey_new},
122 |
123 | {"enable", hotkey_enable},
124 | {"disable", hotkey_disable},
125 | {"__gc", hotkey_gc},
126 |
127 | {}
128 | };
129 |
130 | static EventHandlerRef eventhandler;
131 |
132 | static OSStatus hotkey_callback(EventHandlerCallRef __attribute__ ((unused)) inHandlerCallRef, EventRef inEvent, void *inUserData) {
133 | EventHotKeyID eventID;
134 | GetEventParameter(inEvent, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(eventID), NULL, &eventID);
135 |
136 | lua_State* L = inUserData;
137 |
138 | hotkey_t* hotkey = push_hotkey(L, eventID.id);
139 | lua_pop(L, 1);
140 |
141 | int ref = (GetEventKind(inEvent) == kEventHotKeyPressed ? hotkey->pressedfn : hotkey->releasedfn);
142 | lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
143 | lua_call(L, 0, 0);
144 |
145 | return noErr;
146 | }
147 |
148 | static int meta_gc(lua_State* L) {
149 | RemoveEventHandler(eventhandler);
150 | [handlers release];
151 | return 0;
152 | }
153 |
154 | static const luaL_Reg metalib[] = {
155 | {"__gc", meta_gc},
156 | {}
157 | };
158 |
159 | int luaopen_mjolnir_hotkey_internal(lua_State* L) {
160 | handlers = [[NSMutableIndexSet indexSet] retain];
161 |
162 | luaL_newlib(L, hotkeylib);
163 |
164 | // watch for hotkey events
165 | EventTypeSpec hotKeyPressedSpec[] = {
166 | {kEventClassKeyboard, kEventHotKeyPressed},
167 | {kEventClassKeyboard, kEventHotKeyReleased},
168 | };
169 | InstallEventHandler(GetEventDispatcherTarget(),
170 | hotkey_callback,
171 | sizeof(hotKeyPressedSpec) / sizeof(EventTypeSpec),
172 | hotKeyPressedSpec,
173 | L,
174 | &eventhandler);
175 |
176 | // put hotkey in registry; necessary for luaL_checkudata()
177 | lua_pushvalue(L, -1);
178 | lua_setfield(L, LUA_REGISTRYINDEX, "mjolnir.hotkey");
179 |
180 | // hotkey.__index = hotkey
181 | lua_pushvalue(L, -1);
182 | lua_setfield(L, -2, "__index");
183 |
184 | // set metatable so gc function can cleanup module
185 | luaL_newlib(L, metalib);
186 | lua_setmetatable(L, -2);
187 |
188 | return 1;
189 | }
190 |
--------------------------------------------------------------------------------
/mods/hotkey/mjolnir.hotkey-0.3-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "mjolnir.hotkey"
2 | version = "0.3-1"
3 | local url = "github.com/sdegutis/mjolnir-modules"
4 | local desc = "Mjolnir module to create and manage global hotkeys."
5 | source = {url = "git://" .. url}
6 | description = {
7 | summary = desc,
8 | detailed = desc,
9 | homepage = "https://" .. url,
10 | license = "MIT",
11 | }
12 | supported_platforms = {"macosx"}
13 | dependencies = {
14 | "lua >= 5.2",
15 | "mjolnir.keycodes",
16 | }
17 | build = {
18 | type = "builtin",
19 | modules = {
20 | ["mjolnir.hotkey"] = "hotkey.lua",
21 | ["mjolnir.hotkey.internal"] = "hotkey.m",
22 | },
23 | }
24 |
--------------------------------------------------------------------------------
/mods/keycodes/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | *.xcworkspace
13 | !default.xcworkspace
14 | xcuserdata
15 | profile
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 |
20 | # LuaRocks
21 | *.o
22 | *.so
23 | *.rock
24 |
--------------------------------------------------------------------------------
/mods/keycodes/keycodes.lua:
--------------------------------------------------------------------------------
1 | --- === mjolnir.keycodes ===
2 | --- Functionality for converting between key-strings and key-codes.
3 |
4 | --- mjolnir.keycodes.map = {...}
5 | --- Variable
6 | --- A mapping from string representation of a key to its keycode, and vice versa.
7 | --- For example: keycodes[1] == "s", and keycodes["s"] == 1, and so on.
8 | --- This is primarily used by the mjolnir.eventtap and mjolnir.hotkey extensions.
9 | ---
10 | --- Valid strings are any single-character string, or any of the following strings:
11 | ---
12 | --- f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
13 | --- f16, f17, f18, f19, f20, pad, pad*, pad+, pad/, pad-, pad=,
14 | --- pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7, pad8, pad9,
15 | --- padclear, padenter, return, tab, space, delete, escape, help,
16 | --- home, pageup, forwarddelete, end, pagedown, left, right, down, up
17 |
18 | local keycodes = require "mjolnir.keycodes.internal"
19 | keycodes.map = keycodes._cachemap()
20 |
21 | --- mjolnir.keycodes.inputsourcechanged(fn())
22 | --- Function
23 | --- Sets the function to be called when your input source (i.e. qwerty, dvorak, colemac) changes.
24 | --- You can use this to rebind your hotkeys or whatever.
25 | --- Note: setting this will un-set functions previously registered by this function.
26 | function keycodes.inputsourcechanged(fn)
27 | if keycodes._callback then keycodes._callback:_stop() end
28 | keycodes._callback = keycodes._newcallback(function()
29 | keycodes.map = keycodes._cachemap()
30 | if fn then
31 | local ok, err = xpcall(fn, debug.traceback)
32 | if not ok then mjolnir.showerror(err) end
33 | end
34 | end)
35 | end
36 |
37 | keycodes.inputsourcechanged()
38 |
39 | return keycodes
40 |
--------------------------------------------------------------------------------
/mods/keycodes/mjolnir.keycodes-0.2-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "mjolnir.keycodes"
2 | version = "0.2-1"
3 | local url = "github.com/sdegutis/mjolnir-modules"
4 | local desc = "Mjolnir module to convert between key-strings and key-codes."
5 | source = {url = "git://" .. url}
6 | description = {
7 | summary = desc,
8 | detailed = desc,
9 | homepage = "https://" .. url,
10 | license = "MIT",
11 | }
12 | supported_platforms = {"macosx"}
13 | dependencies = {
14 | "lua >= 5.2",
15 | }
16 | build = {
17 | type = "builtin",
18 | modules = {
19 | ["mjolnir.keycodes"] = "keycodes.lua",
20 | ["mjolnir.keycodes.internal"] = "keycodes.m",
21 | },
22 | }
23 |
--------------------------------------------------------------------------------
/mods/screen/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | *.xcworkspace
13 | !default.xcworkspace
14 | xcuserdata
15 | profile
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 |
20 | # LuaRocks
21 | *.o
22 | *.so
23 | *.rock
24 |
--------------------------------------------------------------------------------
/mods/screen/mjolnir.screen-0.2-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "mjolnir.screen"
2 | version = "0.2-1"
3 | local url = "github.com/sdegutis/mjolnir-modules"
4 | local desc = "Mjolnir module to inspect and manipulate screens (i.e. monitors)."
5 | source = {url = "git://" .. url}
6 | description = {
7 | summary = desc,
8 | detailed = desc,
9 | homepage = "https://" .. url,
10 | license = "MIT",
11 | }
12 | supported_platforms = {"macosx"}
13 | dependencies = {
14 | "lua >= 5.2",
15 | "mjolnir.fnutils",
16 | "mjolnir.geometry",
17 | }
18 | build = {
19 | type = "builtin",
20 | modules = {
21 | ["mjolnir.screen"] = "screen.lua",
22 | ["mjolnir.screen.internal"] = "screen.m",
23 | },
24 | }
25 |
--------------------------------------------------------------------------------
/mods/screen/screen.lua:
--------------------------------------------------------------------------------
1 | --- === mjolnir.screen ===
2 | ---
3 | --- Manipulate screens (i.e. monitors).
4 | ---
5 | --- You usually get a screen through a window (see `mjolnir.window.screen`). But you can get screens by themselves through this module, albeit not in any defined/useful order.
6 | ---
7 | --- Mjolnir's coordinate system assumes a grid that is the union of every screen's rect (see `mjolnir.screen.fullframe`).
8 | ---
9 | --- Every window's position (i.e. `topleft`) and size are relative to this grid, and they're usually within the grid. A window that's semi-offscreen only intersects the grid.
10 |
11 | local screen = require "mjolnir.screen.internal"
12 | local fnutils = require "mjolnir.fnutils"
13 | local geometry = require "mjolnir.geometry"
14 |
15 | --- mjolnir.screen:fullframe() -> rect
16 | --- Method
17 | --- Returns the screen's rect in absolute coordinates, including the dock and menu.
18 | function screen:fullframe()
19 | local primary_screen = screen.allscreens()[1]
20 | local f = self:_frame()
21 | f.y = primary_screen:_frame().h - f.h - f.y
22 | return f
23 | end
24 |
25 | --- mjolnir.screen:frame() -> rect
26 | --- Method
27 | --- Returns the screen's rect in absolute coordinates, without the dock or menu.
28 | function screen:frame()
29 | local primary_screen = screen.allscreens()[1]
30 | local f = self:_visibleframe()
31 | f.y = primary_screen:_frame().h - f.h - f.y
32 | return f
33 | end
34 |
35 | --- mjolnir.screen:next() -> screen
36 | --- Method
37 | --- Returns the screen 'after' this one (I have no idea how they're ordered though); this method wraps around to the first screen.
38 | function screen:next()
39 | local screens = screen.allscreens()
40 | local i = fnutils.indexof(screens, self) + 1
41 | if i > # screens then i = 1 end
42 | return screens[i]
43 | end
44 |
45 | --- mjolnir.screen:previous() -> screen
46 | --- Method
47 | --- Returns the screen 'before' this one (I have no idea how they're ordered though); this method wraps around to the last screen.
48 | function screen:previous()
49 | local screens = screen.allscreens()
50 | local i = fnutils.indexof(screens, self) - 1
51 | if i < 1 then i = # screens end
52 | return screens[i]
53 | end
54 |
55 | local function first_screen_in_direction(screen, numrotations)
56 | if #screen.allscreens() == 1 then
57 | return nil
58 | end
59 |
60 | -- assume looking to east
61 |
62 | -- use the score distance/cos(A/2), where A is the angle by which it
63 | -- differs from the straight line in the direction you're looking
64 | -- for. (may have to manually prevent division by zero.)
65 |
66 | -- thanks mark!
67 |
68 | local otherscreens = fnutils.filter(screen.allscreens(), function(s) return s ~= screen end)
69 | local startingpoint = geometry.rectmidpoint(screen:fullframe())
70 | local closestscreens = {}
71 |
72 | for _, s in pairs(otherscreens) do
73 | local otherpoint = geometry.rectmidpoint(s:fullframe())
74 | otherpoint = geometry.rotateccw(otherpoint, startingpoint, numrotations)
75 |
76 | local delta = {
77 | x = otherpoint.x - startingpoint.x,
78 | y = otherpoint.y - startingpoint.y,
79 | }
80 |
81 | if delta.x > 0 then
82 | local angle = math.atan2(delta.y, delta.x)
83 | local distance = geometry.hypot(delta)
84 | local anglediff = -angle
85 | local score = distance / math.cos(anglediff / 2)
86 | table.insert(closestscreens, {s = s, score = score})
87 | end
88 | end
89 |
90 | table.sort(closestscreens, function(a, b) return a.score < b.score end)
91 |
92 | if #closestscreens > 0 then
93 | return closestscreens[1].s
94 | else
95 | return nil
96 | end
97 | end
98 |
99 | --- mjolnir.screen:toeast()
100 | --- Method
101 | --- Get the first screen to the east of this one, ordered by proximity.
102 | function screen:toeast() return first_screen_in_direction(self, 0) end
103 |
104 | --- mjolnir.screen:towest()
105 | --- Method
106 | --- Get the first screen to the west of this one, ordered by proximity.
107 | function screen:towest() return first_screen_in_direction(self, 2) end
108 |
109 | --- mjolnir.screen:tonorth()
110 | --- Method
111 | --- Get the first screen to the north of this one, ordered by proximity.
112 | function screen:tonorth() return first_screen_in_direction(self, 1) end
113 |
114 | --- mjolnir.screen:tosouth()
115 | --- Method
116 | --- Get the first screen to the south of this one, ordered by proximity.
117 | function screen:tosouth() return first_screen_in_direction(self, 3) end
118 |
119 | return screen
120 |
--------------------------------------------------------------------------------
/mods/screen/screen.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 | #define get_screen_arg(L, idx) *((NSScreen**)luaL_checkudata(L, idx, "mjolnir.screen"))
6 |
7 | static void geom_pushrect(lua_State* L, NSRect rect) {
8 | lua_newtable(L);
9 | lua_pushnumber(L, rect.origin.x); lua_setfield(L, -2, "x");
10 | lua_pushnumber(L, rect.origin.y); lua_setfield(L, -2, "y");
11 | lua_pushnumber(L, rect.size.width); lua_setfield(L, -2, "w");
12 | lua_pushnumber(L, rect.size.height); lua_setfield(L, -2, "h");
13 | }
14 |
15 | static int screen_frame(lua_State* L) {
16 | NSScreen* screen = get_screen_arg(L, 1);
17 | geom_pushrect(L, [screen frame]);
18 | return 1;
19 | }
20 |
21 | static int screen_visibleframe(lua_State* L) {
22 | NSScreen* screen = get_screen_arg(L, 1);
23 | geom_pushrect(L, [screen visibleFrame]);
24 | return 1;
25 | }
26 |
27 | /// mjolnir.screen:id(screen) -> number
28 | /// Method
29 | /// Returns a screen's unique ID.
30 | static int screen_id(lua_State* L) {
31 | NSScreen* screen = get_screen_arg(L, 1);
32 | lua_pushnumber(L, [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] doubleValue]);
33 | return 1;
34 | }
35 |
36 | /// mjolnir.screen:name(screen) -> string
37 | /// Method
38 | /// Returns the preferred name for the screen set by the manufacturer.
39 | static int screen_name(lua_State* L) {
40 | NSScreen* screen = get_screen_arg(L, 1);
41 | CGDirectDisplayID screen_id = [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] intValue];
42 |
43 | NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(screen_id), kIODisplayOnlyPreferredName);
44 | NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
45 |
46 | if ([localizedNames count])
47 | lua_pushstring(L, [[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]);
48 |
49 | else
50 | lua_pushnil(L);
51 |
52 | return 1;
53 | }
54 |
55 | /// mjolnir.screen.settint(redarray, greenarray, bluearray)
56 | /// Function
57 | /// Set the tint on a screen; experimental.
58 | static int screen_settint(lua_State* L) {
59 | lua_len(L, 1); int red_len = lua_tonumber(L, -1);
60 | lua_len(L, 2); int green_len = lua_tonumber(L, -1);
61 | lua_len(L, 3); int blue_len = lua_tonumber(L, -1);
62 |
63 | CGGammaValue c_red[red_len];
64 | CGGammaValue c_green[green_len];
65 | CGGammaValue c_blue[blue_len];
66 |
67 | lua_pushnil(L);
68 | while (lua_next(L, 1) != 0) {
69 | int i = lua_tonumber(L, -2) - 1;
70 | c_red[i] = lua_tonumber(L, -1);
71 | lua_pop(L, 1);
72 | }
73 |
74 | lua_pushnil(L);
75 | while (lua_next(L, 1) != 0) {
76 | int i = lua_tonumber(L, -2) - 1;
77 | c_green[i] = lua_tonumber(L, -1);
78 | lua_pop(L, 1);
79 | }
80 |
81 | lua_pushnil(L);
82 | while (lua_next(L, 1) != 0) {
83 | int i = lua_tonumber(L, -2) - 1;
84 | c_blue[i] = lua_tonumber(L, -1);
85 | lua_pop(L, 1);
86 | }
87 |
88 | CGSetDisplayTransferByTable(CGMainDisplayID(), red_len, c_red, c_green, c_blue);
89 |
90 | return 0;
91 | }
92 |
93 | static int screen_gc(lua_State* L) {
94 | NSScreen* screen = get_screen_arg(L, 1);
95 | [screen release];
96 | return 0;
97 | }
98 |
99 | static int screen_eq(lua_State* L) {
100 | NSScreen* screenA = get_screen_arg(L, 1);
101 | NSScreen* screenB = get_screen_arg(L, 2);
102 | lua_pushboolean(L, [screenA isEqual: screenB]);
103 | return 1;
104 | }
105 |
106 | void new_screen(lua_State* L, NSScreen* screen) {
107 | NSScreen** screenptr = lua_newuserdata(L, sizeof(NSScreen**));
108 | *screenptr = [screen retain];
109 |
110 | luaL_getmetatable(L, "mjolnir.screen");
111 | lua_setmetatable(L, -2);
112 | }
113 |
114 | /// mjolnir.screen.allscreens() -> screen[]
115 | /// Constructor
116 | /// Returns all the screens there are.
117 | static int screen_allscreens(lua_State* L) {
118 | lua_newtable(L);
119 |
120 | int i = 1;
121 | for (NSScreen* screen in [NSScreen screens]) {
122 | lua_pushnumber(L, i++);
123 | new_screen(L, screen);
124 | lua_settable(L, -3);
125 | }
126 |
127 | return 1;
128 | }
129 |
130 | /// mjolnir.screen.mainscreen() -> screen
131 | /// Constructor
132 | /// Returns the 'main' screen, i.e. the one containing the currently focused window.
133 | static int screen_mainscreen(lua_State* L) {
134 | new_screen(L, [NSScreen mainScreen]);
135 | return 1;
136 | }
137 |
138 | static const luaL_Reg screenlib[] = {
139 | {"allscreens", screen_allscreens},
140 | {"mainscreen", screen_mainscreen},
141 | {"settint", screen_settint},
142 |
143 | {"_frame", screen_frame},
144 | {"_visibleframe", screen_visibleframe},
145 | {"id", screen_id},
146 | {"name", screen_name},
147 |
148 | {NULL, NULL}
149 | };
150 |
151 | int luaopen_mjolnir_screen_internal(lua_State* L) {
152 | luaL_newlib(L, screenlib);
153 |
154 | if (luaL_newmetatable(L, "mjolnir.screen")) {
155 | lua_pushvalue(L, -2);
156 | lua_setfield(L, -2, "__index");
157 |
158 | lua_pushcfunction(L, screen_gc);
159 | lua_setfield(L, -2, "__gc");
160 |
161 | lua_pushcfunction(L, screen_eq);
162 | lua_setfield(L, -2, "__eq");
163 | }
164 | lua_pop(L, 1);
165 |
166 | return 1;
167 | }
168 |
--------------------------------------------------------------------------------
/sample-plugin/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | *.xcworkspace
13 | !default.xcworkspace
14 | xcuserdata
15 | profile
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 |
20 | # LuaRocks
21 | *.o
22 | *.so
23 | *.rock
24 |
--------------------------------------------------------------------------------
/sample-plugin/README.md:
--------------------------------------------------------------------------------
1 | This is a sample project to demonstrate writing a Mjolnir plugin.
2 |
3 | ### Your module's require-path
4 |
5 | Our sample module is called "mjolnir.yourid.foobar". This is both the
6 | name of the module, and its require-path. It's a good practice to make
7 | the module name and require path the same thing.
8 |
9 | ### Picking a name for your module
10 |
11 | You should prefix your module's name with "mjolnir." followed by a
12 | short unique identifier owned by you, e.g. maybe your initials. Don't
13 | use "yourid", that's just here for example. For example, my grid
14 | module is published as "mjolnir.sd.grid" where "sd" are my initials.
15 |
16 | ### Installing prerequisites
17 |
18 | Before you begin, you'll need to install Lua 5.2, LuaRocks, and
19 | MoonRocks. (If you have Mjolnir installed, you've probably already
20 | done the first two.)
21 |
22 | ~~~bash
23 | $ brew install homebrew/versions/lua52
24 | $ brew install luarocks --with-lua52
25 | $ luarocks install --server=http://rocks.moonscript.org moonrocks
26 | ~~~
27 |
28 | ### A note about ARC
29 |
30 | If you're writing a module that contains any Objective-C, you'll
31 | probably have to write it without ARC. When LuaRocks compiles your
32 | module, it sets `CC="export MACOSX_DEPLOYMENT_TARGET=10.5; gcc"` for
33 | some reason, and it doesn't set the `-fobjc-arc` flag. You can try to
34 | change the build rules to fix these, but it's way more trouble than
35 | it's worth. It's easiest to do what I do and just skip using ARC.
36 |
37 | ### Optionally create an Xcode project
38 |
39 | If you're writing a module that has some C or Objective-C, you may
40 | want to create a little Xcode project for it. That way, you get
41 | autocompletion and other helpful Xcode features.
42 |
43 | 1. New Xcode Project -> Framework & Library -> C/C++ Library
44 | 2. Add `/usr/local/include` to "Header Search Paths"
45 | 3. Add `/usr/local/lib` to "Library Search Paths"
46 | 4. Add `-llua` to "Other Linker Flags"
47 | 5. Add your `.m` file to the Xcode project
48 | 6. Add `#import ` to the top of your `.m` file
49 | 7. Turn off ARC
50 |
51 | Keep in mind that this Xcode project has literally nothing to do with
52 | the actual binary that this will result in. LuaRocks takes care of
53 | that on its own, with its own build script. The Xcode project is
54 | purely here as a convenience. If you'd rather skip this whole step and
55 | write your Objective-C code in another editor, that works too.
56 |
57 | ### Building and testing your module
58 |
59 | LuaRocks has a helpful command to build and install the LuaRocks
60 | module in the current directory:
61 |
62 | ~~~bash
63 | $ luarocks make
64 | ~~~
65 |
66 | Then, just launch Mjolnir, require your module, and test it out:
67 |
68 | ~~~lua
69 | local foobar = require "mjolnir.yourid.foobar"
70 | print(foobar.addnumbers(1, 2))
71 | ~~~
72 |
73 | You can repeat this process any number of times, since I'm pretty sure
74 | `luarocks make` will overwrite any pre-existing locally installed
75 | module with the same name.
76 |
77 | ### Publishing your module
78 |
79 | ~~~bash
80 | $ luarocks make
81 | ~~~
82 |
83 | Now test it thoroughly. Make sure it actually works. Automated tests
84 | are not enough, actually load it up in Mjolnir and use it. Preferrably
85 | for a few days.
86 |
87 | Then, patch a MoonRocks file as specified below.
88 |
89 | You'll need to register an account at https://rocks.moonscript.org/
90 | and create an API key in the Settings page for the next steps:
91 |
92 | ~~~bash
93 | $ luarocks pack mjolnir.yourid.foobar
94 | $ moonrocks upload --skip-pack mjolnir.yourid.foobar-0.1-1.rockspec
95 | $ moonrocks upload mjolnir.yourid.foobar-0.1-1.macosx-x86_64.rock
96 | ~~~
97 |
98 | Congratulations, it's now available for everyone!
99 |
100 | ### Patching the MoonRocks file
101 |
102 | MoonRocks is almost entirely free of any Lua 5.1-specific
103 | features. All except two lines.
104 |
105 | So edit `/usr/local/share/lua/5.2/moonrocks/actions.lua`:
106 |
107 | Apply this pseudo-patch manually:
108 |
109 | ~~~lua
110 | - local fn, err = loadfile(fname)
111 | + local fn, err = loadfile(fname, nil, rockspec)
112 |
113 | - setfenv(fn, rockspec)
114 | ~~~
115 |
--------------------------------------------------------------------------------
/sample-plugin/foobar.lua:
--------------------------------------------------------------------------------
1 | local foobar = require "mjolnir.yourid.foobar.internal"
2 | -- If you don't have a C or Objective-C submodule, the above line gets simpler:
3 | -- local foobar = {}
4 |
5 | -- If your module depends on other Mjolnir modules, require them into locals like this:
6 | local application = require "mjolnir.application"
7 |
8 | -- Simple functions that can be defined in Lua, should be defined in Lua:
9 | function foobar.subtractnumbers(a, b)
10 | return a - b
11 | end
12 |
13 | -- Always return your top-level module; never set globals.
14 | return foobar
15 |
--------------------------------------------------------------------------------
/sample-plugin/foobar.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 | static int foobar_addnumbers(lua_State* L) {
6 | int a = luaL_checknumber(L, 1);
7 | int b = luaL_checknumber(L, 2);
8 | lua_pushnumber(L, a + b);
9 | return 1;
10 | }
11 |
12 | static const luaL_Reg foobarlib[] = {
13 | {"addnumbers", foobar_addnumbers},
14 |
15 | {} // necessary sentinel
16 | };
17 |
18 |
19 | /* NOTE: The substring "mjolnir_yourid_foobar_internal" in the following function's name
20 | must match the require-path of this file, i.e. "mjolnir.yourid.foobar.internal". */
21 |
22 | int luaopen_mjolnir_yourid_foobar_internal(lua_State* L) {
23 | luaL_newlib(L, foobarlib);
24 | return 1;
25 | }
26 |
--------------------------------------------------------------------------------
/sample-plugin/mjolnir.yourid.foobar-0.1-1.rockspec:
--------------------------------------------------------------------------------
1 | -- `package` is the require-path.
2 | --
3 | -- Note: this must match the filename also.
4 | package = "mjolnir.yourid.foobar"
5 |
6 | -- `version` has two parts, your module's version (0.1) and the
7 | -- rockspec's version (1) in case you change metadata without
8 | -- changing the module's source code.
9 | --
10 | -- Note: the version must match the version in the filename.
11 | version = "0.1-1"
12 |
13 | -- General metadata:
14 |
15 | local url = "github.com/yourname/mjolnir.yourid.foobar"
16 | local desc = "Mjolnir module to add and subtract numbers."
17 |
18 | source = {url = "git://" .. url}
19 | description = {
20 | summary = desc,
21 | detailed = desc,
22 | homepage = "https://" .. url,
23 | license = "MIT",
24 | }
25 |
26 | -- Dependencies:
27 |
28 | supported_platforms = {"macosx"}
29 | dependencies = {
30 | "lua >= 5.2",
31 | -- You can add Mjolnir core modules as dependencies,
32 | -- i.e. "mjolnir.application", "mjolnir.hotkey", whatever.
33 | --
34 | -- For example, if your module depends on `mjolnir.fnutils`,
35 | -- uncomment the following line:
36 | --
37 | -- "mjolnir.fnutils",
38 | }
39 |
40 | -- Build rules:
41 |
42 | build = {
43 | type = "builtin",
44 | modules = {
45 | -- This is the top-level module:
46 | ["mjolnir.yourid.foobar"] = "foobar.lua",
47 |
48 | -- If you have an internal C or Objective-C submodule, include it here:
49 | ["mjolnir.yourid.foobar.internal"] = "foobar.m",
50 |
51 | -- Note: the key on the left side is the require-path; the value
52 | -- on the right is the filename relative to the current dir.
53 | },
54 | }
55 |
--------------------------------------------------------------------------------
/screenshots/dict.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/screenshots/dict.gif
--------------------------------------------------------------------------------
/screenshots/grid.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjolnirapp/mjolnir/1c862deb31742d4b2dc593b74c29a24b33917254/screenshots/grid.gif
--------------------------------------------------------------------------------