diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 388b5a2727..70cd48406b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] php: ["8.0", "8.1", "8.2", "8.3"] rust: [stable, nightly] - clang: ["15", "17"] + clang: ["15", "17", "18"] phpts: [ts, nts] exclude: # ext-php-rs requires nightly Rust when on Windows. @@ -29,9 +29,9 @@ jobs: - os: ubuntu-latest phpts: ts - os: macos-latest - clang: "17" + clang: "18" - os: ubuntu-latest - clang: "15" + clang: "18" - os: windows-latest clang: "15" env: @@ -43,9 +43,11 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} + tools: phpize, php-config env: phpts: ${{ matrix.phpts }} debug: true + update: true - name: Setup Rust uses: dtolnay/rust-toolchain@master with: @@ -64,27 +66,30 @@ jobs: - name: Cache LLVM and Clang id: cache-llvm uses: actions/cache@v3 - if: "!contains(matrix.os, 'windows')" + if: ${{ !contains(matrix.os, 'windows') }} with: path: ${{ runner.temp }}/llvm-${{ matrix.clang }} key: ${{ matrix.os }}-llvm-${{ matrix.clang }} - name: Setup LLVM & Clang id: clang - uses: KyleMayes/install-llvm-action@v1 - if: "!contains(matrix.os, 'windows')" + uses: KyleMayes/install-llvm-action@master + if: ${{ !contains(matrix.os, 'windows') }} with: version: ${{ matrix.clang }} directory: ${{ runner.temp }}/llvm-${{ matrix.clang }} cached: ${{ steps.cache-llvm.outputs.cache-hit }} - name: Configure Clang - if: "!contains(matrix.os, 'windows')" + if: ${{ !contains(matrix.os, 'windows') }} run: | echo "LIBCLANG_PATH=${{ runner.temp }}/llvm-${{ matrix.clang }}/lib" >> $GITHUB_ENV echo "LLVM_VERSION=${{ steps.clang.outputs.version }}" >> $GITHUB_ENV echo "LLVM_CONFIG_PATH=${{ runner.temp }}/llvm-${{ matrix.clang }}/bin/llvm-config" >> $GITHUB_ENV - name: Configure Clang (macOS only) - if: "contains(matrix.os, 'macos')" + if: ${{ contains(matrix.os, 'macos') }} run: echo "SDKROOT=$(xcrun --show-sdk-path)" >> $GITHUB_ENV + - name: Install libsqlite3 (OSX only) + if: ${{ contains(matrix.os, 'macos-latest') }} + run: brew reinstall sqlite # Build - name: Build env: diff --git a/Cargo.toml b/Cargo.toml index 357778d20a..4f93d67525 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ skeptic = "0.13" [build-dependencies] anyhow = "1" -bindgen = "0.68.1" +bindgen = "0.69.4" cc = "1.0" skeptic = "0.13" @@ -41,11 +41,7 @@ closure = [] embed = [] [workspace] -members = [ - "crates/macros", - "crates/cli", - "tests" -] +members = ["crates/macros", "crates/cli", "tests"] [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docs"] diff --git a/build.rs b/build.rs index 5afef52e2d..e038a6ce7d 100644 --- a/build.rs +++ b/build.rs @@ -84,7 +84,12 @@ impl PHPInfo { .output() .context("Failed to call `php -i`")?; if !cmd.status.success() { - bail!("Failed to call `php -i` status code {}", cmd.status); + let stderr = String::from_utf8_lossy(&cmd.stderr); + bail!( + "Failed to call `php -i` status code {} with stderr: {}", + cmd.status, + stderr + ); } let stdout = String::from_utf8_lossy(&cmd.stdout); Ok(Self(stdout.to_string())) diff --git a/docsrs_bindings.rs b/docsrs_bindings.rs index aade607af2..17cccbcfe7 100644 --- a/docsrs_bindings.rs +++ b/docsrs_bindings.rs @@ -1,4 +1,4 @@ -/* automatically generated by rust-bindgen 0.68.1 */ +/* automatically generated by rust-bindgen 0.69.4 */ #[repr(C)] #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] @@ -82,6 +82,7 @@ where } pub const ZEND_DEBUG: u32 = 1; pub const _ZEND_TYPE_NAME_BIT: u32 = 16777216; +pub const _ZEND_TYPE_LITERAL_NAME_BIT: u32 = 8388608; pub const _ZEND_TYPE_NULLABLE_BIT: u32 = 2; pub const HT_MIN_SIZE: u32 = 8; pub const IS_UNDEF: u32 = 0; @@ -198,81 +199,91 @@ pub const CONST_CS: u32 = 0; pub const CONST_PERSISTENT: u32 = 1; pub const CONST_NO_FILE_CACHE: u32 = 2; pub const CONST_DEPRECATED: u32 = 4; -pub type __dev_t = ::std::os::raw::c_ulong; -pub type __uid_t = ::std::os::raw::c_uint; -pub type __gid_t = ::std::os::raw::c_uint; -pub type __ino_t = ::std::os::raw::c_ulong; -pub type __mode_t = ::std::os::raw::c_uint; -pub type __nlink_t = ::std::os::raw::c_ulong; -pub type __off_t = ::std::os::raw::c_long; -pub type __off64_t = ::std::os::raw::c_long; -pub type __time_t = ::std::os::raw::c_long; -pub type __blksize_t = ::std::os::raw::c_long; -pub type __blkcnt_t = ::std::os::raw::c_long; -pub type __syscall_slong_t = ::std::os::raw::c_long; -pub type gid_t = __gid_t; -pub type uid_t = __uid_t; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __sigset_t { - pub __val: [::std::os::raw::c_ulong; 16usize], -} +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_longlong; +pub type __uint64_t = ::std::os::raw::c_ulonglong; +pub type __darwin_time_t = ::std::os::raw::c_long; +pub type __darwin_blkcnt_t = __int64_t; +pub type __darwin_blksize_t = __int32_t; +pub type __darwin_dev_t = __int32_t; +pub type __darwin_gid_t = __uint32_t; +pub type __darwin_ino64_t = __uint64_t; +pub type __darwin_mode_t = __uint16_t; +pub type __darwin_off_t = __int64_t; +pub type __darwin_uid_t = __uint32_t; +pub type uid_t = __darwin_uid_t; +pub type dev_t = __darwin_dev_t; +pub type mode_t = __darwin_mode_t; +pub type blkcnt_t = __darwin_blkcnt_t; +pub type blksize_t = __darwin_blksize_t; +pub type gid_t = __darwin_gid_t; +pub type nlink_t = __uint16_t; +pub type off_t = __darwin_off_t; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct timespec { - pub tv_sec: __time_t, - pub tv_nsec: __syscall_slong_t, + pub tv_sec: __darwin_time_t, + pub tv_nsec: ::std::os::raw::c_long, } -pub type FILE = _IO_FILE; +pub type fpos_t = __darwin_off_t; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct _IO_marker { - _unused: [u8; 0], +pub struct __sbuf { + pub _base: *mut ::std::os::raw::c_uchar, + pub _size: ::std::os::raw::c_int, } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct _IO_codecvt { +pub struct __sFILEX { _unused: [u8; 0], } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct _IO_wide_data { - _unused: [u8; 0], -} -pub type _IO_lock_t = ::std::os::raw::c_void; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _IO_FILE { - pub _flags: ::std::os::raw::c_int, - pub _IO_read_ptr: *mut ::std::os::raw::c_char, - pub _IO_read_end: *mut ::std::os::raw::c_char, - pub _IO_read_base: *mut ::std::os::raw::c_char, - pub _IO_write_base: *mut ::std::os::raw::c_char, - pub _IO_write_ptr: *mut ::std::os::raw::c_char, - pub _IO_write_end: *mut ::std::os::raw::c_char, - pub _IO_buf_base: *mut ::std::os::raw::c_char, - pub _IO_buf_end: *mut ::std::os::raw::c_char, - pub _IO_save_base: *mut ::std::os::raw::c_char, - pub _IO_backup_base: *mut ::std::os::raw::c_char, - pub _IO_save_end: *mut ::std::os::raw::c_char, - pub _markers: *mut _IO_marker, - pub _chain: *mut _IO_FILE, - pub _fileno: ::std::os::raw::c_int, - pub _flags2: ::std::os::raw::c_int, - pub _old_offset: __off_t, - pub _cur_column: ::std::os::raw::c_ushort, - pub _vtable_offset: ::std::os::raw::c_schar, - pub _shortbuf: [::std::os::raw::c_char; 1usize], - pub _lock: *mut _IO_lock_t, - pub _offset: __off64_t, - pub _codecvt: *mut _IO_codecvt, - pub _wide_data: *mut _IO_wide_data, - pub _freeres_list: *mut _IO_FILE, - pub _freeres_buf: *mut ::std::os::raw::c_void, - pub __pad5: usize, - pub _mode: ::std::os::raw::c_int, - pub _unused2: [::std::os::raw::c_char; 20usize], -} +pub struct __sFILE { + pub _p: *mut ::std::os::raw::c_uchar, + pub _r: ::std::os::raw::c_int, + pub _w: ::std::os::raw::c_int, + pub _flags: ::std::os::raw::c_short, + pub _file: ::std::os::raw::c_short, + pub _bf: __sbuf, + pub _lbfsize: ::std::os::raw::c_int, + pub _cookie: *mut ::std::os::raw::c_void, + pub _close: ::std::option::Option< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, + >, + pub _read: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_char, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int, + >, + pub _seek: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: fpos_t, + arg3: ::std::os::raw::c_int, + ) -> fpos_t, + >, + pub _write: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_char, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int, + >, + pub _ub: __sbuf, + pub _extra: *mut __sFILEX, + pub _ur: ::std::os::raw::c_int, + pub _ubuf: [::std::os::raw::c_uchar; 3usize], + pub _nbuf: [::std::os::raw::c_uchar; 1usize], + pub _lb: __sbuf, + pub _blksize: ::std::os::raw::c_int, + pub _offset: fpos_t, +} +pub type FILE = __sFILE; pub type zend_long = i64; pub type zend_ulong = u64; pub type zend_off_t = i64; @@ -685,21 +696,24 @@ pub type zend_class_arrayaccess_funcs = _zend_class_arrayaccess_funcs; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct stat { - pub st_dev: __dev_t, - pub st_ino: __ino_t, - pub st_nlink: __nlink_t, - pub st_mode: __mode_t, - pub st_uid: __uid_t, - pub st_gid: __gid_t, - pub __pad0: ::std::os::raw::c_int, - pub st_rdev: __dev_t, - pub st_size: __off_t, - pub st_blksize: __blksize_t, - pub st_blocks: __blkcnt_t, - pub st_atim: timespec, - pub st_mtim: timespec, - pub st_ctim: timespec, - pub __glibc_reserved: [__syscall_slong_t; 3usize], + pub st_dev: dev_t, + pub st_mode: mode_t, + pub st_nlink: nlink_t, + pub st_ino: __darwin_ino64_t, + pub st_uid: uid_t, + pub st_gid: gid_t, + pub st_rdev: dev_t, + pub st_atimespec: timespec, + pub st_mtimespec: timespec, + pub st_ctimespec: timespec, + pub st_birthtimespec: timespec, + pub st_size: off_t, + pub st_blocks: blkcnt_t, + pub st_blksize: blksize_t, + pub st_flags: __uint32_t, + pub st_gen: __uint32_t, + pub st_lspare: __int32_t, + pub st_qspare: [__int64_t; 2usize], } pub type zend_stream_fsizer_t = ::std::option::Option usize>; @@ -1339,15 +1353,7 @@ pub struct _zend_execute_data { pub run_time_cache: *mut *mut ::std::os::raw::c_void, pub extra_named_params: *mut zend_array, } -pub type __jmp_buf = [::std::os::raw::c_long; 8usize]; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __jmp_buf_tag { - pub __jmpbuf: __jmp_buf, - pub __mask_was_saved: ::std::os::raw::c_int, - pub __saved_mask: __sigset_t, -} -pub type jmp_buf = [__jmp_buf_tag; 1usize]; +pub type sigjmp_buf = [::std::os::raw::c_int; 49usize]; pub type zend_executor_globals = _zend_executor_globals; extern "C" { pub static mut executor_globals: zend_executor_globals; @@ -1424,7 +1430,7 @@ pub struct _zend_executor_globals { pub symtable_cache_ptr: *mut *mut zend_array, pub symbol_table: zend_array, pub included_files: HashTable, - pub bailout: *mut jmp_buf, + pub bailout: *mut sigjmp_buf, pub error_reporting: ::std::os::raw::c_int, pub exit_status: ::std::os::raw::c_int, pub function_table: *mut HashTable, @@ -1992,7 +1998,7 @@ pub struct _php_stream { pub wrapperthis: *mut ::std::os::raw::c_void, pub wrapperdata: zval, pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, pub mode: [::std::os::raw::c_char; 16usize], pub flags: u32, pub res: *mut zend_resource, @@ -2011,105 +2017,122 @@ pub struct _php_stream { } impl _php_stream { #[inline] - pub fn is_persistent(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + pub fn is_persistent(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } } #[inline] - pub fn set_is_persistent(&mut self, val: u8) { + pub fn set_is_persistent(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] - pub fn in_free(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 2u8) as u8) } + pub fn in_free(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 2u8) as u16) } } #[inline] - pub fn set_in_free(&mut self, val: u8) { + pub fn set_in_free(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(1usize, 2u8, val as u64) } } #[inline] - pub fn eof(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u8) } + pub fn eof(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) } } #[inline] - pub fn set_eof(&mut self, val: u8) { + pub fn set_eof(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(3usize, 1u8, val as u64) } } #[inline] - pub fn __exposed(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u8) } + pub fn __exposed(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) } } #[inline] - pub fn set___exposed(&mut self, val: u8) { + pub fn set___exposed(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(4usize, 1u8, val as u64) } } #[inline] - pub fn fclose_stdiocast(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 2u8) as u8) } + pub fn fclose_stdiocast(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 2u8) as u16) } } #[inline] - pub fn set_fclose_stdiocast(&mut self, val: u8) { + pub fn set_fclose_stdiocast(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(5usize, 2u8, val as u64) } } #[inline] - pub fn has_buffered_data(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u8) } + pub fn has_buffered_data(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u16) } } #[inline] - pub fn set_has_buffered_data(&mut self, val: u8) { + pub fn set_has_buffered_data(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(7usize, 1u8, val as u64) } } #[inline] + pub fn fclose_stdiocast_flush_in_progress(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u16) } + } + #[inline] + pub fn set_fclose_stdiocast_flush_in_progress(&mut self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) + } + } + #[inline] pub fn new_bitfield_1( - is_persistent: u8, - in_free: u8, - eof: u8, - __exposed: u8, - fclose_stdiocast: u8, - has_buffered_data: u8, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + is_persistent: u16, + in_free: u16, + eof: u16, + __exposed: u16, + fclose_stdiocast: u16, + has_buffered_data: u16, + fclose_stdiocast_flush_in_progress: u16, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); __bindgen_bitfield_unit.set(0usize, 1u8, { - let is_persistent: u8 = unsafe { ::std::mem::transmute(is_persistent) }; + let is_persistent: u16 = unsafe { ::std::mem::transmute(is_persistent) }; is_persistent as u64 }); __bindgen_bitfield_unit.set(1usize, 2u8, { - let in_free: u8 = unsafe { ::std::mem::transmute(in_free) }; + let in_free: u16 = unsafe { ::std::mem::transmute(in_free) }; in_free as u64 }); __bindgen_bitfield_unit.set(3usize, 1u8, { - let eof: u8 = unsafe { ::std::mem::transmute(eof) }; + let eof: u16 = unsafe { ::std::mem::transmute(eof) }; eof as u64 }); __bindgen_bitfield_unit.set(4usize, 1u8, { - let __exposed: u8 = unsafe { ::std::mem::transmute(__exposed) }; + let __exposed: u16 = unsafe { ::std::mem::transmute(__exposed) }; __exposed as u64 }); __bindgen_bitfield_unit.set(5usize, 2u8, { - let fclose_stdiocast: u8 = unsafe { ::std::mem::transmute(fclose_stdiocast) }; + let fclose_stdiocast: u16 = unsafe { ::std::mem::transmute(fclose_stdiocast) }; fclose_stdiocast as u64 }); __bindgen_bitfield_unit.set(7usize, 1u8, { - let has_buffered_data: u8 = unsafe { ::std::mem::transmute(has_buffered_data) }; + let has_buffered_data: u16 = unsafe { ::std::mem::transmute(has_buffered_data) }; has_buffered_data as u64 }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let fclose_stdiocast_flush_in_progress: u16 = + unsafe { ::std::mem::transmute(fclose_stdiocast_flush_in_progress) }; + fclose_stdiocast_flush_in_progress as u64 + }); __bindgen_bitfield_unit } } @@ -2343,15 +2366,6 @@ extern "C" { } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct hostent { - pub h_name: *mut ::std::os::raw::c_char, - pub h_aliases: *mut *mut ::std::os::raw::c_char, - pub h_addrtype: ::std::os::raw::c_int, - pub h_length: ::std::os::raw::c_int, - pub h_addr_list: *mut *mut ::std::os::raw::c_char, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct php_file_globals { pub pclose_ret: ::std::os::raw::c_int, pub def_chunk_size: usize, @@ -2365,9 +2379,6 @@ pub struct php_file_globals { pub stream_filters: *mut HashTable, pub wrapper_errors: *mut HashTable, pub pclose_wait: ::std::os::raw::c_int, - pub tmp_host_info: hostent, - pub tmp_host_buf: *mut ::std::os::raw::c_char, - pub tmp_host_buf_len: usize, } extern "C" { pub static mut file_globals: php_file_globals; diff --git a/src/flags.rs b/src/flags.rs index da3a6844c8..7570783666 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -418,7 +418,7 @@ mod tests { test!(IS_DOUBLE, Double); test!(IS_STRING, String); test!(IS_ARRAY, Array); - assert_eq!(DataType::try_from(IS_OBJECT), Ok(DataType::Object(None))); + assert_eq!(DataType::from(IS_OBJECT), DataType::Object(None)); test!(IS_RESOURCE, Resource); test!(IS_REFERENCE, Reference); test!(IS_CONSTANT_AST, ConstantExpression); @@ -429,7 +429,7 @@ mod tests { test!(IS_INTERNED_STRING_EX, String); test!(IS_STRING_EX, String); test!(IS_ARRAY_EX, Array); - assert_eq!(DataType::try_from(IS_OBJECT_EX), Ok(DataType::Object(None))); + assert_eq!(DataType::from(IS_OBJECT_EX), DataType::Object(None)); test!(IS_RESOURCE_EX, Resource); test!(IS_REFERENCE_EX, Reference); test!(IS_CONSTANT_AST_EX, ConstantExpression); diff --git a/tests/src/lib.rs b/tests/src/lib.rs index ec5c49d620..83dee897c7 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -120,7 +120,6 @@ pub fn get_module(module: ModuleBuilder) -> ModuleBuilder { #[cfg(test)] mod integration { use std::env; - use std::path::PathBuf; use std::process::Command; use std::sync::Once; @@ -139,7 +138,7 @@ mod integration { pub fn run_php(file: &str) -> bool { setup(); - let mut path = PathBuf::from(env::current_dir().expect("Could not get cwd")); + let mut path = env::current_dir().expect("Could not get cwd"); path.pop(); path.push("target"); path.push("debug");