D: crossplatform way to move to top level of path? - path

I have got path in variable like:
D:\foo\bar\baz\file.txt
It can be also like:
/foo/bar/baz/file.txt
I need way to cross-platform may to move to bar directory.
I found only one way, but it's look like hack:
writeln(mystr.replaceLast("baz" ~ dirSeparator ~ "file.txt", ""));

std.path has 2 functions for this: buildNormalizedPath and asNormalizedPath.
The only difference between them is that asNormalizedPath won't allocate memory.

For some reason dpaste using dmd 2.068.2 isn't too happy about this. But it is correct code.
import std.path;
import std.stdio;
void main() {
version(Posix) {
writeln(buildNormalizedPath("/a/b/c", "../d"));
} else version(Windows) {
writeln(buildNormalizedPath("c:\\\\a\\b\\c", "..\\d"));
}
}

Related

Elegant way to execute code on function exit in Dart

Suppose we need to execute some code when a function finishes, no matter how.
Example:
void myFunc() async {
await myLock.acquire();
if(...) {
myLock.release();
return;
}
...
myLock.release();
}
Many languages have features that allow to achieve this in a more elegant way than just manually calling myLock.release() before every return statement (For example defer in Go). Is something like that also possible in Dart?
Dart does not have RAII. You instead would need to use try-finally.
(Dart did recently (in 2.17) add Finalizers, but those would fire when objects are garbage collected, which might happen at some non-deterministic time, if ever.)
And just for the record, an example of using try/finally:
void myFunc() async {
await myLock.acquire();
try {
if(...) {
return;
}
...
} finally {
myLock.release();
}
}
You'd want to start the try after allocating the resource, so that you don't try to release if allocation throws.

Rollup: make module globally accessible without need to import

I want module sync-fetch to be accessible globally without need to import in each component and be named as simple fetch.
Also I want to extend it with custom method then.
Now in rollup.config.js there are:
export default {
...
output: {
...
intro: `const fetch = require('sync-fetch');
fetch.Response.prototype.then = function(foo) {
return foo(this);
}`
},
};
And it works, but looks dangerous) Is intro is the only way to do it?
If you want to make it seem less dangerous, you could put that code in a file and then return the contents of it in a function. The output.intro option also takes a function that returns the code as a string.
{
output: {
intro: () => require('fs/promises').readFile('path/to/the/file.js', 'utf-8')
}
}

Have single line empty constructors, but braces on newline everywhere else

I am looking for a way to make clang-format allow single line empty constructors, but to put braces on the newline everywhere else.
Ideally I want to support these three cases all with one clang config.
Test::Test(const std::string &name) : name(name) {}
std::string Test::get_name()
{
return name;
}
void Test::blank()
{
}
Is there a way to special case constructors in anyway? Even being able to have empty functions on a single line the same as constructors would be acceptable. But putting short functions on a single line is not acceptable.
This doesn't solve all the issues, but it solves my main case.
AllowShortFunctionsOnASingleLine: InlineOnly
This will allow short functions in class definitions to be single line.
From https://clang.llvm.org/docs/ClangFormatStyleOptions.html
SFS_InlineOnly (in configuration: InlineOnly) Only merge functions defined inside a class. Same as “inline”, except it does not implies “empty”: i.e. top level empty functions are not merged either.
class Foo {
void f() { foo(); }
};
void f() {
foo();
}
void f() {
}
This combined with BreakBeforeBraces: Allman gives me the desired result.

Reading static files under a library in Dart?

I am writing a library in Dart and I have static files under the library folder. I want to be able to read those files, but I'm not sure how to retrieve the path to it... there is not __FILE__ or $0 like in some other languages.
Update: It seems that I was not clear enough. Let this help you understand me:
test.dart
import 'foo.dart';
void main() {
print(Foo.getMyPath());
}
foo.dart
library asd;
class Foo {
static Path getMyPath() => new Path('resources/');
}
It gives me the wrong folder location. It gives me the path to test.dart + resources/, but I want the path to foo.dart + resources/.
As mentioned, you can use mirrors. Here's an example using what you wanted to achieve:
test.dart
import 'foo.dart';
void main() {
print(Foo.getMyPath());
}
foo.dart
library asd;
import 'dart:mirrors';
class Foo {
static Path getMyPath() => new Path('${currentMirrorSystem().libraries['asd'].url}/resources/');
}
It should output something like:
/Users/Kai/test/lib/resources/
There will probably be a better way to do this in a future release. I will update the answer when this is the case.
Update: You could also define a private method in the library:
/**
* Returns the path to the root of this library.
*/
_getRootPath() {
var pathString = new Path(currentMirrorSystem().libraries['LIBNAME'].url).directoryPath.toString().replaceFirst('file:///', '');
return pathString;
}
The dart mirrors API (still experimental, and not available on all platforms such as dart2js yet) exposes a url getter on the LibraryMirror. This should give you what you want.
I'm not aware of any other way to get this information on a library.
#import('dart:mirrors');
#import('package:mylib/mylib.dart');
main(){
final urlOfLib = currentMirrorSystem().libraries['myLibraryName'].url;
}
Generally the usual method of accessing resources which are located at a static position with your library is by use using a relative path.
#import('dart:io');
...
var filePath = new Path('resources/cool.txt');
var file = new File.fromPath(filePath);
// And if you really wanted, you can then get the full path
// Note: below is for example only. It is missing various
// integrity checks like error handling.
file.fullPath.then((path_str) {
print(path_str);
});
See addition API information on Path and on File
As an aside.. If you absolutely wanted to get the same type of output as __FILE__ you can do something like the following:
#import('dart:io');
...
var opts = new Options();
var path = new Path(opts.script);
var file = new File.fromPath(path);
file.fullPath().then((path_str) {
print(path_str);
});

How to change the level of AX info messages

In Dynamics AX 2009 I am trying to determine the level of indentation of an info message. What I want is something similar to this:
Prefix
Info1
Info2
Prefix2
Info3
I found this:
http://www.doens.be/2010/05/the-ax-infolog/
But don't want to use a loop, so I thought something like this might work:
setprefix("Prefix");
{
info("Info1");
info("Info2");
}
setprefix("Prefix2");
{
info("Info3");
}
But it doesn't. Is there a way to do this in x++, and what are the rules as to what indent level is currently active?
setPrefix in AX sets (adds) the prefix for the current execution scope, and when leaving the scope the prefix is automatically reset to the previous level. You can use getPrefix to check the current execution prefix.
2 hacks can help you recieve the expected result:
#1
static void TestJob(Args _args)
{
void sub1()
{
setprefix("Prefix");
info("Info1");
info("Info2");
}
void sub2()
{
setprefix("Prefix2");
info("Info3");
}
;
setPrefix("Main");
sub1();
sub2();
}
#2
static void TestJob(Args _args)
{
setPrefix("Main");
info("Prefix\tInfo1");
info("Prefix\tInfo2");
info("Prefix2\tInfo3");
}

Resources