Showing posts with label DLang-utilities. Show all posts
Showing posts with label DLang-utilities. Show all posts

Wednesday, October 31, 2018

D language front-end merged with GCC 9; some sample D programs

By Vasudev Ram


The D Language Front-End Merged Into GCC 9 (phoronix.com)

HN thread about it.

D is a nice language, and fast both to compile and run. It has a wide range of features, but one can get started with it without learning all of them. It's fast both to compile and to run. Dev time is fast too.

I commented on the HN thread above too, giving a list of some of my own small D language programs (mainly command-line utilities) that can serve as a quick introduction to some of the different things that you can do with D.

I've reproduced the links to those D programs for the convenience of my readers, below:

"Here are a handful of D programs that use various features of the language and some of its libraries, on my blog. Most of them are simple command-line utilities to do various things. Readers may find them of use to get a flavor of the language and to know some of the kinds of things it can be used for."

A few of the posts are about interviews with D language people too.

Don't miss the interview where the creators or key people from the C++, Rust, D and Go languages talk to each other on a panel about some of the pros and cons of their respective languages - and the incident near the end of the video, involving Bjarne Stroustrup (the LangNext video below).

Here are those D-related posts:

Porting the text pager from Python to D (DLang)

Simple parallel processing in D with std.parallelism

Video: Interview: GoingNative 6: Walter Bright and Andrei Alexandrescu - D Programming Language

Using std.datetime.StopWatch to time sections of D code

Read from CSV with D, write to PDF with Python

Command line D utility - find files matching a pattern under a directory

min_fgrep: minimal fgrep command in D

num_cores: find number of cores in your PC's processor

Calling a simple C function from D - strcmp

Component programming in D - DDJ article by Walter Bright

Func-y D + Python pipeline to generate PDF

Interview: Ruminations on D: Walter Bright, DLang creator

file_sizes utility in D: print sizes of all files under a directory tree

Video: C++, Rust, D and Go: Panel at LangNext '14

deltildefiles: D language utility to recursively delete vim backup files

[DLang]: A simple file download utility in D

Getting CPU info with D (the D language)


- Vasudev Ram - Online Python training and consulting

I conduct online courses on Python programming, Unix / Linux commands and shell scripting and SQL programming and database design, with course material and personal coaching sessions.

The course details and testimonials are here.

Contact me for details of course content, terms and schedule.

DPD: Digital Publishing for Ebooks and Downloads.

Learning Linux? Hit the ground running with my vi quickstart tutorial. I wrote it for two Windows system administrator friends who were given charge of Unix systems. They said it made it easy for them to start using vi on Unix.

Check out WP Engine, powerful WordPress hosting.

Creating or want to create online products for sale? Check out ConvertKit, email marketing for online creators.

Own a piece of Americana: Jacob Bromwell: Legendary American Cookware

Teachable: feature-packed course creation platform, with unlimited video, courses and students.

See my posts about: Python * DLang * xtopdf

Check out my My ActiveState Code recipes (over 90 of them, mostly on Python)

Follow me on:


Friday, October 14, 2016

Command line D utility - find files matching a pattern under a directory

By Vasudev Ram

Hi readers,

I wrote this utility in D recently, to find files matching a pattern (a wildcard) under a specified directory. Here is the program, find_files.d:
/************************************************************************
find_files.d
Author: Vasudev Ram
Compile with Digital Mars D compiler using the command:
dmd find_files.d
Usage: find_files dir patt
Finds files under directory 'dir' that match file wildcard 
pattern 'patt'.
The usual file wildcard patterns that an OS like Windows or 
Linux supports, such as *.txt, budget*.xls, my_files*, etc.,
are supported.
Copyright 2016 Vasudev Ram
Web site: https://vasudevram.github.io
Blog: http://jugad2.blogspot.com
Product updates: https://gumroad.com/vasudevram/follow
************************************************************************/

import std.stdio; 
import std.file;

string __version__ = "0.1";

