Automatic header files creator. It creates a header file after a given filename.c, naming it after its original name, as filename.h. In case a filename.h already exists, autotad will scan it and keep the written comments in the new version.
-
What will be written in filename.h?
- functions and structs written in filename.c. If a function is written in filename.h but it is removed from filename.c, it will not be kept on further executions.
- typedefs and includes written in filename.h will be kept upon further executions.
- Comments written right above functions, structs and typedefs in filename.h will be kept upon further executions.
- Every file will be written following the template below (for a file named filename.h):
#ifndef FILENAME_H #define FILENAME_H ... #endif
-
What arguments can be passed?
- filename.c: autotad creates header based on filename.c (".c" is not necessary. However, if it's written "filename.", ending with '.', autotad will not recognise the file).
- comment-off: when this argument is present, autotad will not create new automatic comment sections for new functions or structs.
If filename is passed as a parameter, autotad will search for a filename.h file in the current directory. Otherwise, the function name will be asked via standard input, then it will search for it. It can process multiples files given via argv. The arguments' order does not matter.
-
Any tips?
- There is a section for tips and warnings later in this README.
-
Example of execution?
- Pretty simple and straightforward. It can be executed both through the executable file or directly by the Lua script:
./autotad function1.c function2 comment-off
lua autotad.lua function1.c function2 comment-off
- There are more detailed execution examples in the last section.
Functions are written in filename.h keeping their parameter names from filename.c. They are written in the order they are read from filename.c. For example, if we have, in filename.c:
void function1(int i, char *c){
...
return;
}
int function2(){
...
return 0;
}
This will be written in filename.h:
/*
* Comment section
*/
void function1(int i, char *c);
/*
* Comment section
*/
int function2();
Note: How autotad deals with comments is detailed later.
When a struct is read in filename.c, it will be defined as a type in filename.h. Structs are always written in filename.h like their names in filename.c with its first letter capitalized. For example, if we have, in filename.c:
struct str_example{
int i;
float f;
};
This will be written in filename.h:
/*
* Comment section
*/
typedef struct str_example Str_example;
Typedefs written directly in filename.h (other than those defined by structs) are also kept on further executions, along their comments. However, autotad will not write in filename.h a typedef defined in filename.c. The same applies to includes written in filename.h
// This is in filename.h and it WILL be kept upon further executions
typedef int elem;
They are always written on the top of filename.h, before structs and functions. Includes are written before typedefs.
Writing AUTOTAD_PRIVATE in a comment in filename.c makes autotad ignore the next function or structure. For example, in filename.c:
/* AUTOTAD_PRIVATE */
struct str_example{
int i;
float f;
};
//AUTOTAD_PRIVATE
void function2(){
...
return;
}
void function3(){
...
return;
}
Only function3 will be written in filename.h. Writing it inside a function or struct will have no effect.
If filename.h doesn't exist, a new file will be created. Otherwise, autotad will scan the whole file and store all comments with their respective functions, structs or typedefs as keys in a dictionary. These comments will be rewritten in the new filename.h along their respective key.
Comments written in filename.c will not be written in filename.h.
By default, the header file is created writing a comment section above every new function or struct read in the .c file. An example is shown below.
/*
* Comment section
*/
void function(int i, char *c);
This can be disabled by using comment-off as an argument via argv when executing the script. Notice that, once the file is written, the comment section will later be identified as function's comment, so it will be copied on further executions even when using comment-off.
Only the comment section right above the functions, structs or typedefs will be kept after executing autotad over an existing filename.h file, as shown below.
// This comment
// WILL NOT
// be kept in the new file
/*
* This comment WILL
* be kept in the new file
*/
void function1(int i);
/* This comment
* WILL NOT
* be kept in the new file
*/
// This comment WILL
// be kept in the new file
void function2(int i);
An important detail about how the keys are used in the dictionaries:
- Structs and other typedefs are stored in the dictionary using their whole line as a key. As for functions, only their names are used as keys. That means we can modify the parameters or the return type in filename.c, but, as long as we do not change the function name, its previous comment will be kept on further executions.
- Do not declare functions and structs with a curly brace below their name. I assume every function and struct will be declared with the first curly brace in line. For example, instead of writing:
void function()
{
...
return;
}
Write it like this:
void function(){
...
return;
}
Writing them differently will result in an error.
- Avoid using both curly braces in a single line. Curly braces are used for scope control, and I generally assume every function, loop or any other structure with its own scope to use at least two different lines. Although I haven't found any error associated with this, writing them in a single line might result in unexpected output, since I don't usually declare anything in this format. So, for example, instead of writing:
while(condition){ }
Write it like this:
while(condition){
}
However, using a single line if without curly braces, for example, like in if (condition) break;
will not cause any possible bug.
- Be careful changing functions' names. As stated before, you can change their return type or their parameters, but changing their name will make autotad indentify them as a new function. That said, for functions returning pointers, avoid writing ' * ' along the function's name, or autotad will indentify it as part of the function's name. For example, instead of writing:
char *a_string_function(){
...
return string;
}
Write it like this:
char* a_string_function(){
...
return string;
}
So there will be no possible mistake identifying what is the function's name and what is the return type.
- Use a Makefile. To avoid repetitive and boring commands, it is largely recommended to use this script in a Makefile before compiling all files. A simple Makefile would do:
c:
./autotad filename.c
gcc -o main main.c filename.c
So when make c
is called, autotad will be executed.
Given filename.c:
struct exStr{
int i;
char c;
};
void function1(int i){
...
return;
}
//AUTOTAD_PRIVATE
void function2(int i){
...
return;
}
int function3(float f){
...
return 1;
}
After executing ./autotad filename.c
, this will be the output in filename.h:
#ifndef FILENAME_H
#define FILENAME_H
/*
* Comment section
*/
typedef struct exStr ExStr;
/*
* Comment section
*/
void function1(int i);
/*
* Comment section
*/
int function3(float f);
#endif
Changing filename.h (editing comments and adding a new typedef):
#ifndef FILENAME_H
#define FILENAME_H
/*
* This struct
* is here as an example
*/
typedef struct exStr ExStr;
// this is the glorious function1
void function1(int i);
/* I'm adding this typedef here just for clarity */
typedef int elem;
// hey another function
float function3(float f);
#endif
And changing filename.c (removing function1 and adding function4):
struct exStr{
int i;
char c;
};
float function4(char *string){
...
return f_var;
}
//AUTOTAD_PRIVATE
void function2(int i){
...
return;
}
int function3(float f){
...
return 1;
}
After executing ./autotad filename.c comment-off
, the new filename.h will be:
#ifndef FILENAME_H
#define FILENAME_H
/* I'm adding this typedef here just for clarity */
typedef int elem;
/*
* This struct
* is here as an example
*/
typedef struct exStr ExStr;
void function4(int i);
// hey another function
float function3(float f);
#endif
In the same fashion, multiple files can be given via argv:
./autotad filename1.c filename2.c filename3.c comment-off
It will process each file, creating their respective header file. comment-off
will be applied to all three files.