![]() |
|
Bash or Shell script to create source and header |
OnlineCop
Member #7,919
October 2006
![]() |
I often find myself writing the same structure for all of my class headers. I want to eliminate repetitive tasks, so I'd like to automate this by making it into a shell script. I'm using a Mac, and I understand there's something called the Automator, but I've never used it before so have no idea what it's for or how to use it, so thought I'd ask a question that people on OTHER platforms might find in the future and be able to use. I'd like to create a shell script that will perform the following:
I'm not exactly certain the format (and the whole "$(filename)" format is borrowed from the makefile style), and I don't know how to supply arguments to shell scripts, so any help is appreciated. Even if the help is in the form of "RTM found at website ___"
|
kazzmir
Member #1,786
December 2001
![]() |
Try this. #!/bin/sh if [ "x$1" = "x" ]; then echo "Supply an argument" fi name=$1 sed template.h -e "s/\$(filename)/${name}/g" > $name.h Use: $ ./create foo $ cat foo.h #ifndef foo_h #define foo_h class foo { public: // Constructor foo(); // Destructor virtual ~foo(); }; #endif // foo_h
|
bamccaig
Member #7,536
July 2006
![]() |
1#!/bin/bash
2
3function do_header
4{
5 if [ -e "$header_path" ]; then
6 read -p "'$header_path' already exists. Overwrite? (yes/no) ";
7
8 if [ x$REPLY != xyes ]; then
9 return 0;
10 fi
11 fi
12
13 # --- QnD: Header File ---
14 echo "#ifndef $header_guard" > $header_path;
15 echo " #define $header_guard" >> $header_path;
16 echo >> $header_path;
17
18 if [ x$namespace != x ]; then
19 indent=" ";
20 echo "namespace $namespace" >> $header_path;
21 echo "{" >> $header_path;
22 fi
23
24 echo "${indent}class $name" >> $header_path;
25 echo "${indent}{" >> $header_path;
26 echo "${indent}public:" >> $header_path;
27 echo "${indent} ${name}(void);" >> $header_path;
28 echo "${indent} virtual ~${name}(void);" >> $header_path;
29 echo "${indent}};" >> $header_path;
30
31 if [ x$namespace != x ]; then
32 echo "}" >> $header_path;
33 fi
34
35 echo >> $header_path;
36 echo "#endif //${header_guard}" >> $header_path;
37 echo >> $header_path;
38}
39
40function do_source
41{
42 if [ -e "$source_path" ]; then
43 read -p "'$source_path' already exists. Overwrite? (yes/no) ";
44
45 if [ x$REPLY != xyes ]; then
46 return 0;
47 fi
48 fi
49
50 # QnD --- Source File ---
51 echo "#include <${header_file}>" > $source_path;
52 echo >> $source_path;
53
54 if [ x$namespace != x ]; then
55 indent=" ";
56 echo "namespace $namespace" >> $source_path;
57 echo "{" >> $source_path;
58 fi
59
60 echo "${indent}${name}::${name}(void)" >> $source_path;
61 echo "${indent}{" >> $source_path;
62 echo "${indent} // TODO" >> $source_path;
63 echo "${indent}}" >> $source_path;
64 echo >> $source_path;
65 echo "${indent}${name}::~${name}(void)" >> $source_path;
66 echo "${indent}{" >> $source_path;
67 echo "${indent} // TODO" >> $source_path;
68 echo "${indent}}" >> $source_path;
69
70 if [ x$namespace != x ]; then
71 echo "}" >> $source_path;
72 fi
73
74 echo >> $source_path;
75}
76
77if [ x$1 = x ]; then
78 echo "Usage: $0 NAME [NAMESPACE]";
79 echo;
80 echo "Where NAME is the name of the file/class and NAMESPACE is the namespace.";
81
82 exit -1;
83fi
84
85name="`echo "$1" | sed -r 's/\s+//g'`";
86namespace="`echo "$2" | sed -r 's/\s+//g'`";
87header_guard="`echo "$name" | tr [:lower:] [:upper:]`_HPP";
88header_file="${name}.hpp";
89
90if [ -d include ]; then
91 incdir=include/;
92fi
93
94header_path="${incdir}${header_file}";
95
96do_header;
97
98source_file="${name}.cpp";
99
100if [ -d src ]; then
101 srcdir=src/;
102fi
103
104source_path="${srcdir}${source_file}";
105
106do_source;
[bamccaig@sephiroth temp]$ ls -la total 8 drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 12:09 . drwxrwxr-x 36 bamccaig bamccaig 4096 2009-07-23 11:10 .. [bamccaig@sephiroth temp]$ addclass foo [bamccaig@sephiroth temp]$ ls -la total 16 drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 12:10 . drwxrwxr-x 36 bamccaig bamccaig 4096 2009-07-23 11:10 .. -rw-rw-r-- 1 bamccaig bamccaig 85 2009-07-23 12:10 foo.cpp -rw-rw-r-- 1 bamccaig bamccaig 118 2009-07-23 12:10 foo.hpp [bamccaig@sephiroth temp]$ cat foo.hpp #ifndef FOO_HPP #define FOO_HPP class foo { public: foo(void); virtual ~foo(void); }; #endif //FOO_HPP [bamccaig@sephiroth temp]$ cat foo.cpp #include <foo.hpp> foo::foo(void) { // TODO } foo::~foo(void) { // TODO } [bamccaig@sephiroth temp]$ mkdir include src [bamccaig@sephiroth temp]$ addclass foo bar [bamccaig@sephiroth temp]$ ls -Rla .: total 24 drwxrwxr-x 4 bamccaig bamccaig 4096 2009-07-23 12:11 . drwxrwxr-x 36 bamccaig bamccaig 4096 2009-07-23 11:10 .. -rw-rw-r-- 1 bamccaig bamccaig 85 2009-07-23 12:10 foo.cpp -rw-rw-r-- 1 bamccaig bamccaig 118 2009-07-23 12:10 foo.hpp drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 12:35 include drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 12:35 src ./include: total 12 drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 12:35 . drwxrwxr-x 4 bamccaig bamccaig 4096 2009-07-23 12:11 .. -rw-rw-r-- 1 bamccaig bamccaig 160 2009-07-23 12:35 foo.hpp ./src: total 12 drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 12:35 . drwxrwxr-x 4 bamccaig bamccaig 4096 2009-07-23 12:11 .. -rw-rw-r-- 1 bamccaig bamccaig 135 2009-07-23 12:35 foo.cpp [bamccaig@sephiroth temp]$ cat include/foo.hpp #ifndef FOO_HPP #define FOO_HPP namespace bar { class foo { public: foo(void); virtual ~foo(void); }; } #endif //FOO_HPP [bamccaig@sephiroth temp]$ cat src/foo.cpp #include <foo.hpp> namespace bar { foo::foo(void) { // TODO } foo::~foo(void) { // TODO } }
That's actually kind of useful. Imagine stubbing out a whole project with just a series of commands... -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
OnlineCop
Member #7,919
October 2006
![]() |
bamccaig said: That's actually kind of useful. I might just go ahead and try to create a library of bash functions to create file stubs for different types of symbols (enums, structs, classes, functions, main, etc.). When you do, post them here. I'd certainly be interested in them. I can even see derived classes being handy: #ifndef FOO_HPP #define FOO_HPP #include "bar.hpp" class foo : public bar { public: foo(); virtual ~foo(); }; #endif //FOO_HPP
|
ixilom
Member #7,167
April 2006
![]() |
I did something similar with PHP some time ago. ___________________________________________ |
OnlineCop
Member #7,919
October 2006
![]() |
I actually hadn't noticed that, with only minor modifications, bamccaig's code already DOES have all the necessary support for inheritance. Now onto phase 2: the Allegro Timer template. You know the one... it won't exceed a certain FPS under light operation, but will start to dynamically skip frames based on refresh preferences under heavy loads. It also maintains a low CPU usage (around 1%) unless it starts really getting into heavy 3D rendering
|
bamccaig
Member #7,536
July 2006
![]() |
Updated to include namespace support in header guards and file paths (i.e., namespace foo { class bar; } becomes FOO_BAR_HPP, include/foo/bar.hpp, and src/foo/bar.cpp). Obviously everybody does this a little bit different, but this is how I would do it at this particular point in time. 1#!/bin/bash
2
3function do_header
4{
5 if [ -e "$header_path" ]; then
6 read -p "'$header_path' already exists. Overwrite? (yes/no) ";
7
8 if [ x$REPLY != xyes ]; then
9 return 0;
10 fi
11 fi
12
13 # --- QnD: Header File ---
14 echo "#ifndef $header_guard" > $header_path;
15 echo " #define $header_guard" >> $header_path;
16 echo >> $header_path;
17
18 if [ x$namespace != x ]; then
19 indent=" ";
20 echo "namespace $namespace" >> $header_path;
21 echo "{" >> $header_path;
22 fi
23
24 echo "${indent}class $name" >> $header_path;
25 echo "${indent}{" >> $header_path;
26 echo "${indent}public:" >> $header_path;
27 echo "${indent} ${name}(void);" >> $header_path;
28 echo "${indent} virtual ~${name}(void);" >> $header_path;
29 echo "${indent}};" >> $header_path;
30
31 if [ x$namespace != x ]; then
32 echo "}" >> $header_path;
33 fi
34
35 echo >> $header_path;
36 echo "#endif //${header_guard}" >> $header_path;
37 echo >> $header_path;
38}
39
40function do_source
41{
42 if [ -e "$source_path" ]; then
43 read -p "'$source_path' already exists. Overwrite? (yes/no) ";
44
45 if [ x$REPLY != xyes ]; then
46 return 0;
47 fi
48 fi
49
50 # QnD --- Source File ---
51 echo "#include <${nsdir}${header_file}>" > $source_path;
52 echo >> $source_path;
53
54 if [ x$namespace != x ]; then
55 indent=" ";
56 echo "namespace $namespace" >> $source_path;
57 echo "{" >> $source_path;
58 fi
59
60 echo "${indent}${name}::${name}(void)" >> $source_path;
61 echo "${indent}{" >> $source_path;
62 echo "${indent} // TODO" >> $source_path;
63 echo "${indent}}" >> $source_path;
64 echo >> $source_path;
65 echo "${indent}${name}::~${name}(void)" >> $source_path;
66 echo "${indent}{" >> $source_path;
67 echo "${indent} // TODO" >> $source_path;
68 echo "${indent}}" >> $source_path;
69
70 if [ x$namespace != x ]; then
71 echo "}" >> $source_path;
72 fi
73
74 echo >> $source_path;
75}
76
77if [ x$1 = x ]; then
78 echo "Usage: $0 NAME [NAMESPACE]";
79 echo;
80 echo "Where NAME is the name of the file/class and NAMESPACE is the namespace.";
81
82 exit -1;
83fi
84
85name="`echo "$1" | sed -r 's/\s+//g'`";
86namespace="`echo "$2" | sed -r 's/\s+//g'`";
87
88if [ x$namespace = x ]; then
89 header_guard="`echo "$name" | tr [:lower:] [:upper:]`_HPP";
90else
91 header_guard="`echo "\`echo "${namespace}" | sed -r 's/::/_/g'\`_${name}" | tr [:lower:] [:upper:]`_HPP";
92fi
93
94header_file="${name}.hpp";
95
96if [ -d include ]; then
97 incdir=include/;
98fi
99
100if [ x$namespace != x ]; then
101 nsdir="`echo "$namespace" | sed -r 's/::/\//g'`/"; 102 mkdir -p "${incdir}${nsdir}";
103fi
104
105header_path="${incdir}${nsdir}${header_file}";
106
107do_header;
108
109source_file="${name}.cpp";
110
111if [ -d src ]; then
112 srcdir=src/;
113fi
114
115if [ x$namespace != x ]; then
116 mkdir -p "${srcdir}${nsdir}";
117fi
118
119source_path="${srcdir}${nsdir}${source_file}";
120
121do_source;
[bamccaig@sephiroth temp]$ ls -la total 8 drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 23:48 . drwxrwxr-x 36 bamccaig bamccaig 4096 2009-07-23 15:28 .. [bamccaig@sephiroth temp]$ mkdir include src [bamccaig@sephiroth temp]$ addclass foo bar::baz [bamccaig@sephiroth temp]$ ls -Rla .: total 16 drwxrwxr-x 4 bamccaig bamccaig 4096 2009-07-23 23:48 . drwxrwxr-x 36 bamccaig bamccaig 4096 2009-07-23 15:28 .. drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 include drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 src ./include: total 12 drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 . drwxrwxr-x 4 bamccaig bamccaig 4096 2009-07-23 23:48 .. drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 bar ./include/bar: total 12 drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 . drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 .. drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 23:48 baz ./include/bar/baz: total 12 drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 23:48 . drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 .. -rw-rw-r-- 1 bamccaig bamccaig 189 2009-07-23 23:48 foo.hpp ./src: total 12 drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 . drwxrwxr-x 4 bamccaig bamccaig 4096 2009-07-23 23:48 .. drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 bar ./src/bar: total 12 drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 . drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 .. drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 23:48 baz ./src/bar/baz: total 12 drwxrwxr-x 2 bamccaig bamccaig 4096 2009-07-23 23:48 . drwxrwxr-x 3 bamccaig bamccaig 4096 2009-07-23 23:48 .. -rw-rw-r-- 1 bamccaig bamccaig 140 2009-07-23 23:48 foo.cpp [bamccaig@sephiroth temp]$ cat */*/*/* #ifndef BAR_BAZ_FOO_HPP #define BAR_BAZ_FOO_HPP namespace bar::baz { class foo { public: foo(void); virtual ~foo(void); }; } #endif //BAR_BAZ_FOO_HPP #include <bar/baz/foo.hpp> namespace bar::baz { foo::foo(void) { // TODO } foo::~foo(void) { // TODO } } [bamccaig@sephiroth temp]$
I probably find nested namespaces more structurally obvious than qualified ones, but that would require more manipulation of arguments so I just settled for QnD right now. ** EDIT ** Note: One of the <code> lines (the highlighted line) apparently lost a backslash in the parsing stage. I think I fixed it by escaping it, but there could be more so I'm going to attach the script to make sure the code is available. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Peter Wang
Member #23
April 2000
|
Don't forget here documents. #!/bin/sh base=$(basename $1 .c) cat <<EOF #include "${base}.h" /* blah blah */ EOF
|
bamccaig
Member #7,536
July 2006
![]() |
I said: ... namespace bar::baz { ...
I probably find nested namespaces more structurally obvious than qualified ones, but that would require more manipulation of arguments so I just settled for QnD right now.
Hmmm, wait, maybe I'm confusing C# syntax with C++ syntax. Is this legal in C++? namespace bar::baz { } It isn't compiling... [bamccaig@sephiroth temp]$ g++ -Iinclude src/bar/baz/foo.cpp -c In file included from src/bar/baz/foo.cpp:2: include/bar/baz/foo.hpp:4: error: expected `{' before ‘::’ token include/bar/baz/foo.hpp:4: error: function definition does not declare parameters src/bar/baz/foo.cpp:3: error: expected `{' before ‘::’ token src/bar/baz/foo.cpp:3: error: function definition does not declare parameters src/bar/baz/foo.cpp:14: error: expected `}' at end of input src/bar/baz/foo.cpp:14: error: expected `}' at end of input [bamccaig@sephiroth temp]$
...and I can't find any tutorials or guides that suggest this syntax is supported. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
alethiophile
Member #9,349
December 2007
![]() |
The following is me trying to type out from scratch my 'mksfp' (make single-file project) script: 1#!/bin/bash
2
3cp ~/.mksfp/Makefile.template ./Makefile
4
5pcmd="'s/EXENAME/"$1"/g;'";
6
7perl -pie $pcmd Makefile
8
9cat >main.c <<EOF
10#include <stdio.h>
11#include <stdlib.h>
12
13int main(int argc, char **argv) {
14 // insert program here
15}
16
17EOF
The Makefile.template: EXE= EXENAME OFILES= main.o $(EXE): $(OFILES) $(CC) -o $@ $(OFILES) .o.c: $(CC) -c -Wall $< clean: -rm *.o $(EXE) I probably made some mistake or other typing it. -- |
|