diff options
Diffstat (limited to 'lib/LXRng/Lang')
-rw-r--r-- | lib/LXRng/Lang/C.pm | 137 | ||||
-rw-r--r-- | lib/LXRng/Lang/Generic.pm | 22 | ||||
-rw-r--r-- | lib/LXRng/Lang/Undefined.pm | 45 |
3 files changed, 204 insertions, 0 deletions
diff --git a/lib/LXRng/Lang/C.pm b/lib/LXRng/Lang/C.pm new file mode 100644 index 0000000..c88f424 --- /dev/null +++ b/lib/LXRng/Lang/C.pm @@ -0,0 +1,137 @@ +package LXRng::Lang::C; + +use strict; +use Subst::Complex; + +use base qw(LXRng::Lang::Generic); + + +sub doindex { + return 1; +} + +sub ctagslangname { + return 'c'; +} + +sub ctagsopts { + return ('--c-types=+lpx'); +} + +sub pathexp { + return qr/\.[ch]$/; +} + +my $_identifier_re = qr( + (?m:^|(?<=[^a-zA-Z0-9_\#])) # Non-symbol chars. + (_*[a-zA-Z][a-zA-Z0-9_]*) # The symbol. + \b + )x; + +sub identifier_re { + return $_identifier_re; +} + +my $_reserved ||= { map { $_ => 1 } + qw(asm auto break case char continue default do + double else enum extern float for fortran goto + if int long register return short signed sizeof + static struct switch typedef union unsigned + void volatile while + #define #else #endif #if #ifdef #ifndef #include + #undef)}; + +sub reserved { + return $_reserved; +} + +sub parsespec { + return ['atom', '\\\\.', undef, + 'comment', '/\*', '\*/', + 'comment', '//', "\$", + 'string', '"', '"', + 'string', "'", "'", + 'include', '#\s*include', "\$"]; +} + +sub typemap { + return { + 'c' => 'class', + 'd' => 'macro (un)definition', + 'e' => 'enumerator', + 'f' => 'function definition', + 'g' => 'enumeration name', + 'm' => 'class, struct, or union member', + 'n' => 'namespace', + 'p' => 'function prototype or declaration', + 's' => 'structure name', + 't' => 'typedef', + 'u' => 'union name', + 'v' => 'variable definition', + 'x' => 'extern or forward variable declaration', + 'i' => 'interface'}; +} + +sub markuphandlers { + my ($self, $context, $node, $markup) = @_; + + my $index = $context->config->{'index'}; + my $syms = $index->symbols_by_file($context->tree, $context->release, + $node->name); + my $idre = $self->identifier_re(); + + my %subst; + + my $format_newline = $markup->make_format_newline($node); + $subst{'comment'} = new Subst::Complex + qr/\n/ => $format_newline, + qr/[^\n]+/ => sub { $markup->format_comment(@_) }; + + $subst{'string'} = new Subst::Complex + qr/\n/ => $format_newline, + qr/[^\n\"\']+/ => sub { $markup->format_string(@_) }; + + $subst{'include'} = new Subst::Complex + qr/\n/ => $format_newline, + qr/(include\s*\")(.*?)(\")/ => sub { + $markup->format_include([$self->resolve_include($context, $node, @_)], + @_) }, + + qr/(include\s*\<)(.*?)(\>)/ => sub { + $markup->format_include([$self->resolve_include($context, $node, @_)], + @_) }; + + $subst{'code'} = new Subst::Complex + qr/\n/ => $format_newline, + qr/[^\n]*/ => sub { $markup->format_code($idre, $syms, @_) }; + + $subst{'start'} = new Subst::Complex + qr/^/ => $format_newline; + + return \%subst; +} + +sub resolve_include { + my ($self, $context, $node, $frag) = @_; + + if ($frag =~ /include\s+<(.*?)>/) { + return $self->expand_include($context, $node, $1); + } + elsif ($frag =~ /include\s+\"(.*?)\"/) { + my $incl = $1; + my $bare = $1; + my $name = $node->name(); + if ($name =~ /(.*\/)/) { + $incl = $1.$incl; + 1 while $incl =~ s,/[^/]+/../,/,; + + my $file = $context->config->{'repository'}->node($incl, $context->release); + return $incl if $file; + return $self->expand_include($context, $node, $bare); + } + } + + return (); +} + +1; diff --git a/lib/LXRng/Lang/Generic.pm b/lib/LXRng/Lang/Generic.pm new file mode 100644 index 0000000..29443f4 --- /dev/null +++ b/lib/LXRng/Lang/Generic.pm @@ -0,0 +1,22 @@ +package LXRng::Lang::Generic; + +use strict; + +sub expand_include { + my ($self, $context, $node, $include) = @_; + + return () unless $context->config->{'include_maps'}; + + my $file = $node->name(); + foreach my $map (@{$context->config->{'include_maps'}}) { + my @key = $file =~ /($$map[0])/ or next; + my @val = $include =~ /($$map[1])/ or next; + shift(@key); + shift(@val); + my @paths = $$map[2]->(@key, @val); + + return map { /([^\/].*)/ ? $1 : $_ } @paths; + } +} + +1; diff --git a/lib/LXRng/Lang/Undefined.pm b/lib/LXRng/Lang/Undefined.pm new file mode 100644 index 0000000..c4c3c72 --- /dev/null +++ b/lib/LXRng/Lang/Undefined.pm @@ -0,0 +1,45 @@ +package LXRng::Lang::Undefined; + +use strict; +use Subst::Complex; + +use base qw(LXRng::Lang::Generic); + + +sub doindex { + return 0; +} + +sub pathexp { + return qr/$/; +} + +sub reserved { + return {}; +} + +sub parsespec { + return ['atom', '\\\\.', undef]; +} + +sub typemap { + return {}; +} + +sub markuphandlers { + my ($self, $context, $node, $markup) = @_; + + my $format_newline = $markup->make_format_newline($node); + + my %subst; + $subst{'code'} = new Subst::Complex + qr/\n/ => $format_newline, + qr/[^\n]*/ => sub { $markup->format_raw(@_) }; + + $subst{'start'} = new Subst::Complex + qr/^/ => $format_newline; + + return \%subst; +} + +1; |