Navalla Supporting the evolution of a new free world.

 

C / C++ Formatter

DESCRIPTION

Adds syntax highlighting to C and C++ code.

SYNOPSIS

Perl

require( 'cpp_formatter.pl' );
# load c++ source code
# ...
print "<pre>", cpp_format( $cpp_code ), "</pre>\n";

Perl-CGI

<?perl
App::require_pl( 'cpp_formatter.pl' );
# load c++ source code
# ...
print "<pre>", cpp_format( $cpp_code ), "</pre>\n";
?>

COPYRIGHT

The library is free software. You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.

SOURCE CODE

# *******************
# * file: cpp_formatter.pl
# * license: GPL or Artistic License
# * copyright: Christian Mueller <chrmue[at]cpan.org>
# ******************************************************

use strict;
our( $Cpp_Pragmas, $Cpp_Keywords, $Cpp_CppKeywords );

sub cpp_format {
    my( $code, $pre ) = @_;
    my(
        $out, $str, $len, $space, $tab, $lf, $sub, $i, $m, $p1, $p2, $l,
        $type
    );
    defined $pre or $pre = 1;
    $out = '';
    $code =~ s/\r//gs;
    $len = length( $code );
    if( $pre ) {
        $space = ' ';
        $lf = "\n";
        $tab = "&nbsp;&nbsp;&nbsp;&nbsp;";
    }
    else {
        $space = '&nbsp;';
        $lf = "<br />\n";
        $tab = "&nbsp;&nbsp;&nbsp;&nbsp;";
    }
    for( $i = 0; $i < $len; ) {
        while( 1 ) {
            $m = substr( $code, $i, 1 );
            if( $m eq ' ' ) {
                $out .= $space;
            }
            elsif( $m eq "\n" ) {
                $out .= $lf;
            }
            elsif( $m eq "\t" ) {
                $out .= $tab;
            }
            else {
                last;
            }
            $i ++;
        }
        $l = cpp_get_token( $code, $i, $len, $type );
        $l = 1 if $l <= 0;
        $str = substr( $code, $i, $l );
        $str =~ s/\&/&amp;/gs;
        $str =~ s/\</&lt;/gs;
        $str =~ s/\>/&gt;/gs;
        $str =~ s/\t/$tab/gs;
        $out .= "<span class=\"Cpp_${type}\">${str}</span>";
        $i += $l;
        while( 1 ) {
            $m = substr( $code, $i, 1 );
            if( $m eq ' ' ) {
                $out .= $space;
            }
            elsif( $m eq "\n" ) {
                $out .= $lf;
            }
            elsif( $m eq "\t" ) {
                $out .= $tab;
            }
            else {
                last;
            }
            $i ++;
        }
    }
    return $out;
}

