NAME
C::Utility - utilities for generating C programs
VERSION
This documents C::Utility version 0.008 corresponding to git commit 254fcf98172f70b3e91137bfb558afdff11a3e75 released on Tue Mar 27 13:49:35 2018 +0900.
DESCRIPTION
This module contains functions which assist in automatic generation of C programs. "convert_to_c_string" converts a string into a string with characters correctly escaped for use in a C program. "convert_to_c_string_pc" does the same thing plus escaping percent signs so that they may be used as format strings for printf. "ch_files" makes a header file name from a C file name. "escape_string" escapes double quotes. "valid_c_variable" checks whether a string is valid as a C variable. "wrapper_name" returns a C preprocessor wrapper name. "print_top_h_wrapper" prints the top wrapper for a header file, and "print_bottom_h_wrapper" prints the bottom part. "print_include" prints #include
statements. "hash_to_c_file" converts a Perl hash into a compilable C file with the keys as C strings. "line_directive" prints a C line directive. "brute_force_line" puts line directives on every line. "add_lines" converts the string #line to line directives as do "linein" and "lineout". "remove_quotes" removes leading and trailing quotes. "stamp_file" adds a printed stamp to a file handle.
FUNCTIONS
convert_to_c_string
my $c_string = convert_to_c_string ($perl_string);
This converts a Perl string into a C string. For example,
use C::Utility 'convert_to_c_string';
my $string =<<'EOF';
The quick "brown" fox\@farm
jumped %over the lazy dog.
EOF
print convert_to_c_string ($string);
produces output
"The quick \"brown\" fox\@farm\n"
"jumped %over the lazy dog.\n"
(This example is included as fox.pl in the distribution.)
It also removes backslashes from before the @ symbol, so \@ is transformed to @.
convert_to_c_string_pc
my $c_string = convert_to_c_string_pc ($string);
As "convert_to_c_string", but also with % (the percent character) converted to a double percent, %%. This is for generating strings which may be used as C format strings without generating an error because of embedded percent characters.
use C::Utility 'convert_to_c_string_pc';
my $string =<<'EOF';
The quick "brown" fox\@farm
jumped %over the lazy dog.
EOF
print convert_to_c_string_pc ($string);
produces output
"The quick \"brown\" fox\@farm\n"
"jumped %%over the lazy dog.\n"
(This example is included as fox-pc.pl in the distribution.)
c_string
Alias for "convert_to_c_string".
ch_files
my $hfile = ch_files ($c_file_name);
This makes a .h filename from a .c filename, and backs up both C and .h files using File::Versions. See also "c_to_h_name".
escape_string
my $escaped_string = escape_string ($normal_string);
Escape double quotes (") in a string with a backslash.
c_to_h_name
my $h_file = c_to_h_name ("frog.c");
# $h_file = "frog.h".
Make a .h file name from a .c file name.
valid_c_variable
valid_c_variable ($variable_name);
This returns 1 if $variable_name
is a valid C variable, the undefined value otherwise. It tests for two things, first that the argument only contains the allowed characters for a C variable, and second that the argument is not a C keyword like "goto" or "volatile".
wrapper_name
my $wrapper = wrapper_name ($file_name);
Given a file name, this returns a suitable C preprocessor wrapper name based on the file name. The preprocessor wrapper name is just the uppercase version of the file name with hyphens and dots replaced with underscores. This does not strip out directory paths from $file_name
, since it would usually be an error to include a particular directory path in a header file's wrapper.
print_top_h_wrapper
print_top_h_wrapper ($file_handle, $file_name);
# Prints #ifndef wrapper at top of file.
Print an "include wrapper" for a .h file to $file_handle
. For example,
#ifndef MY_FILE
#define MY_FILE
The name of the wrapper comes from "wrapper_name" applied to $file_name
. If $file_handle
is a scalar reference, this concatenates the wrapper to the scalar.
See also "print_bottom_h_wrapper".
print_bottom_h_wrapper
print_bottom_h_wrapper ($file_handle, $file_name);
Print the bottom part of an include wrapper for a .h file to $file_handle
.
The name of the wrapper comes from "wrapper_name" applied to $file_name
.
If $file_handle
is a scalar reference, this concatenates the wrapper to the scalar.
See also "print_top_h_wrapper".
print_include
print_include ($file_handle, $file_name);
Print an #include statement for a .h file named $file_name
to $file_handle
:
#include "file.h"
hash_to_c_file
my $h_file = hash_to_c_file ($c_file_name, \%hash);
Output a Perl hash as a set of const char * strings. For example,
use FindBin '$Bin';
use C::Utility 'hash_to_c_file';
use File::Slurper 'read_text';
my $file = "$Bin/my.c";
my $hfile = hash_to_c_file ($file, { version => '0.01', author => 'Michael Caine' });
print "C file:\n\n";
print read_text ($file);
print "\nHeader file:\n\n";
print read_text ($hfile);
unlink $file, $hfile or die $!;
produces output
C file:
#include "my.h"
const char * author = "Michael Caine";
const char * version = "0.01";
Header file:
#ifndef MY_H
#define MY_H
extern const char * author; /* "Michael Caine" */
extern const char * version; /* "0.01" */
#endif /* MY_H */
(This example is included as michael-caine.pl in the distribution.)
The keys of the hash are checked with "valid_c_variable", and the routine dies if they are not valid C variable names.
A third argument, $prefix
, contains an optional prefix to add to all the variable names:
hash_to_c_file ('that.c', {ok => 'yes'}, 'super_');
prints
const char * super_ok = "yes";
The behaviour of returning the name of the header file was added in version 0.006.
line_directive
line_directive ($fh, 42, "file.x")
prints
#line 42 "file.x"
to $fh
. This prints a C preprocessor line directive to the file specified by $fh
. If $fh
is a scalar reference, it concatenates the line directive to the end of it.
use C::Utility 'line_directive';
my $out = '';
line_directive (\$out, 99, "balloons.c");
print $out;
produces output
#line 99 "balloons.c"
(This example is included as line-directive.pl in the distribution.)
brute_force_line
brute_force_line ($input_file, $output_file);
Read $input_file
, put #line directives on every single line, and write that to $output_file
. This is a fix used to force line numbers into a file before it is processed by Template.
add_lines
my $text = add_lines ($file);
Read $file
, and replace strings of the form #line in the file with a C-style line directive using $file
before it is processed by Template. Also add a line directive to the first line of the file. $file
must be in the UTF-8 encoding. The line directives are given the full path name of the file using "rel2abs" in File::Spec.
remove_quotes
my $unquoted_string = remove_quotes ($string);
This removes the leading and trailing quotes from $string
. It also removes the "joining quotes" in composite C strings. Thus input of the form "composite " "C" " string" is converted into composite C string without the quotes.
linein
my $intext = linein ($infile);
Given a file $infile, this opens the file, reads it in, replaces the text #linein
in the file with a C line directive referring to the original file, then returns the complete text as its return value.
lineout
lineout ($outtext, $outfile);
Given a C output text $outtext
and a file name $outfile, this writes out the text to $outfile, replacing the text #lineout
with an appropriate line directive using $outfile
as the file name and the lines of the file as the line numbers.
use FindBin '$Bin';
use C::Utility 'lineout';
use File::Slurper 'read_text';
my $file = "$Bin/some.c";
my $c = <<EOF;
static void unknown (int x) { return x; }
#lineout
int main () { return 0; }
EOF
lineout ($c, $file);
print read_text ($file);
unlink $file or die $!;
produces output
static void unknown (int x) { return x; }
#line 2 "/usr/home/ben/projects/c-utility/examples/some.c"
int main () { return 0; }
(This example is included as lineout.pl in the distribution.)
stamp_file
stamp_file ($fh);
Add a stamp to file handle $fh
containing the name of the program which created it, and the time of generation.
The name of the C file output can be added as a second argument:
stamp_file ($fh, $name);
If $fh
is a scalar reference, the stamp is concatenated to it.
use C::Utility 'stamp_file';
my $out = '';
stamp_file (\$out);
print $out;
produces output
/*
This C file was generated by /usr/home/ben/projects/c-utility/examples/stamp-file.pl at Fri Oct 13 18:20:44 2017.
*/
(This example is included as stamp-file.pl in the distribution.)
This function was added in version 0.006.
read_includes
my $includes = read_includes ($file);
Read lines of the form
#include "some.h"
from $file
and return the list of included files as an array reference.
This function was added in version 0.008.
DEPENDENCIES
- Carp
-
Carp is used to report errors.
- File::Spec
-
File::Spec is used to get the base name of the file from the argument to "hash_to_c_file", and to get the absolute name of the file in "add_lines".
- File::Versions
-
File::Versions is used to back up files
- C::Tokenize
-
C::Tokenize is used by "read_includes".
- File::Slurper
-
File::Slurper is used by "read_includes".
HISTORY
Most of the functions in this module are for supporting automated C code generators.
C::Utility was on CPAN, but then deleted between version 0.005 and version 0.006. I don't know of anyone who was using the module, but I decided to restore it to CPAN anyway, since I'm still using and maintaining it, and it might be useful to somebody.
AUTHOR
Ben Bullock, <bkb@cpan.org>
COPYRIGHT & LICENCE
This package and associated files are copyright (C) 2012-2018 Ben Bullock.
You can use, copy, modify and redistribute this package and associated files under the Perl Artistic Licence or the GNU General Public Licence.