filepath Base on windows not working after cross compilation (Golang) - go

If I have a path on linux/OSX such as filepath := /Users/jamesbond/some/where/file.txt
then I can do
name := path.Base(filepath)
and name will be file.txt
however on windows this does not work. The returned value of name is still /Users/jamesbond/some/where/file.txt
I guess I can see why, as the function base has
for len(path) > 0 && path[len(path)-1] == '/' {
path = path[0 : len(path)-1]
}
i.e its clearly really only setup for linux/OSX style file paths.
I am cross compiling from OSX for windows. I guess that the library on windows has the corect / in the SDK, but how can I handle this regardless of OS? Is there a way to convert or something before, then use Base function?
What would be the recommended way to write this code once and it work on all OSes?

Related

How to find Mac documents path (language independent)

I need to find the documents folder path using golang on MacOS. I can do like this:
docsPath := os.Getenv("HOME") + "/Documents"
But I don't know if "Documents" is a valid solution for other OS languages. What if the Mac is Italian language? Is there a way to find out for sure? Or where can I find the proven information that it is always "Documents"? Sadly I do not have access to any Mac other than English.
MacOS places all user files and folders to /Users/%username%/, e.g. for me /Users/lisitsky.
Documents are located at subfolder /Users/username/Documents. You look at it name in terminal by ls /Users/username/Documents.
Finder shows localized names for standard folders in your language but uses standard names on system level.
Also you may check os/user module.
func main() {
usr, _ := user.Current()
dir := usr.HomeDir
fmt.Println(dir, path.Join(dir, "Documents"))
}

How to get the parent directory path of a path in FreePascal/Lazarus?

I have a path to a directory saved as a string, and wanted to know how I can easily and robustly extract the parent directory from this string?
I tried to see if there is some method for this in FileUtil and SysUtils, but haven't found anything so far.
The simplest way is to find the last path delimiter character and trim the source string. BTW there are some alternative:
program Project1;
uses
sysutils;
var
sExe: string;
sParent: string;
sParentProper: string;
begin
sExe := ExtractFilePath(ParamStr(0)); // Get executable directory
Writeln(sExe);
sParent := IncludeTrailingPathDelimiter(sExe) + '..' + PathDelim; // Make parent path for executable
Writeln(sParent);
sParentProper := ExpandFileName(sParent); // Get absolute path based on relative path
WriteLn(sParentProper);
Readln;
end.
And output is:
C:\Users\nd\AppData\Local\Temp\
C:\Users\nd\AppData\Local\Temp\..\
C:\Users\nd\AppData\Local\
So using this technique the proper way is ExpandFileName(IncludeTrailingPathDelimiter(sBasePath) + '..')
PS: We are using only sysutils unit so it is pure FPC solution and it is not require any LCL libraries.
An even simpler way to do this would be:
parentDirPath := ExtractFilePath(ExcludeTrailingPathDelimiter(thePath));
This works on the three major platforms (Linux, Mac OS X and Windows), and thePath may refer to a file or a folder.
Well, I of course figured it out only after asking about it here:
parentDirPath := FileUtil.ExtractFileNameOnly(
FileUtil.ChompPathDelim(theSubDirPath));
... will do!
The FileUtil.ChompPathDelim() part is necessary to "fool" FPC to believe the top folder is a "file" (so no trailing slash allowed).

How to get the parent folder of a Windows user's profile path using C++

I am trying get the parent folder of a Windows user's profile path. But I couldn't find any "parameter" to get this using SHGetSpecialFolderPath, so far I am using CSIDL_PROFILE.
Expected Path:
Win7 - "C:\Users"
Windows XP - "C:\Documents and Settings"
For most purposes other than displaying the path to a user, it should work to append "\\.." (or "..\\" if it ends with a backslash) to the path in question.
With the shell libary version 6.0 you have the CSIDL_PROFILES (not to be confused with CSIDL_PROFILE) which gives you what you want. This value was removed (see here), you have to use your own workaround.
On any prior version you'll have to implement your own workaround, such as looking for the possible path separator(s), i.e. \ and / on Windows, and terminate the string at the last one. A simple version of this could use strrchr (or wcsrchr) to locate the backslash and then, assuming the string is writable, terminate the string at that location.
Example:
char* path;
// Retrieve the path at this point, e.g. "C:\\Users\\username"
char* lastSlash = strrchr(path, '\\');
if(!lastSlash)
lastSlash = strrchr(path, '/');
if(lastSlash)
*lastSlash = 0;
Or of course GetProfilesDirectory (that eluded me) which you pointed out in a comment to this answer.

