⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generic.pm

📁 重新包装过的lxr
💻 PM
字号:
# -*- tab-width: 4 -*- ################################################# $Id: Generic.pm,v 1.1.1.1 2006/04/26 07:48:23 hellwolf Exp $## Implements generic support for any language that ectags can parse.# This may not be ideal support, but it should at least work until# someone writes better support.## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.package LXR::Lang::Generic;$CVSID = '$Id: Generic.pm,v 1.1.1.1 2006/04/26 07:48:23 hellwolf Exp $ ';use strict;use LXR::Common;use LXR::Lang;use vars qw($AUTOLOAD);my $generic_config;@LXR::Lang::Generic::ISA = ('LXR::Lang');sub new {	my ($proto, $pathname, $release, $lang) = @_;	my $class = ref($proto) || $proto;	my $self = {};	bless($self, $class);	$$self{'release'}  = $release;	$$self{'language'} = $lang;	read_config() unless defined $generic_config;	%$self = (%$self, %$generic_config);	# Set langid	$$self{'langid'} = $self->langinfo('langid');	die "No langid for language $lang" if !defined $self->langid;	return $self;}# This is only executed once, saving the overhead of processing the# config file each time.  Because it is only done once, we also use# this to check the version of ctags.sub read_config {	open(CONF, $config->genericconf) || die "Can't open " . $config->genericconf . ", $!";	local ($/) = undef;	my $config_contents = <CONF>;	$config_contents =~ /(.*)/s;	$config_contents = $1;                                                        #untaint it	$generic_config  = eval("\n#line 1 \"generic.conf\"\n" . $config_contents);	die($@) if $@;	close CONF;	# Setup the ctags to declid mapping	my $langmap = $generic_config->{'langmap'};	foreach my $lang (keys %$langmap) {		my $typemap = $langmap->{$lang}{'typemap'};		foreach my $type (keys %$typemap) {			$typemap->{$type} = $index->getdecid($langmap->{$lang}{'langid'}, $typemap->{$type});		}	}	my $ctags = $config->ectagsbin;	$ENV{'PATH'} = '/bin:/usr/local/bin:/usr/bin:/usr/sbin';	my $version = `$ctags --version`;	$version =~ /Exuberant ctags +(\d+)/i;	if ($1 < 5) {		die "Exuberant ctags version 5 or above required, found $version\n";	}}sub indexfile {	my ($self, $name, $path, $fileid, $index, $config) = @_;	my $typemap = $self->langinfo('typemap');	my $langforce = ${ $self->eclangnamemapping }{ $self->language };	if (!defined $langforce) {		$langforce = $self->language;	}	if ($config->ectagsbin) {		open(CTAGS,			join(" ",				$config->ectagsbin, $self->ectagsopts, "--excmd=number",				"--language-force=$langforce", "-f", "-", $path, "|")		  )		  or die "Can't run ectags, $!";		while (<CTAGS>) {			chomp;			my ($sym, $file, $line, $type, $ext) = split(/\t/, $_);			$line =~ s/;\"$//;  #" fix fontification			$ext  =~ /language:(\w+)/;			$type = $typemap->{$type};			if (!defined $type) {				print "Warning: Unknown type ", (split(/\t/, $_))[3], "\n";				next;			}			# TODO: can we make it more generic in parsing the extension fields?			if (defined($ext) && $ext =~ /^(struct|union|class|enum):(.*)/) {				$ext = $2;				$ext =~ s/::<anonymous>//g;			} else {				$ext = undef;			}			$index->index($sym, $fileid, $line, $self->langid, $type, $ext);		}		close(CTAGS);	}}# This method returns the regexps used by SimpleParse to break the# code into different blocks such as code, string, include, comment etc.# Since this depends on the language, it's configured via generic.confsub parsespec {	my ($self) = @_;	my @spec = $self->langinfo('spec');	return @spec;}# Process a chunk of code# Basically, look for anything that looks like an identifier, and if# it is then make it a hyperlink, unless it's a reserved word in this# language.# Parameters:#   $code - reference to the code to markup#   @itag - ???# TODO : Make the handling of identifier recognition language dependantsub processcode {	my ($self, $code) = @_;	my ($start, $id);	$$code =~ s {(^|[^\w\#])([\w~][\w]*)\b}	# Replace identifier by link unless it's a reserved word	{	  $1.		(		  grep(/^$2$/, $self->langinfo('reserved')) ? "<span class='reserved'>$2</span>" : 		  ($index->issymbol($2, $$self{'release'}) ? join($2, @{$$self{'itag'}}) : $2)		);	}ge;}## Find references to symbols in the file#sub referencefile {	my ($self, $name, $path, $fileid, $index, $config) = @_;	require LXR::SimpleParse;	# Use dummy tabwidth here since it doesn't matter for referencing	&LXR::SimpleParse::init(new FileHandle($path), 1, $self->parsespec);	my $linenum = 1;	my ($btype, $frag) = &LXR::SimpleParse::nextfrag;	my @lines;	my $ls;	while (defined($frag)) {		@lines = ($frag =~ /(.*?\n)/g, $frag =~ /([^\n]*)$/);		if (defined($btype)) {			if ($btype eq 'comment' or $btype eq 'string' or $btype eq 'include') {				$linenum += @lines - 1;			} else {				print "BTYPE was: $btype\n";			}		} else {			my $l;			my $string;			foreach $l (@lines) {				foreach (					$l =~ /(?:^|[^a-zA-Z_\#]) 	# Non-symbol chars.				 (\~?_*[a-zA-Z][a-zA-Z0-9_]*) # The symbol.				 \b/ogx				  )				{					$string = $_;					#		  print "considering $string\n";					if (!grep(/^$string$/, $self->langinfo('reserved'))						&& $index->issymbol($string))					{						#			print "adding $string to references\n";						$index->reference($string, $fileid, $linenum);					}				}				$linenum++;			}			$linenum--;		}		($btype, $frag) = &LXR::SimpleParse::nextfrag;	}	print("+++ $linenum\n");}# Autoload magic to allow access using $generic->variable syntax# blatently ripped from Config.pm - I still don't fully understand how# this works.sub variable {	my ($self, $var, $val) = @_;	$self->{variables}{$var}{value} = $val if defined($val);	return $self->{variables}{$var}{value}	  || $self->vardefault($var);}sub varexpand {	my ($self, $exp) = @_;	$exp =~ s/\$\{?(\w+)\}?/$self->variable($1)/ge;	return $exp;}sub value {	my ($self, $var) = @_;	if (exists($self->{$var})) {		my $val = $self->{$var};		if (ref($val) eq 'ARRAY') {			return map { $self->varexpand($_) } @$val;		} elsif (ref($val) eq 'CODE') {			return $val;		} else {			return $self->varexpand($val);		}	} else {		return undef;	}}sub AUTOLOAD {	my $self = shift;	(my $var = $AUTOLOAD) =~ s/.*:://;	my @val = $self->value($var);	if (ref($val[0]) eq 'CODE') {		return $val[0]->(@_);	} else {		return wantarray ? @val : $val[0];	}}sub langinfo {	my ($self, $item) = @_;	my $val;	my $map = $self->langmap;	die if !defined $map;	if (exists $$map{ $self->language }) {		$val = $$map{ $self->language };	} else {		return undef;	}	if (defined $val && defined $$val{$item}) {		if (ref($$val{$item}) eq 'ARRAY') {			return wantarray ? @{ $$val{$item} } : $$val{$item};		}		return $$val{$item};	} else {		return undef;	}}1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -