When I checked the man-page for dlopen on iOS it says:
When path contains a slash (i.e. a full path or a partial path) dlopen()
searches the following the following until it finds a compatible Mach-O
file: $DYLD_LIBRARY_PATH (with leaf name from path ), current working
directory (for partial paths), $DYLD_FALLBACK_LIBRARY_PATH (with leaf
name from path ).
but according to POSIX (Open Group):
The file argument is used to construct a pathname to the object file. If file contains a slash character, the file argument is used as the pathname for the file. Otherwise, file is used in an implementation-defined manner to yield a pathname.
So if you follow POSIX you could use dlopen("/path/to/lib", 0) to open precisely that file, but according to the iOS documentation it would search for a Mach-O file named lib in $DYLD_LIBRARY_PATH, current directory and finally $DYLD_FALLBACK_LIBRARY_PATH.
If I really want to open just /path/to/lib under iOS and not any (possibly malign) lib found in the search path, what could I do?
(If I understand it correctly POSIX allows you to use a relative path too. Would that imply that it's a path relative to the current working directory then?)
Related
In a file path, the set of "words" or folder names required to specify a specific file in a hierarchy of directories is called the path to the file, which is called path name. Path name can be either absolute or relative. In relative form, a sort of patterns like "./", "../", "../../", ... can be used to show the file/folder depth corresponding to the project base folder.
I know what they do or implying by behavior, but what are they called? Do they have a specific name? For example, what is called "../" or "..\" in a file system?
Briefly, it is called levelup notion.
Let's start with defining path:
A path is a slash-separated list of directory names followed by either
a directory name or a file name. A directory is the same as a folder.
Then, we look at types of paths: Absolute and relative paths!
An absolute, or full, path begins with a drive letter, whereas a relative path refers to a location that is relative to a current directory.
In relative paths we may use dot and double-dot symbols. A dot here means the current directory itself. And the double-dot notation, which is called level-up, is used for moving up in the hierarchy.
Now to change the directory using the dot notion we do as follows:
A single dot represents the current directory itself. for example:
in a command line interface (e.g. PowerShell):
cd . will not change the directory as itself point to the current directory.
To change the directory using the level-up notion we do as follows:
each double-dot notions takes you one level up, meaning one folder closer to the base drive or root folder in the hierarchy.
Look at the example below for different cases of using levelup notions:
Coc in Neovim seems to be unable to see #include <avr/io.h> since I'm guessing that it's include path isn't known by coc. How can I allow coc to see this include path?
A solution was found to be the following:
In the root of your project directory (the base of compilation) add a file called compile_flags.txt.
To the compile_flags.txt file, for the AVR includes, add -I/usr/avr/include.
NOTE: The compile_flags.txt file only accepts a single argument per line, so the actual contents of this file should be
-I
/usr/avr/include
References:
JSON Compilation Database Format Specification
I am trying to get this short script to work. All it should do is take the contents of the folder in Application Support/App of the local user and move it to a usb.
set localLocation to POSIX path of (path to library folder from user domain) & "Application\\ Support/myApp" as text
set usbLocation to "/Volumes/myUsb/myApp"
tell application "Finder" to move entire contents of folder localLocation to folder usbLocation
There is a folder available in both directories (USB & Computer) which match the custom path description described here as "myApp". The code has an error in the first section of the tell, where it is unable to locate the folder in the Application Support. I am not sure why this is the case and I also am struggling to understand the difference between HFS and POSIX, which one is meant to be used? I have a feeling there is a possible concatenate error with types. I am a beginner, please help.
Thankyou!
Understanding how AppleScript deals with file and folder references is a headache, and it's very well known to be convoluted and fussy about file specifiers and path strings.
Simple definitions:
Posix path: A path made up of forward slashes that separate folders in a directory tree, e.g. /Users/CK/Downloads/Some_File.txt.
The root (top-level) directory is represented by a single forward
slash, /. Every posix path is descended from this root directory,
so, generally speaking, posix paths must start with a forward slash.
Folder paths ideally end with a terminating forward slash; file paths
do not; but this is not strict.
HFS path: A path made up of colons that separate folders in a directory tree, e.g. Macintosh HD:Users:CK:Downloads:Some_File.txt.
The root directory is represented by Macintosh HD:, which always
begins an HFS path (unless your system hard drive is called something
else). Folder paths ideally end with a terminating colon; file paths
do not; this is semi-strict.
That's literally all you need to know about posix paths and HFS paths to do some AppleScripting. The tough part is getting to grips with AppleScript's file class types. There are three:
alias: These are your friends, and are the most versatile when used with either Finder or System Events, and when referring to
either files or folders. They are an AppleScript object that
contain a file reference that points to an existing file. Trying
to assign an alias class type to a file reference of a file that
does not exist will throw an error.
file: These are a file reference object that may point to a file that doesn't exist (yet). It qualifies an HFS path string,
identifying it as not just a piece of text, but a path to a file. The
key difference between file and alias is that file is a static
reference, meaning that if it points to a file with a given name, and
that file's name changes, the file object will now reference a file
that does not exist. An alias, on the other hand, dynamically
shifts its reference even after a file is renamed or moved.
POSIX file: If you like using posix paths (and you should), the POSIX file object is your best friend. It takes a posix path
string and qualifies it as a path to a file in much the same way
file does for HFS path strings. Likewise, it is a static reference
and can point to files or folders that don't exist.
My recommendation
My feeling is that HFS paths are an unnecessary complication to what could have been an easy inter-formulation between command line users and AppleScripting. They do confuse people, and since the notation is so widely observed through the results returned by an AppleScript, they appear mandatory in their use.
They are not. I, personally, never use HFS paths. (Almost never).
One isn't intrinsically better than the other, and it is really just a personal preference. So my advice is to pick one style that you're most comfortable with, and learn how to manipulate that type of path in the AppleScript setting.
As I use posix paths, I concern myself with POSIX file objects, and alias objects. That's what I'll focus on now for the rest of this answer.
Your script
Your script threw its first error because you attempted to escape the spaces within the file path string, possibly a habit from typing in a terminal. You don't need to escape any characters in a file string, except for the backslash \, as file path strings will always be enclosed within double quotes.
Still addressing the first line of your script, you have quite correctly retrieved the path to the library folder (which returns an alias); turned it into a posix path string; then appended the "Application Support/myApp" path text. However, it may be helpful to know that you can actually get the path to the application support folder, so your first line can become:
set localLocation to POSIX path of (path to application support from user domain) & "myApp"
The result is a posix path string, but not a file object (but that's fine at the moment).
Your next line then explicitly declares a posix path string:
set usbLocation to "/Volumes/myUsb/myApp"
which is absolutely fine.
The bit that comes next is the tricky stuff: working with Finder:
tell application "Finder" to move entire contents of ¬
folder localLocation to folder usbLocation
That said, you had it almost perfect. Because you're using posix paths, you either need to turn them into alias objects, or explain to finder that it's dealing with a posix path, which is what the POSIX file object does.
To create a POSIX file object, you can either prepend the POSIX file specifier to the posix path string like this:
set usbLocation to POSIX file "/Volumes/myUsb/myApp"
or do a more conventional coercion into a type class like this:
set usbLocation to "/Volumes/myUsb/myApp" as POSIX file
In either case, AppleScript turns this into a file object and converts it to an HFS path. If you run that line just above by itself, AppleScript returns this:
file "Macintosh HD:Volumes:myUsb:myApp"
So, already, we can see there's an equivalence between file objects and HFS paths versus POSIX file objects and posix paths.
You can choose to edit lines 1 and 2 of your script to construct these POSIX file objects straight away; or you can do it at the point where you are interacting with Finder:
tell application "Finder" to move entire contents of ¬
folder (localLocation as POSIX file) to folder (usbLocation as POSIX file)
If doing it here, you have to coerce using as, possibly because prepending it as an object specifier interferes with folder in the role of an object specifier.
That should successfully move all the files into their new location. The other way you could do it is by moving the folder instead of its contents, which is probably quicker if there are many files and sub-directories. Just change the destination path accordingly:
set localLocation to POSIX path of (path to application support folder from user domain) & "myApp" as POSIX file
set usbLocation to POSIX file "/Volumes/myUsb/"
tell application "Finder" to move folder localLocation to folder usbLocation with replacing
(the with replacing is because the folder myApp in the destination will be getting replaced by the folder myApp coming from your hard drive.)
Finally, for completeness, I'll briefly talk about alias objects:
Alias objects
Constructing alias objects from posix paths is fairly simple, and requires two steps. Firstly, you construct the POSIX file object as I showed you above. Then, you coerce this object into an alias. It can be done on one line:
set usbLocation to POSIX file "/Volumes/myUsb/myApp" as alias
or
set usbLocation to "/Volumes/myUsb/myApp" as POSIX file as alias
Remember, however, that alias objects point to files and folders that already exist. Therefore, there will be some instances where you can declare your POSIX file object immediately from a posix path string that points to a non-existent file that, for example, you will be creating. But you can only coerce it into an alias after the file has been created.
One reason you might want to use alias objects is because they are dynamic, as I mentioned before (or, they should be). So if you set localLocation as an alias object at the start, then moved the folder to its destination as in my very last Finder example, the alias object should now automatically point to /Volumes/myUsb/myApp/ (although it doesn't always work successfully, as one of the many bugs AppleScript has).
The other, more important, reason to use alias objects is that they translate directly between the different applications AppleScript interacts with: not all utilise POSIX file objects, and some may not utilise HFS paths; but they virtually all know what an alias object is.
This is key when switching between Finder and System Events for file handling. Generally speaking, file and folder handling is best done with System Events rather than Finder. But, there are a couple of things you can only do in Finder: set a file tag (label index); get the selected files (selection); and know which target folder has focus at the present time (insertion location).
Retrieving the selection in Finder returns Finder-specific classes, namely document files. One cannot utilise these objects with System Events. However, the selection as alias list is something that can be manipulated by System Events:
tell application "Finder" to set S to selection as alias list
tell application "System Events" to get properties of item 1 of S
Finally, the third reason to utilise alias objects is because, for some reason, retrieving files as alias objects is noticeably faster than retrieving them as any other class object. Testing this on the contents of my downloads folder (which is small enough to not keep me waiting, but large enough to get Finder working), the results were:
tell application "Finder" to get entire contents of ¬
(path to downloads folder) as alias list
-- 1.45s
tell application "Finder" to get entire contents of ¬
(path to downloads folder)
-- 2.29s
They are identical statements, with the exception of the coercion to an alias list (a list of alias file objects) in the first. The speed benefit will be more noticeable on larger folders.
Utilising alias objects with Finder is a little easier/simpler than with file or POSIX file objects, because alias objects don't make a distinction between files and folders in the way that the other two do. In your script, it's necessary with Finder to use the folder specifier with the POSIX file objects; with an alias object, you don't need to:
set localLocation to POSIX path of (path to application support folder from user domain) & "myApp" as POSIX file as alias
set usbLocation to POSIX file "/Volumes/myUsb/" as alias
tell application "Finder" to move localLocation to usbLocation with replacing
I disagree to be discouraged from using HFS paths.
If you have to use the Finder it's the most convenient way since the Finder doesn't accept POSIX paths.
To address a folder on the top level of an external volume there is another short way in Finder terminology : folder "foo" of disk "bar".
set localLocation to (path to application support folder from user domain as text) & "myApp"
tell application "Finder" to move entire contents of folder localLocation to folder "myApp" of disk "myUsb"
However entire contents in Finder can be extremely slow. The shell is much faster.
set localLocation to POSIX path of (path to application support folder from user domain) & "myApp/"
set usbLocation to "/Volumes/myUsb/myApp"
do shell script "/bin/cp " & quoted form of localLocation & "*" & space & quoted form of usbLocation
What is the procedure or method add a path to a file in the {$I ...} line?
I have a file that I want the compiler to be able to find.
For example, say I have downloaded a file named "abc.inc" that receives a file error as follows:
F1026 File not found: 'abc'
The file in code is something like this:
{$I abc.inc}
My question is how do you write a file path in code to a particular folder in my project?
For example, let's say my file "abc" is located this path: project\comps\jcl\abc.inc
How would I write in code {$I abc.inc} "is located in path comps\jcl\abc.inc ?
I think I know how {$I functions... How to add/include/incorporate "abc.inc" file into my project using code. How do I write a path in code?
The answer can be found in the documentation:
If the filename does not specify a directory path, then, in addition to searching for the file in the same directory as the current module, Delphi searches in the directories specified in the Search path input box on the Delphi Compiler page of the Project > Options dialog box.
This documentation text is vague at best. What actually happens if you specify a relative path, is that the path is taken to be relative to the file which contains the $INCLUDE directive.
So if the file to be included is not in the same directory as the source file that is including it then your options are to:
Specify the absolute path of the include file, or
Specify the path of the include file, relative to the source file containing the $INCLUDE directive, or
Add the directory containing the include file to the search path.
For me, a path was always something that "walks the way to something", but without the "something".
Like a chicken following bread crumbs until it hits the target. But the target is not part of the path. That's what I believe.
So, example: C:/foo/bar = the path. C:/foo/bar/something.html = Path and the "Target".
Can someone tell me what are the correct terms here? How do I call such a path with file?
"Full path"?
"Full qualified path"?
"Path with File Name"? (not precise! "Path with File Name and Extension" ... way too long)
Sure there's a special name for this. Want to know! :)
Nice chicken example... I think you mean absolute path
but, It doesn't matter what the path points to, be it a directory, file, device or otherwise
Wikipedia says:
A path, the general form of a filename or of a directory name, specifies a unique location in a file system.
It doesn't even require an extension, as other mechanisms work out the filetype.
/foo/bar/file.txt = Absolute path
/foo/bar = An absolute path to a directory
../foo = A relative path to a directory, from current directory
./file.txt = A relative path to a file, from current directory (Unix)
file.txt = A relative path too
Also
Systems can use either absolute or relative paths. A full path or absolute path is a path that points to the same location on one file system regardless of the working directory or combined paths. It is usually written in reference to a root directory.
The distinction between files and directories isn't catered for with a path. A path is always a path to something, be it a file or a directory:
/a/b/c is the path to c regardless of what type (file, directory, device) the end point is.
Also checkout basenames
basename is a standard UNIX computer program, when basename is given a pathname, it will delete any prefix up to the last slash ('/') character and return the result. basename is described in the Single UNIX Specification and is primarily used in shell scripts.
From LINFO
A path is the address of an object
(i.e., file, directory or link) on a
filesystem.
So, unfortunately, you are looking for a specificity of terms that isn't part of the accepted usage. You'll have to define your own terms.
I beleive it is called "full name" regardless of the "target" type, just because everything in UNIX is a file, including a directory. So if a foo is the target (as you called it), then foo is the name, while C:\Direcotry\foo or /usr/bin/foo is the foo's full name.
i have been thinking about it too lately, because in Everything, the path do not include the "target" itself. but when i search in Wikipedia, it say that the target is included.
in your example, you have implicitly assume that there is "only one" target at the end of the bread crumbs. and someone tell the chicken to follow the bread crumbs and then it can get to the target.
what if there are 2 objects in the end? if someone did not tell which one is the target, e.g. include the target itself in the path, the chicken will never know its target.
you can also think like this: for a path which include the file, the target is not the file, but its content or some other imformation of the file.
back to the file system, assume there is several file in a folder. if file name is not included in its path, then they all have same path and you can not find a specific file through its path alone.