void usage(string[] args) {
    debug {
        stderr.write("You gave the command: ");
        foreach(arg; args)
            stderr.write(arg, " ");
        stderr.writeln;
    }
    
    stderr.writeln(args[0], " (Find Files) v", __version__);
    stderr.writeln("Copyright 2016 Vasudev Ram" ~
    " - https://vasudevram.github.io");
    stderr.writeln("Usage: ", args[0], " dir pattern");
    stderr.writeln("Recursively find filenames, under directory 'dir', ");
    stderr.writeln("that match the literal or wildcard string 'pattern'.");
}

int main(string[] args) {

    // Check for and get correct command-line arguments.
    if (args.length != 3) {
        usage(args);
        return 1;
    }
    auto top_dir = args[1];
    if (!exists(top_dir) || !isDir(top_dir)) {
        stderr.writeln("The name ", top_dir, 
        " does not exist or is not a directory.");
        usage(args);
        return 1;
    }
    auto pattern = args[2];

    try {
        debug writeln(args[0], ": Finding files under directory: ", 
        top_dir, " that match pattern: ", pattern);
        foreach (de; dirEntries(top_dir, pattern, SpanMode.breadth)) {
            writeln(de.name);
        }
    }
    catch (Exception e) {
        stderr.writeln("Caught Exception: msg = ", e.msg);
        return 1;
    }
    return 0;
}
Compile command:
$ dmd -offf find_files.d
The -of flag is for "output file", and is used to specify the .EXE file to be created. The command creates ff.exe on Windows).

Compile command to create debug version (the statements prefixed 'debug' will also run):
$ dmd -debug -offf find_files.d

Here is the output from a few test runs of the find_files utility:

Run with no arguments - shows usage:
$ ff
ff (Find Files) v0.1
Copyright 2016 Vasudev Ram - https://vasudevram.github.io
Usage: ff dir pattern
Recursively find filenames, under directory 'dir',
that match the literal or wildcard string 'pattern'.
Run with one argument, a non-existent directory - shows usage, since number of arguments is invalid:
$ ff z
ff (Find Files) v0.1
Copyright 2016 Vasudev Ram - https://vasudevram.github.io
Usage: ff dir pattern
Recursively find filenames, under directory 'dir',
that match the literal or wildcard string 'pattern'.
Run with two argument, a non-existent directory and a file wildcard, * - gives message that the directory does not exist, and shows usage:
$ ff z *
The name z does not exist or is not a directory.
ff (Find Files) v0.1
Copyright 2016 Vasudev Ram - https://vasudevram.github.io
Usage: ff dir pattern
Recursively find filenames, under directory 'dir',
that match the literal or wildcard string 'pattern'.
Run with two argument, an existing directory and a file wildcard, * - gives the output of the files matching the wildcard under that directory (recursively):
$ ff . *
.\dir1
.\dir1\a.txt
.\dir1\dir11
.\dir1\dir11\b.txt
.\dir2
.\dir2\c.txt
.\dir2\dir21
.\dir2\dir21\d.txt
.\ff.exe
.\ff.obj
.\ffd.exe
.\find_files.d
.\find_files.d~
Note: It will find hidden files too, i.e. those with a H attribute, as shown by the DOS command DIR /A. If you find any issue with the utility, please describe it, with the error message, in the comments.

You can get the find_files utility (as source code) from here on my Gumroad product store:

https://gum.co/find_files

Compile the find_files.d program with the Digital Mars D compiler using the command:

dmd find_files.d

whhich will create the executable file find_files.exe.

Run:

find_files

to get help on the usage of the utility. The examples above in this post have more details.

- Enjoy.

Drawing of magnifying glass at top of post, by:

Yours truly.

- Vasudev Ram - Online Python training and consulting

Get updates on my software products / ebooks / courses.

Jump to posts: Python   DLang   xtopdf

Subscribe to my blog by email

My ActiveState recipes

Managed WordPress Hosting by FlyWheel



Saturday, October 1, 2016

min_fgrep: minimal fgrep command in D

By Vasudev Ram

min_fgrep pattern < file

The Unix fgrep command finds fixed-string patterns (i.e. not regular expression patterns) in its input and prints the lines containing them. It is part of the grep family of Unix commands, which also includes grep itself, and egrep.