sub cpp_get_token {
    my( $str, $offset, $len, $type ) = @_;
    my( $i, $ch, $l, $br );
    $str = substr( $str, $offset );
    $ch = substr( $str, 0, 1 );
    if( $ch eq '/' ) {
        $ch = substr( $str, 1, 1 );
        if( $ch eq '/' ) {
            $i = index( $str, "\n", 2 );
            $_[3] = 'CMT';
            return $i >= 0 ? $i : $len - $offset;
        }
        elsif( $ch eq '*' ) {
            $i = index( $str, '*/', 2 );
            $_[3] = 'CMT';
            return $i >= 0 ? $i + 2 : $len - $offset;
        }
        $_[3] = 'OP';
        return 1;
    }
    elsif( $ch eq '(' || $ch eq ')' ) {
        $_[3] = 'PAR';
        return 1;
    }
    elsif( $ch eq '{' || $ch eq '}' ) {
        $_[3] = 'CBR';
        return 1;
    }
    elsif( $ch eq '[' || $ch eq ']' ) {
        $_[3] = 'SBR';
        return 1;
    }
    elsif( $ch eq ',' ) {
        $_[3] = 'COMMA';
        return 1;
    }
    elsif( $ch eq ';' ) {
        $_[3] = 'SEMI';
        return 1;
    }
    elsif( $ch eq '+' || $ch eq '%' || $ch eq '!' || $ch eq '&' ||
        $ch eq '|' || $ch eq ':' || $ch eq '>' || $ch eq '^' ||
        $ch eq '~' || $ch eq '.' || $ch eq '<' || $ch eq '*' ||
        $ch eq '?' || $ch eq '=' || $ch eq '-'
    ) {
        $_[3] = 'OP';
        return 1;
    }
    elsif( $ch eq '\\' ) {
        $_[3] = 'ESC';
        $ch = substr( $str, 1, 1 );
        return $ch eq '"' || $ch eq '\'' || $ch eq '/' ? 2 : 1;
    }
    elsif( $ch eq '"' || $ch eq '\'' ) {
        $_[3] = 'STR';
        $i = 0;
        while( 1 ) {
            # not perfect but fast
            $l = index( $str, "\n", $i + 1 );
            $i = index( $str, $ch, $i + 1 );
            return $l if $l >= 0 && $l < $i;
            return $len - $offset if $i < 0;
            if( substr( $str, $i - 1, 1 ) ne '\\' ||
                substr( $str, $i - 2, 1 ) eq '\\'
            ) { 
                return $i + 1;
            }
        }
    }
    elsif( $ch ge '0' && $ch le '9' ) {
        if( $ch eq '0' && substr( $str, 1, 1 ) eq 'x' ) {
            for( $i = 2; ; $i ++ ) {
                $ch = substr( $str, $i, 1 );
                if( ($ch lt '0' || $ch gt '9') &&
                    ($ch lt 'a' || $ch gt 'f') &&
                    ($ch lt 'A' || $ch gt 'F')
                ) {
                    last;
                }
            }
        }
        else {
            for( $i = 1; ; $i ++ ) {
                $ch = substr( $str, $i, 1 );
                last if $ch lt '0' || $ch gt '9' || $ch ne '.';
            }
        }
        $_[3] = 'NUM';
        return $i;
    }
    elsif( $ch eq '#' ) {
        if( $str =~ m/^\#\s*(\w+)/ ) {
            if( index( $Cpp_Pragmas, $1 ) >= 0 ) {
                $_[3] = 'PRAGMA';
            }
            else {
                $_[3] = 'ID';
            }
            return $+[0];
        }
        $_[3] = 'ID';
        return 1;
    }
    elsif( $str =~ m/^[\w\_]+/ ) {
        $ch = ' ' . $& . ' ';
        if( index( $Cpp_Keywords, $ch ) >= 0 ) {
            $_[3] = 'KWD';
        }
        elsif( index( $Cpp_CppKeywords, $ch ) >= 0 ) {
            $_[3] = 'KWD_CPP';
        }
        else {
            $_[3] = 'ID';
        }
        return $+[0];
    }
    $_[3] = 'ID';
    return 1;
}

$Cpp_Pragmas = q/
define elif else endif error if ifdef ifndef include include_next
line pragma undef
/;

$Cpp_Keywords = q/
__asm __based __cdecl __declspec __except __far __fastcall __finally __fortran
__huge __inline __int16
__int32 __int64 __int8 __interrupt __leave __loadds __near __pascal __saveregs
__segment __segname __self __stdcall __try __uuidof
auto
bool break
case char const continue
default defined do double
else enum extern
float for
goto
if int
long
register return
short signed sizeof static struct switch
typedef
union unsigned
void volatile
while
/;

$Cpp_CppKeywords = q/
__multiple_inheritance __single_inheritance __virtual_inheritance
catch class const_cast
delete dynamic_cast
explicit export
false friend
inline
mutable
namespace new
operator
private protected public
reinterpret_cast
static_cast
template this throw true try typeid typename
using
virtual
wchar_t
/;

$Cpp_Pragmas =~ tr/\n/ /;
$Cpp_Keywords =~ tr/\n/ /;
$Cpp_CppKeywords =~ tr/\n/ /;

1;

STYLESHEET FORMAT

The webpage uses the stylsheet settings below to highlight C++ source code.

span.Cpp_KWD, span.Cpp_CBR, span.Cpp_SEMI, span.Cpp_PRAGMA {
    color: blue;
}
span.Cpp_KWD_CPP, span.Cpp_NUM {
    color: red;
}
span.Cpp_STR {
    color: gray;
}
span.Cpp_CMT {
    color: teal;
}
span.Cpp_OP, span.Cpp_PAR, span.Cpp_SBR, span.Cpp_COMMA, span.Cpp_ESC {
    color: green;
}
 
UNITE FOR CHILDREN - UNITE AGAINST AIDS
 
Generated with Perl 5.10.0 and Perl-CGI 1.0 over FastCGI within 11.31ms in memory safe mode.