How do I find iTunes library folder on Mac and Windows?

I made an application that parse the iTunes library to retrieve its content. It works fine in most cases but if a user moved his library somewhere else than the default iTunes folder (see: http://lifehacker.com/238296/ultranewb--how-to-move-your-itunes-library-to-an-external-drive), then I need a way to find this path.
On Mac, I was looking into ~/Library/Preferences/com.apple.iTunes.plist. There is a setting called "alis:1:iTunes Library Location" but it contains several parameters all concatenated and converted to hexadecimal.
On Windows, I found this file "C:\Documents and Settings\\Application Data\Apple Computer\iTunes\iTunesPrefs.xml" that contains a setting "iTunes Library XML Location:1" but this one is encoded.
Any help would be greatly appreciated.
Thanks!
On Windows, the iTunes Library XML Location:1 entry in iTunesPrefs.xml is a Base 64 encoded Unicode string, so you'll need to decode it before you can use it. On my PC, it decodes to C:\Documents and Settings\Emerick\My Documents\My Music\iTunes\iTunes Music Library.xml.
It should be relatively easy to decode this value using your language of choice; your platform may even provide utility libraries that make this trivial. In C#, for example, the decoding function would look something like this:
static public string DecodeBase64(string encodedData)
{
byte[] encodedBytes = System.Convert.FromBase64String(encodedData);
return System.Text.UnicodeEncoding.Unicode.GetString(encodedBytes);
}
I can't help you with the Windows stuff, but on the Mac what you're seeing in that prefs file is old-school alias handle data. Take a look at or just use Chris Hanson's BDAlias class to convert it to a path.
http://github.com/rentzsch/bdalias
As the others point out "alis:1:iTunes Library Location" is alias data. Here's how I find the path from the data in OS X using Python.
#!/usr/bin/env python
import commands, plistlib
from Carbon import File
from os.path import expanduser
PLIST_PATH = '~/Library/Preferences/com.apple.iTunes.plist'
PLIST_KEY = 'alis:1:iTunes Library Location'
def resolve_path_from_alias_data( alis ):
fs_ref = File.Alias( rawdata=alis ).FSResolveAlias( None )[0]
file_path = fs_ref.as_pathname()
return file_path
plist_str = commands.getoutput( '/usr/bin/plutil -convert xml1 -o - "' + expanduser( PLIST_PATH ) + '"' )
plist_data = plistlib.readPlistFromString( plist_str )
alis_data = plist_data[ PLIST_KEY ].data
file_path = resolve_path_from_alias_data( alis_data )
print repr( file_path )
Unfortunately, iTunes no longer uses "alis:1:iTunes Library Location" so this no longer works. Now iTunes 11 uses an entry called "RDoc:132:Documents" which seems to be completely different. I have posted a similar question with the appropriate iTunes 11 details.
Actually, my answer works just fine as of OS X 10.9.1. I'm not sure whether it stopped due to some error I made, or if Apple quietly reverted something. Either way, it's working again on my Mac.

Checking if a Folder/File is Hidden/System in Windows C/C++

I am writing a Cross platform application using C++/STL/Boost and I realized they do not provide a way to check if a folder or file is hidden or is a system file in Windows.
What's the simplest way to do this in C/C++ for Windows ?
Ideally I have a std::string with the path (either to a file or folder), and would return if it's hidden or is a system file. best if it works across all windows versions. I am using MinGW g++ to compile this as well.
GetFileAttributes will work for this.
It takes a path to either a file or a directory as a parameter and returns set of flags including FILE_ATTRIBUTE_HIDDEN and FILE_ATTRIBUTE_SYSTEM.
DWORD attributes = GetFileAttributes(path);
if (attributes & FILE_ATTRIBUTE_HIDDEN) ...
if (attributes & FILE_ATTRIBUTE_SYSTEM) ...

Resources