Config.pm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. # $Id: Config.pm,v 1.8 2006/12/30 02:53:48 reed%reedloden.com Exp $
  2. package LXR::Config;
  3. use LXR::Common;
  4. require Exporter;
  5. @ISA = qw(Exporter);
  6. # @EXPORT = '';
  7. $confname = 'lxr.conf';
  8. sub new {
  9. my ($class, @parms) = @_;
  10. my $self = {};
  11. bless($self);
  12. $self->_initialize(@parms);
  13. return(treeify($self));
  14. }
  15. my %aliases;
  16. sub resolvealias {
  17. my ($orig, $xp) = @_;
  18. my $real = $orig;
  19. my %seen = ();
  20. while (defined $aliases{$real}) {
  21. if (defined $xp) {
  22. return ${$xp}{$real} if (defined ${$xp}{$real});
  23. }
  24. # detect alias loops
  25. if ($seen{$aliases{$real}}) {
  26. warn "alias loops: $real <=> " . $aliases{$real};
  27. return $real;
  28. }
  29. $real = $aliases{$real};
  30. $seen{$real} = 1;
  31. }
  32. return $real;
  33. }
  34. sub treeify {
  35. my ($self) = @_;
  36. #If there are multiple definitions of sourceroot in lxr.conf then
  37. #this installation is configured for multiple trees. For a single
  38. #tree "sourceroot" is a single directory where the source can be
  39. #found. If the file contains multiple definitions of sourceroot then
  40. #each definition is a tree,directory pair.
  41. #remove the extra space that i stupidly added when parsing lxr.conf
  42. $self->{'sourceroot'} =~ s/^\s+//;
  43. $self->{'sourceprefix'} =~ s/^\s+//;
  44. $self->{'rewriteurl'} =~ s/^\s+//;
  45. my $baseurl = $self->{'baseurl'};
  46. if ($baseurl =~ m!^https?://([^/]+)(/.*)!) {
  47. my ($hostport, $path) = ($1, $2);
  48. my $https = env_or('HTTPS', 0);
  49. my $server_name = env_or('SERVER_NAME', 'localhost');
  50. my $default_port = $https ? 443 : 80;
  51. my $env_port = env_or('SERVER_PORT', '80');
  52. my $port = $default_port eq $env_port ? '' : ':' . $env_port;
  53. my $proto = $default_port == 443 ? 'https://' : 'http://';
  54. $baseurl = join('',
  55. $proto,
  56. $server_name,
  57. $port,
  58. $path);
  59. } else {
  60. my $https = env_or('HTTPS', 0);
  61. $baseurl = ($https ? 'https://' : 'http://') . $baseurl;
  62. }
  63. $self->{'baseurl'} = $baseurl;
  64. if ((($self->{'virtroot'} || '') eq '') &&
  65. $baseurl =~ m{https?://[^/]*?(/.+?)/?$}) {
  66. # auto detect virtroot
  67. $self->{'virtroot'} = $1;
  68. }
  69. if ($self->{'sourceroot'} =~ /\S\s+\S/) {
  70. $self->{'oldroot'} = $self->{'sourceroot'};
  71. #since there's whitespace within the root directory definition
  72. #there is one or more tree defined. (Using directory names with
  73. #embedded spaces here would be a bad thing.)
  74. my %treehash = split(/\s+/, $self->{'sourceroot'});
  75. $self->{'alias'} =~ s/^\s+//;
  76. %aliases = split(/\s+/, $self->{'alias'});
  77. foreach my $alias (keys %aliases) {
  78. if (defined $treehash{$alias}) {
  79. if (0) {
  80. print STDERR ("Defining an alias for an existing tree '$alias'");
  81. }
  82. next;
  83. }
  84. $treehash{$alias} = $treehash{resolvealias($alias)};
  85. }
  86. $self->{'treehash'} = \%treehash;
  87. my %rewritehash = split(/\s+/, $self->{'rewriteurl'});
  88. my @treelist = sort keys %treehash;
  89. $self->{'trees'} = \@treelist;
  90. {
  91. # To compute which tree we're looking at, grab the second to last
  92. # component from the script name which will be of the form:
  93. # /seamonkey/source
  94. my $treename = $ENV{'SCRIPT_NAME'};
  95. $treename =~ s|.*/([^/]+)/[^/]*|$1|;
  96. my $root = $treehash{$treename};
  97. if (defined $root) {
  98. $self->{'treename'} = $treename;
  99. # Match the tree name against our list of trees and extract
  100. # the proper directory. Set "sourceroot" to this directory.
  101. $self->{'sourceroot'} = $root;
  102. #set srcrootname to tree name
  103. $self->{'srcrootname'} = $treename;
  104. #set rewriteurl to tree name
  105. $self->{'rewriteurl'} = $rewritehash{$treename};
  106. #append tree name to virtroot
  107. $self->{'virtroot'} .= '/' . $treename;
  108. #store the original baseurl as realbaseurl for use by index.cgi
  109. $self->{'realbaseurl'} = $self->{'baseurl'};
  110. #append tree name to baseurl
  111. $self->{'baseurl'} .= $treename;
  112. #append tree name to dbdir
  113. $self->{'dbdir'} .= "/" . (resolvealias($treename));
  114. }
  115. }
  116. #find the cvsroot to sed in proper bonsai url
  117. my $path = $self->{'sourceroot'};
  118. if (defined $path) {
  119. my @pathdirs = split(/\//, $path);
  120. my $pathnum = @pathdirs;
  121. $self->{'bonsaicvsroot'} = $pathdirs[$pathnum - 1];
  122. }
  123. my %treehashp = split(/\s+/, $self->{'sourceprefix'});
  124. foreach my $alias (keys %aliases) {
  125. if (defined $treehash{$alias}) {
  126. if (0) {
  127. print STDERR ("Defining an alias for an existing sourceprefix '$alias'");
  128. }
  129. next;
  130. }
  131. $treehashp{$alias} = $treehash{resolvealias($alias, \%treehashp)};
  132. }
  133. my $treename = $self->{'treename'};
  134. my $sourceprefix;
  135. if (defined $treename) {
  136. $sourceprefix = $treehashp{resolvealias($treename, \%treehashp)};
  137. }
  138. $self->{'sourceprefix'} = $sourceprefix;
  139. } else {
  140. $self->{'treename'} = '';
  141. }
  142. return($self);
  143. }
  144. sub makevalueset {
  145. my $val = shift;
  146. my @valset;
  147. if ($val =~ /^\s*\(([^\)]*)\)/) {
  148. @valset = split(/\s*,\s*/,$1);
  149. } elsif ($val =~ /^\s*\[\s*(\S*)\s*\]/) {
  150. if (open(VALUESET, "$1")) {
  151. $val = join('',<VALUESET>);
  152. close(VALUESET);
  153. @valset = split("\n",$val);
  154. } else {
  155. @valset = ();
  156. }
  157. } else {
  158. @valset = ();
  159. }
  160. return(@valset);
  161. }
  162. sub parseconf {
  163. my $line = shift;
  164. my @items = ();
  165. my $item;
  166. foreach $item ($line =~ /\s*(\[.*?\]|\(.*?\)|\".*?\"|\S+)\s*(?:$|,)/g) {
  167. if ($item =~ /^\[\s*(.*?)\s*\]/) {
  168. if (open(LISTF, "$1")) {
  169. $item = '('.join(',',<LISTF>).')';
  170. close(LISTF);
  171. } else {
  172. $item = '';
  173. }
  174. }
  175. if ($item =~ s/^\((.*)\)/$1/s) {
  176. $item = join("\0",($item =~ /\s*(\S+)\s*(?:$|,)/gs));
  177. }
  178. $item =~ s/^\"(.*)\"/$1/;
  179. push(@items, $item);
  180. }
  181. return(@items);
  182. }
  183. sub _initialize {
  184. my ($self, $conf) = @_;
  185. my ($dir, $arg);
  186. unless ($conf) {
  187. $conf = $0;
  188. if ($conf =~ m{/}) {
  189. $conf =~ s{/[^/]+$}{/};
  190. } else {
  191. $conf = './';
  192. }
  193. $conf .= $confname;
  194. }
  195. unless (open(CONFIG, $conf)) {
  196. &fatal("Couldn't open configuration file \"$conf\".");
  197. }
  198. $self->{'sourceroot'} = '';
  199. $self->{'sourceprefix'} = '';
  200. $self->{'rewriteurl'} = '';
  201. $self->{'alias'} = '';
  202. { my @ary = ();
  203. $self->{'variables'} = \@ary;
  204. }
  205. while (<CONFIG>) {
  206. s/\s*\#.*|\s+$//;
  207. next if /^$/;
  208. if (($dir, $arg) = /^\s*(\S+):\s*(.*)/) {
  209. if ($dir eq 'variable') {
  210. @args = &parseconf($arg);
  211. if ($args[0]) {
  212. $self->{vardescr}->{$args[0]} = $args[1];
  213. push(@{$self->{variables}},$args[0]);
  214. $self->{varrange}->{$args[0]} = [split(/\0/,$args[2])];
  215. $self->{vdefault}->{$args[0]} = $args[3];
  216. $self->{vdefault}->{$args[0]} ||=
  217. $self->{varrange}->{$args[0]}->[0];
  218. $self->{variable}->{$args[0]} =
  219. $self->{vdefault}->{$args[0]};
  220. }
  221. } elsif ($dir eq 'sourceroot' ||
  222. $dir eq 'sourceprefix' ||
  223. $dir eq 'sourceoverlay' ||
  224. $dir eq 'alias' ||
  225. $dir eq 'srcrootname' ||
  226. $dir eq 'virtroot' ||
  227. $dir eq 'baseurl' ||
  228. $dir eq 'rewriteurl' ||
  229. $dir eq 'incprefix' ||
  230. $dir eq 'dbdir' ||
  231. $dir eq 'bonsaihome' ||
  232. $dir eq 'glimpsebin' ||
  233. $dir eq 'htmlhead' ||
  234. $dir eq 'htmltail' ||
  235. $dir eq 'sourcehead' ||
  236. $dir eq 'sourcetail' ||
  237. $dir eq 'sourcedirhead' ||
  238. $dir eq 'sourcedirtail' ||
  239. $dir eq 'diffhead' ||
  240. $dir eq 'difftail' ||
  241. $dir eq 'findhead' ||
  242. $dir eq 'findtail' ||
  243. $dir eq 'identhead' ||
  244. $dir eq 'identref' ||
  245. $dir eq 'identtail' ||
  246. $dir eq 'searchhead' ||
  247. $dir eq 'searchtail' ||
  248. $dir eq 'htmldir' ||
  249. $dir eq 'treechooser' ||
  250. $dir eq 'treeentry' ||
  251. $dir eq 'revchooser' ||
  252. $dir eq 'reventry' ||
  253. 0) {
  254. if ($arg =~ /([^\n]+)/) {
  255. if ($dir eq 'sourceroot' ||
  256. $dir eq 'sourceprefix' ||
  257. $dir eq 'rewriteurl' ||
  258. $dir eq 'alias') {
  259. $self->{$dir} .= " " . $1;
  260. }else{
  261. $self->{$dir} = $1;
  262. }
  263. }
  264. } elsif ($dir eq 'map') {
  265. if ($arg =~ /(\S+)\s+(\S+)/) {
  266. push(@{$self->{maplist}}, [$1,$2]);
  267. }
  268. } else {
  269. &warning("Unknown config directive (\"$dir\")");
  270. }
  271. next;
  272. }
  273. &warning("Noise in config file (\"$_\")");
  274. }
  275. }
  276. sub allvariables {
  277. my $self = shift;
  278. return(@{$self->{variables}});
  279. }
  280. sub variable {
  281. my ($self, $var, $val) = @_;
  282. $self->{variable}->{$var} = $val if defined($val);
  283. return($self->{variable}->{$var});
  284. }
  285. sub vardefault {
  286. my ($self, $var) = @_;
  287. return($self->{vdefault}->{$var});
  288. }
  289. sub vardescription {
  290. my ($self, $var, $val) = @_;
  291. $self->{vardescr}->{$var} = $val if defined($val);
  292. return($self->{vardescr}->{$var});
  293. }
  294. sub varrange {
  295. my ($self, $var) = @_;
  296. return(@{$self->{varrange}->{$var}});
  297. }
  298. sub varexpand {
  299. my ($self, $exp) = @_;
  300. $exp =~ s/\$\{?(\w+)\}?/$self->{variable}->{$1}/g;
  301. return($exp);
  302. }
  303. sub varexpandit {
  304. my ($self, $item) = @_;
  305. return undef unless defined $self->{$item};
  306. return($self->varexpand($self->{$item}));
  307. }
  308. sub baseurl {
  309. my $self = shift;
  310. return varexpandit($self, 'baseurl');
  311. }
  312. sub realbaseurl {
  313. my $self = shift;
  314. return varexpandit($self, 'realbaseurl') || varexpandit($self, 'baseurl');
  315. }
  316. sub sourceroot {
  317. my $self = shift;
  318. return varexpandit($self, 'sourceroot');
  319. }
  320. sub treehash {
  321. my $self = shift;
  322. return %self->treehash;
  323. }
  324. sub prefix {
  325. my $self = shift;
  326. my $prefix = $self->{'sourceprefix'};
  327. return $prefix;
  328. }
  329. sub rewriteurl {
  330. my $self = shift;
  331. my $prefix = $self->{'rewriteurl'};
  332. return $prefix;
  333. }
  334. sub sourcerootname {
  335. my $self = shift;
  336. return($self->varexpand(defined $self->{'sourceprefix'} ? $self->{'sourceprefix'} : $self->{'srcrootname'}));
  337. }
  338. sub virtroot {
  339. my $self = shift;
  340. return varexpandit($self, 'virtroot');
  341. }
  342. sub incprefix {
  343. my $self = shift;
  344. return varexpandit($self, 'incprefix');
  345. }
  346. sub bonsaihome {
  347. my $self = shift;
  348. return varexpandit($self, 'bonsaihome');
  349. }
  350. sub dbdir {
  351. my $self = shift;
  352. return varexpandit($self, 'dbdir');
  353. }
  354. sub glimpsebin {
  355. my $self = shift;
  356. return varexpandit($self, 'glimpsebin');
  357. }
  358. sub htmlhead {
  359. my $self = shift;
  360. return varexpandit($self, 'htmlhead');
  361. }
  362. sub htmltail {
  363. my $self = shift;
  364. return varexpandit($self, 'htmltail');
  365. }
  366. sub diffhead {
  367. my $self = shift;
  368. return varexpandit($self, 'diffhead');
  369. }
  370. sub difftail {
  371. my $self = shift;
  372. return varexpandit($self, 'difftail');
  373. }
  374. sub sourcehead {
  375. my $self = shift;
  376. return varexpandit($self, 'sourcehead');
  377. }
  378. sub sourcetail {
  379. my $self = shift;
  380. return varexpandit($self, 'sourcetail');
  381. }
  382. sub sourcedirhead {
  383. my $self = shift;
  384. return varexpandit($self, 'sourcedirhead');
  385. }
  386. sub sourcedirtail {
  387. my $self = shift;
  388. return varexpandit($self, 'sourcedirtail');
  389. }
  390. sub findhead {
  391. my $self = shift;
  392. return varexpandit($self, 'findhead');
  393. }
  394. sub findtail {
  395. my $self = shift;
  396. return varexpandit($self, 'findtail');
  397. }
  398. sub identhead {
  399. my $self = shift;
  400. return varexpandit($self, 'identhead');
  401. }
  402. sub identref {
  403. my $self = shift;
  404. return varexpandit($self, 'identref');
  405. }
  406. sub identtail {
  407. my $self = shift;
  408. return varexpandit($self, 'identtail');
  409. }
  410. sub searchhead {
  411. my $self = shift;
  412. return varexpandit($self, 'searchhead');
  413. }
  414. sub searchtail {
  415. my $self = shift;
  416. return varexpandit($self, 'searchtail');
  417. }
  418. sub htmldir {
  419. my $self = shift;
  420. return varexpandit($self, 'htmldir');
  421. }
  422. sub treechooser {
  423. my $self = shift;
  424. return varexpandit($self, 'treechooser');
  425. }
  426. sub treeentry {
  427. my $self = shift;
  428. return varexpandit($self, 'treeentry');
  429. }
  430. sub revchooser {
  431. my $self = shift;
  432. return varexpandit($self, 'revchooser');
  433. }
  434. sub reventry {
  435. my $self = shift;
  436. return varexpandit($self, 'reventry');
  437. }
  438. sub mappath {
  439. my ($self, $path, @args) = @_;
  440. my (%oldvars) = %{$self->{variable}};
  441. my ($m);
  442. foreach $m (@args) {
  443. $self->{variable}->{$1} = $2 if $m =~ /(.*?)=(.*)/;
  444. }
  445. foreach $m (@{$self->{maplist}}) {
  446. $path =~ s/$m->[0]/$self->varexpand($m->[1])/e;
  447. }
  448. $self->{variable} = {%oldvars};
  449. return($path);
  450. }
  451. #sub mappath {
  452. # my ($self, $path) = @_;
  453. # my ($m);
  454. #
  455. # foreach $m (@{$self->{maplist}}) {
  456. # $path =~ s/$m->[0]/$self->varexpand($m->[1])/e;
  457. # }
  458. # return($path);
  459. #}
  460. 1;