All three of grep, fgrep and egrep originally had slightly different behaviors (with respect to number and types of patterns supported), although, according to the Open Group link in the previous paragraph, fgrep is marked as LEGACY. I'm guessing that means the functionality of fgrep is now included in grep, via some command-line option, and maybe the same for egrep too.

Here is a minimal fgrep-like program written in D. It does not support reading from a filename given as a command-line argument, in this initial version; it only supports reading from stdin (standard input), which means you have to either redirect its standard input to come from a file, or pipe the output of another command to it.
/*
File: min_fgrep.d
Purpose: A minimal fgrep-like command in D.
Author: Vasudev Ram
Copyright 2016 Vasudev Ram
Web site: https://vasudevram.github.io
Blog: http://jugad2.blogspot.com
Product store: https://gumroad.com/vasudevram
*/

import std.stdio;
import std.algorithm.searching;

void usage(string[] args) {
    stderr.writeln("Usage: ", args[0], " pattern");
    stderr.writeln("Prints lines from standard input that contain pattern.");
}

int main(string[] args) {
    if (args.length != 2) {
        stderr.writeln("No pattern given.");
        usage(args);
        return 1;
    }

    string pattern = args[1];
    try {
        foreach(line; stdin.byLine)
        {
            if (canFind(line, pattern)) {
                writeln(line);
            }
        }
    } catch (Exception e) {
        stderr.writeln("Caught an Exception. ", e.msg);
    }
    return 0;
}
Compile with:
$ dmd min_fgrep.d
I ran it with its standard input redirected to come from its own source file:
$ min_fgrep < min_fgrep.d string
and got the output:
void usage(string[] args) {
int main(string[] args) {
    string pattern = args[1];
(Bold style added by me in the post, not part of the min_fgrep output, unlike with some greps.)

Running it as part of a pipeline:

$ type min_fgrep.d | min_fgrep string > c
gave the same output. The interesting thing here is not the min_fgrep program itself - that is very simple, as can be seen from the code. What is interesting is that the canFind function is not specific to type string; instead it is from the std.algorithm.searching module of the D standard library (Phobos), and it is generalized - i.e. it works on D ranges, which are a rather cool and powerful feature of D. This is done using D's template metaprogramming / generic programming features. And since the version of the function specialized to the string type is generated at compile time, there is no run-time overhead due to genericity (I need to verify the exact details, but I think that is what happens).

- Vasudev Ram - Online Python training and consulting

Get updates on my software products / ebooks / courses.

Jump to posts: Python   DLang   xtopdf

Subscribe to my blog by email

My ActiveState recipes

FlyWheel - Managed WordPress Hosting


Thursday, September 22, 2016

num_cores: find number of cores in your PC's processor

By Vasudev Ram

Here is a simple D language utility, num_cores.d, which, when compiled (once) and run (any number of times), will show you the number of cores in the processor in your PC:
// num_cores.d
// A utility to show the number of cores in the processor in your PC.

import std.stdio;
import std.parallelism;

int num_cores() {
    return totalCPUs;
}

void main() {
    writeln("This computer's processor has ", num_cores, " core(s).");
}
The program uses the function totalCPUs from the D standard library module std.parallelism to get the number of cores.

To use it, download and install a D compiler such as DMD, the Digital Mars D compiler (or LDC or GDC). Use of DMD is shown here.

Then compile the program with:
dmd num_cores.d
Then run it:
num_cores
Output:
This computer's processor has 4 core(s).

- Vasudev Ram - Online Python training and consulting

Get updates on my software products / ebooks / courses.

Jump to posts: Python   DLang   xtopdf

Subscribe to my blog by email

My ActiveState recipes



Sunday, July 31, 2016

deltildefiles: D language utility to recursively delete vim backup files

By Vasudev Ram

~

Here's a small utility I wrote in D (the D programming language). The utility is called deltildefiles (for "delete tilde files"). It lets you delete all files whose names end in "~", the tilde character (Wikipedia), under a specified directory, recursively, i.e. including such files found in sub-directories.

[ BTW, check out the Wikipedia article about tilde, linked above. It has many interesting uses in various domains, not just computer programming, for example, in physics, mathematics, economics, electronics and even juggling :) ]

The vim editor (if the option :se backup is set) names its backups of the files you edit, with the same file name as the original file, plus a tilde at the end. Of course, you can do the same task as this utility deltildefiles, with just a batch file (or two) which uses DEL (with or without /S) on Windows), so I just wrote this for fun and learning. However, if you want to enhance the task with other conditions, etc., then a program (or at least a script, in Python, Perl or other language) may be the better way to go, rather than writing an awkward batch file (even if that is possible) or using PowerShell (haven't used the latter). Another alternative is to use a shell script on Linux, or if you use Cygwin or other Unix emulation on Windows, to use the find and rm commands, that come with it, like:

$ find $dirName -print -name '*~' -exec rm {} \; # or some variation

Be careful with the above command. If you make a typing mistake, like omitting the ~, it could end up deleting the wrong files, and potentially many of them. This is also one reason to make the command into a binary (like I have done) or a shell script, test it thoroughly with dummy / safe data, and from then onward, only use that, instead of typing the find command each time - at least for commands that can delete data or cause other damage.

Anyway, here is the code for deltildefiles.d:
/****************************************************************
File: deltildefiles.d
Purpose: To delete vim backup files, i.e. files ending with ~.
Compile with:
$ dmd deltildefiles.d

Author: Vasudev Ram
Copyright 2016 Vasudev Ram
Web site: https://vasudevram.github.io
Products: https://gumroad.com/vasudevram

Description: To delete all files whose names end with 
the tilde character (~) in the directory subtree 
specified as the command-line argument. 

When you edit a file abc.txt with the vim editor, it will 
first make a backup in the file abc.txt~ (note ~ character
at end of file name). Over time, these files can accumulate.
This utility helps you to delete all such vim backup files 
in a specified directory and its subdirectories.

Use with caution and at your own risk!!!
On most operating systems, once a file is deleted this way
(versus sending to the Recycle Bin on Windows), it is not 
recoverable, unless you have installed some undelete utility.
****************************************************************/

import std.stdio;
import std.file;

void usage(string[] args) {
    stderr.writeln("Usage: ", args[0], " dirName");
    stderr.writeln(
        "Recursively delete files whose names end with ~ under dirName.");
}

int main(string[] args) {
    if (args.length != 2) {
        usage(args);
        return 1;
    }
    string dirName = args[1];
    // Check if dirName exists.
    if (!exists(dirName)) {
        stderr.writeln("Error: ", dirName, " not found. Exiting.");
        return 1;
    }
    // Check if dirName is not the NUL device and is actually a directory.
    if (dirName == "NUL" || !DirEntry(dirName).isDir()) {
        stderr.writeln("Error: ", dirName, " is not a directory. Exiting.");
        return 1;
    }
    try {
        foreach(DirEntry de; dirEntries(args[1], "*~", SpanMode.breadth)) {
            // The isFile() check may be enough, also need to check for
            // Windows vs POSIX behavior.
            if (de.isFile() && !de.isDir()) {
                writeln("Deleting ", de.name());
                remove(de.name());
            }
        }
    } catch (FileException) {
        stderr.writeln("Caught a FileException. Exiting.");
        return 1;
    } catch (Exception) {
        stderr.writeln("Caught an Exception. Exiting.");
        return 1;
    }
    return 0;
}
Compile it with:
$ dmd deltildefiles.d
And you can run it like this:
$ deltildefiles .
which will delete all files ending in ~, in and under the current directory. If you give a file name instead of a directory name, or if you give a non-existent directory name, it gives an error message and exits.

It seems to work as of now, based on some testing I did. May have a few bugs since I haven't tested it exhaustively. May make a few improvements to it over time, such as generalizing from ~ to filename wildcards, more error handling, verbose / quiet flags, etc.

Translate this post into another language with Google Translate
(and, just for kicks, click the speaker icon below the right hand side text box at the above Translate page :).

- Vasudev Ram - Online Python training and consulting

Follow me on Gumroad to get email updates about my products.


My Python posts     Subscribe to my blog by email

My ActiveState recipes