- 追加された行はこの色です。
- 削除された行はこの色です。
*[[Rust:http://www.rust-lang.org/]] [#ybc68f10]
#ref(http://upload.wikimedia.org/wikipedia/en/thumb/d/d5/Rust_programming_language_black_logo.svg/200px-Rust_programming_language_black_logo.svg.png,right,around,nolink,Rust)
&color(White,#5F2F2F){ ''◆CONTENTS◆'' };&br;
#contents
*Summary [#jf7ccbcc]
-[[The Rust Programming Language:http://www.rust-lang.org/]]
-https://github.com/rust-lang/rust
--https://github.com/rust-lang/rust/wiki
---https://github.com/rust-lang/rust/wiki/Doc-detailed-release-notes
-https://github.com/rust-lang/rust/blob/master/src/liblibc/lib.rs
-[[Wikipedia.ja:Rust_(プログラミング言語)]]
-http://static.rust-lang.org/doc/master/guide-ffi.html
-[[Rust 基礎文法最速マスター (rust 0.7 編):http://gifnksm.hatenablog.jp/entry/2013/07/15/170736]]
-http://qiita.com/tags/rust
-http://wontfix.blogspot.jp/search/label/rust
-[[Rust Advent Calendar 2013 - Qiita [キータ]:http://qiita.com/advent-calendar/2013/rust]]
-http://stackoverflow.com/questions/tagged/rust
--http://stackoverflow.com/questions/21569718/exit-rust-program-early
*[[fwdsumatrapdf>SumatraPDF/fwdsumatrapdf]] &aname(fwdsumatrapdf); [#ge410d95]
**Rust 版 [#j7127f95]
rustc 0.11.0 で動作確認しています.~
MinGW Shell (MSYS) から以下のようにしてビルドします.~
rustc fwdsumatrapdf.rs
----
-fwdsumatrapdf.rs
----
// vim: ts=4 sw=4 expandtab:
// rustc fwdsumatrapdf.rs
extern crate libc;
use libc::{c_int, c_uint, c_short, c_ushort, c_long, c_ulong, c_char, c_void, size_t, wchar_t};
use std::io;
use std::os;
use std::mem;
use std::ptr;
static timeout: c_uint = 10000;
static hkey_local_machine: u32 = 0x80000002;
static key_query_value: u32 = 0x01;
static key_path: &'static str = r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\SumatraPDF.exe";
static cp_acp: u32 = 0;
static wc_no_best_fit_chars: u32 = 1024;
type BOOL = c_int;
type LPBOOL = *mut c_int;
type UINT = c_uint;
type BYTE = u8;
type LPBYTE = *mut BYTE;
type VOID = c_void;
type LPVOID = *mut c_void;
type HSZ = LPVOID;
type HCONV = LPVOID;
type HDDEDATA = LPVOID;
type HANDLE = LPVOID;
type HKEY = HANDLE;
type PHKEY = *mut HKEY;
type REGSAM = c_uint;
type LONG = c_long;
type WORD = u16;
type DWORD = c_ulong;
type LPWORD = *mut DWORD;
type LPDWORD = *mut DWORD;
type CCHAR = c_char;
type CHAR = c_char;
type WCHAR = wchar_t;
type LPCWSTR = *const WCHAR;
type LPWSTR = *mut WCHAR;
type LPCSTR = *const CHAR;
type LPSTR = *mut CHAR;
type SIZE_T = size_t;
struct STARTUPINFOW {
cb: DWORD,
lpReserved: LPWSTR,
lpDesktop: LPWSTR,
lpTitle: LPWSTR,
dwX: DWORD,
dwY: DWORD,
dwXSize: DWORD,
dwYSize: DWORD,
dwXCountChars: DWORD,
dwYCountChars: DWORD,
dwFillAttribute: DWORD,
dwFlags: DWORD,
wShowWindow: WORD,
cbReserved2: WORD,
lpReserved2: LPBYTE,
hStdInput: HANDLE,
hStdOutput: HANDLE,
hStdError: HANDLE
}
type LPSTARTUPINFOW = *mut STARTUPINFOW;
struct PROCESS_INFORMATION {
hProcess: HANDLE,
hThread: HANDLE,
dwProcessId: DWORD,
dwThreadId: DWORD
}
type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION;
#[cfg(target_os = "win32", target_arch = "x86")]
#[link_name = "advapi32"]
#[allow(non_snake_case_functions)]
extern "stdcall" {
fn RegOpenKeyExW(
hKey: HKEY,
lpSubKey: LPCWSTR,
ulOptions: DWORD,
samDesired: REGSAM,
phkResult: PHKEY)
-> LONG;
fn RegQueryValueExW(
hKey: HKEY,
lpValueName: LPCWSTR,
lpReserved: LPDWORD,
lpType: LPDWORD,
lpData: LPBYTE,
lpcbData: LPDWORD)
-> LONG;
fn RegCloseKey(
hKey: HKEY)
-> LONG;
}
#[cfg(target_os = "win32", target_arch = "x86")]
#[link_name = "user32"]
#[allow(non_snake_case_functions)]
extern "stdcall" {
fn DdeInitializeW(pidInst: *mut DWORD, pfnCallback: *mut c_void, afCmd: c_uint, ulRes: c_uint) -> c_uint;
fn DdeUninitialize(idInst: DWORD) -> c_int;
fn DdeCreateStringHandleW(idInst: DWORD, psz: LPWSTR, iCodePage: c_int) -> HSZ;
fn DdeFreeStringHandle(idInst: DWORD, hsz: HSZ) -> BOOL;
fn DdeCreateDataHandle(idInst: DWORD, pSrc: LPBYTE, cb: DWORD, cbOff: DWORD, hszItem: *c_int, wFmt: c_uint, afCmd: c_uint) -> HDDEDATA;
fn DdeFreeDataHandle(hData: HDDEDATA) -> BOOL;
fn DdeConnect(idInst: DWORD, hszService: HSZ, hszTopic: HSZ, pCC: *mut c_void) -> HCONV;
fn DdeDisconnect(hConv: HCONV) -> BOOL;
fn DdeClientTransaction(pData: LPBYTE, cbData: DWORD, hConv: HCONV, hszItem: *c_int, wFmt: c_uint, wType: c_uint, dwTimeout: c_uint, pdwResult: *c_int) -> HDDEDATA;
fn WaitForInputIdle(hProcess: HANDLE, dwMilliseconds: DWORD) -> DWORD;
}
#[cfg(target_os = "win32", target_arch = "x86")]
#[link_name = "kernel32"]
#[allow(non_snake_case_functions)]
extern "stdcall" {
fn CreateProcessW(
lpApplicationName: LPCWSTR,
lpCommandLine: LPWSTR,
lpProcessAttributes: *c_int,
lpThreadAttributes: *c_int,
bInheritHandles: BOOL,
dwCreationFlags: DWORD,
lpEnvironment: LPVOID,
lpCurrentDirectory: LPCWSTR,
lpStartupInfo: LPSTARTUPINFOW,
lpProcessInformation: LPPROCESS_INFORMATION)
-> BOOL;
fn WideCharToMultiByte(
CodePage: UINT,
dwFlags: DWORD,
lpWideCharStr: LPCWSTR,
cchWideChar: c_int,
lpMultiByteStr: LPSTR,
cchMultiByte: c_int,
lpDefaultChar: LPCSTR,
lpUserdDefaultChar: LPBOOL)
-> c_int;
}
#[allow(non_snake_case_functions)]
fn runSumatraPDF() {
unsafe {
let mut si = STARTUPINFOW {
cb: 0,
lpReserved: ptr::mut_null(),
lpDesktop: ptr::mut_null(),
lpTitle: ptr::mut_null(),
dwX: 0,
dwY: 0,
dwXSize: 0,
dwYSize: 0,
dwXCountChars: 0,
dwYCountChars: 0,
dwFillAttribute: 0,
dwFlags: 0,
wShowWindow: 0,
cbReserved2: 0,
lpReserved2: ptr::mut_null(),
hStdInput: ptr::mut_null(),
hStdOutput: ptr::mut_null(),
hStdError: ptr::mut_null()};
let mut pi = PROCESS_INFORMATION {
hProcess: ptr::mut_null(),
hThread: ptr::mut_null(),
dwProcessId: 0,
dwThreadId: 0};
let mut subKey = ptr::mut_null();
let mut dwType = 0u32;
let mut sz = 0u32;
RegOpenKeyExW(hkey_local_machine as HKEY, key_path.to_utf16().as_ptr(), 0, key_query_value, &mut subKey);
RegQueryValueExW(subKey, ptr::null(), ptr::mut_null(), &mut dwType, ptr::mut_null(), &mut sz);
let mut sumatraPDFRegistry_wchar: Vec<u8> = Vec::from_fn(sz as uint, |idx| 0);
RegQueryValueExW(subKey, ptr::null(), ptr::mut_null(), &mut dwType, sumatraPDFRegistry_wchar.as_mut_ptr(), &mut sz);
RegCloseKey(subKey);
let sumatraPDFRegLength = ((sz - 2) / 2) as c_uint;
let mut sumatraPDFRegistry: Vec<u8> = Vec::from_fn(sumatraPDFRegLength as uint, |idx| 0);
WideCharToMultiByte(cp_acp, wc_no_best_fit_chars, sumatraPDFRegistry_wchar.as_ptr() as *u16, -1, sumatraPDFRegistry.as_mut_ptr() as *mut i8, sumatraPDFRegLength as i32, ptr::null(), ptr::mut_null());
let sumatraPDFCommandLine = format!("\"{}\" -reuse-instance", sumatraPDFRegistry.into_ascii().into_str());
si.cb = mem::size_of::<STARTUPINFOW>() as DWORD;
CreateProcessW(ptr::null(), sumatraPDFCommandLine.to_utf16().as_mut_ptr(), ptr::null(), ptr::null(), 0, 0, ptr::mut_null(), ptr::null(), &mut si, &mut pi);
WaitForInputIdle(pi.hProcess, timeout);
}
}
#[allow(non_snake_case_functions)]
fn ddeExecute(server: &str, topic: &str, command: &str) {
unsafe {
let appcmd_clientonly = 0x10;
let cp_winunicode = 1200;
let cf_unicodetext = 13;
let xclass_flags = 0x4000;
let xtyp_execute = (0x0050 | xclass_flags);
let mut idInstance = 0u32;
let mut hszServer = ptr::mut_null();
let mut hszTopic = ptr::mut_null();
let mut hConvClient = ptr::mut_null();
let mut hDdeData = ptr::mut_null();
let mut hDdeTransactionData = ptr::mut_null();
loop {
DdeInitializeW(&mut idInstance, ptr::mut_null(), appcmd_clientonly, 0);
if idInstance == 0u32 { writeln!(io::stderr(), "DdeInitializeW error"); break; }
hszServer = DdeCreateStringHandleW(idInstance, server.to_utf16().as_mut_ptr(), cp_winunicode);
if hszServer == ptr::mut_null() { writeln!(io::stderr(), "DdeCreateStringHandleW error"); break; }
hszTopic = DdeCreateStringHandleW(idInstance, topic.to_utf16().as_mut_ptr(), cp_winunicode);
if hszTopic == ptr::mut_null() { writeln!(io::stderr(), "DdeCreateStringHandleW error"); break; }
hConvClient = DdeConnect(idInstance, hszServer, hszTopic, ptr::mut_null());
if hConvClient == ptr::mut_null() {
runSumatraPDF();
hConvClient = DdeConnect(idInstance, hszServer, hszTopic, ptr::mut_null());
if hConvClient == ptr::mut_null() { writeln!(io::stderr(), "DdeConnect error"); break; }
}
hDdeData = DdeCreateDataHandle(idInstance, command.to_utf16().as_mut_ptr() as LPBYTE, ((command.char_len() + 1)*mem::size_of::<wchar_t>()) as DWORD, 0, ptr::null(), cf_unicodetext, 0);
if hDdeData == ptr::mut_null() { writeln!(io::stderr(), "DdeCreateDataHandle error"); break; }
hDdeTransactionData = DdeClientTransaction(hDdeData as LPBYTE, -1 as DWORD, hConvClient, ptr::null(), 0, xtyp_execute, timeout, ptr::null());
if hDdeTransactionData == ptr::mut_null() { writeln!(io::stderr(), "DdeClientTransaction error"); break; }
break;
}
if hDdeTransactionData != ptr::mut_null() { DdeFreeDataHandle(hDdeTransactionData); }
if hDdeData != ptr::mut_null() { DdeFreeDataHandle(hDdeData); }
if hszServer != ptr::mut_null() { DdeFreeStringHandle(idInstance, hszServer); }
if hszTopic != ptr::mut_null() { DdeFreeStringHandle(idInstance, hszTopic); }
if hConvClient != ptr::mut_null() { DdeDisconnect(hConvClient); }
if idInstance != 0u32 { DdeUninitialize(idInstance); }
}
}
fn main() {
let args = os::args();
if args.len() != 4 {
writeln!(io::stderr(), "Usage: {} pdf tex line", args.get(0));
unsafe { libc::exit(2 as libc::c_int); }
}
let pdf = args.get(1);
let tex = args.get(2);
let line = args.get(3);
let forwardSearch = format!("[ForwardSearch(\"{}\",\"{}\",{},0,0,0)]", pdf, tex, line);
match forwardSearch.to_c_str().as_str() {
//Some(ref command) => {
// runSumatraPDF();
// ddeExecute("SUMATRA", "control", *command);
//},
Some(ref command) => ddeExecute("SUMATRA", "control", *command),
None => ()
}
}
----