Previous Post | Top | Next Post |
TOC
This was originally written and created around 2013 and may require to be updated. (2021)
CLI programs
The command line interface (CLI) program requires to parse its command line arguments. Here are simple example code snippets.
Please note I chose the coding style which is the most legible for each language. I know there are other ways …
Shell
Shell script (short option only)
Shell program with short command line options.
Source code for the shell script: cli_s
#!/bin/sh
verbose=0
while getopts "af:v" opt ; do
case $opt in
a) echo "Option a"
;;
f) cat "$OPTARG"
;;
v) verbose=1
;;
-) break
;;
?) echo "Usage: $0: [-a] [-v] [-f file] args ..."
exit 1
;;
esac
done
shift $(($OPTIND - 1))
printf "Remaining arguments are: %s\n" "$*"
Please note shell variables are used.
- OPTARG : option argument
- OPTIND : index of the next element to be processed
TIP: No long option like “--file ...
”.
The POSIX getopts
is available as a shell buildin command of BASH/DASH.
(Please note s
at the end. The older Bell Labs derived external command is
called getopt
.)
Shell script (long and short option)
Shell program with long and short command line options.
Source code for the shell script: cli_l
#!/bin/sh
verbose=0
while [ "$#" -gt "0" ]; do
case $1 in
-a) echo "Option a"
;;
-f|--file)
shift
cat $1
;;
-v) verbose=1
;;
--long) echo "Option long"
;;
--longextra)
shift
echo "Option longextra with $1"
;;
--) shift
break
;;
-*) echo "Unknown option: $1"
echo "Usage: $0 [-a] [-f|--file file] [-v] args ..."
exit 1
;;
*) break
;;
esac
shift
done
printf "Remaining arguments are: %s\n" "$*"
TIP: You must type as “-a -f ...
” and not as “-af ...
”
Here I avoided the use of getopts
/getopt
for long option support to gain maximum portability.
Python
Python script with argparse
Simple example program with long and short command line options.
Source code for Python with argparse
#!/usr/bin/python3
# vim:se tw=0 sts=4 ts=4 et cindent:
def main():
import argparse, sys
parser = argparse.ArgumentParser(description='This is skelton program.')
parser.add_argument('-a', action="store_true", dest="opt_a",
default=False, help='operation mode')
parser.add_argument('-f', '--file', action="store", dest="filename",
help='input filename')
parser.add_argument('-v', action="store_true", dest="verbose",
default=False, help='vebosity')
parser.add_argument('args', nargs='*', help='arguments')
parser.add_argument('--long', action="store_true", dest="opt_long",
help='long mode')
parser.add_argument('--longextra', action="store", dest="long",
help='long extra mode')
args = parser.parse_args()
if args.opt_a:
print("option a")
if args.filename:
print("filename = " + args.filename)
with open(args.filename) as f:
for line in f:
print (line[:-1])
if args.verbose:
print("option verbose")
if args.opt_long:
print("option long")
if args.long:
print("longextra = " + args.long)
if args.args:
print("args = " , args.args)
if __name__ == '__main__':
main()
Execution examples with auto generated help
$ ./cli --help
usage: cli [-h] [-a] [-f FILENAME] [-v] [--long] [--longextra LONG]
[args [args ...]]
This is skelton program.
positional arguments:
args arguments
optional arguments:
-h, --help show this help message and exit
-a operation mode
-f FILENAME, --file FILENAME
input filename
-v vebosity
--long long mode
--longextra LONG long extra mode
$ ./cli -avf BOGUS.txt --long --longextra=FOO cli BOGUS.txt
option a
filename = BOGUS.txt
This is BOGUS.txt here.
EOF here :-)
option verbose
option long
longextra = FOO
args = ['cli', 'BOGUS.txt']
$ ./cli -b
usage: cli [-h] [-a] [-f FILENAME] [-v] [--long] [--longextra LONG]
[args [args ...]]
cli: error: unrecognized arguments: -b
TIP: Older programs may use getopt
module which is not as object oriented as argparse
.
See:
- “argparse” in “The Python Standard Library”.
- “Argparse Tutorial” in “Python HOWTOs”.
- Comments in the file such as
/usr/lib/python3.2/argparse.py
providing theargparse
module.
Actual module file on the system can be obtained by running The Python interpreter interactively as follows.
$ /usr/bin/python3 -q
>>> import argparse
>>> print (argparse.__file__)
/usr/lib/python3.2/argparse.py
Python script with cliapp
cliapp is a Python framework for Unix-like command line programs and provides a unified supports for the command line and the configuration file.
This seems to be interesting and is used by the backup program obnam
(1).
Source code for Python with cliapp
#!/usr/bin/env python
# vim:se tw=0 sts=4 ts=4 et cindent:
'''
Example using cliapp framework. (Python2 only)
'''
import cliapp
import logging
class ExampleApp(cliapp.Application):
def add_settings(self):
self.settings.boolean(['append', 'a'], 'append mode')
self.settings.string(['file', 'f'], 'configuration filename',
metavar='FILENAME')
self.settings.boolean(['verbose', 'v'], 'verbose mode')
self.settings.boolean(['long'], 'long mode')
self.settings.string(['longextra'], 'longextra mode',
metavar='LONG')
def process_inputs(self, args):
self.counts = 0
cliapp.Application.process_inputs(self, args)
self.output.write('There were %s lines in %s.\n'
% (self.counts, args))
print('append=%s' % self.settings['append'])
print('verbose=%s' % self.settings['verbose'])
print('long=%s' % self.settings['long'])
print('longextra=%s' % self.settings['longextra'])
if self.settings['file']:
print("filename = %s" % self.settings['file'])
with open(self.settings['file']) as f:
for line in f:
print (line[:-1])
def process_input_line(self, name, line):
self.counts += 1
if __name__ == '__main__':
app = ExampleApp('Cli', version='0.1',
description="Cli as a command line program example",
epilog="Copyright (C) 2012 Osamu Aoki")
app.settings.config_files = ['example.conf']
app.run()
Execution examples with auto generated help
$ ./cli --help
Usage: Cli [options]
Cli as a command line program example
Options:
--version show program's version number and exit
-h, --help show this help message and exit
--output=FILE write output to FILE, instead of standard output
-a, --append append mode
--no-append
-f FILENAME, --file=FILENAME
configuration filename
-v, --verbose verbose mode
--no-verbose
--long long mode
--no-long
--longextra=LONG longextra mode
Configuration files and settings:
--dump-config write out the entire current configuration
--no-default-configs
clear list of configuration files to read
--config=FILE add FILE to config files
--help-all show all options
Logging:
--log=FILE write log entries to FILE (default is to not write log
files at all); use "syslog" to log to system log, or
"none" to disable logging
--log-level=LEVEL log at LEVEL, one of debug, info, warning, error,
critical, fatal (default: debug)
--log-max=SIZE rotate logs larger than SIZE, zero for never (default:
0)
--log-keep=N keep last N logs (10)
--log-mode=MODE set permissions of new log files to MODE (octal;
default 0600)
Peformance:
--dump-memory-profile=METHOD
make memory profiling dumps using METHOD, which is one
of: none, simple, meliae, or heapy (default: simple)
--memory-dump-interval=SECONDS
make memory profiling dumps at least SECONDS apart
Copyright (C) 2012 Osamu Aoki
$ ./cli -avf BOGUS.txt --long --longextra=FOO cli BOGUS.txt
There were 45 lines in ['cli', 'BOGUS.txt'].
append=True
verbose=True
long=True
longextra=FOO
filename = BOGUS.txt
This is BOGUS.txt here.
EOF here :-)
$ ./cli -b
Usage: Cli [options]
Cli: error: no such option: -b
Lua
Lua script (long and short option)
Simple example program with long and short command line options.
Source code for the Lua script: cli
#!/usr/bin/lua
verbose = 0
i = 1
while (i <= #arg) do
if (arg[i] == '-a') then
print("Option a")
elseif (arg[i] == '-f' or arg[i] == '--file') then
i = i +1
for line in io.lines(arg[i]) do
print(line)
end
elseif (arg[i] == '-v') then
verbose = 1
elseif (arg[i] == '--long') then
print("Option long")
elseif (string.sub(arg[i],1,11) == '--longextra') then
print("Option longextra with " .. string.sub(arg[i], 13))
elseif (arg[i] == '--') then
i = i +1
break
elseif (string.sub(arg[i], 1, 1) == '-') then
print("Unknown option: " .. arg[i])
print("Usage: " .. arg[0] ..
" [-a] [-f|--file file] [-v] [--long] [--longextra=value] [args...]")
return(1)
else
break
end
i = i + 1
end
i0 = i - 1
for i = 1, #arg - i0, 1 do
print("ARG[" .. i .. "] = " .. arg[i + i0])
end
Execution examples with auto generated help
$ ./cli --help
Unknown option: --help
Usage: ./cli [-a] [-f|--file file] [-v] [--long] [--longextra=value] [args...]
$ ./cli -a -v -f BOGUS.txt --long --longextra=FOO cli BOGUS.txt
Option a
Option long
Option longextra with FOO
ARG[1] = cli
ARG[2] = BOGUS.txt
$ ./cli -b
Unknown option: -b
Usage: ./cli [-a] [-f|--file file] [-v] [--long] [--longextra=value] [args...]
TIP: You must type as “-a -f ...
” and not as “-af ...
”
Perl
Perl script with Getopt::Long
Simple example program with long and short command line options.
Source code for Perl with Getopt::Long
#!/usr/bin/perl -w
use strict;
use Getopt::Long;
# Global variables
use vars qw(%opt $verbose $helpmsg);
%opt = ();
$verbose = 0;
$helpmsg = "Usage: $0 [-a] [-v] [-f|--file name] [--long] [--longextra extra]...\n";
sub main()
{
&GetOptions(
"a"=>\$opt{'a'},
"f|file=s"=>\$opt{'f'},
"h|help"=>\$opt{'h'},
"v"=>\$opt{'v'},
"long"=>\$opt{'long'},
"longextra=s"=>\$opt{'longextra'}) or die $helpmsg;
if ($opt{'a'}) {
print "Option a\n";
}
if ($opt{'h'}) {
print $helpmsg;
}
if ($opt{'f'}) {
print("Option f with $opt{'f'}\n");
open(INPUT_FILE, $opt{'f'})
or die "Couldn't open $opt{'f'}!";
while (<INPUT_FILE>) {
print "$_";
}
close(INPUT_FILE)
}
if ($opt{'v'}) {
$verbose = 1;
}
if ($opt{'long'}) {
print "Option long\n";
}
if ($opt{'longextra'}) {
print "Option f with $opt{'longextra'}\n";
}
if ($ARGV[0]) {
print "Other things found on the command line:\n";
}
foreach (@ARGV) {
print "ARG=$_\n";
}
}
main();
TIP: Older programs with short command line options may use functions such as
getopt("af:v")
or getopts("af:v")
with use Getopt::Std;
which set global
variables $opt_a
, $opt_f
, $opt_v
.
Execution examples with auto generated help
$ ./cli --help
Usage: ./cli [-a] [-v] [-f|--file name] [--long] [--longextra extra]...
$ ./cli -a -v -f BOGUS.txt --long --longextra=FOO cli BOGUS.txt
Option a
Option f with BOGUS.txt
This is BOGUS.txt here.
EOF here :-)
Option long
Option f with FOO
Other things found on the command line:
ARG=cli
ARG=BOGUS.txt
$ ./cli -b
Unknown option: b
Usage: ./cli [-a] [-v] [-f|--file name] [--long] [--longextra extra]...
C
Writing a code with the iteration over unknown length lines is not easy with C since it requires dynamic memory allocation for the line buffer. We will come back to such coding later.
C with getopt()
Simple example program with short command line options.
Source code for C with getopt()
/* a short command line option example */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h> /* getopt */
int main(int argc, char **argv)
{
int c;
int verbose = 0;
while ((c = getopt(argc, argv, "af:v")) != -1) {
switch (c) {
case 'a':
printf("option a\n");
break;
case 'f':
printf("option f with %s.\n", optarg);
break;
case 'v':
verbose = 1;
break;
default:
printf("unknown option = %c = ascii(0%x)\n",
optopt, optopt);
printf("return value of getopt() = %c\n", c);
}
}
printf("verbose mode = %i\n", verbose);
if (optind < argc) {
int j = 1;
while (optind < argc) {
printf("argument[%i]=%s\n", j, argv[optind++]);
j++;
}
}
return EXIT_SUCCESS;
}
Please note few global external variables used.
char *optarg
: pointer to the option argument stringint optind
: index for the next argument to be processedint opterr
: set to zero for quieting error messageint optopt
:
C with getopt_long()
Simple example program with long and short command line options.
Source code for C with getopt_long()
/* a long command line option example */
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h> /* getopt_long */
int main(int argc, char **argv)
{
int c;
int i = 0;
int verbose = 0;
static struct option longopts[] = {
{"append", no_argument, 0, 'a'},
{"verbose", no_argument, 0, 'v'},
{"file", required_argument, 0, 'f'},
{"long", no_argument, 0, 0},
{"longextra", required_argument, 0, 0},
{NULL, 0, NULL, 0}
};
while ((c = getopt_long(argc, argv, "af:v", longopts, &i)) != -1) {
switch (c) {
case 0: /* for longopts[all][3] == 0 */
printf ("option %s", longopts[i].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case 'a':
printf("option a\n");
break;
case 'f':
printf("option f with %s.\n", optarg);
break;
case 'v':
verbose = 1;
break;
default:
printf("unknown option = %c = ascii(0%x)\n", optopt, optopt);
printf("return value of getopt_long() = %c\n", c);
}
}
printf("verbose mode = %i\n", verbose);
if (optind < argc) {
int j = 1;
while (optind < argc) {
printf("argument[%i]=%s\n", j, argv[optind++]);
j++;
}
}
return EXIT_SUCCESS;
}
Please note few global external variables used just like getopt()
.
In order to avoid GNU vs. BSD incompatibility, the following may be a good idea:
- Do not define
-W
option. - Third component of
longopts[]
must be 0. (as in the above example) - Always put all of arguments after all the options when calling the compiled program with
getopt_long()
.
See FreeBSD 8.0 getopt_long(3) manual.
C++
The golden rule of C++ programing: “If you can not find something in the C++ Standard Library, look for it in Boost libraries.”
- http://gcc.gnu.org/onlinedocs/gcc-4.7.1/libstdc++/manual/[The GNU C++ Library]
- http://gcc.gnu.org/onlinedocs/gcc-4.7.1/libstdc++/api/[libstdc++ Source Documentation]
- Boost C++ Libraries
Simple example program with long and short command line options.
Source code for C++ with boost::program_options
#include <boost/program_options.hpp>
#include <iostream>
#include <iterator>
#include <stdlib.h>
using namespace std;
// A helper function to simplify the main part.
template<class T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
copy(v.begin(), v.end(), ostream_iterator<T>(cout, " "));
return os;
}
int main(int argc, char **argv)
{
string file;
string extra;
try {
namespace po = boost::program_options;
po::options_description visible("SYNTAX: cli [OPTION ...] files ...");
visible.add_options()
("append,a", "append option")
("help,h", "help message")
("verbose,v", "verbose option")
("file,f", po::value<string>(&file), "file option")
("long", "long option")
("longextra", po::value<string>(&extra), "longextra option")
;
po::options_description hidden;
hidden.add_options()
("input-file", po::value< vector<string> >(), "input file")
;
po::positional_options_description p;
p.add("input-file", -1);
po::options_description desc;
desc.add(visible).add(hidden);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv)
.options(desc).positional(p).run(), vm);
po::notify(vm);
if (vm.count("help")) {
cout << visible << "\n";
return EXIT_FAILURE;
}
if (vm.count("append")) {
cout << "append mode\n";
}
if (vm.count("verbose")) {
cout << "verbose mode\n";
}
if (vm.count("file")) {
cout << "Filename: "
<< file << "\n";
} else {
cout << "Filename: (unset)\n";
}
if (vm.count("long")) {
cout << "long mode\n";
}
if (vm.count("longextra")) {
cout << "Longextra: "
<< extra << "\n";
} else {
cout << "Longextra: (unset)\n";
}
if (vm.count("input-file")) {
cout << "Input files are: "
<< vm["input-file"].as< vector<string> >() << "\n";
}
}
catch(exception& e) {
cerr << "E: " << e.what() << "\n";
return EXIT_FAILURE;
}
catch(...) {
cerr << "E: unknown type!\n";
}
return EXIT_SUCCESS;
}
Let’s compile cli.cxx
to create the ELF object cli
and run it.
$ g++ -Wall -lboost_program_options -o cli cli.cxx
$ ./cli -avf BOGUS.txt --long --longextra=FOO X1 X2
append mode
verbose mode
Filename: BOGUS.txt
long mode
Longextra: FOO
Input files are: X1 X2
$ ./cli -b
E: unknown option -b
$ ./cli --help
SYNTAX: cli [OPTION ...] files ...:
-a [ --append ] append option
-h [ --help ] help message
-v [ --verbose ] verbose option
-f [ --file ] arg file option
--long long option
--longextra arg longextra option
Vala
Simple Vala example programs with long and short command line options using GLib.
Simple non-OOP style (no class)
Source code cli-1.vala
in Vala language
static bool append = false;
static bool verbose = false;
static bool op_long = false;
static string filename = null;
static string longextra = null;
// sources is a string array containing all non-option arguments
// https://mail.gnome.org/archives/vala-list/2009-March/msg00090.html
[CCode (array_length = false, array_null_terminated = true)]
static string[] sources;
const OptionEntry[] options = {
{ "append", 'a', 0, OptionArg.NONE, ref append,
"Set append mode", null },
{ "verbose", 'v', 0, OptionArg.NONE, ref verbose,
"Set verbose mode", null },
{ "file", 'f', 0, OptionArg.FILENAME, ref filename,
"Use F file", "F"},
{ "long", 0, 0, OptionArg.NONE, ref op_long,
"Set long mode", null },
{ "longextra", 0, 0, OptionArg.STRING, ref longextra,
"Set longextra to M", "M" },
{ "", 0, 0, OptionArg.FILENAME_ARRAY, ref sources,
null, "FILE..." },
{ null }
};
int main (string[] args) {
// initialize locale
Intl.setlocale (LocaleCategory.ALL, "");
//
stdout.printf ("command = %s\n", args[0]);
stdout.printf ("basename = %s\n", Path.get_basename(args[0]));
try {
// parse command line options with GLib
var opt_context = new OptionContext ("- Cli");
opt_context.set_help_enabled (true);
opt_context.add_main_entries (options, null);
opt_context.parse (ref args);
} catch (OptionError e) {
stdout.printf ("%s\n", e.message);
stdout.printf (
"Run '%s --help' to see a full list of available command line options.\n",
args[0]);
return 1;
}
// print variables
if (verbose) {
stdout.printf ("Cli: verbose ON\n");
}
if (append) {
stdout.printf ("Cli: appemd ON\n");
}
if (op_long) {
stdout.printf ("Cli: long ON\n");
}
if (filename != null) {
stdout.printf ("Cli: file = %s\n", filename);
}
if (longextra != null) {
stdout.printf ("Cli: longextra = %s\n", longextra);
}
if (sources != null) {
int i = 0;
foreach (string s in sources) {
stdout.printf("sources[%i]=%s\n", i, s);
i++;
}
}
return 0;
}
TIP: The above example skips specifying GLib
for the parent class since it is
the default for Vala.
Let’s compile cli-1.vala
to create the ELF object cli-1
and run it.
$ valac -v cli-1.vala
/path/to/vala/cli-1.vala.c: In function ‘main’:
/path/to/vala/cli-1.vala.c:204:2: warning: ‘g_type_init’ is deprecated (declared ...
g_type_init ();
^
Loaded package `/usr/share/vala-0.20/vapi/glib-2.0.vapi'
Loaded package `/usr/share/vala-0.20/vapi/gobject-2.0.vapi'
cc -o '/path/to/vala/cli-1' '/path/to/vala/cli-1.vala.c' -I/usr/include/glib-2.0 ...
$ ./cli-1 -avf BOGUS.txt --long --longextra=FOO X1 X2
command = ./cli-1
basename = cli-1
Cli: verbose ON
Cli: appemd ON
Cli: long ON
Cli: file = BOGUS.txt
Cli: longextra = FOO
sources[0]=X1
sources[1]=X2
$ ./cli-1 -b
command = ./cli-1
basename = cli-1
Unknown option -b
Run './cli-1 --help' to see a full list of available command line options.
$ ./cli-1 --help
command = ./cli-1
basename = cli-1
Usage:
cli-1 [OPTION...] FILE... - Cli
Help Options:
-h, --help Show help options
Application Options:
-a, --append Set append mode
-v, --verbose Set verbose mode
-f, --file=F Use F file
--long Set long mode
--longextra=M Set longextra to M
You can get the C source as:
$ valac -C cli-1.vala
$ wc -l cli-1.vala ; wc -l cli-1.c
75 cli-1.vala
221 cli-1.c
$ cat cli-1.c |sed -e 's/ / /g'|fold # tab => 4 spaces
/* cli-1.c generated by valac 0.20.1, the Vala compiler
* generated from cli-1.vala, do not modify */
#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <stdio.h>
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_option_context_free0(var) ((var == NULL) ? NULL : (var = (g_option_co
ntext_free (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var),
NULL)))
extern gboolean append;
gboolean append = FALSE;
extern gboolean verbose;
gboolean verbose = FALSE;
extern gboolean op_long;
gboolean op_long = FALSE;
extern gchar* filename;
gchar* filename = NULL;
extern gchar* longextra;
gchar* longextra = NULL;
extern gchar** sources;
gchar** sources = NULL;
gint _vala_main (gchar** args, int args_length1);
static gint _vala_array_length (gpointer array);
const GOptionEntry options[7] = {{"append", 'a', 0, G_OPTION_ARG_NONE, &append,
"Set append mode", NULL}, {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Set
verbose mode", NULL}, {"file", 'f', 0, G_OPTION_ARG_FILENAME, &filename, "Use F
file", "F"}, {"long", (gchar) 0, 0, G_OPTION_ARG_NONE, &op_long, "Set long mode"
, NULL}, {"longextra", (gchar) 0, 0, G_OPTION_ARG_STRING, &longextra, "Set longe
xtra to M", "M"}, {"", (gchar) 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &sources, NULL
, "FILE..."}, {NULL}};
gint _vala_main (gchar** args, int args_length1) {
gint result = 0;
FILE* _tmp0_;
gchar** _tmp1_;
gint _tmp1__length1;
const gchar* _tmp2_;
FILE* _tmp3_;
gchar** _tmp4_;
gint _tmp4__length1;
const gchar* _tmp5_;
gchar* _tmp6_ = NULL;
gchar* _tmp7_;
gboolean _tmp18_;
gboolean _tmp20_;
gboolean _tmp22_;
const gchar* _tmp24_;
const gchar* _tmp27_;
gchar** _tmp30_;
gint _tmp30__length1;
GError * _inner_error_ = NULL;
setlocale (LC_ALL, "");
_tmp0_ = stdout;
_tmp1_ = args;
_tmp1__length1 = args_length1;
_tmp2_ = _tmp1_[0];
fprintf (_tmp0_, "command = %s\n", _tmp2_);
_tmp3_ = stdout;
_tmp4_ = args;
_tmp4__length1 = args_length1;
_tmp5_ = _tmp4_[0];
_tmp6_ = g_path_get_basename (_tmp5_);
_tmp7_ = _tmp6_;
fprintf (_tmp3_, "basename = %s\n", _tmp7_);
_g_free0 (_tmp7_);
{
GOptionContext* _tmp8_;
GOptionContext* opt_context;
GOptionContext* _tmp9_;
GOptionContext* _tmp10_;
GOptionContext* _tmp11_;
_tmp8_ = g_option_context_new ("- Cli");
opt_context = _tmp8_;
_tmp9_ = opt_context;
g_option_context_set_help_enabled (_tmp9_, TRUE);
_tmp10_ = opt_context;
g_option_context_add_main_entries (_tmp10_, options, NULL);
_tmp11_ = opt_context;
g_option_context_parse (_tmp11_, &args_length1, &args, &_inner_error_);
if (_inner_error_ != NULL) {
_g_option_context_free0 (opt_context);
if (_inner_error_->domain == G_OPTION_ERROR) {
goto __catch0_g_option_error;
}
_g_option_context_free0 (opt_context);
g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FIL
E__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain)
, _inner_error_->code);
g_clear_error (&_inner_error_);
return 0;
}
_g_option_context_free0 (opt_context);
}
goto __finally0;
__catch0_g_option_error:
{
GError* e = NULL;
FILE* _tmp12_;
GError* _tmp13_;
const gchar* _tmp14_;
FILE* _tmp15_;
gchar** _tmp16_;
gint _tmp16__length1;
const gchar* _tmp17_;
e = _inner_error_;
_inner_error_ = NULL;
_tmp12_ = stdout;
_tmp13_ = e;
_tmp14_ = _tmp13_->message;
fprintf (_tmp12_, "%s\n", _tmp14_);
_tmp15_ = stdout;
_tmp16_ = args;
_tmp16__length1 = args_length1;
_tmp17_ = _tmp16_[0];
fprintf (_tmp15_, "Run '%s --help' to see a full list of available comma
nd line options.\n", _tmp17_);
result = 1;
_g_error_free0 (e);
return result;
}
__finally0:
if (_inner_error_ != NULL) {
g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, _
_LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inn
er_error_->code);
g_clear_error (&_inner_error_);
return 0;
}
_tmp18_ = verbose;
if (_tmp18_) {
FILE* _tmp19_;
_tmp19_ = stdout;
fprintf (_tmp19_, "Cli: verbose ON\n");
}
_tmp20_ = append;
if (_tmp20_) {
FILE* _tmp21_;
_tmp21_ = stdout;
fprintf (_tmp21_, "Cli: appemd ON\n");
}
_tmp22_ = op_long;
if (_tmp22_) {
FILE* _tmp23_;
_tmp23_ = stdout;
fprintf (_tmp23_, "Cli: long ON\n");
}
_tmp24_ = filename;
if (_tmp24_ != NULL) {
FILE* _tmp25_;
const gchar* _tmp26_;
_tmp25_ = stdout;
_tmp26_ = filename;
fprintf (_tmp25_, "Cli: file = %s\n", _tmp26_);
}
_tmp27_ = longextra;
if (_tmp27_ != NULL) {
FILE* _tmp28_;
const gchar* _tmp29_;
_tmp28_ = stdout;
_tmp29_ = longextra;
fprintf (_tmp28_, "Cli: longextra = %s\n", _tmp29_);
}
_tmp30_ = sources;
_tmp30__length1 = _vala_array_length (sources);
if (_tmp30_ != NULL) {
gint i;
gchar** _tmp31_;
gint _tmp31__length1;
i = 0;
_tmp31_ = sources;
_tmp31__length1 = _vala_array_length (sources);
{
gchar** s_collection = NULL;
gint s_collection_length1 = 0;
gint _s_collection_size_ = 0;
gint s_it = 0;
s_collection = _tmp31_;
s_collection_length1 = _tmp31__length1;
for (s_it = 0; s_it < _tmp31__length1; s_it = s_it + 1) {
gchar* _tmp32_;
gchar* s = NULL;
_tmp32_ = g_strdup (s_collection[s_it]);
s = _tmp32_;
{
FILE* _tmp33_;
gint _tmp34_;
const gchar* _tmp35_;
gint _tmp36_;
_tmp33_ = stdout;
_tmp34_ = i;
_tmp35_ = s;
fprintf (_tmp33_, "sources[%i]=%s\n", _tmp34_, _tmp35_);
_tmp36_ = i;
i = _tmp36_ + 1;
_g_free0 (s);
}
}
}
}
result = 0;
return result;
}
int main (int argc, char ** argv) {
g_type_init ();
return _vala_main (argv, argc);
}
static gint _vala_array_length (gpointer array) {
int length;
length = 0;
if (array) {
while (((gpointer*) array)[length]) {
length++;
}
}
return length;
}
Since no OOP techniques are used, the resulting C code does not have GObject related macros.
But some libraries from GLib are used, the resulting C code has automatically
generated memory management codes such as _g_option_context_free0
,
_g_error_free0
, and _g_free0
.
OOP style (main outside of class)
Source code cli-2.vala
in Vala language
class Cli : Object {
private static bool append = false;
private static bool verbose = false;
private static bool op_long = false;
private static string filename = null;
private static string longextra = null;
// sources is a string array containing all non-option arguments
// https://mail.gnome.org/archives/vala-list/2009-March/msg00090.html
[CCode (array_length = false, array_null_terminated = true)]
private static string[] sources;
private const OptionEntry[] options = {
{ "append", 'a', 0, OptionArg.NONE, ref append,
"Set append mode", null },
{ "verbose", 'v', 0, OptionArg.NONE, ref verbose,
"Set verbose mode", null },
{ "file", 'f', 0, OptionArg.FILENAME, ref filename,
"Use F file", "F"},
{ "long", 0, 0, OptionArg.NONE, ref op_long,
"Set long mode", null },
{ "longextra", 0, 0, OptionArg.STRING, ref longextra,
"Set longextra to M", "M" },
{ "", 0, 0, OptionArg.FILENAME_ARRAY, ref sources,
null, "FILE..." },
{ null }
};
public int parse (string[] args) {
// parse command line
try {
// parse command line options with GLib
var opt_context = new OptionContext ("- Cli");
opt_context.set_help_enabled (true);
opt_context.add_main_entries (options, null);
opt_context.parse (ref args);
} catch (OptionError e) {
stdout.printf ("%s\n", e.message);
stdout.printf (
"Run '%s --help' to see a full list of available command line options.\n",
args[0]);
return 1;
}
return 0;
}
public int run () {
// print variables
if (verbose) {
stdout.printf ("Cli: verbose ON\n");
}
if (append) {
stdout.printf ("Cli: appemd ON\n");
}
if (op_long) {
stdout.printf ("Cli: long ON\n");
}
if (filename != null) {
stdout.printf ("Cli: file = %s\n", filename);
}
if (longextra != null) {
stdout.printf ("Cli: longextra = %s\n", longextra);
}
if (sources != null) {
int i = 0;
foreach (string s in sources) {
stdout.printf("sources[%i]=%s\n", i, s);
i++;
}
}
return 0;
}
}
int main (string[] args) {
// initialize locale
Intl.setlocale (LocaleCategory.ALL, "");
//
stdout.printf ("command = %s\n", args[0]);
stdout.printf ("basename = %s\n", Path.get_basename(args[0]));
var cli = new Cli ();
cli.parse (args);
return cli.run ();
}
TIP: The above example skips specifying GLib
for the parent class since it is
the default for Vala.
Let’s compile cli-2.vala
to create the ELF object cli-2
and run it.
$ valac -v cli-2.vala
/path/to/vala/cli-2.vala.c: In function ‘main’:
/path/to/vala/cli-2.vala.c:304:2: warning: ‘g_type_init’ is deprecated (declared ...
g_type_init ();
^
Loaded package `/usr/share/vala-0.20/vapi/glib-2.0.vapi'
Loaded package `/usr/share/vala-0.20/vapi/gobject-2.0.vapi'
cc -o '/path/to/vala/cli-2' '/path/to/vala/cli-2.vala.c' -I/usr/include/glib-2.0 ...
$ ./cli-2 -avf BOGUS.txt --long --longextra=FOO X1 X2
command = ./cli-2
basename = cli-2
Cli: verbose ON
Cli: appemd ON
Cli: long ON
Cli: file = BOGUS.txt
Cli: longextra = FOO
sources[0]=X1
sources[1]=X2
$ ./cli-2 -b
command = ./cli-2
basename = cli-2
Unknown option -b
Run './cli-2 --help' to see a full list of available command line options.
$ ./cli-2 --help
command = ./cli-2
basename = cli-2
Usage:
cli-2 [OPTION...] FILE... - Cli
Help Options:
-h, --help Show help options
Application Options:
-a, --append Set append mode
-v, --verbose Set verbose mode
-f, --file=F Use F file
--long Set long mode
--longextra=M Set longextra to M
You can get the C source as:
$ valac -C cli-2.vala
$ wc -l cli-2.vala ; wc -l cli-2.c
86 cli-2.vala
321 cli-2.c
$ cat cli-2.c |sed -e 's/ / /g'|fold # tab => 4 spaces
/* cli-2.c generated by valac 0.20.1, the Vala compiler
* generated from cli-2.vala, do not modify */
#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <locale.h>
#define TYPE_CLI (cli_get_type ())
#define CLI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CLI, Cli))
#define CLI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CLI, CliClass))
#define IS_CLI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CLI))
#define IS_CLI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CLI))
#define CLI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CLI, CliClass
))
typedef struct _Cli Cli;
typedef struct _CliClass CliClass;
typedef struct _CliPrivate CliPrivate;
#define _g_option_context_free0(var) ((var == NULL) ? NULL : (var = (g_option_co
ntext_free (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var),
NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (va
r), NULL)))
struct _Cli {
GObject parent_instance;
CliPrivate * priv;
};
struct _CliClass {
GObjectClass parent_class;
};
static gpointer cli_parent_class = NULL;
static gboolean cli_append;
static gboolean cli_append = FALSE;
static gboolean cli_verbose;
static gboolean cli_verbose = FALSE;
static gboolean cli_op_long;
static gboolean cli_op_long = FALSE;
static gchar* cli_filename;
static gchar* cli_filename = NULL;
static gchar* cli_longextra;
static gchar* cli_longextra = NULL;
static gchar** cli_sources;
static gchar** cli_sources = NULL;
GType cli_get_type (void) G_GNUC_CONST;
enum {
CLI_DUMMY_PROPERTY
};
gint cli_parse (Cli* self, gchar** args, int args_length1);
gint cli_run (Cli* self);
Cli* cli_new (void);
Cli* cli_construct (GType object_type);
static void cli_finalize (GObject* obj);
gint _vala_main (gchar** args, int args_length1);
static gint _vala_array_length (gpointer array);
static const GOptionEntry CLI_options[7] = {{"append", 'a', 0, G_OPTION_ARG_NONE
, &cli_append, "Set append mode", NULL}, {"verbose", 'v', 0, G_OPTION_ARG_NONE,
&cli_verbose, "Set verbose mode", NULL}, {"file", 'f', 0, G_OPTION_ARG_FILENAME,
&cli_filename, "Use F file", "F"}, {"long", (gchar) 0, 0, G_OPTION_ARG_NONE, &c
li_op_long, "Set long mode", NULL}, {"longextra", (gchar) 0, 0, G_OPTION_ARG_STR
ING, &cli_longextra, "Set longextra to M", "M"}, {"", (gchar) 0, 0, G_OPTION_ARG
_FILENAME_ARRAY, &cli_sources, NULL, "FILE..."}, {NULL}};
gint cli_parse (Cli* self, gchar** args, int args_length1) {
gint result = 0;
GError * _inner_error_ = NULL;
g_return_val_if_fail (self != NULL, 0);
{
GOptionContext* _tmp0_;
GOptionContext* opt_context;
GOptionContext* _tmp1_;
GOptionContext* _tmp2_;
GOptionContext* _tmp3_;
_tmp0_ = g_option_context_new ("- Cli");
opt_context = _tmp0_;
_tmp1_ = opt_context;
g_option_context_set_help_enabled (_tmp1_, TRUE);
_tmp2_ = opt_context;
g_option_context_add_main_entries (_tmp2_, CLI_options, NULL);
_tmp3_ = opt_context;
g_option_context_parse (_tmp3_, &args_length1, &args, &_inner_error_);
if (_inner_error_ != NULL) {
_g_option_context_free0 (opt_context);
if (_inner_error_->domain == G_OPTION_ERROR) {
goto __catch0_g_option_error;
}
_g_option_context_free0 (opt_context);
g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FIL
E__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain)
, _inner_error_->code);
g_clear_error (&_inner_error_);
return 0;
}
_g_option_context_free0 (opt_context);
}
goto __finally0;
__catch0_g_option_error:
{
GError* e = NULL;
FILE* _tmp4_;
GError* _tmp5_;
const gchar* _tmp6_;
FILE* _tmp7_;
gchar** _tmp8_;
gint _tmp8__length1;
const gchar* _tmp9_;
e = _inner_error_;
_inner_error_ = NULL;
_tmp4_ = stdout;
_tmp5_ = e;
_tmp6_ = _tmp5_->message;
fprintf (_tmp4_, "%s\n", _tmp6_);
_tmp7_ = stdout;
_tmp8_ = args;
_tmp8__length1 = args_length1;
_tmp9_ = _tmp8_[0];
fprintf (_tmp7_, "Run '%s --help' to see a full list of available comman
d line options.\n", _tmp9_);
result = 1;
_g_error_free0 (e);
return result;
}
__finally0:
if (_inner_error_ != NULL) {
g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, _
_LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inn
er_error_->code);
g_clear_error (&_inner_error_);
return 0;
}
result = 0;
return result;
}
gint cli_run (Cli* self) {
gint result = 0;
gboolean _tmp0_;
gboolean _tmp2_;
gboolean _tmp4_;
const gchar* _tmp6_;
const gchar* _tmp9_;
gchar** _tmp12_;
gint _tmp12__length1;
g_return_val_if_fail (self != NULL, 0);
_tmp0_ = cli_verbose;
if (_tmp0_) {
FILE* _tmp1_;
_tmp1_ = stdout;
fprintf (_tmp1_, "Cli: verbose ON\n");
}
_tmp2_ = cli_append;
if (_tmp2_) {
FILE* _tmp3_;
_tmp3_ = stdout;
fprintf (_tmp3_, "Cli: appemd ON\n");
}
_tmp4_ = cli_op_long;
if (_tmp4_) {
FILE* _tmp5_;
_tmp5_ = stdout;
fprintf (_tmp5_, "Cli: long ON\n");
}
_tmp6_ = cli_filename;
if (_tmp6_ != NULL) {
FILE* _tmp7_;
const gchar* _tmp8_;
_tmp7_ = stdout;
_tmp8_ = cli_filename;
fprintf (_tmp7_, "Cli: file = %s\n", _tmp8_);
}
_tmp9_ = cli_longextra;
if (_tmp9_ != NULL) {
FILE* _tmp10_;
const gchar* _tmp11_;
_tmp10_ = stdout;
_tmp11_ = cli_longextra;
fprintf (_tmp10_, "Cli: longextra = %s\n", _tmp11_);
}
_tmp12_ = cli_sources;
_tmp12__length1 = _vala_array_length (cli_sources);
if (_tmp12_ != NULL) {
gint i;
gchar** _tmp13_;
gint _tmp13__length1;
i = 0;
_tmp13_ = cli_sources;
_tmp13__length1 = _vala_array_length (cli_sources);
{
gchar** s_collection = NULL;
gint s_collection_length1 = 0;
gint _s_collection_size_ = 0;
gint s_it = 0;
s_collection = _tmp13_;
s_collection_length1 = _tmp13__length1;
for (s_it = 0; s_it < _tmp13__length1; s_it = s_it + 1) {
gchar* _tmp14_;
gchar* s = NULL;
_tmp14_ = g_strdup (s_collection[s_it]);
s = _tmp14_;
{
FILE* _tmp15_;
gint _tmp16_;
const gchar* _tmp17_;
gint _tmp18_;
_tmp15_ = stdout;
_tmp16_ = i;
_tmp17_ = s;
fprintf (_tmp15_, "sources[%i]=%s\n", _tmp16_, _tmp17_);
_tmp18_ = i;
i = _tmp18_ + 1;
_g_free0 (s);
}
}
}
}
result = 0;
return result;
}
Cli* cli_construct (GType object_type) {
Cli * self = NULL;
self = (Cli*) g_object_new (object_type, NULL);
return self;
}
Cli* cli_new (void) {
return cli_construct (TYPE_CLI);
}
static void cli_class_init (CliClass * klass) {
cli_parent_class = g_type_class_peek_parent (klass);
G_OBJECT_CLASS (klass)->finalize = cli_finalize;
}
static void cli_instance_init (Cli * self) {
}
static void cli_finalize (GObject* obj) {
Cli * self;
self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_CLI, Cli);
G_OBJECT_CLASS (cli_parent_class)->finalize (obj);
}
GType cli_get_type (void) {
static volatile gsize cli_type_id__volatile = 0;
if (g_once_init_enter (&cli_type_id__volatile)) {
static const GTypeInfo g_define_type_info = { sizeof (CliClass), (GBaseI
nitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) cli_class_init, (GClas
sFinalizeFunc) NULL, NULL, sizeof (Cli), 0, (GInstanceInitFunc) cli_instance_ini
t, NULL };
GType cli_type_id;
cli_type_id = g_type_register_static (G_TYPE_OBJECT, "Cli", &g_define_ty
pe_info, 0);
g_once_init_leave (&cli_type_id__volatile, cli_type_id);
}
return cli_type_id__volatile;
}
gint _vala_main (gchar** args, int args_length1) {
gint result = 0;
FILE* _tmp0_;
gchar** _tmp1_;
gint _tmp1__length1;
const gchar* _tmp2_;
FILE* _tmp3_;
gchar** _tmp4_;
gint _tmp4__length1;
const gchar* _tmp5_;
gchar* _tmp6_ = NULL;
gchar* _tmp7_;
Cli* _tmp8_;
Cli* cli;
gchar** _tmp9_;
gint _tmp9__length1;
gint _tmp10_ = 0;
setlocale (LC_ALL, "");
_tmp0_ = stdout;
_tmp1_ = args;
_tmp1__length1 = args_length1;
_tmp2_ = _tmp1_[0];
fprintf (_tmp0_, "command = %s\n", _tmp2_);
_tmp3_ = stdout;
_tmp4_ = args;
_tmp4__length1 = args_length1;
_tmp5_ = _tmp4_[0];
_tmp6_ = g_path_get_basename (_tmp5_);
_tmp7_ = _tmp6_;
fprintf (_tmp3_, "basename = %s\n", _tmp7_);
_g_free0 (_tmp7_);
_tmp8_ = cli_new ();
cli = _tmp8_;
_tmp9_ = args;
_tmp9__length1 = args_length1;
cli_parse (cli, _tmp9_, _tmp9__length1);
_tmp10_ = cli_run (cli);
result = _tmp10_;
_g_object_unref0 (cli);
return result;
}
int main (int argc, char ** argv) {
g_type_init ();
return _vala_main (argv, argc);
}
static gint _vala_array_length (gpointer array) {
int length;
length = 0;
if (array) {
while (((gpointer*) array)[length]) {
length++;
}
}
return length;
}
It is obvious that the Vala code is much shorter than the generated C code. The Vala compiler took care chores of generating CPP macros for GObject with.
- No prefix.
cli
,CLI
,Cli
: object type (= class) namecli_get_type()
: returning GType of object CLI
OOP style (main inside of class)
Source code cli-3.vala
in Vala language
class Cli : Object {
private static bool append = false;
private static bool verbose = false;
private static bool op_long = false;
private static string filename = null;
private static string longextra = null;
// sources is a string array containing all non-option arguments
// https://mail.gnome.org/archives/vala-list/2009-March/msg00090.html
[CCode (array_length = false, array_null_terminated = true)]
private static string[] sources;
private const OptionEntry[] options = {
{ "append", 'a', 0, OptionArg.NONE, ref append,
"Set append mode", null },
{ "verbose", 'v', 0, OptionArg.NONE, ref verbose,
"Set verbose mode", null },
{ "file", 'f', 0, OptionArg.FILENAME, ref filename,
"Use F file", "F"},
{ "long", 0, 0, OptionArg.NONE, ref op_long,
"Set long mode", null },
{ "longextra", 0, 0, OptionArg.STRING, ref longextra,
"Set longextra to M", "M" },
{ "", 0, 0, OptionArg.FILENAME_ARRAY, ref sources,
null, "FILE..." },
{ null }
};
private int parse (string[] args) {
// parse command line
try {
// parse command line options with GLib
var opt_context = new OptionContext ("- Cli");
opt_context.set_help_enabled (true);
opt_context.add_main_entries (options, null);
opt_context.parse (ref args);
} catch (OptionError e) {
stdout.printf ("%s\n", e.message);
stdout.printf (
"Run '%s --help' to see a full list of available command line options.\n",
args[0]);
return 1;
}
return 0;
}
private int run () {
// print variables
if (verbose) {
stdout.printf ("Cli: verbose ON\n");
}
if (append) {
stdout.printf ("Cli: appemd ON\n");
}
if (op_long) {
stdout.printf ("Cli: long ON\n");
}
if (filename != null) {
stdout.printf ("Cli: file = %s\n", filename);
}
if (longextra != null) {
stdout.printf ("Cli: longextra = %s\n", longextra);
}
if (sources != null) {
int i = 0;
foreach (string s in sources) {
stdout.printf("sources[%i]=%s\n", i, s);
i++;
}
}
return 0;
}
public static int main (string[] args) {
// initialize locale
Intl.setlocale (LocaleCategory.ALL, "");
//
stdout.printf ("command = %s\n", args[0]);
stdout.printf ("basename = %s\n", Path.get_basename(args[0]));
var cli = new Cli ();
cli.parse (args);
return cli.run ();
}
}
TIP: The above example skips specifying GLib
for the parent class since it is
the default for Vala.
Let’s compile cli-3.vala
to create the ELF object cli-3
and run it.
$ valac -v cli-3.vala
/path/to/vala/cli-3.vala.c: In function ‘main’:
/path/to/vala/cli-3.vala.c:263:2: warning: ‘g_type_init’ is deprecated (declared ...
g_type_init ();
^
Loaded package `/usr/share/vala-0.20/vapi/glib-2.0.vapi'
Loaded package `/usr/share/vala-0.20/vapi/gobject-2.0.vapi'
cc -o '/path/to/vala/cli-3' '/path/to/vala/cli-3.vala.c' -I/usr/include/glib-2.0 ...
$ ./cli-3 -avf BOGUS.txt --long --longextra=FOO X1 X2
command = ./cli-3
basename = cli-3
Cli: verbose ON
Cli: appemd ON
Cli: long ON
Cli: file = BOGUS.txt
Cli: longextra = FOO
sources[0]=X1
sources[1]=X2
$ ./cli-3 -b
command = ./cli-3
basename = cli-3
Unknown option -b
Run './cli-3 --help' to see a full list of available command line options.
$ ./cli-3 --help
command = ./cli-3
basename = cli-3
Usage:
cli-3 [OPTION...] FILE... - Cli
Help Options:
-h, --help Show help options
Application Options:
-a, --append Set append mode
-v, --verbose Set verbose mode
-f, --file=F Use F file
--long Set long mode
--longextra=M Set longextra to M
You can get the C source as:
$ valac -C cli-3.vala
$ wc -l cli-3.vala ; wc -l cli-3.c
87 cli-3.vala
321 cli-3.c
$ cat cli-3.c |sed -e 's/ / /g'|fold # tab => 4 spaces
/* cli-3.c generated by valac 0.20.1, the Vala compiler
* generated from cli-3.vala, do not modify */
#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <locale.h>
#define TYPE_CLI (cli_get_type ())
#define CLI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CLI, Cli))
#define CLI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CLI, CliClass))
#define IS_CLI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CLI))
#define IS_CLI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CLI))
#define CLI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CLI, CliClass
))
typedef struct _Cli Cli;
typedef struct _CliClass CliClass;
typedef struct _CliPrivate CliPrivate;
#define _g_option_context_free0(var) ((var == NULL) ? NULL : (var = (g_option_co
ntext_free (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var),
NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (va
r), NULL)))
struct _Cli {
GObject parent_instance;
CliPrivate * priv;
};
struct _CliClass {
GObjectClass parent_class;
};
static gpointer cli_parent_class = NULL;
static gboolean cli_append;
static gboolean cli_append = FALSE;
static gboolean cli_verbose;
static gboolean cli_verbose = FALSE;
static gboolean cli_op_long;
static gboolean cli_op_long = FALSE;
static gchar* cli_filename;
static gchar* cli_filename = NULL;
static gchar* cli_longextra;
static gchar* cli_longextra = NULL;
static gchar** cli_sources;
static gchar** cli_sources = NULL;
GType cli_get_type (void) G_GNUC_CONST;
enum {
CLI_DUMMY_PROPERTY
};
static gint cli_parse (Cli* self, gchar** args, int args_length1);
static gint cli_run (Cli* self);
gint cli_main (gchar** args, int args_length1);
Cli* cli_new (void);
Cli* cli_construct (GType object_type);
static void cli_finalize (GObject* obj);
static gint _vala_array_length (gpointer array);
static const GOptionEntry CLI_options[7] = {{"append", 'a', 0, G_OPTION_ARG_NONE
, &cli_append, "Set append mode", NULL}, {"verbose", 'v', 0, G_OPTION_ARG_NONE,
&cli_verbose, "Set verbose mode", NULL}, {"file", 'f', 0, G_OPTION_ARG_FILENAME,
&cli_filename, "Use F file", "F"}, {"long", (gchar) 0, 0, G_OPTION_ARG_NONE, &c
li_op_long, "Set long mode", NULL}, {"longextra", (gchar) 0, 0, G_OPTION_ARG_STR
ING, &cli_longextra, "Set longextra to M", "M"}, {"", (gchar) 0, 0, G_OPTION_ARG
_FILENAME_ARRAY, &cli_sources, NULL, "FILE..."}, {NULL}};
static gint cli_parse (Cli* self, gchar** args, int args_length1) {
gint result = 0;
GError * _inner_error_ = NULL;
g_return_val_if_fail (self != NULL, 0);
{
GOptionContext* _tmp0_;
GOptionContext* opt_context;
GOptionContext* _tmp1_;
GOptionContext* _tmp2_;
GOptionContext* _tmp3_;
_tmp0_ = g_option_context_new ("- Cli");
opt_context = _tmp0_;
_tmp1_ = opt_context;
g_option_context_set_help_enabled (_tmp1_, TRUE);
_tmp2_ = opt_context;
g_option_context_add_main_entries (_tmp2_, CLI_options, NULL);
_tmp3_ = opt_context;
g_option_context_parse (_tmp3_, &args_length1, &args, &_inner_error_);
if (_inner_error_ != NULL) {
_g_option_context_free0 (opt_context);
if (_inner_error_->domain == G_OPTION_ERROR) {
goto __catch0_g_option_error;
}
_g_option_context_free0 (opt_context);
g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FIL
E__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain)
, _inner_error_->code);
g_clear_error (&_inner_error_);
return 0;
}
_g_option_context_free0 (opt_context);
}
goto __finally0;
__catch0_g_option_error:
{
GError* e = NULL;
FILE* _tmp4_;
GError* _tmp5_;
const gchar* _tmp6_;
FILE* _tmp7_;
gchar** _tmp8_;
gint _tmp8__length1;
const gchar* _tmp9_;
e = _inner_error_;
_inner_error_ = NULL;
_tmp4_ = stdout;
_tmp5_ = e;
_tmp6_ = _tmp5_->message;
fprintf (_tmp4_, "%s\n", _tmp6_);
_tmp7_ = stdout;
_tmp8_ = args;
_tmp8__length1 = args_length1;
_tmp9_ = _tmp8_[0];
fprintf (_tmp7_, "Run '%s --help' to see a full list of available comman
d line options.\n", _tmp9_);
result = 1;
_g_error_free0 (e);
return result;
}
__finally0:
if (_inner_error_ != NULL) {
g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, _
_LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inn
er_error_->code);
g_clear_error (&_inner_error_);
return 0;
}
result = 0;
return result;
}
static gint cli_run (Cli* self) {
gint result = 0;
gboolean _tmp0_;
gboolean _tmp2_;
gboolean _tmp4_;
const gchar* _tmp6_;
const gchar* _tmp9_;
gchar** _tmp12_;
gint _tmp12__length1;
g_return_val_if_fail (self != NULL, 0);
_tmp0_ = cli_verbose;
if (_tmp0_) {
FILE* _tmp1_;
_tmp1_ = stdout;
fprintf (_tmp1_, "Cli: verbose ON\n");
}
_tmp2_ = cli_append;
if (_tmp2_) {
FILE* _tmp3_;
_tmp3_ = stdout;
fprintf (_tmp3_, "Cli: appemd ON\n");
}
_tmp4_ = cli_op_long;
if (_tmp4_) {
FILE* _tmp5_;
_tmp5_ = stdout;
fprintf (_tmp5_, "Cli: long ON\n");
}
_tmp6_ = cli_filename;
if (_tmp6_ != NULL) {
FILE* _tmp7_;
const gchar* _tmp8_;
_tmp7_ = stdout;
_tmp8_ = cli_filename;
fprintf (_tmp7_, "Cli: file = %s\n", _tmp8_);
}
_tmp9_ = cli_longextra;
if (_tmp9_ != NULL) {
FILE* _tmp10_;
const gchar* _tmp11_;
_tmp10_ = stdout;
_tmp11_ = cli_longextra;
fprintf (_tmp10_, "Cli: longextra = %s\n", _tmp11_);
}
_tmp12_ = cli_sources;
_tmp12__length1 = _vala_array_length (cli_sources);
if (_tmp12_ != NULL) {
gint i;
gchar** _tmp13_;
gint _tmp13__length1;
i = 0;
_tmp13_ = cli_sources;
_tmp13__length1 = _vala_array_length (cli_sources);
{
gchar** s_collection = NULL;
gint s_collection_length1 = 0;
gint _s_collection_size_ = 0;
gint s_it = 0;
s_collection = _tmp13_;
s_collection_length1 = _tmp13__length1;
for (s_it = 0; s_it < _tmp13__length1; s_it = s_it + 1) {
gchar* _tmp14_;
gchar* s = NULL;
_tmp14_ = g_strdup (s_collection[s_it]);
s = _tmp14_;
{
FILE* _tmp15_;
gint _tmp16_;
const gchar* _tmp17_;
gint _tmp18_;
_tmp15_ = stdout;
_tmp16_ = i;
_tmp17_ = s;
fprintf (_tmp15_, "sources[%i]=%s\n", _tmp16_, _tmp17_);
_tmp18_ = i;
i = _tmp18_ + 1;
_g_free0 (s);
}
}
}
}
result = 0;
return result;
}
gint cli_main (gchar** args, int args_length1) {
gint result = 0;
FILE* _tmp0_;
gchar** _tmp1_;
gint _tmp1__length1;
const gchar* _tmp2_;
FILE* _tmp3_;
gchar** _tmp4_;
gint _tmp4__length1;
const gchar* _tmp5_;
gchar* _tmp6_ = NULL;
gchar* _tmp7_;
Cli* _tmp8_;
Cli* cli;
gchar** _tmp9_;
gint _tmp9__length1;
gint _tmp10_ = 0;
setlocale (LC_ALL, "");
_tmp0_ = stdout;
_tmp1_ = args;
_tmp1__length1 = args_length1;
_tmp2_ = _tmp1_[0];
fprintf (_tmp0_, "command = %s\n", _tmp2_);
_tmp3_ = stdout;
_tmp4_ = args;
_tmp4__length1 = args_length1;
_tmp5_ = _tmp4_[0];
_tmp6_ = g_path_get_basename (_tmp5_);
_tmp7_ = _tmp6_;
fprintf (_tmp3_, "basename = %s\n", _tmp7_);
_g_free0 (_tmp7_);
_tmp8_ = cli_new ();
cli = _tmp8_;
_tmp9_ = args;
_tmp9__length1 = args_length1;
cli_parse (cli, _tmp9_, _tmp9__length1);
_tmp10_ = cli_run (cli);
result = _tmp10_;
_g_object_unref0 (cli);
return result;
}
int main (int argc, char ** argv) {
g_type_init ();
return cli_main (argv, argc);
}
Cli* cli_construct (GType object_type) {
Cli * self = NULL;
self = (Cli*) g_object_new (object_type, NULL);
return self;
}
Cli* cli_new (void) {
return cli_construct (TYPE_CLI);
}
static void cli_class_init (CliClass * klass) {
cli_parent_class = g_type_class_peek_parent (klass);
G_OBJECT_CLASS (klass)->finalize = cli_finalize;
}
static void cli_instance_init (Cli * self) {
}
static void cli_finalize (GObject* obj) {
Cli * self;
self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_CLI, Cli);
G_OBJECT_CLASS (cli_parent_class)->finalize (obj);
}
GType cli_get_type (void) {
static volatile gsize cli_type_id__volatile = 0;
if (g_once_init_enter (&cli_type_id__volatile)) {
static const GTypeInfo g_define_type_info = { sizeof (CliClass), (GBaseI
nitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) cli_class_init, (GClas
sFinalizeFunc) NULL, NULL, sizeof (Cli), 0, (GInstanceInitFunc) cli_instance_ini
t, NULL };
GType cli_type_id;
cli_type_id = g_type_register_static (G_TYPE_OBJECT, "Cli", &g_define_ty
pe_info, 0);
g_once_init_leave (&cli_type_id__volatile, cli_type_id);
}
return cli_type_id__volatile;
}
static gint _vala_array_length (gpointer array) {
int length;
length = 0;
if (array) {
while (((gpointer*) array)[length]) {
length++;
}
}
return length;
}
It is obvious that the Vala code is much shorter than the generated C code. The Vala compiler took care chores of generating CPP macros for GObject with.
- No prefix.
cli
,CLI
,Cli
: object type (= class) namecli_get_type()
: returning GType of object CLI
Previous Post | Top | Next Post |