Program name

From Rosetta Code
Revision as of 01:59, 6 August 2011 by rosettacode>Mcandre (Added LLVM)
Program name is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

It is useful to programmatically access a program's name, e.g. for determining whether the user ran "python hello.py", or "python hellocaller.py", a program importing the code from "hello.py".

Examples from GitHub.

C

It might not be very useful for a C program to access source filenames, because C code must be compiled into an executable, and anything could have happened to the source file after the compilation. However, C can access the executable's filename.

<lang c>#include <stdio.h>

int main(int argc, char **argv) { printf("Executable: %s\n", argv[0]);

return 0; }</lang>

To get the source information about some part of code, use compiler defined macros. Most compilers support them or some variation of. <lang c>#include <stdio.h>

int main() { printf("This code was in file %s in function %s, at line %d\n", __FILE__, __FUNCTION__, __LINE__); return 0; }</lang>

C++

C++ has difficulty accessing source code filenames, because C code must be compiled into an executable. However, C++ can access the executable's filename.

<lang cpp>#include <iostream>

using namespace std;

int main(int argc, char **argv) { char *program = argv[0]; cout << "Program: " << program << endl;

return 0; }</lang>

Chicken Scheme

Getting the program name is tricky. When interpreted, the script name will be printed. When compiled, the executable name will be printed.

<lang scheme>#!/bin/bash

  1. |

exec csi -ss $0 ${1+"$@"} exit |#

(use posix) (require-extension srfi-1) ; lists (require-extension srfi-13) ; strings

(define (main args) (let ((prog (cdr (program)))) (display (format "Program: ~a\n" prog)) (exit)))

(define (program) (if (string=? (car (argv)) "csi") (let ((s-index (list-index (lambda (x) (string-contains x "-s")) (argv)))) (if (number? s-index) (cons 'interpreted (list-ref (argv) (+ 1 s-index))) (cons 'unknown ""))) (cons 'compiled (car (argv)))))

(if (equal? (car (program)) 'compiled) (main (cdr (argv))))</lang>

Clojure

If the shebang is used to run the script directly, this prints the script name. Otherwise, it prints nil.

<lang clojure>":";exec clj -m `basename $0 .clj` $0 ${1+"$@"} ":";exit

(ns scriptname (:gen-class))

(defn -main [& args] (def program (nth args 0)) (println "Program:" program))</lang>

Common Lisp

Shebangs require a special tweak to ~/.clisprc.lisp.

<lang lisp>;;; Play nice with shebangs (set-dispatch-macro-character #\# #\!

(lambda (stream character n)
 (declare (ignore character n))
 (read-line stream nil nil t)
 nil))</lang>

<lang lisp>#!/bin/bash

  1. |

exec clisp -q -q $0 $0 ${1+"$@"} exit |#

Usage
./scriptname.lisp

(defun main (args)

(let ((program (car args)))
 (format t "Program: ~a~%" program)
 (quit)))
With help from Francois-Rene Rideau
http://tinyurl.com/cli-args

(let ((args

      #+clisp ext:*args*
      #+sbcl sb-ext:*posix-argv*
      #+clozure (ccl::command-line-arguments)
      #+gcl si:*command-args*
      #+ecl (loop for i from 0 below (si:argc) collect (si:argv i))
      #+cmu extensions:*command-line-strings*
      #+allegro (sys:command-line-arguments)
      #+lispworks sys:*line-arguments-list*
    ))
 (if (member (pathname-name *load-truename*)
             args
             :test #'(lambda (x y) (search x y :test #'equalp)))
   (main args)))</lang>

D

Will print name of executable. <lang d>import std.stdio;

void main(string[] args) {

   writeln(args[0]);	

}</lang>

Emacs Lisp

<lang lisp>:;exec emacs -batch -l $0 -f main $*

Shebang from John Swaby
http://www.emacswiki.org/emacs/EmacsScripts

(defun main ()

(let ((program (nth 2 command-line-args)))
 (message "Program: %s" program)))</lang>

Erlang

Erlang's macros hold information about the running module.

<lang erlang>-module(scriptname).

main(_) -> Program = ?FILE, io:format("Program: ~s~n", [Program]).</lang>

Haskell

Haskell has an impure function for this.

<lang haskell>#!/usr/bin/env runhaskell

module ScriptName where

import System (getProgName)

main :: IO () main = do program <- getProgName putStrLn $ "Program: " ++ program</lang>

Java

Java mainly has notions of classes.

<lang java>public class ScriptName { public static void main(String[] args) { String program = new ScriptName().getClass().getName(); System.out.println("Program: " + program); } }</lang>

LLVM

Like C, LLVM can use argv to access the executable's filename.

<lang sh>$ make llvm-as scriptname.ll llc scriptname.bc gcc -o scriptname scriptname.s ./scriptname Program: ./scriptname</lang>

Makefile

<lang make>all: scriptname.ll llvm-as scriptname.ll llc scriptname.bc gcc -o scriptname scriptname.s ./scriptname

clean: -rm scriptname -rm scriptname.s -rm scriptname.bc</lang>

<lang llvm>@msg_main = internal constant [13 x i8] c"Program: %s\0A\00"

declare i32 @printf(i8* noalias nocapture, ...)

define i32 @main(i32 %argc, i8** %argv) { %program = load i8** %argv call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @msg_main, i32 0, i32 0), i8* %program)

ret i32 0 }</lang>

Lua

Lua's arg is like C's argv.

<lang lua>#!/usr/bin/env lua

function main(arg) local program = arg[0] print("Program: " .. program) end

if type(package.loaded[(...)]) ~= "userdata" then main(arg) else module(..., package.seeall) end</lang>

newLISP

newLISP has a function, (main-args int) for this.

<lang lisp>#!/usr/bin/env newlisp

(let ((program (main-args 1)))

 (println (format "Program: %s" program))
 (exit))</lang>

Node.js

Node.js has a global variable for this.

<lang javascript>#!/usr/bin/env node /*jslint nodejs:true */

function main() { var program = __filename; console.log("Program: " + program); }

if (!module.parent) { main(); }</lang>

Perl

<lang perl>#!/usr/bin/env perl

use strict; use warnings;

sub main { my $program = $0; print "Program: $program\n"; }

unless(caller) { main; }</lang>

Perl 6

In Perl 6, the name of the program being executed is in the special global variable $*PROGRAM_NAME. <lang perl6>say $*PROGRAM_NAME;</lang>

PHP

PHP has a global dictionary for this.

<lang php><?php $program = $_SERVER["SCRIPT_NAME"]; echo "Program: $program\n"; ?></lang>

Python

<lang python>#!/usr/bin/env python

import inspect

def main(): program = inspect.getfile(inspect.currentframe()) print "Program: %s" % program

if __name__=="__main__": main()</lang>

R

R's syntax is complicated, but doable.

<lang R>#!/usr/bin/env Rscript

getProgram <- function(args) { sub("--file=", "", args[grep("--file=", args)]) }

args <- commandArgs(trailingOnly = FALSE) program <- getProgram(args)

cat("Program: ", program, "\n")

q("no")</lang>

Ruby

<lang ruby>#!/usr/bin/env ruby

def main program = __FILE__ puts "Program: #{program}" end

if __FILE__==$0 main end</lang>

Tcl

<lang tcl>#!/usr/bin/env tclsh

proc main {args} {

   set program $::argv0
   puts "Program: $program"

}

if {$::argv0 eq [info script]} {

   main {*}$::argv

}</lang>

UNIX Shell

In Bash: <lang sh>#!/usr/bin/env sh

export program=$BASH_SOURCE echo "Program: $program"</lang>